blob: 29054aa53fac61193e183d48d4baf27c01705d1f [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tv.data;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.KeyEvent;
import com.android.tv.util.StringUtils;
import java.util.Objects;
/**
* A convenience class to handle channel number.
*/
public final class ChannelNumber implements Comparable<ChannelNumber> {
private static final int[] CHANNEL_DELIMITER_KEYCODES = {
KeyEvent.KEYCODE_MINUS, KeyEvent.KEYCODE_NUMPAD_SUBTRACT, KeyEvent.KEYCODE_PERIOD,
KeyEvent.KEYCODE_NUMPAD_DOT, KeyEvent.KEYCODE_SPACE
};
/** The major part of the channel number. */
public String majorNumber;
/** The flag which indicates whether it has a delimiter or not. */
public boolean hasDelimiter;
/** The major part of the channel number. */
public String minorNumber;
public ChannelNumber() {
reset();
}
public void reset() {
setChannelNumber("", false, "");
}
private void setChannelNumber(String majorNumber, boolean hasDelimiter, String minorNumber) {
this.majorNumber = majorNumber;
this.hasDelimiter = hasDelimiter;
this.minorNumber = minorNumber;
}
@Override
public String toString() {
if (hasDelimiter) {
return majorNumber + Channel.CHANNEL_NUMBER_DELIMITER + minorNumber;
}
return majorNumber;
}
@Override
public int compareTo(@NonNull ChannelNumber another) {
int major = Integer.parseInt(majorNumber);
int minor = hasDelimiter ? Integer.parseInt(minorNumber) : 0;
int opponentMajor = Integer.parseInt(another.majorNumber);
int opponentMinor = another.hasDelimiter
? Integer.parseInt(another.minorNumber) : 0;
if (major == opponentMajor) {
return minor - opponentMinor;
}
return major - opponentMajor;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ChannelNumber) {
ChannelNumber channelNumber = (ChannelNumber) obj;
return TextUtils.equals(majorNumber, channelNumber.majorNumber)
&& TextUtils.equals(minorNumber, channelNumber.minorNumber)
&& hasDelimiter == channelNumber.hasDelimiter;
}
return super.equals(obj);
}
@Override
public int hashCode() {
return Objects.hash(majorNumber, hasDelimiter, minorNumber);
}
public static boolean isChannelNumberDelimiterKey(int keyCode) {
for (int delimiterKeyCode : CHANNEL_DELIMITER_KEYCODES) {
if (delimiterKeyCode == keyCode) {
return true;
}
}
return false;
}
/**
* Returns the ChannelNumber instance.
* <p>
* Note that all the channel number argument should be normalized by
* {@link Channel#normalizeDisplayNumber}. The channels retrieved from
* {@link ChannelDataManager} are already normalized.
*/
public static ChannelNumber parseChannelNumber(String number) {
if (number == null) {
return null;
}
ChannelNumber ret = new ChannelNumber();
int indexOfDelimiter = number.indexOf(Channel.CHANNEL_NUMBER_DELIMITER);
if (indexOfDelimiter == 0 || indexOfDelimiter == number.length() - 1) {
return null;
} else if (indexOfDelimiter < 0) {
ret.majorNumber = number;
if (!isInteger(ret.majorNumber)) {
return null;
}
} else {
ret.hasDelimiter = true;
ret.majorNumber = number.substring(0, indexOfDelimiter);
ret.minorNumber = number.substring(indexOfDelimiter + 1);
if (!isInteger(ret.majorNumber) || !isInteger(ret.minorNumber)) {
return null;
}
}
return ret;
}
/**
* Compares the channel numbers.
* <p>
* Note that all the channel number arguments should be normalized by
* {@link Channel#normalizeDisplayNumber}. The channels retrieved from
* {@link ChannelDataManager} are already normalized.
*/
public static int compare(String lhs, String rhs) {
ChannelNumber lhsNumber = parseChannelNumber(lhs);
ChannelNumber rhsNumber = parseChannelNumber(rhs);
// Null first
if (lhsNumber == null && rhsNumber == null) {
return StringUtils.compare(lhs, rhs);
} else if (lhsNumber == null /* && rhsNumber != null */) {
return -1;
} else if (rhsNumber == null) {
return 1;
}
return lhsNumber.compareTo(rhsNumber);
}
private static boolean isInteger(String string) {
try {
Integer.parseInt(string);
} catch(NumberFormatException | NullPointerException e) {
return false;
}
return true;
}
}