diff --git a/java/build.xml b/java/build.xml
index 18e30b26f..32157351e 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -45,6 +45,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -73,6 +87,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/libphonenumber/pom.xml b/java/libphonenumber/pom.xml
index 8fd96216b..756de62b4 100644
--- a/java/libphonenumber/pom.xml
+++ b/java/libphonenumber/pom.xml
@@ -28,6 +28,20 @@
com/google/i18n/phonenumbers/data
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ **/SingleFileMetadataSourceImpl.class
+ **/SingleFileMetadataSourceImpl.java
+ **/PhoneNumberMetadataProtoFile
+ **/PhoneNumberMetadataProtoForTestingFile
+
+
+
+
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/SingleFileMetadataSourceImpl.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/SingleFileMetadataSourceImpl.java
new file mode 100644
index 000000000..1b03fd485
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/SingleFileMetadataSourceImpl.java
@@ -0,0 +1,98 @@
+package com.google.i18n.phonenumbers;
+
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of {@link MetadataSource} that reads from a resource file
+ * during initialization.
+ */
+public final class SingleFileMetadataSourceImpl implements MetadataSource {
+
+ private static final Logger logger =
+ Logger.getLogger(SingleFileMetadataSourceImpl.class.getName());
+
+ private static final String META_DATA_FILE =
+ "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoFile";
+
+ // A mapping from a region code to the PhoneMetadata for that region.
+ // Note: Synchronization, though only needed for the Android version of the library, is used in
+ // all versions for consistency.
+ private final Map regionToMetadataMap =
+ Collections.synchronizedMap(new HashMap());
+
+ // A mapping from a country calling code for a non-geographical entity to the PhoneMetadata for
+ // that country calling code. Examples of the country calling codes include 800 (International
+ // Toll Free Service) and 808 (International Shared Cost Service).
+ // Note: Synchronization, though only needed for the Android version of the library, is used in
+ // all versions for consistency.
+ private final Map countryCodeToNonGeographicalMetadataMap =
+ Collections.synchronizedMap(new HashMap());
+
+ // It is assumed that metadataLoader is not null.
+ public SingleFileMetadataSourceImpl(MetadataLoader metadataLoader) {
+ InputStream input = metadataLoader.loadMetadata(META_DATA_FILE);
+ if (input == null) {
+ throw new IllegalStateException(
+ "no metadata available for PhoneNumberUtil: " + META_DATA_FILE);
+ }
+ PhoneMetadataCollection metadataCollection = loadMetadataAndCloseInput(input);
+ for (PhoneMetadata metadata : metadataCollection.getMetadataList()) {
+ String regionCode = metadata.getId();
+ int countryCallingCode = metadata.getCountryCode();
+ if (PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode)) {
+ countryCodeToNonGeographicalMetadataMap.put(countryCallingCode, metadata);
+ } else {
+ regionToMetadataMap.put(regionCode, metadata);
+ }
+ }
+ }
+
+ @Override
+ public PhoneMetadata getMetadataForRegion(String regionCode) {
+ return regionToMetadataMap.get(regionCode);
+ }
+
+ @Override
+ public PhoneMetadata getMetadataForNonGeographicalRegion(int countryCallingCode) {
+ return countryCodeToNonGeographicalMetadataMap.get(countryCallingCode);
+ }
+
+ /**
+ * Loads the metadata protocol buffer from the given stream and closes the stream afterwards. Any
+ * exceptions that occur while reading the stream are propagated (though exceptions that occur
+ * when the stream is closed will be ignored).
+ *
+ * @param source the non-null stream from which metadata is to be read.
+ * @return the loaded metadata protocol buffer.
+ */
+ private static PhoneMetadataCollection loadMetadataAndCloseInput(InputStream source) {
+ PhoneMetadataCollection metadataCollection = new PhoneMetadataCollection();
+ try {
+ // Read in metadata for each region.
+ ObjectInputStream in = new ObjectInputStream(source);
+ metadataCollection.readExternal(in);
+ return metadataCollection;
+ } catch (IOException e) {
+ logger.log(Level.WARNING, e.toString());
+ } finally {
+ try {
+ source.close();
+ } catch (IOException e) {
+ logger.log(Level.WARNING, e.toString());
+ }
+ }
+ return metadataCollection;
+ }
+}
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoFile b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoFile
new file mode 100644
index 000000000..bb8b6e904
Binary files /dev/null and b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoFile differ
diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTestingFile b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTestingFile
new file mode 100644
index 000000000..1ddfc3afe
Binary files /dev/null and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTestingFile differ
diff --git a/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar b/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar
index 7a6578efb..6e0b5bcbc 100644
Binary files a/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar and b/tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar differ
diff --git a/tools/java/java-build/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java b/tools/java/java-build/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
index 57980faf6..1390865bb 100644
--- a/tools/java/java-build/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
+++ b/tools/java/java-build/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
@@ -50,6 +50,7 @@ public class BuildMetadataProtoFromXml extends Command {
// Command line parameter names.
private static final String INPUT_FILE = "input-file";
private static final String OUTPUT_DIR = "output-dir";
+ private static final String OUTPUT_FILE = "output-file";
private static final String DATA_PREFIX = "data-prefix";
private static final String MAPPING_CLASS = "mapping-class";
private static final String COPYRIGHT = "copyright";
@@ -60,6 +61,8 @@ public class BuildMetadataProtoFromXml extends Command {
"\n" +
" --" + INPUT_FILE + "=PATH Read phone number metadata in XML format from PATH.\n" +
" --" + OUTPUT_DIR + "=PATH Use PATH as the root directory for output files.\n" +
+ " --" + OUTPUT_FILE + "=PATH Writes to PATH.\n" +
+ " Only 1 of " + OUTPUT_DIR + " or " + OUTPUT_FILE + " must be specified.\n" +
" --" + DATA_PREFIX +
"=PATH Use PATH (relative to " + OUTPUT_DIR + ") as the basename when\n" +
" writing phone number metadata (one file per region) in\n" +
@@ -76,6 +79,7 @@ public class BuildMetadataProtoFromXml extends Command {
CLASS_NAME + " \\\n" +
" --" + INPUT_FILE + "=resources/PhoneNumberMetadata.xml \\\n" +
" --" + OUTPUT_DIR + "=java/libphonenumber/src/com/google/i18n/phonenumbers \\\n" +
+ " --" + OUTPUT_FILE + "=java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMetadataProto \\\n" +
" --" + DATA_PREFIX + "=data/PhoneNumberMetadataProto \\\n" +
" --" + MAPPING_CLASS + "=CountryCodeToRegionCodeMap \\\n" +
" --" + COPYRIGHT + "=2010 \\\n" +
@@ -98,6 +102,7 @@ public class BuildMetadataProtoFromXml extends Command {
String inputFile = null;
String outputDir = null;
+ String outputFile = null;
String dataPrefix = null;
String mappingClass = null;
String copyright = null;
@@ -116,6 +121,8 @@ public class BuildMetadataProtoFromXml extends Command {
inputFile = value;
} else if (OUTPUT_DIR.equals(key)) {
outputDir = value;
+ } else if (OUTPUT_FILE.equals(key)) {
+ outputFile = value;
} else if (DATA_PREFIX.equals(key)) {
dataPrefix = value;
} else if (MAPPING_CLASS.equals(key)) {
@@ -133,7 +140,7 @@ public class BuildMetadataProtoFromXml extends Command {
}
if (inputFile == null ||
- outputDir == null ||
+ ((outputDir == null) == (outputFile == null)) ||
dataPrefix == null ||
mappingClass == null ||
copyright == null) {
@@ -141,24 +148,33 @@ public class BuildMetadataProtoFromXml extends Command {
return false;
}
- String filePrefix = new File(outputDir, dataPrefix).getPath();
-
try {
PhoneMetadataCollection metadataCollection =
BuildMetadataFromXml.buildPhoneMetadataCollection(inputFile, liteBuild);
- for (PhoneMetadata metadata : metadataCollection.getMetadataList()) {
- String regionCode = metadata.getId();
- // For non-geographical country calling codes (e.g. +800), or for alternate formats, use the
- // country calling codes instead of the region code to form the file name.
- if (regionCode.equals("001") || regionCode.isEmpty()) {
- regionCode = Integer.toString(metadata.getCountryCode());
+ if (outputDir != null) {
+ String filePrefix = new File(outputDir, dataPrefix).getPath();
+ for (PhoneMetadata metadata : metadataCollection.getMetadataList()) {
+ String regionCode = metadata.getId();
+ // For non-geographical country calling codes (e.g. +800), or for alternate formats, use the
+ // country calling codes instead of the region code to form the file name.
+ if (regionCode.equals("001") || regionCode.isEmpty()) {
+ regionCode = Integer.toString(metadata.getCountryCode());
+ }
+ PhoneMetadataCollection outMetadataCollection = new PhoneMetadataCollection();
+ outMetadataCollection.addMetadata(metadata);
+ FileOutputStream outputForRegion = new FileOutputStream(filePrefix + "_" + regionCode);
+ ObjectOutputStream out = new ObjectOutputStream(outputForRegion);
+ outMetadataCollection.writeExternal(out);
+ out.close();
}
- PhoneMetadataCollection outMetadataCollection = new PhoneMetadataCollection();
- outMetadataCollection.addMetadata(metadata);
- FileOutputStream outputForRegion = new FileOutputStream(filePrefix + "_" + regionCode);
- ObjectOutputStream out = new ObjectOutputStream(outputForRegion);
- outMetadataCollection.writeExternal(out);
+ }
+
+ if (outputFile != null) {
+ String fileName = new File(outputFile, dataPrefix).getPath();
+ FileOutputStream output = new FileOutputStream(fileName);
+ ObjectOutputStream out = new ObjectOutputStream(output);
+ metadataCollection.writeExternal(out);
out.close();
}
diff --git a/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar b/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar
index fd8fb6bcf..17d6931fc 100644
Binary files a/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar and b/tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar differ