Home | History | Annotate | Download | only in prefixmapper
      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     */
     47   public void readPrefixTimeZonesMap(SortedMap<Integer, String> sortedPrefixTimeZoneMap) {
     48     phonePrefixMap.readPhonePrefixMap(sortedPrefixTimeZoneMap);
     49   }
     50 
     51   /**
     52    * Supports Java Serialization.
     53    */
     54   public void writeExternal(ObjectOutput objectOutput) throws IOException {
     55     phonePrefixMap.writeExternal(objectOutput);
     56   }
     57 
     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    */
     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    */
     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    */
    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    */
    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
    123   public String toString() {
    124     return phonePrefixMap.toString();
    125   }
    126 }
    127