1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.data; 18 19 import android.support.annotation.NonNull; 20 import android.view.KeyEvent; 21 22 /** 23 * A convenience class to handle channel number. 24 */ 25 public final class ChannelNumber implements Comparable<ChannelNumber> { 26 public static final String PRIMARY_CHANNEL_DELIMITER = "-"; 27 public static final String[] CHANNEL_DELIMITERS = {"-", ".", " "}; 28 29 private static final int[] CHANNEL_DELIMITER_KEYCODES = { 30 KeyEvent.KEYCODE_MINUS, KeyEvent.KEYCODE_NUMPAD_SUBTRACT, KeyEvent.KEYCODE_PERIOD, 31 KeyEvent.KEYCODE_NUMPAD_DOT, KeyEvent.KEYCODE_SPACE 32 }; 33 34 public String majorNumber; 35 public boolean hasDelimiter; 36 public String minorNumber; 37 38 public ChannelNumber() { 39 reset(); 40 } 41 42 public ChannelNumber(String major, boolean hasDelimiter, String minor) { 43 setChannelNumber(major, hasDelimiter, minor); 44 } 45 46 public void reset() { 47 setChannelNumber("", false, ""); 48 } 49 50 public void setChannelNumber(String majorNumber, boolean hasDelimiter, String minorNumber) { 51 this.majorNumber = majorNumber; 52 this.hasDelimiter = hasDelimiter; 53 this.minorNumber = minorNumber; 54 } 55 56 @Override 57 public String toString() { 58 if (hasDelimiter) { 59 return majorNumber + PRIMARY_CHANNEL_DELIMITER + minorNumber; 60 } 61 return majorNumber; 62 } 63 64 @Override 65 public int compareTo(@NonNull ChannelNumber another) { 66 int major = Integer.parseInt(majorNumber); 67 int minor = hasDelimiter ? Integer.parseInt(minorNumber) : 0; 68 69 int opponentMajor = Integer.parseInt(another.majorNumber); 70 int opponentMinor = another.hasDelimiter 71 ? Integer.parseInt(another.minorNumber) : 0; 72 if (major == opponentMajor) { 73 return minor - opponentMinor; 74 } 75 return major - opponentMajor; 76 } 77 78 public static boolean isChannelNumberDelimiterKey(int keyCode) { 79 for (int delimiterKeyCode : CHANNEL_DELIMITER_KEYCODES) { 80 if (delimiterKeyCode == keyCode) { 81 return true; 82 } 83 } 84 return false; 85 } 86 87 public static ChannelNumber parseChannelNumber(String number) { 88 if (number == null) { 89 return null; 90 } 91 ChannelNumber ret = new ChannelNumber(); 92 int indexOfDelimiter = -1; 93 for (String delimiter : CHANNEL_DELIMITERS) { 94 indexOfDelimiter = number.indexOf(delimiter); 95 if (indexOfDelimiter >= 0) { 96 break; 97 } 98 } 99 if (indexOfDelimiter == 0 || indexOfDelimiter == number.length() - 1) { 100 return null; 101 } 102 if (indexOfDelimiter < 0) { 103 ret.majorNumber = number; 104 if (!isInteger(ret.majorNumber)) { 105 return null; 106 } 107 } else { 108 ret.hasDelimiter = true; 109 ret.majorNumber = number.substring(0, indexOfDelimiter); 110 ret.minorNumber = number.substring(indexOfDelimiter + 1); 111 if (!isInteger(ret.majorNumber) || !isInteger(ret.minorNumber)) { 112 return null; 113 } 114 } 115 return ret; 116 } 117 118 public static int compare(String lhs, String rhs) { 119 ChannelNumber lhsNumber = parseChannelNumber(lhs); 120 ChannelNumber rhsNumber = parseChannelNumber(rhs); 121 if (lhsNumber == null && rhsNumber == null) { 122 return 0; 123 } else if (lhsNumber == null /* && rhsNumber != null */) { 124 return -1; 125 } else if (lhsNumber != null && rhsNumber == null) { 126 return 1; 127 } 128 return lhsNumber.compareTo(rhsNumber); 129 } 130 131 public static boolean isInteger(String string) { 132 try { 133 Integer.parseInt(string); 134 } catch(NumberFormatException e) { 135 return false; 136 } catch(NullPointerException e) { 137 return false; 138 } 139 return true; 140 } 141 } 142