1 /* 2 * Copyright (C) 2012 The Libphonenumber Authors 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.google.i18n.phonenumbers.prefixmapper; 18 19 import com.google.i18n.phonenumbers.PhoneNumberUtil; 20 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; 21 22 import java.io.Externalizable; 23 import java.io.IOException; 24 import java.io.ObjectInput; 25 import java.io.ObjectOutput; 26 import java.util.LinkedList; 27 import java.util.List; 28 import java.util.SortedMap; 29 import java.util.StringTokenizer; 30 31 /** 32 * A utility that maps phone number prefixes to a list of strings describing the time zones to 33 * which each prefix belongs. 34 */ 35 public class PrefixTimeZonesMap implements Externalizable { 36 private final PhonePrefixMap phonePrefixMap = new PhonePrefixMap(); 37 private static final String RAW_STRING_TIMEZONES_SEPARATOR = "&"; 38 39 /** 40 * Creates a {@link PrefixTimeZonesMap} initialized with {@code sortedPrefixTimeZoneMap}. Note 41 * that the underlying implementation of this method is expensive thus should not be called by 42 * time-critical applications. 43 * 44 * @param sortedPrefixTimeZoneMap a map from phone number prefixes to their corresponding time 45 * zones, sorted in ascending order of the phone number prefixes as integers. 46 */ readPrefixTimeZonesMap(SortedMap<Integer, String> sortedPrefixTimeZoneMap)47 public void readPrefixTimeZonesMap(SortedMap<Integer, String> sortedPrefixTimeZoneMap) { 48 phonePrefixMap.readPhonePrefixMap(sortedPrefixTimeZoneMap); 49 } 50 51 /** 52 * Supports Java Serialization. 53 */ writeExternal(ObjectOutput objectOutput)54 public void writeExternal(ObjectOutput objectOutput) throws IOException { 55 phonePrefixMap.writeExternal(objectOutput); 56 } 57 readExternal(ObjectInput objectInput)58 public void readExternal(ObjectInput objectInput) throws IOException { 59 phonePrefixMap.readExternal(objectInput); 60 } 61 62 /** 63 * Returns the list of time zones {@code key} corresponds to. 64 * 65 * <p>{@code key} could be the calling country code and the full significant number of a 66 * certain number, or it could be just a phone-number prefix. 67 * For example, the full number 16502530000 (from the phone-number +1 650 253 0000) is a valid 68 * input. Also, any of its prefixes, such as 16502, is also valid. 69 * 70 * @param key the key to look up 71 * @return the list of corresponding time zones 72 */ lookupTimeZonesForNumber(long key)73 private List<String> lookupTimeZonesForNumber(long key) { 74 // Lookup in the map data. The returned String may consist of several time zones, so it must be 75 // split. 76 String timezonesString = phonePrefixMap.lookup(key); 77 if (timezonesString == null) { 78 return new LinkedList<String>(); 79 } 80 return tokenizeRawOutputString(timezonesString); 81 } 82 83 /** 84 * As per {@link #lookupTimeZonesForNumber(long)}, but receives the number as a PhoneNumber 85 * instead of a long. 86 * 87 * @param number the phone number to look up 88 * @return the list of corresponding time zones 89 */ lookupTimeZonesForNumber(PhoneNumber number)90 public List<String> lookupTimeZonesForNumber(PhoneNumber number) { 91 long phonePrefix = Long.parseLong(number.getCountryCode() 92 + PhoneNumberUtil.getInstance().getNationalSignificantNumber(number)); 93 return lookupTimeZonesForNumber(phonePrefix); 94 } 95 96 /** 97 * Returns the list of time zones {@code number}'s calling country code corresponds to. 98 * 99 * @param number the phone number to look up 100 * @return the list of corresponding time zones 101 */ lookupCountryLevelTimeZonesForNumber(PhoneNumber number)102 public List<String> lookupCountryLevelTimeZonesForNumber(PhoneNumber number) { 103 return lookupTimeZonesForNumber(number.getCountryCode()); 104 } 105 106 /** 107 * Split {@code timezonesString} into all the time zones that are part of it. 108 */ tokenizeRawOutputString(String timezonesString)109 private List<String> tokenizeRawOutputString(String timezonesString) { 110 StringTokenizer tokenizer = new StringTokenizer(timezonesString, 111 RAW_STRING_TIMEZONES_SEPARATOR); 112 LinkedList<String> timezonesList = new LinkedList<String>(); 113 while (tokenizer.hasMoreTokens()) { 114 timezonesList.add(tokenizer.nextToken()); 115 } 116 return timezonesList; 117 } 118 119 /** 120 * Dumps the mappings contained in the phone prefix map. 121 */ 122 @Override toString()123 public String toString() { 124 return phonePrefixMap.toString(); 125 } 126 } 127