|
|
|
@ -16,6 +16,8 @@ |
|
|
|
|
|
|
|
package com.google.i18n.phonenumbers; |
|
|
|
|
|
|
|
import com.google.auto.value.AutoValue; |
|
|
|
import com.google.common.collect.ImmutableSortedSet; |
|
|
|
import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; |
|
|
|
import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection; |
|
|
|
|
|
|
|
@ -35,6 +37,7 @@ import java.util.SortedSet; |
|
|
|
import java.util.TreeSet; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
import javax.annotation.Nullable; |
|
|
|
|
|
|
|
/** |
|
|
|
* Tool to convert phone number metadata from the XML format to protocol buffer format. |
|
|
|
@ -101,9 +104,25 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
"/* This file is automatically generated by {@link " + CLASS_NAME + "}.\n" + |
|
|
|
" * Please don't modify it directly.\n" + |
|
|
|
" */\n\n"; |
|
|
|
|
|
|
|
private static final String MAP_COMMENT = |
|
|
|
" // A mapping from a country code to the region codes which denote the\n" + |
|
|
|
" // country/region represented by that country code. In the case of multiple\n" + |
|
|
|
" // countries sharing a calling code, such as the NANPA countries, the one\n" + |
|
|
|
" // indicated with \"isMainCountryForCode\" in the metadata should be first.\n"; |
|
|
|
private static final String COUNTRY_CODE_SET_COMMENT = |
|
|
|
" // A set of all country codes for which data is available.\n"; |
|
|
|
private static final String REGION_CODE_SET_COMMENT = |
|
|
|
" // A set of all region codes for which data is available.\n"; |
|
|
|
private static final double CAPACITY_FACTOR = 0.75; |
|
|
|
private static final String CAPACITY_COMMENT = |
|
|
|
" // The capacity is set to %d as there are %d different entries,\n" + |
|
|
|
" // and this offers a load factor of roughly " + CAPACITY_FACTOR + ".\n"; |
|
|
|
|
|
|
|
private static final String REGION_CODE_CONSTS_COMMENT = |
|
|
|
" // Class containing string constants of region codes for easier testing.\n"; |
|
|
|
private static final String REGION_CODE_CONSTS_JAVADOC = |
|
|
|
"/**\n" + |
|
|
|
" * Class containing string constants of region codes for easier testing.\n" + |
|
|
|
" */\n"; |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getCommandName() { |
|
|
|
@ -241,20 +260,6 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
System.out.println("Deleted " + counter + " old files"); |
|
|
|
} |
|
|
|
|
|
|
|
private static final String MAP_COMMENT = |
|
|
|
" // A mapping from a country code to the region codes which denote the\n" + |
|
|
|
" // country/region represented by that country code. In the case of multiple\n" + |
|
|
|
" // countries sharing a calling code, such as the NANPA countries, the one\n" + |
|
|
|
" // indicated with \"isMainCountryForCode\" in the metadata should be first.\n"; |
|
|
|
private static final String COUNTRY_CODE_SET_COMMENT = |
|
|
|
" // A set of all country codes for which data is available.\n"; |
|
|
|
private static final String REGION_CODE_SET_COMMENT = |
|
|
|
" // A set of all region codes for which data is available.\n"; |
|
|
|
private static final double CAPACITY_FACTOR = 0.75; |
|
|
|
private static final String CAPACITY_COMMENT = |
|
|
|
" // The capacity is set to %d as there are %d different entries,\n" + |
|
|
|
" // and this offers a load factor of roughly " + CAPACITY_FACTOR + ".\n"; |
|
|
|
|
|
|
|
private static void writeCountryCallingCodeMappingToJavaFile( |
|
|
|
Map<Integer, List<String>> countryCodeToRegionCodeMap, |
|
|
|
String outputDir, String mappingClass, String copyright) throws IOException { |
|
|
|
@ -269,7 +274,11 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
} |
|
|
|
boolean hasCountryCodes = countryCodeToRegionCodeMap.size() > 1; |
|
|
|
|
|
|
|
ClassWriter writer = new ClassWriter(outputDir, mappingClass, copyright); |
|
|
|
ClassWriter.Builder writer = ClassWriter.builder() |
|
|
|
.setOutputDir(outputDir) |
|
|
|
.setCopyright(Integer.parseInt(copyright)) |
|
|
|
.setModifiers("public") |
|
|
|
.setName(mappingClass); |
|
|
|
|
|
|
|
int capacity = (int) (countryCodeToRegionCodeMap.size() / CAPACITY_FACTOR); |
|
|
|
if (hasRegionCodes && hasCountryCodes) { |
|
|
|
@ -282,10 +291,10 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
writeRegionCodeSet(writer, capacity, regionCodeList); |
|
|
|
} |
|
|
|
|
|
|
|
writer.writeToFile(); |
|
|
|
writer.build().writeToFile(); |
|
|
|
} |
|
|
|
|
|
|
|
private static void writeMap(ClassWriter writer, int capacity, |
|
|
|
private static void writeMap(ClassWriter.Builder writer, int capacity, |
|
|
|
Map<Integer, List<String>> countryCodeToRegionCodeMap) { |
|
|
|
writer.addToBody(MAP_COMMENT); |
|
|
|
|
|
|
|
@ -319,7 +328,7 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
writer.addToBody(" }\n"); |
|
|
|
} |
|
|
|
|
|
|
|
private static void writeRegionCodeSet(ClassWriter writer, int capacity, |
|
|
|
private static void writeRegionCodeSet(ClassWriter.Builder writer, int capacity, |
|
|
|
List<String> regionCodeList) { |
|
|
|
writer.addToBody(REGION_CODE_SET_COMMENT); |
|
|
|
|
|
|
|
@ -340,7 +349,7 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
writer.addToBody(" }\n"); |
|
|
|
} |
|
|
|
|
|
|
|
private static void writeCountryCodeSet(ClassWriter writer, int capacity, |
|
|
|
private static void writeCountryCodeSet(ClassWriter.Builder writer, int capacity, |
|
|
|
Set<Integer> countryCodeSet) { |
|
|
|
writer.addToBody(COUNTRY_CODE_SET_COMMENT); |
|
|
|
|
|
|
|
@ -361,9 +370,15 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
writer.addToBody(" }\n"); |
|
|
|
} |
|
|
|
|
|
|
|
private static void writeRegionCodeConstantsToJavaFile(Collection<String> regionCodeList, String outputDir, String copyright) throws IOException { |
|
|
|
ClassWriter writer = new ClassWriter(outputDir, "RegionCode", copyright, "final"); |
|
|
|
writer.addToBody(REGION_CODE_CONSTS_COMMENT); |
|
|
|
private static void writeRegionCodeConstantsToJavaFile(Collection<String> regionCodeList, |
|
|
|
String outputDir, String copyright) throws IOException { |
|
|
|
ClassWriter.Builder writer = ClassWriter.builder() |
|
|
|
.setOutputDir(outputDir) |
|
|
|
.setName("RegionCode") |
|
|
|
.setModifiers("final") |
|
|
|
.setCopyright(Integer.parseInt(copyright)); |
|
|
|
|
|
|
|
writer.addToJavadoc(REGION_CODE_CONSTS_JAVADOC); |
|
|
|
|
|
|
|
for (String regionCode : regionCodeList) { |
|
|
|
String variableName = regionCode.toUpperCase(); |
|
|
|
@ -376,60 +391,89 @@ public class BuildMetadataProtoFromXml extends Command { |
|
|
|
writer.addToBody(" static final String " + variableName + " = \"" + regionCode + "\";\n"); |
|
|
|
} |
|
|
|
|
|
|
|
writer.writeToFile(); |
|
|
|
writer.build().writeToFile(); |
|
|
|
} |
|
|
|
|
|
|
|
private static final class ClassWriter { |
|
|
|
private final String name; |
|
|
|
private final String copyright; |
|
|
|
private final String modifiers; |
|
|
|
|
|
|
|
private final SortedSet<String> imports; |
|
|
|
private final StringBuffer body; |
|
|
|
private final Formatter formatter; |
|
|
|
private final Writer writer; |
|
|
|
|
|
|
|
ClassWriter(String outputDir, String name, String copyright, String modifiers) throws IOException { |
|
|
|
this.name = name; |
|
|
|
this.copyright = copyright; |
|
|
|
this.modifiers = modifiers; |
|
|
|
|
|
|
|
imports = new TreeSet<String>(); |
|
|
|
body = new StringBuffer(); |
|
|
|
formatter = new Formatter(body); |
|
|
|
writer = new BufferedWriter(new FileWriter(new File(outputDir, name + ".java"))); |
|
|
|
} |
|
|
|
|
|
|
|
ClassWriter(String outputDir, String name, String copyright) throws IOException { |
|
|
|
this(outputDir, name, copyright, "public"); |
|
|
|
@AutoValue |
|
|
|
abstract static class ClassWriter { |
|
|
|
abstract String outputDir(); |
|
|
|
|
|
|
|
abstract Integer copyright(); |
|
|
|
abstract ImmutableSortedSet<String> imports(); |
|
|
|
abstract String javadoc(); |
|
|
|
abstract String modifiers(); |
|
|
|
abstract String name(); |
|
|
|
abstract String body(); |
|
|
|
|
|
|
|
static Builder builder() { |
|
|
|
return new AutoValue_BuildMetadataProtoFromXml_ClassWriter.Builder() |
|
|
|
.setModifiers(""); |
|
|
|
} |
|
|
|
|
|
|
|
void addToImports(String name) { |
|
|
|
imports.add(name); |
|
|
|
} |
|
|
|
@AutoValue.Builder |
|
|
|
abstract static class Builder { |
|
|
|
abstract Builder setOutputDir(String outputDir); |
|
|
|
|
|
|
|
abstract Builder setCopyright(Integer copyright); |
|
|
|
|
|
|
|
abstract ImmutableSortedSet.Builder<String> importsBuilder(); |
|
|
|
final Builder addToImports(String name) { |
|
|
|
importsBuilder().add(name); |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
void addToBody(CharSequence text) { |
|
|
|
body.append(text); |
|
|
|
} |
|
|
|
abstract Builder setJavadoc(String javadoc); |
|
|
|
private final StringBuilder javadocBuilder = new StringBuilder(); |
|
|
|
final Builder addToJavadoc(String text) { |
|
|
|
javadocBuilder.append(text); |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
abstract Builder setName(String name); |
|
|
|
abstract Builder setModifiers(String modifiers); |
|
|
|
|
|
|
|
abstract Builder setBody(String body); |
|
|
|
private final StringBuilder bodyBuilder = new StringBuilder(); |
|
|
|
final Builder addToBody(String text) { |
|
|
|
bodyBuilder.append(text); |
|
|
|
return this; |
|
|
|
} |
|
|
|
final Builder formatToBody(String format, Object... args) { |
|
|
|
Formatter formatter = new Formatter(bodyBuilder); |
|
|
|
formatter.format(format, args); |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
void formatToBody(String format, Object... args) { |
|
|
|
formatter.format(format, args); |
|
|
|
abstract ClassWriter autoBuild(); |
|
|
|
|
|
|
|
final ClassWriter build() { |
|
|
|
setJavadoc(javadocBuilder.toString()); |
|
|
|
setBody(bodyBuilder.toString()); |
|
|
|
return autoBuild(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void writeToFile() throws IOException { |
|
|
|
CopyrightNotice.writeTo(writer, Integer.valueOf(copyright)); |
|
|
|
Writer writer = new BufferedWriter(new FileWriter(new File(outputDir(), name() + ".java"))); |
|
|
|
|
|
|
|
CopyrightNotice.writeTo(writer, copyright()); |
|
|
|
writer.write(GENERATION_COMMENT); |
|
|
|
writer.write("package " + PACKAGE_NAME + ";\n\n"); |
|
|
|
|
|
|
|
if (!imports.isEmpty()) { |
|
|
|
for (String item : imports) { |
|
|
|
if (!imports().isEmpty()) { |
|
|
|
for (String item : imports()) { |
|
|
|
writer.write("import " + item + ";\n"); |
|
|
|
} |
|
|
|
writer.write("\n"); |
|
|
|
} |
|
|
|
|
|
|
|
writer.write((modifiers.isEmpty() ? "" : modifiers + " ") + "class " + name + " {\n"); |
|
|
|
writer.write(body.toString()); |
|
|
|
writer.write(javadoc()); |
|
|
|
if (!modifiers().isEmpty()) { |
|
|
|
writer.write(modifiers() + " "); |
|
|
|
} |
|
|
|
writer.write("class " + name() + " {\n"); |
|
|
|
writer.write(body()); |
|
|
|
writer.write("}\n"); |
|
|
|
|
|
|
|
writer.flush(); |
|
|
|
|