Update libphonenumber to 3.7.1
Bug: 4939002,4989129
Change-Id: If8ba75b91380a0280793bec13000806d72fa2658
diff --git a/README.android b/README.android
index 63b7eac..5779273 100644
--- a/README.android
+++ b/README.android
@@ -1,4 +1,4 @@
URL: http://code.google.com/p/libphonenumber/
-Version: 3.7 (r278)
+Version: 3.7.1 (r294)
License: Apache 2
Description: Google Phone Number Library.
diff --git a/java/build.xml b/java/build.xml
deleted file mode 100644
index 63398b5..0000000
--- a/java/build.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" ?>
-
-<project name="libphonenumber" default="compile">
- <property name="src.dir" value="src"/>
- <property name="test.dir" value="test"/>
- <property name="build.dir" value="build"/>
- <property name="classes.dir" value="${build.dir}/classes"/>
- <property name="jar.dir" value="${build.dir}/jar"/>
- <property name="lib.dir" value="lib"/>
- <property name="report.dir" value="${build.dir}/junitreport"/>
-
- <path id="classpath">
- <fileset dir="${lib.dir}" includes="**/*.jar"/>
- </path>
- <path id="test.classpath">
- <pathelement location="${classes.dir}"/>
- <pathelement location="lib/junit/junit-4.8.1.jar"/>
- <pathelement location="${jar.dir}/${ant.project.name}-test.jar"/>
- <fileset dir="${lib.dir}">
- <include name="**/*.jar"/>
- </fileset>
- </path>
-
- <target name="build-metadata">
- <exec executable="java">
- <arg value="-jar" />
- <arg value="../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar"/>
- <arg value="BuildMetadataProtoFromXml"/>
- <arg value="../resources/PhoneNumberMetaData.xml"/>
- <arg value="src"/>
- <arg value="false"/> <!-- Not for testing. -->
- <arg value="false"/> <!-- No lite metadata. -->
- </exec>
- </target>
-
- <target name="build-test-metadata">
- <exec executable="java">
- <arg value="-jar" />
- <arg value="../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar"/>
- <arg value="BuildMetadataProtoFromXml"/>
- <arg value="../resources/PhoneNumberMetaDataForTesting.xml"/>
- <arg value="test"/>
- <arg value="true"/> <!-- For testing. -->
- <arg value="false"/> <!-- No lite metadata. -->
- </exec>
- </target>
-
- <target name="build-geo-data">
- <exec executable="java">
- <arg value="-jar" />
- <arg value="../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar"/>
- <arg value="GenerateAreaCodeData"/>
- <arg value="../resources/geocoding/"/>
- <arg value="src/com/google/i18n/phonenumbers/geocoding/data"/>
- <arg value="false"/> <!-- Not for testing. -->
- </exec>
- </target>
-
- <target name="build-geo-test-data">
- <exec executable="java">
- <arg value="-jar" />
- <arg value="../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar"/>
- <arg value="GenerateAreaCodeData"/>
- <arg value="../resources/test/geocoding/"/>
- <arg value="test/com/google/i18n/phonenumbers/geocoding/testing_data"/>
- <arg value="false"/> <!-- Not for testing. -->
- </exec>
- </target>
-
- <target name="compile" description="Compile Java source."
- depends="build-metadata,build-geo-data">
- <mkdir dir="${classes.dir}"/>
- <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
- <javac srcdir="${test.dir}" destdir="${classes.dir}" classpathref="classpath" debug="on"/>
- </target>
-
- <target name="jar" depends="compile">
- <mkdir dir="${jar.dir}"/>
- <jar destfile="${jar.dir}/${ant.project.name}.jar">
- <fileset dir="${classes.dir}">
- <include name="**/*.class"/>
- <exclude name="**/*Test*"/>
- <exclude name="**/BuildMetadata*"/>
- <exclude name="**/JSArrayBuilder*"/>
- <exclude name="**/geocoding/*"/>
- </fileset>
- <fileset dir="${src.dir}">
- <include name="**/PhoneNumberMetadataProto*"/>
- </fileset>
- </jar>
- <jar destfile="${jar.dir}/offline-geocoder.jar">
- <fileset dir="${classes.dir}">
- <include name="**/geocoding/*.class"/>
- <exclude name="**/*Test*"/>
- <exclude name="**/geocoding/GenerateAreaCodeData*"/>
- </fileset>
- <fileset dir="${src.dir}">
- <include name="**/geocoding/data/*"/>
- </fileset>
- </jar>
- </target>
-
- <target name="test-jar"
- depends="compile,build-test-metadata,build-geo-test-data">
- <mkdir dir="${jar.dir}"/>
- <jar destfile="${jar.dir}/${ant.project.name}-test.jar">
- <fileset dir="${classes.dir}">
- <include name="**/*.class"/>
- <exclude name="**/*Test*"/>
- </fileset>
- <fileset dir="${src.dir}">
- <include name="**/PhoneNumberMetadataProto*"/>
- </fileset>
- <fileset dir="${test.dir}">
- <include name="**/PhoneNumberMetadataProtoForTesting*"/>
- </fileset>
- <fileset dir="${test.dir}">
- <include name="**/geocoding/testing_data/*"/>
- </fileset>
- </jar>
- </target>
-
- <target name="junit" depends="test-jar">
- <mkdir dir="${report.dir}"/>
- <junit printsummary="yes">
- <classpath refid="test.classpath"/>
- <formatter type="xml"/>
- <batchtest fork="no" todir="${report.dir}">
- <fileset dir="${test.dir}" includes="**/*Test.java"/>
- </batchtest>
- </junit>
- </target>
-
- <target name="junitreport">
- <junitreport todir="${report.dir}">
- <fileset dir="${report.dir}" includes="TEST-*.xml"/>
- <report todir="${report.dir}"/>
- </junitreport>
- </target>
-
- <target name="clean" description="Remove generated files.">
- <delete dir="${build.dir}"/>
- </target>
-
- <target name="clean-build" depends="clean,jar"/>
-</project>
-
diff --git a/java/pom.xml b/java/pom.xml
deleted file mode 100644
index e376262..0000000
--- a/java/pom.xml
+++ /dev/null
@@ -1,286 +0,0 @@
-<?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>libphonenumber</artifactId>
- <version>3.7-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>libphonenumber</name>
- <url>http://code.google.com/p/libphonenumber/</url>
-
- <parent>
- <groupId>org.sonatype.oss</groupId>
- <artifactId>oss-parent</artifactId>
- <version>7</version>
- </parent>
-
- <description>
- Google's common Java library for parsing, formatting, storing and validating international phone numbers.
- Optimized for running on smartphones.
- </description>
-
- <organization>
- <name>Google</name>
- <url>http://www.google.com/</url>
- </organization>
-
- <licenses>
- <license>
- <name>The Apache Software License, Version 2.0</name>
- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
- </license>
- </licenses>
-
- <scm>
- <connection>scm:svn:http://libphonenumber.googlecode.com/svn/trunk/java/</connection>
- <developerConnection>scm:svn:https://libphonenumber.googlecode.com/svn/trunk/java/</developerConnection>
- <url>scm:svn:http://libphonenumber.googlecode.com/svn/trunk/java/</url>
- </scm>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <developers>
- <developer>
- <id>jia.shao.peng</id>
- <name>Shaopeng Jia</name>
- <email>jia.shao.peng@gmail.com</email>
- <organization>Google</organization>
- <roles>
- <role>owner</role>
- <role>developer</role>
- </roles>
- </developer>
- <developer>
- <id>lararennie</id>
- <name>Lara Rennie</name>
- <email>lararennie@google.com</email>
- <organization>Google</organization>
- <roles>
- <role>developer</role>
- </roles>
- </developer>
- </developers>
-
- <contributors>
- <contributor>
- <name>tronikos</name>
- <email>tronikos@gmail.com</email>
- </contributor>
- <contributor>
- <name>g1smd.email</name>
- <email>g1smd.email@gmail.com</email>
- </contributor>
- <contributor>
- <name>Philippe Liard</name>
- <email>philip.liard@gmail.com</email>
- </contributor>
- </contributors>
-
- <build>
- <sourceDirectory>src</sourceDirectory>
- <testSourceDirectory>test</testSourceDirectory>
- <resources>
- <resource>
- <directory>src/com/google/i18n/phonenumbers/data</directory>
- <targetPath>com/google/i18n/phonenumbers/data</targetPath>
- </resource>
- </resources>
- <testResources>
- <testResource>
- <directory>test/com/google/i18n/phonenumbers/data</directory>
- <targetPath>com/google/i18n/phonenumbers/data</targetPath>
- </testResource>
- <testResource>
- <directory>test/com/google/i18n/phonenumbers/geocoding/testing_data</directory>
- <targetPath>com/google/i18n/phonenumbers/geocoding/testing_data</targetPath>
- </testResource>
- </testResources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.3.1</version>
- <configuration>
- <excludes>
- <exclude>**/geocoding/</exclude>
- </excludes>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.1.2</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.7</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-release-plugin</artifactId>
- <version>2.0-beta-7</version>
- <configuration>
- <tagBase>
- https://libphonenumber.googlecode.com/svn/tags/
- </tagBase>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <id>release-sign-artifacts</id>
- <activation>
- <property>
- <name>performRelease</name>
- <value>true</value>
- </property>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>1.1</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals>
- <goal>sign</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <!-- Development profile that triggers the metadata generation. -->
- <profile>
- <id>dev</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2</version>
- <executions>
- <execution>
- <id>build-metadata</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <executable>java</executable>
- <arguments>
- <argument>-jar</argument>
- <argument>../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar</argument>
- <argument>BuildMetadataProtoFromXml</argument>
- <argument>../resources/PhoneNumberMetaData.xml</argument>
- <argument>src</argument>
- <argument>false</argument> <!-- Not for testing. -->
- <argument>false</argument> <!-- No lite metadata. -->
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>build-test-metadata</id>
- <phase>generate-test-sources</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <executable>java</executable>
- <arguments>
- <argument>-jar</argument>
- <argument>../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar</argument>
- <argument>BuildMetadataProtoFromXml</argument>
- <argument>../resources/PhoneNumberMetaDataForTesting.xml</argument>
- <argument>test</argument>
- <argument>true</argument> <!-- For testing. -->
- <argument>false</argument> <!-- No lite metadata. -->
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>build-geo-data</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <executable>java</executable>
- <arguments>
- <argument>-jar</argument>
- <argument>../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar</argument>
- <argument>GenerateAreaCodeData</argument>
- <argument>../resources/geocoding</argument>
- <argument>src/com/google/i18n/phonenumbers/geocoding/data</argument>
- <argument>false</argument> <!-- Not for testing. -->
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>build-geo-test-data</id>
- <phase>generate-test-sources</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <executable>java</executable>
- <arguments>
- <argument>-jar</argument>
- <argument>../tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar</argument>
- <argument>GenerateAreaCodeData</argument>
- <argument>../resources/test/geocoding</argument>
- <argument>test/com/google/i18n/phonenumbers/geocoding/testing_data</argument>
- <argument>true</argument> <!-- For testing. -->
- </arguments>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/java/release_notes.txt b/java/release_notes.txt
index 2fba846..cbcb8a5 100644
--- a/java/release_notes.txt
+++ b/java/release_notes.txt
@@ -1,3 +1,12 @@
+July 5th, 2011
+* Code changes
+ - Refactored AreaCodeMap to minimize binary and memory footprint by using 2 different strategies.
+ - Refactored BuildMetadataFromXml.java and added unittests.
+
+* Metadata changes
+ - Regenerate binaries for all existing area code mapping data with smaller sizes.
+ - Added city-level area code data mapping for US and Canada.
+
June 29th, 2011
* Code changes
- Fixed issue 38, issue 39, issue 41 and issue 43
diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
index ac8e103..da57a13 100644
--- a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
+++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
@@ -1596,11 +1596,11 @@
}
/**
- * Checks whether countryCode represents the country calling code from a region whose national
- * significant number could contain a leading zero. An example of such a region is Italy. Returns
- * false if no metadata for the country is found.
+ * Checks whether the country calling code is from a region whose national significant number
+ * could contain a leading zero. An example of such a region is Italy. Returns false if no
+ * metadata for the country is found.
*/
- boolean isLeadingZeroPossible(int countryCallingCode) {
+ public boolean isLeadingZeroPossible(int countryCallingCode) {
PhoneMetadata mainMetadataForCallingCode = getMetadataForRegion(
getRegionCodeForCountryCode(countryCallingCode));
if (mainMetadataForCallingCode == null) {
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java b/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java
index 644c14b..8b746e3 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMap.java
@@ -19,13 +19,15 @@
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
import java.util.SortedMap;
import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.logging.Logger;
/**
* A utility that maps phone number prefixes to a string describing the geographical area the prefix
@@ -34,73 +36,109 @@
* @author Shaopeng Jia
*/
public class AreaCodeMap implements Externalizable {
- private int numOfEntries = 0;
- private TreeSet<Integer> possibleLengths = new TreeSet<Integer>();
- private int[] phoneNumberPrefixes;
- private String[] descriptions;
+ private final int countryCallingCode;
+ private final boolean isLeadingZeroPossible;
private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
+ private static final Logger LOGGER = Logger.getLogger(AreaCodeMap.class.getName());
+
+ private AreaCodeMapStorageStrategy areaCodeMapStorage;
+
+ // @VisibleForTesting
+ AreaCodeMapStorageStrategy getAreaCodeMapStorage() {
+ return areaCodeMapStorage;
+ }
/**
* Creates an empty {@link AreaCodeMap}. The default constructor is necessary for implementing
* {@link Externalizable}. The empty map could later populated by
* {@link #readAreaCodeMap(java.util.SortedMap)} or {@link #readExternal(java.io.ObjectInput)}.
+ *
+ * @param countryCallingCode the country calling code for the region that the area code map
+ * belongs to.
*/
- public AreaCodeMap() {}
+ public AreaCodeMap(int countryCallingCode) {
+ this.countryCallingCode = countryCallingCode;
+ isLeadingZeroPossible = phoneUtil.isLeadingZeroPossible(countryCallingCode);
+ }
/**
- * Creates an {@link AreaCodeMap} initialized with {@code sortedAreaCodeMap}.
+ * Gets the size of the provided area code 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);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ mapStorage.writeExternal(objectOutputStream);
+ objectOutputStream.flush();
+ int sizeOfStorage = byteArrayOutputStream.size();
+ objectOutputStream.close();
+ return sizeOfStorage;
+ }
+
+ private AreaCodeMapStorageStrategy createDefaultMapStorage() {
+ return new DefaultMapStorage(countryCallingCode, isLeadingZeroPossible);
+ }
+
+ private AreaCodeMapStorageStrategy createFlyweightMapStorage() {
+ return new FlyweightMapStorage(countryCallingCode, isLeadingZeroPossible);
+ }
+
+ /**
+ * 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
+ * make this method quite expensive.
+ */
+ // @VisibleForTesting
+ AreaCodeMapStorageStrategy getSmallerMapStorage(SortedMap<Integer, String> areaCodeMap) {
+ try {
+ AreaCodeMapStorageStrategy flyweightMapStorage = createFlyweightMapStorage();
+ int sizeOfFlyweightMapStorage = getSizeOfAreaCodeMapStorage(flyweightMapStorage, areaCodeMap);
+
+ AreaCodeMapStorageStrategy defaultMapStorage = createDefaultMapStorage();
+ int sizeOfDefaultMapStorage = getSizeOfAreaCodeMapStorage(defaultMapStorage, areaCodeMap);
+
+ return sizeOfFlyweightMapStorage < sizeOfDefaultMapStorage
+ ? flyweightMapStorage : defaultMapStorage;
+ } catch (IOException e) {
+ LOGGER.severe(e.getMessage());
+ return createFlyweightMapStorage();
+ }
+ }
+
+ /**
+ * Creates an {@link AreaCodeMap} initialized with {@code sortedAreaCodeMap}. 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.
*/
public void readAreaCodeMap(SortedMap<Integer, String> sortedAreaCodeMap) {
- numOfEntries = sortedAreaCodeMap.size();
- phoneNumberPrefixes = new int[numOfEntries];
- descriptions = new String[numOfEntries];
- int index = 0;
- for (int prefix : sortedAreaCodeMap.keySet()) {
- phoneNumberPrefixes[index++] = prefix;
- possibleLengths.add((int) Math.log10(prefix) + 1);
- }
- sortedAreaCodeMap.values().toArray(descriptions);
+ areaCodeMapStorage = getSmallerMapStorage(sortedAreaCodeMap);
}
/**
* Supports Java Serialization.
*/
public void readExternal(ObjectInput objectInput) throws IOException {
- numOfEntries = objectInput.readInt();
- if (phoneNumberPrefixes == null || phoneNumberPrefixes.length < numOfEntries) {
- phoneNumberPrefixes = new int[numOfEntries];
+ // Read the area code map storage strategy flag.
+ boolean useFlyweightMapStorage = objectInput.readBoolean();
+ if (useFlyweightMapStorage) {
+ areaCodeMapStorage = new FlyweightMapStorage(countryCallingCode, isLeadingZeroPossible);
+ } else {
+ areaCodeMapStorage = new DefaultMapStorage(countryCallingCode, isLeadingZeroPossible);
}
- if (descriptions == null || descriptions.length < numOfEntries) {
- descriptions = new String[numOfEntries];
- }
- for (int i = 0; i < numOfEntries; i++) {
- phoneNumberPrefixes[i] = objectInput.readInt();
- descriptions[i] = objectInput.readUTF();
- }
- int sizeOfLengths = objectInput.readInt();
- possibleLengths.clear();
- for (int i = 0; i < sizeOfLengths; i++) {
- possibleLengths.add(objectInput.readInt());
- }
+ areaCodeMapStorage.readExternal(objectInput);
}
/**
* Supports Java Serialization.
*/
public void writeExternal(ObjectOutput objectOutput) throws IOException {
- objectOutput.writeInt(numOfEntries);
- for (int i = 0; i < numOfEntries; i++) {
- objectOutput.writeInt(phoneNumberPrefixes[i]);
- objectOutput.writeUTF(descriptions[i]);
- }
- int sizeOfLengths = possibleLengths.size();
- objectOutput.writeInt(sizeOfLengths);
- for (Integer length : possibleLengths) {
- objectOutput.writeInt(length);
- }
+ objectOutput.writeBoolean(areaCodeMapStorage.isFlyweight());
+ areaCodeMapStorage.writeExternal(objectOutput);
}
/**
@@ -110,13 +148,15 @@
* @return the description of the geographical area
*/
String lookup(PhoneNumber number) {
+ int numOfEntries = areaCodeMapStorage.getNumOfEntries();
if (numOfEntries == 0) {
return "";
}
- long phonePrefix =
- Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number));
+ long phonePrefix = isLeadingZeroPossible
+ ? Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number))
+ : Long.parseLong(phoneUtil.getNationalSignificantNumber(number));
int currentIndex = numOfEntries - 1;
- SortedSet<Integer> currentSetOfLengths = possibleLengths;
+ SortedSet<Integer> currentSetOfLengths = areaCodeMapStorage.getPossibleLengths();
while (currentSetOfLengths.size() > 0) {
Integer possibleLength = currentSetOfLengths.last();
String phonePrefixStr = String.valueOf(phonePrefix);
@@ -127,17 +167,18 @@
if (currentIndex < 0) {
return "";
}
- if (phonePrefix == phoneNumberPrefixes[currentIndex]) {
- return descriptions[currentIndex];
+ int currentPrefix = areaCodeMapStorage.getPrefix(currentIndex);
+ if (phonePrefix == currentPrefix) {
+ return areaCodeMapStorage.getDescription(currentIndex);
}
- currentSetOfLengths = possibleLengths.headSet(possibleLength);
+ currentSetOfLengths = currentSetOfLengths.headSet(possibleLength);
}
return "";
}
/**
- * Does a binary search for {@code value} in the phoneNumberPrefixes array from {@code start} to
- * {@code end} (inclusive). Returns the position if {@code value} is found; otherwise, returns the
+ * Does a binary search for {@code value} in the provided array from {@code start} to {@code end}
+ * (inclusive). Returns the position if {@code value} is found; otherwise, returns the
* position which has the largest value that is less than {@code value}. This means if
* {@code value} is the smallest, -1 will be returned.
*/
@@ -145,9 +186,10 @@
int current = 0;
while (start <= end) {
current = (start + end) / 2;
- if (phoneNumberPrefixes[current] == value) {
+ int currentValue = areaCodeMapStorage.getPrefix(current);
+ if (currentValue == value) {
return current;
- } else if (phoneNumberPrefixes[current] > value) {
+ } else if (currentValue > value) {
current--;
end = current;
} else {
@@ -163,10 +205,15 @@
@Override
public String toString() {
StringBuilder output = new StringBuilder();
+ int numOfEntries = areaCodeMapStorage.getNumOfEntries();
+
for (int i = 0; i < numOfEntries; i++) {
- output.append(phoneNumberPrefixes[i]);
+ if (!isLeadingZeroPossible) {
+ output.append(countryCallingCode);
+ }
+ output.append(areaCodeMapStorage.getPrefix(i));
output.append("|");
- output.append(descriptions[i]);
+ output.append(areaCodeMapStorage.getDescription(i));
output.append("\n");
}
return output.toString();
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java b/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java
new file mode 100644
index 0000000..65fb2bd
--- /dev/null
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/AreaCodeMapStorageStrategy.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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.google.i18n.phonenumbers.geocoding;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.SortedMap;
+import java.util.TreeSet;
+
+/**
+ * Abstracts the way area code data is stored into memory and serialized to a stream.
+ *
+ * @author Philippe Liard
+ */
+// @VisibleForTesting
+abstract class AreaCodeMapStorageStrategy {
+ protected final int countryCallingCode;
+ protected final boolean isLeadingZeroPossible;
+ protected int numOfEntries = 0;
+ protected final TreeSet<Integer> possibleLengths = new TreeSet<Integer>();
+
+ /**
+ * Constructs a new area code map storage strategy from the provided country calling code and
+ * boolean parameter.
+ *
+ * @param countryCallingCode the country calling code of the number prefixes contained in the map
+ * @param isLeadingZeroPossible whether the phone number prefixes belong to a region which
+ * {@link PhoneNumberUtil#isLeadingZeroPossible isLeadingZeroPossible}
+ */
+ public AreaCodeMapStorageStrategy(int countryCallingCode, boolean isLeadingZeroPossible) {
+ this.countryCallingCode = countryCallingCode;
+ this.isLeadingZeroPossible = isLeadingZeroPossible;
+ }
+
+ /**
+ * Returns whether the underlying implementation of this abstract class is flyweight.
+ * It is expected to be flyweight if it implements the {@code FlyweightMapStorage} class.
+ *
+ * @return whether the underlying implementation of this abstract class is flyweight
+ */
+ public abstract boolean isFlyweight();
+
+ /**
+ * @return the number of entries contained in the area code map
+ */
+ public int getNumOfEntries() {
+ return numOfEntries;
+ }
+
+ /**
+ * @return the set containing the possible lengths of prefixes
+ */
+ public TreeSet<Integer> getPossibleLengths() {
+ return possibleLengths;
+ }
+
+ /**
+ * Gets the phone number prefix located at the provided {@code index}.
+ *
+ * @param index the index of the prefix that needs to be returned
+ * @return the phone number prefix at the provided index
+ */
+ public abstract int getPrefix(int index);
+
+ /**
+ * Gets the description corresponding to the phone number prefix located at the provided {@code
+ * index}.
+ *
+ * @param index the index of the phone number prefix that needs to be returned
+ * @return the description corresponding to the phone number prefix at the provided index
+ */
+ public abstract String getDescription(int index);
+
+ /**
+ * Sets the internal state of the underlying storage implementation from the provided {@code
+ * sortedAreaCodeMap} that maps phone number prefixes to description strings.
+ *
+ * @param sortedAreaCodeMap a sorted map that maps phone number prefixes including country
+ * calling code to description strings
+ */
+ public abstract void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap);
+
+ /**
+ * 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
+ * @throws IOException if an error occurred reading the provided input stream
+ */
+ public abstract void readExternal(ObjectInput objectInput) throws IOException;
+
+ /**
+ * 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
+ * @throws IOException if an error occurred writing to the provided output stream
+ */
+ public abstract void writeExternal(ObjectOutput objectOutput) throws IOException;
+
+ /**
+ * Utility class used to pass arguments by "reference".
+ */
+ protected static class Reference<T> {
+ private T data;
+
+ T get () {
+ return data;
+ }
+
+ void set (T data) {
+ this.data = data;
+ }
+ }
+
+ /**
+ * Removes the country calling code from the provided {@code prefix} if the country can't have any
+ * leading zero; otherwise it is left as it is. Sets the provided {@code lengthOfPrefixRef}
+ * parameter to the length of the resulting prefix.
+ *
+ * @param prefix a phone number prefix containing a leading country calling code
+ * @param lengthOfPrefixRef a "reference" to an integer set to the length of the resulting
+ * prefix. This parameter is ignored when set to null.
+ * @return the resulting prefix which may have been stripped
+ */
+ protected int stripPrefix(int prefix, Reference<Integer> lengthOfPrefixRef) {
+ int lengthOfCountryCode = (int) Math.log10(countryCallingCode) + 1;
+ int lengthOfPrefix = (int) Math.log10(prefix) + 1;
+ if (!isLeadingZeroPossible) {
+ lengthOfPrefix -= lengthOfCountryCode;
+ prefix -= countryCallingCode * (int) Math.pow(10, lengthOfPrefix);
+ }
+ if (lengthOfPrefixRef != null) {
+ lengthOfPrefixRef.set(lengthOfPrefix);
+ }
+ return prefix;
+ }
+
+ /**
+ * Removes the country calling code from the provided {@code prefix} if the country can't have any
+ * leading zero; otherwise it is left as it is.
+ *
+ * @param prefix a phone number prefix containing a leading country calling code
+ * @return the resulting prefix which may have been stripped
+ */
+ protected int stripPrefix(int prefix) {
+ return stripPrefix(prefix, null);
+ }
+}
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java b/java/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java
new file mode 100644
index 0000000..03dfa15
--- /dev/null
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/DefaultMapStorage.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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.google.i18n.phonenumbers.geocoding;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.SortedMap;
+
+/**
+ * Default area code 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 {
+
+ public DefaultMapStorage(int countryCallingCode, boolean isLeadingZeroPossible) {
+ super(countryCallingCode, isLeadingZeroPossible);
+ }
+
+ private int[] phoneNumberPrefixes;
+ private String[] descriptions;
+
+ @Override
+ public boolean isFlyweight() {
+ return false;
+ }
+
+ @Override
+ public int getPrefix(int index) {
+ return phoneNumberPrefixes[index];
+ }
+
+ @Override
+ public String getDescription(int index) {
+ return descriptions[index];
+ }
+
+ @Override
+ public void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap) {
+ numOfEntries = sortedAreaCodeMap.size();
+ phoneNumberPrefixes = new int[numOfEntries];
+ descriptions = new String[numOfEntries];
+ int index = 0;
+ for (int prefix : sortedAreaCodeMap.keySet()) {
+ Reference<Integer> lengthOfPrefixRef = new Reference<Integer>();
+ int strippedPrefix = stripPrefix(prefix, lengthOfPrefixRef);
+ phoneNumberPrefixes[index++] = strippedPrefix;
+ possibleLengths.add(lengthOfPrefixRef.get());
+ }
+ sortedAreaCodeMap.values().toArray(descriptions);
+ }
+
+ @Override
+ public void readExternal(ObjectInput objectInput) throws IOException {
+ numOfEntries = objectInput.readInt();
+ if (phoneNumberPrefixes == null || phoneNumberPrefixes.length < numOfEntries) {
+ phoneNumberPrefixes = new int[numOfEntries];
+ }
+ if (descriptions == null || descriptions.length < numOfEntries) {
+ descriptions = new String[numOfEntries];
+ }
+ for (int i = 0; i < numOfEntries; i++) {
+ phoneNumberPrefixes[i] = objectInput.readInt();
+ descriptions[i] = objectInput.readUTF();
+ }
+ int sizeOfLengths = objectInput.readInt();
+ possibleLengths.clear();
+ for (int i = 0; i < sizeOfLengths; i++) {
+ possibleLengths.add(objectInput.readInt());
+ }
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput objectOutput) throws IOException {
+ objectOutput.writeInt(numOfEntries);
+ for (int i = 0; i < numOfEntries; i++) {
+ objectOutput.writeInt(phoneNumberPrefixes[i]);
+ objectOutput.writeUTF(descriptions[i]);
+ }
+ int sizeOfLengths = possibleLengths.size();
+ objectOutput.writeInt(sizeOfLengths);
+ for (Integer length : possibleLengths) {
+ objectOutput.writeInt(length);
+ }
+ }
+}
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java b/java/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java
new file mode 100644
index 0000000..abdf7c5
--- /dev/null
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/FlyweightMapStorage.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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.google.i18n.phonenumbers.geocoding;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+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 description duplicates.
+ *
+ * @author Philippe Liard
+ */
+class FlyweightMapStorage extends AreaCodeMapStorageStrategy {
+ // Size of short and integer types in bytes.
+ private static final int SHORT_SIZE = Short.SIZE / 8;
+ private static final int INT_SIZE = Integer.SIZE / 8;
+
+ // The number of bytes used to store a phone number prefix.
+ private int prefixSizeInBytes;
+ // The number of bytes used to store a description index. It is computed from the size of the
+ // description pool containing all the strings.
+ private int descIndexSizeInBytes;
+
+ // Byte buffer of stripped phone number prefixes. A stripped phone number prefix is a phone number
+ // prefix omitting the country code.
+ private ByteBuffer phoneNumberPrefixes;
+ private ByteBuffer descriptionIndexes;
+
+ // Sorted string array of unique description strings.
+ private String[] descriptionPool;
+
+ public FlyweightMapStorage(int countryCallingCode, boolean isLeadingZeroPossible) {
+ super(countryCallingCode, isLeadingZeroPossible);
+ }
+
+ @Override
+ public boolean isFlyweight() {
+ return true;
+ }
+
+ /**
+ * Gets the minimum number of bytes that can be used to store the provided {@code value}.
+ */
+ private static int getOptimalNumberOfBytesForValue(int value) {
+ return value <= Short.MAX_VALUE ? SHORT_SIZE : INT_SIZE;
+ }
+
+ /**
+ * Stores the provided {@code value} to the provided byte {@code buffer} at the specified {@code
+ * index} using the provided {@code wordSize} in bytes. Note that only integer and short sizes are
+ * supported.
+ *
+ * @param buffer the byte buffer to which the value is stored
+ * @param wordSize the number of bytes used to store the provided value
+ * @param index the index in bytes to which the value is stored
+ * @param value the value that is stored assuming it does not require more than the specified
+ * number of bytes.
+ */
+ private static void storeWordInBuffer(ByteBuffer buffer, int wordSize, int index, int value) {
+ index *= wordSize;
+
+ if (wordSize == SHORT_SIZE) {
+ buffer.putShort(index, (short) value);
+ } else {
+ buffer.putInt(index, value);
+ }
+ }
+
+ /**
+ * Reads the {@code value} at the specified {@code index} from the provided byte {@code buffer}.
+ * Note that only integer and short sizes are supported.
+ *
+ * @param buffer the byte buffer from which the value is read
+ * @param wordSize the number of bytes used to store the value
+ * @param index the index in bytes where the value is read from
+ *
+ * @return the value read from the buffer
+ */
+ private static int readWordFromBuffer(ByteBuffer buffer, int wordSize, int index) {
+ index *= wordSize;
+ return wordSize == SHORT_SIZE ? buffer.getShort(index) : buffer.getInt(index);
+ }
+
+ @Override
+ public int getPrefix(int index) {
+ return readWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, index);
+ }
+
+ @Override
+ public String getDescription(int index) {
+ return descriptionPool[readWordFromBuffer(descriptionIndexes, descIndexSizeInBytes, index)];
+ }
+
+ @Override
+ public void readFromSortedMap(SortedMap<Integer, String> sortedAreaCodeMap) {
+ SortedSet<String> descriptionsSet = new TreeSet<String>();
+ numOfEntries = sortedAreaCodeMap.size();
+ prefixSizeInBytes = getOptimalNumberOfBytesForValue(stripPrefix(sortedAreaCodeMap.lastKey()));
+ phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes);
+ Map<Integer, Integer> strippedToUnstrippedPrefixes = new HashMap<Integer, Integer>();
+
+ // 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 : sortedAreaCodeMap.entrySet()) {
+ int prefix = entry.getKey();
+ Reference<Integer> lengthOfPrefixRef = new Reference<Integer>();
+ int strippedPrefix = stripPrefix(prefix, lengthOfPrefixRef);
+ strippedToUnstrippedPrefixes.put(strippedPrefix, prefix);
+ storeWordInBuffer(phoneNumberPrefixes, prefixSizeInBytes, index++, strippedPrefix);
+ possibleLengths.add(lengthOfPrefixRef.get());
+ descriptionsSet.add(entry.getValue());
+ }
+
+ // Create the description pool.
+ descIndexSizeInBytes = getOptimalNumberOfBytesForValue(descriptionsSet.size() - 1);
+ descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes);
+ descriptionPool = new String[descriptionsSet.size()];
+ descriptionsSet.toArray(descriptionPool);
+
+ // Map the phone number prefixes to the descriptions.
+ index = 0;
+ for (int i = 0; i < numOfEntries; i++) {
+ int strippedPrefix = readWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, i);
+ int prefix = strippedToUnstrippedPrefixes.get(strippedPrefix);
+ String description = sortedAreaCodeMap.get(prefix);
+ int positionIndescriptionPool =
+ Arrays.binarySearch(descriptionPool, description, new Comparator<String>() {
+ public int compare(String o1, String o2) { return o1.compareTo(o2); }
+ });
+ storeWordInBuffer(descriptionIndexes, descIndexSizeInBytes, index++,
+ positionIndescriptionPool);
+ }
+ }
+
+ /**
+ * Stores a value which is read from the provided {@code objectInput} to the provided byte {@code
+ * buffer} at the specified {@code index}.
+ *
+ * @param objectInput the object input stream from which the value is read
+ * @param wordSize the number of bytes used to store the value read from the stream
+ * @param outputBuffer the byte buffer to which the value is stored
+ * @param index the index in bytes where the value is stored in the buffer
+ * @throws IOException if an error occurred reading from the object input stream
+ */
+ private static void readExternalWord(ObjectInput objectInput, int wordSize,
+ ByteBuffer outputBuffer, int index) throws IOException {
+ index *= wordSize;
+ if (wordSize == SHORT_SIZE) {
+ outputBuffer.putShort(index, objectInput.readShort());
+ } else {
+ outputBuffer.putInt(index, objectInput.readInt());
+ }
+ }
+
+ @Override
+ public void readExternal(ObjectInput objectInput) throws IOException {
+ // Read binary words sizes.
+ prefixSizeInBytes = objectInput.readInt();
+ descIndexSizeInBytes = objectInput.readInt();
+ // Read possible lengths.
+ int sizeOfLengths = objectInput.readInt();
+ possibleLengths.clear();
+ for (int i = 0; i < sizeOfLengths; i++) {
+ possibleLengths.add(objectInput.readInt());
+ }
+ // Read description pool size.
+ int descriptionPoolSize = objectInput.readInt();
+ // Read description pool.
+ if (descriptionPool == null || descriptionPool.length < descriptionPoolSize) {
+ descriptionPool = new String[descriptionPoolSize];
+ }
+ for (int i = 0; i < descriptionPoolSize; i++) {
+ String description = objectInput.readUTF();
+ descriptionPool[i] = description;
+ }
+ // Read entries.
+ numOfEntries = objectInput.readInt();
+ if (phoneNumberPrefixes == null || phoneNumberPrefixes.capacity() < numOfEntries) {
+ phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes);
+ }
+ if (descriptionIndexes == null || descriptionIndexes.capacity() < numOfEntries) {
+ descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes);
+ }
+ for (int i = 0; i < numOfEntries; i++) {
+ readExternalWord(objectInput, prefixSizeInBytes, phoneNumberPrefixes, i);
+ readExternalWord(objectInput, descIndexSizeInBytes, descriptionIndexes, i);
+ }
+ }
+
+ /**
+ * Writes the value read from the provided byte {@code buffer} at the specified {@code index} to
+ * the provided {@code objectOutput}.
+ *
+ * @param objectOutput the object output stream to which the value is written
+ * @param wordSize the number of bytes used to store the value
+ * @param inputBuffer the byte buffer from which the value is read
+ * @param index the index of the value in the the byte buffer
+ * @throws IOException if an error occurred writing to the provided object output stream
+ */
+ private static void writeExternalWord(ObjectOutput objectOutput, int wordSize,
+ ByteBuffer inputBuffer, int index) throws IOException {
+ index *= wordSize;
+ if (wordSize == SHORT_SIZE) {
+ objectOutput.writeShort(inputBuffer.getShort(index));
+ } else {
+ objectOutput.writeInt(inputBuffer.getInt(index));
+ }
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput objectOutput) throws IOException {
+ // Write binary words sizes.
+ objectOutput.writeInt(prefixSizeInBytes);
+ objectOutput.writeInt(descIndexSizeInBytes);
+ // Write possible lengths.
+ int sizeOfLengths = possibleLengths.size();
+ objectOutput.writeInt(sizeOfLengths);
+ for (Integer length : possibleLengths) {
+ objectOutput.writeInt(length);
+ }
+ // Write description pool size.
+ objectOutput.writeInt(descriptionPool.length);
+ // Write description pool.
+ for (String description : descriptionPool) {
+ objectOutput.writeUTF(description);
+ }
+ // Write entries.
+ objectOutput.writeInt(numOfEntries);
+ for (int i = 0; i < numOfEntries; i++) {
+ writeExternalWord(objectOutput, prefixSizeInBytes, phoneNumberPrefixes, i);
+ writeExternalWord(objectOutput, descIndexSizeInBytes, descriptionIndexes, i);
+ }
+ }
+}
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java b/java/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
index 1489b6b..ce1ab47 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
@@ -79,18 +79,18 @@
return null;
}
if (!availablePhonePrefixMaps.containsKey(fileName)) {
- loadAreaCodeMapFromFile(fileName);
+ loadAreaCodeMapFromFile(fileName, countryCallingCode);
}
return availablePhonePrefixMaps.get(fileName);
}
- private void loadAreaCodeMapFromFile(String fileName) {
+ private void loadAreaCodeMapFromFile(String fileName, int countryCallingCode) {
InputStream source =
PhoneNumberOfflineGeocoder.class.getResourceAsStream(phonePrefixDataDirectory + fileName);
ObjectInputStream in;
try {
in = new ObjectInputStream(source);
- AreaCodeMap map = new AreaCodeMap();
+ AreaCodeMap map = new AreaCodeMap(countryCallingCode);
map.readExternal(in);
availablePhonePrefixMaps.put(fileName, map);
} catch (IOException e) {
@@ -147,6 +147,9 @@
* @return a text description for the given language code for the given phone number
*/
public String getDescriptionForNumber(PhoneNumber number, Locale languageCode) {
+ if (!phoneUtil.isValidNumber(number)) {
+ return "";
+ }
String areaDescription =
getAreaDescriptionForNumber(
number, languageCode.getLanguage(), "", // No script is specified.
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/1_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/1_en
index d69ae59..5e3e83f 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/1_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/1_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/31_nl b/java/src/com/google/i18n/phonenumbers/geocoding/data/31_nl
index f967ac9..4fa31ff 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/31_nl
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/31_nl
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/33_fr b/java/src/com/google/i18n/phonenumbers/geocoding/data/33_fr
index 22a814f..29011e9 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/33_fr
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/33_fr
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/34_es b/java/src/com/google/i18n/phonenumbers/geocoding/data/34_es
index a6efe20..f9f7e4c 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/34_es
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/34_es
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/351_pt b/java/src/com/google/i18n/phonenumbers/geocoding/data/351_pt
index 7602825..9095abd 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/351_pt
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/351_pt
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/39_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/39_en
index 70770e8..fada2f3 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/39_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/39_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/39_it b/java/src/com/google/i18n/phonenumbers/geocoding/data/39_it
index fe09c12..3f5de0f 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/39_it
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/39_it
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_de b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_de
index 9abebd2..e0021ed 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_de
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_de
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_en
index 667abf2..f5c26cc 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_fr b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_fr
index 3d8b7e1..d417de2 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_fr
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_fr
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_it b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_it
index 16fe35d..845a7f6 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/41_it
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/41_it
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/43_de b/java/src/com/google/i18n/phonenumbers/geocoding/data/43_de
index 270c2c9..9be50ca 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/43_de
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/43_de
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/44_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/44_en
index d938bb2..f826dc7 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/44_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/44_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/46_sv b/java/src/com/google/i18n/phonenumbers/geocoding/data/46_sv
index c566c43..a8ebc9c 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/46_sv
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/46_sv
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/49_de b/java/src/com/google/i18n/phonenumbers/geocoding/data/49_de
index 87926bd..0df583f 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/49_de
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/49_de
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/54_es b/java/src/com/google/i18n/phonenumbers/geocoding/data/54_es
index d4df906..5c5f5ec 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/54_es
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/54_es
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/55_pt b/java/src/com/google/i18n/phonenumbers/geocoding/data/55_pt
index 3cab21f..7c2edf9 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/55_pt
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/55_pt
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/56_es b/java/src/com/google/i18n/phonenumbers/geocoding/data/56_es
index f36465f..deb60d9 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/56_es
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/56_es
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/7_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/7_en
index f0521db..b39cd8a 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/7_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/7_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/81_ja b/java/src/com/google/i18n/phonenumbers/geocoding/data/81_ja
index d117824..7efb738 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/81_ja
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/81_ja
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_en
index 964e026..fdeaf4b 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_ko b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_ko
index 69c8afe..5e96f81 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_ko
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_ko
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh
index eccb8a7..f7f64a9 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant
index e677541..a2e1825 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/82_zh_Hant
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/86_zh b/java/src/com/google/i18n/phonenumbers/geocoding/data/86_zh
index 82239cd..ec58dc5 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/86_zh
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/86_zh
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/886_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/886_en
index ede9054..b17f140 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/886_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/886_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh b/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh
index cf47b0a..7b81483 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant b/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant
index 1435c4e..130d643 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/886_zh_Hant
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/90_en b/java/src/com/google/i18n/phonenumbers/geocoding/data/90_en
index fd8a282..3efa0e3 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/90_en
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/90_en
Binary files differ
diff --git a/java/src/com/google/i18n/phonenumbers/geocoding/data/90_tr b/java/src/com/google/i18n/phonenumbers/geocoding/data/90_tr
index 1b6f56d..741cbd5 100644
--- a/java/src/com/google/i18n/phonenumbers/geocoding/data/90_tr
+++ b/java/src/com/google/i18n/phonenumbers/geocoding/data/90_tr
Binary files differ
diff --git a/java/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java b/java/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java
index 07b9451..7d17975 100644
--- a/java/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java
+++ b/java/test/com/google/i18n/phonenumbers/geocoding/AreaCodeMapTest.java
@@ -26,8 +26,6 @@
import java.io.ObjectOutputStream;
import java.util.SortedMap;
import java.util.TreeMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* Unittests for AreaCodeMap.java
@@ -35,85 +33,161 @@
* @author Shaopeng Jia
*/
public class AreaCodeMapTest extends TestCase {
- private final AreaCodeMap areaCodeMap = new AreaCodeMap();
+ private final AreaCodeMap areaCodeMapForUS = new AreaCodeMap(1);
+ private final AreaCodeMap areaCodeMapForIT = new AreaCodeMap(39);
private PhoneNumber number = new PhoneNumber();
- private static final Logger LOGGER = Logger.getLogger(AreaCodeMapTest.class.getName());
- static final String TEST_META_DATA_FILE_PREFIX =
- "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting";
public AreaCodeMapTest() {
+ SortedMap<Integer, String> sortedMapForUS = new TreeMap<Integer, String>();
+ sortedMapForUS.put(1212, "New York");
+ sortedMapForUS.put(1480, "Arizona");
+ sortedMapForUS.put(1650, "California");
+ sortedMapForUS.put(1907, "Alaska");
+ sortedMapForUS.put(1201664, "Westwood, NJ");
+ sortedMapForUS.put(1480893, "Phoenix, AZ");
+ sortedMapForUS.put(1501372, "Little Rock, AR");
+ sortedMapForUS.put(1626308, "Alhambra, CA");
+ sortedMapForUS.put(1650345, "San Mateo, CA");
+ sortedMapForUS.put(1867993, "Dawson, YT");
+ sortedMapForUS.put(1972480, "Richardson, TX");
+
+ areaCodeMapForUS.readAreaCodeMap(sortedMapForUS);
+
+ SortedMap<Integer, String> sortedMapForIT = new TreeMap<Integer, String>();
+ sortedMapForIT.put(3902, "Milan");
+ sortedMapForIT.put(3906, "Rome");
+ sortedMapForIT.put(39010, "Genoa");
+ sortedMapForIT.put(390131, "Alessandria");
+ sortedMapForIT.put(390321, "Novara");
+ sortedMapForIT.put(390975, "Potenza");
+
+ areaCodeMapForIT.readAreaCodeMap(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.
+ sortedMap.put(121212345, "New York");
+ sortedMap.put(148034434, "Arizona");
+ return sortedMap;
+ }
+
+ private static SortedMap<Integer, String> createFlyweightStorageMapCandidate() {
SortedMap<Integer, String> sortedMap = new TreeMap<Integer, String>();
sortedMap.put(1212, "New York");
+ sortedMap.put(1213, "New York");
+ sortedMap.put(1214, "New York");
sortedMap.put(1480, "Arizona");
- sortedMap.put(1650, "California");
- sortedMap.put(1907, "Alaska");
- sortedMap.put(1201664, "Westwood, NJ");
- sortedMap.put(1480893, "Phoenix, AZ");
- sortedMap.put(1501372, "Little Rock, AR");
- sortedMap.put(1626308, "Alhambra, CA");
- sortedMap.put(1650345, "San Mateo, CA");
- sortedMap.put(1867993, "Dawson, YT");
- sortedMap.put(1972480, "Richardson, TX");
+ return sortedMap;
+ }
- areaCodeMap.readAreaCodeMap(sortedMap);
+ public void testGetSmallerMapStorageChoosesDefaultImpl() {
+ AreaCodeMapStorageStrategy mapStorage =
+ new AreaCodeMap(1).getSmallerMapStorage(createDefaultStorageMapCandidate());
+ assertFalse(mapStorage.isFlyweight());
+ }
+
+ public void testGetSmallerMapStorageChoosesFlyweightImpl() {
+ AreaCodeMapStorageStrategy mapStorage =
+ new AreaCodeMap(1).getSmallerMapStorage(createFlyweightStorageMapCandidate());
+ assertTrue(mapStorage.isFlyweight());
}
public void testLookupInvalidNumber_US() {
// central office code cannot start with 1.
number.setCountryCode(1).setNationalNumber(2121234567L);
- assertEquals("New York", areaCodeMap.lookup(number));
+ assertEquals("New York", areaCodeMapForUS.lookup(number));
}
public void testLookupNumber_NJ() {
number.setCountryCode(1).setNationalNumber(2016641234L);
- assertEquals("Westwood, NJ", areaCodeMap.lookup(number));
+ assertEquals("Westwood, NJ", areaCodeMapForUS.lookup(number));
}
public void testLookupNumber_NY() {
number.setCountryCode(1).setNationalNumber(2126641234L);
- assertEquals("New York", areaCodeMap.lookup(number));
+ assertEquals("New York", areaCodeMapForUS.lookup(number));
}
public void testLookupNumber_CA_1() {
number.setCountryCode(1).setNationalNumber(6503451234L);
- assertEquals("San Mateo, CA", areaCodeMap.lookup(number));
+ assertEquals("San Mateo, CA", areaCodeMapForUS.lookup(number));
}
public void testLookupNumber_CA_2() {
number.setCountryCode(1).setNationalNumber(6502531234L);
- assertEquals("California", areaCodeMap.lookup(number));
+ assertEquals("California", areaCodeMapForUS.lookup(number));
}
public void testLookupNumberFound_TX() {
number.setCountryCode(1).setNationalNumber(9724801234L);
- assertEquals("Richardson, TX", areaCodeMap.lookup(number));
+ assertEquals("Richardson, TX", areaCodeMapForUS.lookup(number));
}
public void testLookupNumberNotFound_TX() {
number.setCountryCode(1).setNationalNumber(9724811234L);
- assertEquals("", areaCodeMap.lookup(number));
+ assertEquals("", areaCodeMapForUS.lookup(number));
}
public void testLookupNumber_CH() {
number.setCountryCode(41).setNationalNumber(446681300L);
- assertEquals("", areaCodeMap.lookup(number));
+ assertEquals("", areaCodeMapForUS.lookup(number));
}
- public void testReadWriteExternal() {
- try {
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
- areaCodeMap.writeExternal(objectOutputStream);
- objectOutputStream.flush();
+ public void testLookupNumber_IT() {
+ number.setCountryCode(39).setNationalNumber(212345678L).setItalianLeadingZero(true);
+ assertEquals("Milan", areaCodeMapForIT.lookup(number));
- AreaCodeMap newAreaCodeMap = new AreaCodeMap();
- newAreaCodeMap.readExternal(
- new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
+ number.setNationalNumber(612345678L);
+ assertEquals("Rome", areaCodeMapForIT.lookup(number));
- assertEquals(areaCodeMap.toString(), newAreaCodeMap.toString());
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, e.getMessage());
- fail();
- }
+ number.setNationalNumber(3211234L);
+ assertEquals("Novara", areaCodeMapForIT.lookup(number));
+
+ // A mobile number
+ number.setNationalNumber(321123456L).setItalianLeadingZero(false);
+ assertEquals("", areaCodeMapForIT.lookup(number));
+
+ // An invalid number (too short)
+ number.setNationalNumber(321123L).setItalianLeadingZero(true);
+ assertEquals("Novara", areaCodeMapForIT.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.
+ */
+ private static AreaCodeMap createNewAreaCodeMap(AreaCodeMap areaCodeMap)
+ throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ areaCodeMap.writeExternal(objectOutputStream);
+ objectOutputStream.flush();
+
+ AreaCodeMap newAreaCodeMap = new AreaCodeMap(1);
+ newAreaCodeMap.readExternal(
+ new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
+ return newAreaCodeMap;
+ }
+
+ public void testReadWriteExternalWithDefaultStrategy() throws IOException {
+ AreaCodeMap localAreaCodeMap = new AreaCodeMap(1);
+ localAreaCodeMap.readAreaCodeMap(createDefaultStorageMapCandidate());
+ assertFalse(localAreaCodeMap.getAreaCodeMapStorage().isFlyweight());
+
+ AreaCodeMap newAreaCodeMap;
+ newAreaCodeMap = createNewAreaCodeMap(localAreaCodeMap);
+ assertEquals(localAreaCodeMap.toString(), newAreaCodeMap.toString());
+ }
+
+ public void testReadWriteExternalWithFlyweightStrategy() throws IOException {
+ AreaCodeMap localAreaCodeMap = new AreaCodeMap(1);
+ localAreaCodeMap.readAreaCodeMap(createFlyweightStorageMapCandidate());
+ assertTrue(localAreaCodeMap.getAreaCodeMapStorage().isFlyweight());
+
+ AreaCodeMap newAreaCodeMap;
+ newAreaCodeMap = createNewAreaCodeMap(localAreaCodeMap);
+ assertEquals(localAreaCodeMap.toString(), newAreaCodeMap.toString());
}
}
diff --git a/java/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java b/java/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java
index 0fbdafb..ec5f9bc 100644
--- a/java/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java
+++ b/java/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java
@@ -39,12 +39,16 @@
new PhoneNumber().setCountryCode(82).setNationalNumber(322123456L);
private static final PhoneNumber KO_NUMBER3 =
new PhoneNumber().setCountryCode(82).setNationalNumber(6421234567L);
+ private static final PhoneNumber KO_INVALID_NUMBER =
+ new PhoneNumber().setCountryCode(82).setNationalNumber(1234L);
private static final PhoneNumber US_NUMBER1 =
new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
private static final PhoneNumber US_NUMBER2 =
new PhoneNumber().setCountryCode(1).setNationalNumber(6509600000L);
private static final PhoneNumber US_NUMBER3 =
new PhoneNumber().setCountryCode(1).setNationalNumber(2128120000L);
+ private static final PhoneNumber US_INVALID_NUMBER =
+ new PhoneNumber().setCountryCode(1).setNationalNumber(1234567890L);
private static final PhoneNumber BS_NUMBER1 =
new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L);
private static final PhoneNumber AU_NUMBER =
@@ -90,4 +94,9 @@
assertEquals("\uC81C\uC8FC",
geocoder.getDescriptionForNumber(KO_NUMBER3, Locale.KOREAN));
}
+
+ public void testGetDescritionForInvaildNumber() {
+ assertEquals("", geocoder.getDescriptionForNumber(KO_INVALID_NUMBER, Locale.ENGLISH));
+ assertEquals("", geocoder.getDescriptionForNumber(US_INVALID_NUMBER, Locale.ENGLISH));
+ }
}
diff --git a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/1_en b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/1_en
index 6ef7841..74ef19c 100644
--- a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/1_en
+++ b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/1_en
Binary files differ
diff --git a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en
index 964e026..fdeaf4b 100644
--- a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en
+++ b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en
Binary files differ
diff --git a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko
index 69c8afe..5e96f81 100644
--- a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko
+++ b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_ko
Binary files differ
diff --git a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/86_en b/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/86_en
deleted file mode 100644
index 710e1e7..0000000
--- a/java/test/com/google/i18n/phonenumbers/geocoding/testing_data/86_en
+++ /dev/null
Binary files differ