JAVA: Updated the geocoder
authorroes@google.com <roes@google.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Mon, 23 Sep 2013 11:31:39 +0000 (11:31 +0000)
committerroes@google.com <roes@google.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Mon, 23 Sep 2013 11:31:39 +0000 (11:31 +0000)
git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@612 ee073f10-1060-11df-b6a4-87a95322a99c

16 files changed:
java/build.xml
java/geocoder/pom.xml
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
java/internal/prefixmapper/pom.xml [new file with mode: 0644]
java/internal/prefixmapper/src/com/google/i18n/phonenumbers/prefixmapper/DefaultMapStorage.java [moved from java/geocoder/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java with 87% similarity]
java/internal/prefixmapper/src/com/google/i18n/phonenumbers/prefixmapper/FlyweightMapStorage.java [moved from java/geocoder/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java with 90% similarity]
java/internal/prefixmapper/src/com/google/i18n/phonenumbers/prefixmapper/MappingFileProvider.java [moved from java/geocoder/src/com/google/i18n/phonenumbers/geocoding/MappingFileProvider.java with 96% similarity]
java/internal/prefixmapper/src/com/google/i18n/phonenumbers/prefixmapper/PhonePrefixMap.java [moved from java/geocoder/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java with 53% similarity]
java/internal/prefixmapper/src/com/google/i18n/phonenumbers/prefixmapper/PhonePrefixMapStorageStrategy.java [moved from java/geocoder/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java with 83% similarity]
java/internal/prefixmapper/src/com/google/i18n/phonenumbers/prefixmapper/PrefixFileReader.java [moved from java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PrefixFileReader.java with 88% similarity]
java/internal/prefixmapper/test/com/google/i18n/phonenumbers/prefixmapper/FlyweightMapStorageTest.java [moved from java/geocoder/test/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorageTest.java with 94% similarity]
java/internal/prefixmapper/test/com/google/i18n/phonenumbers/prefixmapper/MappingFileProviderTest.java [moved from java/geocoder/test/com/google/i18n/phonenumbers/geocoding/MappingFileProviderTest.java with 98% similarity]
java/internal/prefixmapper/test/com/google/i18n/phonenumbers/prefixmapper/PhonePrefixMapTest.java [moved from java/geocoder/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java with 60% similarity]
java/internal/prefixmapper/test/com/google/i18n/phonenumbers/prefixmapper/PrefixFileReaderTest.java [moved from java/geocoder/test/com/google/i18n/phonenumbers/geocoding/PrefixFileReaderTest.java with 98% similarity]
java/pom.xml
java/release_notes.txt

index 782a3e8..b1cf341 100644 (file)
@@ -5,6 +5,8 @@
   <property name="libphonenumber.test.dir" value="libphonenumber/test"/>
   <property name="geocoder.src.dir" value="geocoder/src"/>
   <property name="geocoder.test.dir" value="geocoder/test"/>
+  <property name="prefixmapper.src.dir" value="internal/prefixmapper/src"/>
+  <property name="prefixmapper.test.dir" value="internal/prefixmapper/test"/>
   <property name="build.dir" value="build"/>
   <property name="classes.dir" value="${build.dir}/classes"/>
   <property name="jar.dir" value="${build.dir}/jar"/>
   <target name="compile" description="Compile Java source."
           depends="build-phone-metadata,build-short-metadata,build-alternate-metadata,build-geo-data">
     <mkdir dir="${classes.dir}"/>
-    <javac srcdir="${libphonenumber.src.dir};${geocoder.src.dir}"
+    <javac srcdir="${libphonenumber.src.dir};${geocoder.src.dir};${prefixmapper.src.dir}"
            destdir="${classes.dir}" classpathref="classpath" includeAntRuntime="false"/>
-    <javac srcdir="${libphonenumber.test.dir};${geocoder.test.dir}"
+    <javac srcdir="${libphonenumber.test.dir};${geocoder.test.dir};${prefixmapper.test.dir}"
            destdir="${classes.dir}" classpathref="classpath" debug="on"
            includeAntRuntime="false"/>
   </target>
         <exclude name="**/*Test*"/>
         <exclude name="**/BuildMetadata*"/>
         <exclude name="**/geocoding/*"/>
+        <exclude name="**/prefixmapper/*"/>
       </fileset>
       <fileset dir="${libphonenumber.src.dir}">
         <include name="**/PhoneNumberMetadataProto*"/>
     <jar destfile="${jar.dir}/offline-geocoder.jar">
       <fileset dir="${classes.dir}">
         <include name="**/geocoding/*.class"/>
+        <include name="**/prefixmapper/*.class"/>
         <exclude name="**/*Test*"/>
         <exclude name="**/geocoding/GenerateAreaCodeData*"/>
       </fileset>
       <batchtest fork="no" todir="${report.dir}">
         <fileset dir="${geocoder.test.dir}" includes="**/*Test.java"/>
       </batchtest>
+      <batchtest fork="no" todir="${report.dir}">
+        <fileset dir="${prefixmapper.test.dir}" includes="**/*Test.java"/>
+      </batchtest>
     </junit>
     <fail message="Tests failed. Run 'ant junitreport' for more info."
         if="test.failed"/>
index daddfa3..3f5635a 100644 (file)
       <artifactId>libphonenumber</artifactId>
       <version>5.9-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>com.googlecode.libphonenumber</groupId>
+      <artifactId>prefixmapper</artifactId>
+      <version>2.10-SNAPSHOT</version>
+    </dependency>
   </dependencies>
 
 </project>
index b7ef967..d04c7b9 100644 (file)
@@ -19,7 +19,7 @@ package com.google.i18n.phonenumbers.geocoding;
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType;
 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
-import com.google.i18n.phonenumbers.geocoding.PrefixFileReader;
+import com.google.i18n.phonenumbers.prefixmapper.PrefixFileReader;
 
 import java.util.Locale;
 
diff --git a/java/internal/prefixmapper/pom.xml b/java/internal/prefixmapper/pom.xml
new file mode 100644 (file)
index 0000000..4d07277
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.googlecode.libphonenumber</groupId>
+  <artifactId>prefixmapper</artifactId>
+  <version>2.10-SNAPSHOT</version>
+  <packaging>jar</packaging>
+  <url>http://code.google.com/p/libphonenumber/</url>
+
+  <parent>
+    <groupId>com.googlecode.libphonenumber</groupId>
+    <artifactId>libphonenumber-parent</artifactId>
+    <version>5.9-SNAPSHOT</version>
+  </parent>
+
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+    <testResources>
+      <testResource>
+        <directory>../../geocoder/test/com/google/i18n/phonenumbers/geocoding/testing_data</directory>
+        <targetPath>com/google/i18n/phonenumbers/geocoding/testing_data</targetPath>
+      </testResource>
+    </testResources>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.googlecode.libphonenumber</groupId>
+      <artifactId>libphonenumber</artifactId>
+      <version>5.9-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -22,13 +22,13 @@ import java.io.ObjectOutput;
 import java.util.SortedMap;
 
 /**
- * Default area code map storage strategy that is used for data not containing description
+ * Default phone prefix map storage strategy that is used for data not containing description
  * duplications. It is mainly intended to avoid the overhead of the string table management when it
  * is actually unnecessary (i.e no string duplication).
  *
  * @author Shaopeng Jia
  */
-class DefaultMapStorage extends AreaCodeMapStorageStrategy {
+class DefaultMapStorage extends PhonePrefixMapStorageStrategy {
 
   public DefaultMapStorage() {}
 
@@ -46,16 +46,16 @@ class DefaultMapStorage extends AreaCodeMapStorageStrategy {
   }
 
   @Override
-  public void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap) {
-    numOfEntries = sortedAreaCodeMap.size();
+  public void readFromSortedMap(SortedMap<Integer, String> sortedPhonePrefixMap) {
+    numOfEntries = sortedPhonePrefixMap.size();
     phoneNumberPrefixes = new int[numOfEntries];
     descriptions = new String[numOfEntries];
     int index = 0;
-    for (int prefix : sortedAreaCodeMap.keySet()) {
+    for (int prefix : sortedPhonePrefixMap.keySet()) {
       phoneNumberPrefixes[index++] = prefix;
       possibleLengths.add((int) Math.log10(prefix) + 1);
     }
-    sortedAreaCodeMap.values().toArray(descriptions);
+    sortedPhonePrefixMap.values().toArray(descriptions);
   }
 
   @Override
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -27,13 +27,13 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 
 /**
- * Flyweight area code map storage strategy that uses a table to store unique strings and shorts to
- * store the prefix and description indexes when possible. It is particularly space-efficient when
- * the provided area code map contains a lot of redundant descriptions.
+ * Flyweight phone prefix map storage strategy that uses a table to store unique strings and shorts
+ * to store the prefix and description indexes when possible. It is particularly space-efficient
+ * when the provided phone prefix map contains a lot of redundant descriptions.
  *
  * @author Philippe Liard
  */
-final class FlyweightMapStorage extends AreaCodeMapStorageStrategy {
+final class FlyweightMapStorage extends PhonePrefixMapStorageStrategy {
   // Size of short and integer types in bytes.
   private static final int SHORT_NUM_BYTES = Short.SIZE / 8;
   private static final int INT_NUM_BYTES = Integer.SIZE / 8;
@@ -67,30 +67,30 @@ final class FlyweightMapStorage extends AreaCodeMapStorageStrategy {
   }
 
   @Override
-  public void readFromSortedMap(SortedMap<Integer, String> areaCodeMap) {
+  public void readFromSortedMap(SortedMap<Integer, String> phonePrefixMap) {
     SortedSet<String> descriptionsSet = new TreeSet<String>();
-    numOfEntries = areaCodeMap.size();
-    prefixSizeInBytes = getOptimalNumberOfBytesForValue(areaCodeMap.lastKey());
+    numOfEntries = phonePrefixMap.size();
+    prefixSizeInBytes = getOptimalNumberOfBytesForValue(phonePrefixMap.lastKey());
     phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes);
 
     // Fill the phone number prefixes byte buffer, the set of possible lengths of prefixes and the
     // description set.
     int index = 0;
-    for (Entry<Integer, String> entry : areaCodeMap.entrySet()) {
+    for (Entry<Integer, String> entry : phonePrefixMap.entrySet()) {
       int prefix = entry.getKey();
       storeWordInBuffer(phoneNumberPrefixes, prefixSizeInBytes, index, prefix);
       possibleLengths.add((int) Math.log10(prefix) + 1);
       descriptionsSet.add(entry.getValue());
       ++index;
     }
-    createDescriptionPool(descriptionsSet, areaCodeMap);
+    createDescriptionPool(descriptionsSet, phonePrefixMap);
   }
 
   /**
-   * Creates the description pool from the provided set of string descriptions and area code map.
+   * Creates the description pool from the provided set of string descriptions and phone prefix map.
    */
   private void createDescriptionPool(SortedSet<String> descriptionsSet,
-      SortedMap<Integer, String> areaCodeMap) {
+      SortedMap<Integer, String> phonePrefixMap) {
     descIndexSizeInBytes = getOptimalNumberOfBytesForValue(descriptionsSet.size() - 1);
     descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes);
     descriptionPool = new String[descriptionsSet.size()];
@@ -100,7 +100,7 @@ final class FlyweightMapStorage extends AreaCodeMapStorageStrategy {
     int index = 0;
     for (int i = 0; i < numOfEntries; i++) {
       int prefix = readWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, i);
-      String description = areaCodeMap.get(prefix);
+      String description = phonePrefixMap.get(prefix);
       int positionInDescriptionPool = Arrays.binarySearch(descriptionPool, description);
       storeWordInBuffer(descriptionIndexes, descIndexSizeInBytes, index, positionInDescriptionPool);
       ++index;
@@ -134,8 +134,8 @@ final class FlyweightMapStorage extends AreaCodeMapStorageStrategy {
   }
 
   /**
-   * Reads the area code entries from the provided input stream and stores them to the internal byte
-   * buffers.
+   * Reads the phone prefix entries from the provided input stream and stores them to the internal
+   * byte buffers.
    */
   private void readEntries(ObjectInput objectInput) throws IOException {
     numOfEntries = objectInput.readInt();
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import java.io.Externalizable;
 import java.io.IOException;
@@ -33,9 +33,9 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 
 /**
- * A utility which knows the data files that are available for the geocoder to use. The data files
- * contain mappings from phone number prefixes to text descriptions, and are organized by country
- * calling code and language that the text descriptions are in.
+ * A utility which knows the data files that are available for the phone prefix mappers to use.
+ * The data files contain mappings from phone number prefixes to text descriptions, and are
+ * organized by country calling code and language that the text descriptions are in.
  *
  * @author Shaopeng Jia
  */
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
@@ -30,36 +30,36 @@ import java.util.SortedSet;
 import java.util.logging.Logger;
 
 /**
- * A utility that maps phone number prefixes to a string describing the geographical area the prefix
- * covers.
+ * A utility that maps phone number prefixes to a description string, which may be, for example,
+ * the geographical area the prefix covers.
  *
  * @author Shaopeng Jia
  */
-public class AreaCodeMap implements Externalizable {
+public class PhonePrefixMap implements Externalizable {
   private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
-  private static final Logger LOGGER = Logger.getLogger(AreaCodeMap.class.getName());
+  private static final Logger LOGGER = Logger.getLogger(PhonePrefixMap.class.getName());
 
-  private AreaCodeMapStorageStrategy areaCodeMapStorage;
+  private PhonePrefixMapStorageStrategy phonePrefixMapStorage;
 
   // @VisibleForTesting
-  AreaCodeMapStorageStrategy getAreaCodeMapStorage() {
-    return areaCodeMapStorage;
+  PhonePrefixMapStorageStrategy getPhonePrefixMapStorage() {
+    return phonePrefixMapStorage;
   }
 
   /**
-   * Creates an empty {@link AreaCodeMap}. The default constructor is necessary for implementing
+   * Creates an empty {@link PhonePrefixMap}. The default constructor is necessary for implementing
    * {@link Externalizable}. The empty map could later be populated by
-   * {@link #readAreaCodeMap(java.util.SortedMap)} or {@link #readExternal(java.io.ObjectInput)}.
+   * {@link #readPhonePrefixMap(java.util.SortedMap)} or {@link #readExternal(java.io.ObjectInput)}.
    */
-  public AreaCodeMap() {}
+  public PhonePrefixMap() {}
 
   /**
-   * Gets the size of the provided area code map storage. The map storage passed-in will be filled
-   * as a result.
+   * Gets the size of the provided phone prefix map storage. The map storage passed-in will be
+   * filled as a result.
    */
-  private static int getSizeOfAreaCodeMapStorage(AreaCodeMapStorageStrategy mapStorage,
-      SortedMap<Integer, String> areaCodeMap) throws IOException {
-    mapStorage.readFromSortedMap(areaCodeMap);
+  private static int getSizeOfPhonePrefixMapStorage(PhonePrefixMapStorageStrategy mapStorage,
+      SortedMap<Integer, String> phonePrefixMap) throws IOException {
+    mapStorage.readFromSortedMap(phonePrefixMap);
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
     mapStorage.writeExternal(objectOutputStream);
@@ -69,27 +69,29 @@ public class AreaCodeMap implements Externalizable {
     return sizeOfStorage;
   }
 
-  private AreaCodeMapStorageStrategy createDefaultMapStorage() {
+  private PhonePrefixMapStorageStrategy createDefaultMapStorage() {
     return new DefaultMapStorage();
   }
 
-  private AreaCodeMapStorageStrategy createFlyweightMapStorage() {
+  private PhonePrefixMapStorageStrategy createFlyweightMapStorage() {
     return new FlyweightMapStorage();
   }
 
   /**
-   * Gets the smaller area code map storage strategy according to the provided area code map. It
-   * actually uses (outputs the data to a stream) both strategies and retains the best one which
+   * Gets the smaller phone prefix map storage strategy according to the provided phone prefix map.
+   * It actually uses (outputs the data to a stream) both strategies and retains the best one which
    * make this method quite expensive.
    */
   // @VisibleForTesting
-  AreaCodeMapStorageStrategy getSmallerMapStorage(SortedMap<Integer, String> areaCodeMap) {
+  PhonePrefixMapStorageStrategy getSmallerMapStorage(SortedMap<Integer, String> phonePrefixMap) {
     try {
-      AreaCodeMapStorageStrategy flyweightMapStorage = createFlyweightMapStorage();
-      int sizeOfFlyweightMapStorage = getSizeOfAreaCodeMapStorage(flyweightMapStorage, areaCodeMap);
+      PhonePrefixMapStorageStrategy flyweightMapStorage = createFlyweightMapStorage();
+      int sizeOfFlyweightMapStorage = getSizeOfPhonePrefixMapStorage(flyweightMapStorage,
+                                                                     phonePrefixMap);
 
-      AreaCodeMapStorageStrategy defaultMapStorage = createDefaultMapStorage();
-      int sizeOfDefaultMapStorage = getSizeOfAreaCodeMapStorage(defaultMapStorage, areaCodeMap);
+      PhonePrefixMapStorageStrategy defaultMapStorage = createDefaultMapStorage();
+      int sizeOfDefaultMapStorage = getSizeOfPhonePrefixMapStorage(defaultMapStorage,
+                                                                   phonePrefixMap);
 
       return sizeOfFlyweightMapStorage < sizeOfDefaultMapStorage
           ? flyweightMapStorage : defaultMapStorage;
@@ -100,57 +102,57 @@ public class AreaCodeMap implements Externalizable {
   }
 
   /**
-   * Creates an {@link AreaCodeMap} initialized with {@code sortedAreaCodeMap}.  Note that the
+   * Creates an {@link PhonePrefixMap} initialized with {@code sortedPhonePrefixMap}.  Note that the
    * underlying implementation of this method is expensive thus should not be called by
    * time-critical applications.
    *
-   * @param sortedAreaCodeMap  a map from phone number prefixes to descriptions of corresponding
-   *     geographical areas, sorted in ascending order of the phone number prefixes as integers.
+   * @param sortedPhonePrefixMap  a map from phone number prefixes to descriptions of those prefixes
+   * sorted in ascending order of the phone number prefixes as integers.
    */
-  public void readAreaCodeMap(SortedMap<Integer, String> sortedAreaCodeMap) {
-    areaCodeMapStorage = getSmallerMapStorage(sortedAreaCodeMap);
+  public void readPhonePrefixMap(SortedMap<Integer, String> sortedPhonePrefixMap) {
+    phonePrefixMapStorage = getSmallerMapStorage(sortedPhonePrefixMap);
   }
 
   /**
    * Supports Java Serialization.
    */
   public void readExternal(ObjectInput objectInput) throws IOException {
-    // Read the area code map storage strategy flag.
+    // Read the phone prefix map storage strategy flag.
     boolean useFlyweightMapStorage = objectInput.readBoolean();
     if (useFlyweightMapStorage) {
-      areaCodeMapStorage = new FlyweightMapStorage();
+      phonePrefixMapStorage = new FlyweightMapStorage();
     } else {
-      areaCodeMapStorage = new DefaultMapStorage();
+      phonePrefixMapStorage = new DefaultMapStorage();
     }
-    areaCodeMapStorage.readExternal(objectInput);
+    phonePrefixMapStorage.readExternal(objectInput);
   }
 
   /**
    * Supports Java Serialization.
    */
   public void writeExternal(ObjectOutput objectOutput) throws IOException {
-    objectOutput.writeBoolean(areaCodeMapStorage instanceof FlyweightMapStorage);
-    areaCodeMapStorage.writeExternal(objectOutput);
+    objectOutput.writeBoolean(phonePrefixMapStorage instanceof FlyweightMapStorage);
+    phonePrefixMapStorage.writeExternal(objectOutput);
   }
 
   /**
-   * Returns the description of the geographical area the {@code number} corresponds to. This method
-   * distinguishes the case of an invalid prefix and a prefix for which the name is not available in
-   * the current language. If the description is not available in the current language an empty
-   * string is returned. If no description was found for the provided number, null is returned.
+   * Returns the description of the {@code number}. This method distinguishes the case of an invalid
+   * prefix and a prefix for which the name is not available in the current language. If the
+   * description is not available in the current language an empty string is returned. If no
+   * description was found for the provided number, null is returned.
    *
    * @param number  the phone number to look up
-   * @return  the description of the geographical area
+   * @return  the description of the number
    */
   String lookup(PhoneNumber number) {
-    int numOfEntries = areaCodeMapStorage.getNumOfEntries();
+   int numOfEntries = phonePrefixMapStorage.getNumOfEntries();
     if (numOfEntries == 0) {
       return null;
     }
     long phonePrefix =
         Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number));
     int currentIndex = numOfEntries - 1;
-    SortedSet<Integer> currentSetOfLengths = areaCodeMapStorage.getPossibleLengths();
+    SortedSet<Integer> currentSetOfLengths = phonePrefixMapStorage.getPossibleLengths();
     while (currentSetOfLengths.size() > 0) {
       Integer possibleLength = currentSetOfLengths.last();
       String phonePrefixStr = String.valueOf(phonePrefix);
@@ -161,9 +163,9 @@ public class AreaCodeMap implements Externalizable {
       if (currentIndex < 0) {
         return null;
       }
-      int currentPrefix = areaCodeMapStorage.getPrefix(currentIndex);
+      int currentPrefix = phonePrefixMapStorage.getPrefix(currentIndex);
       if (phonePrefix == currentPrefix) {
-        return areaCodeMapStorage.getDescription(currentIndex);
+        return phonePrefixMapStorage.getDescription(currentIndex);
       }
       currentSetOfLengths = currentSetOfLengths.headSet(possibleLength);
     }
@@ -180,7 +182,7 @@ public class AreaCodeMap implements Externalizable {
     int current = 0;
     while (start <= end) {
       current = (start + end) >>> 1;
-      int currentValue = areaCodeMapStorage.getPrefix(current);
+      int currentValue = phonePrefixMapStorage.getPrefix(current);
       if (currentValue == value) {
         return current;
       } else if (currentValue > value) {
@@ -194,10 +196,10 @@ public class AreaCodeMap implements Externalizable {
   }
 
   /**
-   * Dumps the mappings contained in the area code map.
+   * Dumps the mappings contained in the phone prefix map.
    */
   @Override
   public String toString() {
-    return areaCodeMapStorage.toString();
+    return phonePrefixMapStorage.toString();
   }
 }
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -23,13 +23,13 @@ import java.util.SortedMap;
 import java.util.TreeSet;
 
 /**
- * Abstracts the way area code data is stored into memory and serialized to a stream. It is used by
- * {@link AreaCodeMap} to support the most space-efficient storage strategy according to the
+ * Abstracts the way phone prefix data is stored into memory and serialized to a stream. It is used
+ * by {@link PhonePrefixMap} to support the most space-efficient storage strategy according to the
  * provided data.
  *
  * @author Philippe Liard
  */
-abstract class AreaCodeMapStorageStrategy {
+abstract class PhonePrefixMapStorageStrategy {
   protected int numOfEntries = 0;
   protected final TreeSet<Integer> possibleLengths = new TreeSet<Integer>();
 
@@ -53,18 +53,18 @@ abstract class AreaCodeMapStorageStrategy {
 
   /**
    * Sets the internal state of the underlying storage implementation from the provided {@code
-   * sortedAreaCodeMap} that maps phone number prefixes to description strings.
+   * sortedPhonePrefixMap} that maps phone number prefixes to description strings.
    *
-   * @param sortedAreaCodeMap  a sorted map that maps phone number prefixes including country
+   * @param sortedPhonePrefixMap  a sorted map that maps phone number prefixes including country
    *    calling code to description strings
    */
-  public abstract void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap);
+  public abstract void readFromSortedMap(SortedMap<Integer, String> sortedPhonePrefixMap);
 
   /**
    * Sets the internal state of the underlying storage implementation reading the provided {@code
    * objectInput}.
    *
-   * @param objectInput  the object input stream from which the area code map is read
+   * @param objectInput  the object input stream from which the phone prefix map is read
    * @throws IOException  if an error occurred reading the provided input stream
    */
   public abstract void readExternal(ObjectInput objectInput) throws IOException;
@@ -73,13 +73,13 @@ abstract class AreaCodeMapStorageStrategy {
    * Writes the internal state of the underlying storage implementation to the provided {@code
    * objectOutput}.
    *
-   * @param objectOutput  the object output stream to which the area code map is written
+   * @param objectOutput  the object output stream to which the phone prefix map is written
    * @throws IOException  if an error occurred writing to the provided output stream
    */
   public abstract void writeExternal(ObjectOutput objectOutput) throws IOException;
 
   /**
-   * @return  the number of entries contained in the area code map
+   * @return  the number of entries contained in the phone prefix map
    */
   public int getNumOfEntries() {
     return numOfEntries;
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
 
@@ -40,7 +40,8 @@ public class PrefixFileReader {
   private MappingFileProvider mappingFileProvider = new MappingFileProvider();
   // A mapping from countryCallingCode_lang to the corresponding phone prefix map that has been
   // loaded.
-  private Map<String, AreaCodeMap> availablePhonePrefixMaps = new HashMap<String, AreaCodeMap>();
+  private Map<String, PhonePrefixMap> availablePhonePrefixMaps =
+      new HashMap<String, PhonePrefixMap>();
 
   public PrefixFileReader(String phonePrefixDataDirectory) {
     this.phonePrefixDataDirectory = phonePrefixDataDirectory;
@@ -61,25 +62,25 @@ public class PrefixFileReader {
     }
   }
 
-  private AreaCodeMap getPhonePrefixDescriptions(
+  private PhonePrefixMap getPhonePrefixDescriptions(
       int prefixMapKey, String language, String script, String region) {
     String fileName = mappingFileProvider.getFileName(prefixMapKey, language, script, region);
     if (fileName.length() == 0) {
       return null;
     }
     if (!availablePhonePrefixMaps.containsKey(fileName)) {
-      loadAreaCodeMapFromFile(fileName);
+      loadPhonePrefixMapFromFile(fileName);
     }
     return availablePhonePrefixMaps.get(fileName);
   }
 
-  private void loadAreaCodeMapFromFile(String fileName) {
+  private void loadPhonePrefixMapFromFile(String fileName) {
     InputStream source =
         PrefixFileReader.class.getResourceAsStream(phonePrefixDataDirectory + fileName);
     ObjectInputStream in = null;
     try {
       in = new ObjectInputStream(source);
-      AreaCodeMap map = new AreaCodeMap();
+      PhonePrefixMap map = new PhonePrefixMap();
       map.readExternal(in);
       availablePhonePrefixMaps.put(fileName, map);
     } catch (IOException e) {
@@ -117,14 +118,13 @@ public class PrefixFileReader {
     // prefix of 4 digits for NANPA instead, e.g. 1650.
     int phonePrefix = (countryCallingCode != 1) ?
         countryCallingCode : (1000 + (int) (number.getNationalNumber() / 10000000));
-    AreaCodeMap phonePrefixDescriptions =
+    PhonePrefixMap phonePrefixDescriptions =
         getPhonePrefixDescriptions(phonePrefix, lang, script, region);
-    String description = (phonePrefixDescriptions != null)
-        ? phonePrefixDescriptions.lookup(number)
-        : null;
+    String description = (phonePrefixDescriptions != null) ?
+        phonePrefixDescriptions.lookup(number) : null;
     // When a location is not available in the requested language, fall back to English.
     if ((description == null || description.length() == 0) && mayFallBackToEnglish(lang)) {
-      AreaCodeMap defaultMap = getPhonePrefixDescriptions(phonePrefix, "en", "", "");
+      PhonePrefixMap defaultMap = getPhonePrefixDescriptions(phonePrefix, "en", "", "");
       if (defaultMap == null) {
         return "";
       }
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import junit.framework.TestCase;
 
@@ -33,7 +33,7 @@ import java.util.TreeMap;
  * @author Philippe Liard
  */
 public class FlyweightMapStorageTest extends TestCase {
-  private static final SortedMap<Integer, String> areaCodeMap;
+  private static final SortedMap<Integer, String> phonePrefixMap;
   static {
     SortedMap<Integer, String> tmpMap = new TreeMap<Integer, String>();
     tmpMap.put(331402, "Paris");
@@ -42,7 +42,7 @@ public class FlyweightMapStorageTest extends TestCase {
     tmpMap.put(334911, "Marseille");
     tmpMap.put(334912, "");
     tmpMap.put(334913, "");
-    areaCodeMap = Collections.unmodifiableSortedMap(tmpMap);
+    phonePrefixMap = Collections.unmodifiableSortedMap(tmpMap);
   }
 
   private FlyweightMapStorage mapStorage;
@@ -50,7 +50,7 @@ public class FlyweightMapStorageTest extends TestCase {
   @Override
   protected void setUp() throws Exception {
     mapStorage = new FlyweightMapStorage();
-    mapStorage.readFromSortedMap(areaCodeMap);
+    mapStorage.readFromSortedMap(phonePrefixMap);
   }
 
   public void testReadFromSortedMap() {
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.i18n.phonenumbers.geocoding;
+package com.google.i18n.phonenumbers.prefixmapper;
 
 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
 import junit.framework.TestCase;
@@ -28,16 +28,16 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 
 /**
- * Unittests for AreaCodeMap.java
+ * Unittests for PhonePrefixMap.java
  *
  * @author Shaopeng Jia
  */
-public class AreaCodeMapTest extends TestCase {
-  private final AreaCodeMap areaCodeMapForUS = new AreaCodeMap();
-  private final AreaCodeMap areaCodeMapForIT = new AreaCodeMap();
+public class PhonePrefixMapTest extends TestCase {
+  private final PhonePrefixMap phonePrefixMapForUS = new PhonePrefixMap();
+  private final PhonePrefixMap phonePrefixMapForIT = new PhonePrefixMap();
   private PhoneNumber number = new PhoneNumber();
 
-  public AreaCodeMapTest() {
+  public PhonePrefixMapTest() {
     SortedMap<Integer, String> sortedMapForUS = new TreeMap<Integer, String>();
     sortedMapForUS.put(1212, "New York");
     sortedMapForUS.put(1480, "Arizona");
@@ -51,7 +51,7 @@ public class AreaCodeMapTest extends TestCase {
     sortedMapForUS.put(1867993, "Dawson, YT");
     sortedMapForUS.put(1972480, "Richardson, TX");
 
-    areaCodeMapForUS.readAreaCodeMap(sortedMapForUS);
+    phonePrefixMapForUS.readPhonePrefixMap(sortedMapForUS);
 
     SortedMap<Integer, String> sortedMapForIT = new TreeMap<Integer, String>();
     sortedMapForIT.put(3902, "Milan");
@@ -61,12 +61,12 @@ public class AreaCodeMapTest extends TestCase {
     sortedMapForIT.put(390321, "Novara");
     sortedMapForIT.put(390975, "Potenza");
 
-    areaCodeMapForIT.readAreaCodeMap(sortedMapForIT);
+    phonePrefixMapForIT.readPhonePrefixMap(sortedMapForIT);
   }
 
   private static SortedMap<Integer, String> createDefaultStorageMapCandidate() {
     SortedMap<Integer, String> sortedMap = new TreeMap<Integer, String>();
-    // Make the area codes bigger to store them using integer.
+    // Make the phone prefixs bigger to store them using integer.
     sortedMap.put(121212345, "New York");
     sortedMap.put(148034434, "Arizona");
     return sortedMap;
@@ -82,111 +82,112 @@ public class AreaCodeMapTest extends TestCase {
   }
 
   public void testGetSmallerMapStorageChoosesDefaultImpl() {
-    AreaCodeMapStorageStrategy mapStorage =
-        new AreaCodeMap().getSmallerMapStorage(createDefaultStorageMapCandidate());
+    PhonePrefixMapStorageStrategy mapStorage =
+        new PhonePrefixMap().getSmallerMapStorage(createDefaultStorageMapCandidate());
     assertFalse(mapStorage instanceof FlyweightMapStorage);
   }
 
   public void testGetSmallerMapStorageChoosesFlyweightImpl() {
-    AreaCodeMapStorageStrategy mapStorage =
-        new AreaCodeMap().getSmallerMapStorage(createFlyweightStorageMapCandidate());
+    PhonePrefixMapStorageStrategy mapStorage =
+        new PhonePrefixMap().getSmallerMapStorage(createFlyweightStorageMapCandidate());
     assertTrue(mapStorage instanceof FlyweightMapStorage);
   }
 
   public void testLookupInvalidNumber_US() {
     // central office code cannot start with 1.
     number.setCountryCode(1).setNationalNumber(2121234567L);
-    assertEquals("New York", areaCodeMapForUS.lookup(number));
+    assertEquals("New York", phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumber_NJ() {
     number.setCountryCode(1).setNationalNumber(2016641234L);
-    assertEquals("Westwood, NJ", areaCodeMapForUS.lookup(number));
+    assertEquals("Westwood, NJ", phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumber_NY() {
     number.setCountryCode(1).setNationalNumber(2126641234L);
-    assertEquals("New York", areaCodeMapForUS.lookup(number));
+    assertEquals("New York", phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumber_CA_1() {
     number.setCountryCode(1).setNationalNumber(6503451234L);
-    assertEquals("San Mateo, CA", areaCodeMapForUS.lookup(number));
+    assertEquals("San Mateo, CA", phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumber_CA_2() {
     number.setCountryCode(1).setNationalNumber(6502531234L);
-    assertEquals("California", areaCodeMapForUS.lookup(number));
+    assertEquals("California", phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumberFound_TX() {
     number.setCountryCode(1).setNationalNumber(9724801234L);
-    assertEquals("Richardson, TX", areaCodeMapForUS.lookup(number));
+    assertEquals("Richardson, TX", phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumberNotFound_TX() {
     number.setCountryCode(1).setNationalNumber(9724811234L);
-    assertNull(areaCodeMapForUS.lookup(number));
+    assertNull(phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumber_CH() {
     number.setCountryCode(41).setNationalNumber(446681300L);
-    assertNull(areaCodeMapForUS.lookup(number));
+    assertNull(phonePrefixMapForUS.lookup(number));
   }
 
   public void testLookupNumber_IT() {
     number.setCountryCode(39).setNationalNumber(212345678L).setItalianLeadingZero(true);
-    assertEquals("Milan", areaCodeMapForIT.lookup(number));
+    assertEquals("Milan", phonePrefixMapForIT.lookup(number));
 
     number.setNationalNumber(612345678L);
-    assertEquals("Rome", areaCodeMapForIT.lookup(number));
+    assertEquals("Rome", phonePrefixMapForIT.lookup(number));
 
     number.setNationalNumber(3211234L);
-    assertEquals("Novara", areaCodeMapForIT.lookup(number));
+    assertEquals("Novara", phonePrefixMapForIT.lookup(number));
 
     // A mobile number
     number.setNationalNumber(321123456L).setItalianLeadingZero(false);
-    assertNull(areaCodeMapForIT.lookup(number));
+    assertNull(phonePrefixMapForIT.lookup(number));
 
     // An invalid number (too short)
     number.setNationalNumber(321123L).setItalianLeadingZero(true);
-    assertEquals("Novara", areaCodeMapForIT.lookup(number));
+    assertEquals("Novara", phonePrefixMapForIT.lookup(number));
   }
 
   /**
-   * Creates a new area code map serializing the provided area code map to a stream and then reading
-   * this stream. The resulting area code map is expected to be strictly equal to the provided one
-   * from which it was generated.
+   * Creates a new phone prefix map serializing the provided phone prefix map to a stream and then
+   * reading this stream. The resulting phone prefix map is expected to be strictly equal to the
+   * provided one from which it was generated.
    */
-  private static AreaCodeMap createNewAreaCodeMap(AreaCodeMap areaCodeMap) throws IOException {
+  private static PhonePrefixMap createNewPhonePrefixMap(
+      PhonePrefixMap phonePrefixMap) throws IOException {
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
-    areaCodeMap.writeExternal(objectOutputStream);
+    phonePrefixMap.writeExternal(objectOutputStream);
     objectOutputStream.flush();
 
-    AreaCodeMap newAreaCodeMap = new AreaCodeMap();
-    newAreaCodeMap.readExternal(
+    PhonePrefixMap newPhonePrefixMap = new PhonePrefixMap();
+    newPhonePrefixMap.readExternal(
         new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
-    return newAreaCodeMap;
+    return newPhonePrefixMap;
   }
 
   public void testReadWriteExternalWithDefaultStrategy() throws IOException {
-    AreaCodeMap localAreaCodeMap = new AreaCodeMap();
-    localAreaCodeMap.readAreaCodeMap(createDefaultStorageMapCandidate());
-    assertFalse(localAreaCodeMap.getAreaCodeMapStorage() instanceof FlyweightMapStorage);
+    PhonePrefixMap localPhonePrefixMap = new PhonePrefixMap();
+    localPhonePrefixMap.readPhonePrefixMap(createDefaultStorageMapCandidate());
+    assertFalse(localPhonePrefixMap.getPhonePrefixMapStorage() instanceof FlyweightMapStorage);
 
-    AreaCodeMap newAreaCodeMap;
-    newAreaCodeMap = createNewAreaCodeMap(localAreaCodeMap);
-    assertEquals(localAreaCodeMap.toString(), newAreaCodeMap.toString());
+    PhonePrefixMap newPhonePrefixMap;
+    newPhonePrefixMap = createNewPhonePrefixMap(localPhonePrefixMap);
+    assertEquals(localPhonePrefixMap.toString(), newPhonePrefixMap.toString());
   }
 
   public void testReadWriteExternalWithFlyweightStrategy() throws IOException {
-    AreaCodeMap localAreaCodeMap = new AreaCodeMap();
-    localAreaCodeMap.readAreaCodeMap(createFlyweightStorageMapCandidate());
-    assertTrue(localAreaCodeMap.getAreaCodeMapStorage() instanceof FlyweightMapStorage);
+    PhonePrefixMap localPhonePrefixMap = new PhonePrefixMap();
+    localPhonePrefixMap.readPhonePrefixMap(createFlyweightStorageMapCandidate());
+    assertTrue(localPhonePrefixMap.getPhonePrefixMapStorage() instanceof FlyweightMapStorage);
 
-    AreaCodeMap newAreaCodeMap;
-    newAreaCodeMap = createNewAreaCodeMap(localAreaCodeMap);
-    assertEquals(localAreaCodeMap.toString(), newAreaCodeMap.toString());
+    PhonePrefixMap newPhonePrefixMap;
+    newPhonePrefixMap = createNewPhonePrefixMap(localPhonePrefixMap);
+    assertEquals(localPhonePrefixMap.toString(), newPhonePrefixMap.toString());
   }
 }
index e79f924..092a7ec 100644 (file)
@@ -81,6 +81,7 @@
     <module>libphonenumber</module>
     <module>geocoder</module>
     <module>demo</module>
+    <module>internal/prefixmapper</module>
   </modules>
 
   <build>
index 8672eb8..d6a2243 100644 (file)
@@ -1,3 +1,7 @@
+Sep 23, 2013: libphonenumber-5.8.5
+* Code changes:
+  - Restructured the geocoder, moving the utility classes to a new module internal/prefixmapper.
+
 Sep 20, 2013: libphonenumber-5.8.4
 * Metadata changes:
  - Adding a token to indicate which countries have mobile portability.