TOOLS: Add unit tests for BuildMetadataFromXml.
authorphilip.liard@gmail.com <philip.liard@gmail.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Tue, 5 Jul 2011 07:34:45 +0000 (07:34 +0000)
committerphilip.liard@gmail.com <philip.liard@gmail.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Tue, 5 Jul 2011 07:34:45 +0000 (07:34 +0000)
git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@291 ee073f10-1060-11df-b6a4-87a95322a99c

cpp/src/phonenumbers/default_logger.cc
cpp/src/phonenumbers/default_logger.h
tools/java/common/src/com/google/i18n/phonenumbers/tools/BuildMetadataFromXml.java
tools/java/common/test/com/google/i18n/phonenumbers/tools/BuildMetadataFromXmlTest.java [new file with mode: 0644]
tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar
tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar

index 766e215a845625e3b813b1a628a8fd7947aa1712..538c1b30d10777e6e98fe6f33c09e55983992a3a 100644 (file)
@@ -14,9 +14,6 @@
 
 // Author: Philippe Liard
 
-// This file should not be compiled when using Google base/.
-#ifndef USE_GOOGLE_BASE
-
 #include <iostream>
 
 #include "phonenumbers/default_logger.h"
@@ -50,5 +47,3 @@ void StdoutLogger::WriteLevel() {
 
 }  // namespace phonenumbers
 }  // namespace i18n
-
-#endif  // USE_GOOGLE_BASE
index 28212ff7f2001b2f76e9b5b9cecbcf265438767e..53ec9cd7a56756cea8f69b56715ad7b010b3a894 100644 (file)
 #ifndef I18N_PHONENUMBERS_DEFAULT_LOGGER_H_
 #define I18N_PHONENUMBERS_DEFAULT_LOGGER_H_
 
-#ifdef USE_GOOGLE_BASE
-
-namespace i18n {
-namespace phonenumbers {
-
-// If Google base/ is used, LOG() and VLOG() from base/logging.h are used
-// therefore the default logger implementation (StdoutLogger) instantiated in
-// phonenumberutil will actually never be used. Thus provide a dummy
-// implementation of this logger.
-class StdoutLogger : public Logger {
- public:
-  virtual ~StdoutLogger() {}
-
-  virtual void WriteLevel() {}
-  virtual void WriteMessage(const string& /* msg */) {}
-};
-
-}  // namespace phonenumbers
-}  // namespace i18n
-
-#else
-
 #include <string>
 
 #include "phonenumbers/logger.h"
@@ -125,5 +103,4 @@ class StdoutLogger : public Logger {
 }  // namespace phonenumbers
 }  // namespace i18n
 
-#endif  // USE_GOOGLE_BASE
 #endif  // I18N_PHONENUMBERS_DEFAULT_LOGGER_H_
index 3b19d736f74a41fd26379f5c1f208f6705bfa93d..7986689266a66996a554c30cc5afbebcca5353d0 100644 (file)
@@ -32,6 +32,7 @@ import java.util.Map;
 import java.util.TreeMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.logging.Logger;
 import java.util.regex.Pattern;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -44,7 +45,44 @@ import javax.xml.parsers.DocumentBuilderFactory;
  */
 public class BuildMetadataFromXml {
   private static final Logger LOGGER = Logger.getLogger(BuildMetadataFromXml.class.getName());
-  private static Boolean liteBuild;
+  private static boolean liteBuild;
+
+  // String constants used to fetch the XML nodes and attributes.
+  private static final String CARRIER_CODE_FORMATTING_RULE = "carrierCodeFormattingRule";
+  private static final String COUNTRY_CODE = "countryCode";
+  private static final String EXAMPLE_NUMBER = "exampleNumber";
+  private static final String FIXED_LINE = "fixedLine";
+  private static final String FORMAT = "format";
+  private static final String GENERAL_DESC = "generalDesc";
+  private static final String INTERNATIONAL_PREFIX = "internationalPrefix";
+  private static final String INTL_FORMAT = "intlFormat";
+  private static final String LEADING_DIGITS = "leadingDigits";
+  private static final String LEADING_ZERO_POSSIBLE = "leadingZeroPossible";
+  private static final String MAIN_COUNTRY_FOR_CODE = "mainCountryForCode";
+  private static final String MOBILE = "mobile";
+  private static final String NATIONAL_NUMBER_PATTERN = "nationalNumberPattern";
+  private static final String NATIONAL_PREFIX = "nationalPrefix";
+  private static final String NATIONAL_PREFIX_FORMATTING_RULE = "nationalPrefixFormattingRule";
+  private static final String NATIONAL_PREFIX_FOR_PARSING = "nationalPrefixForParsing";
+  private static final String NATIONAL_PREFIX_TRANSFORM_RULE = "nationalPrefixTransformRule";
+  private static final String NO_INTERNATIONAL_DIALLING = "noInternationalDialling";
+  private static final String NUMBER_FORMAT = "numberFormat";
+  private static final String PAGER = "pager";
+  private static final String PATTERN = "pattern";
+  private static final String PERSONAL_NUMBER = "personalNumber";
+  private static final String POSSIBLE_NUMBER_PATTERN = "possibleNumberPattern";
+  private static final String PREFERRED_EXTN_PREFIX = "preferredExtnPrefix";
+  private static final String PREFERRED_INTERNATIONAL_PREFIX = "preferredInternationalPrefix";
+  private static final String PREMIUM_RATE = "premiumRate";
+  private static final String SHARED_COST = "sharedCost";
+  private static final String TOLL_FREE = "tollFree";
+  private static final String UAN = "uan";
+  private static final String VOIP = "voip";
+
+  // @VisibleForTesting
+  static void setLiteBuild(boolean b) {
+    liteBuild = b;
+  }
 
   // Build the PhoneMetadataCollection from the input XML file.
   public static PhoneMetadataCollection buildPhoneMetadataCollection(String inputXmlFile,
@@ -70,7 +108,7 @@ public class BuildMetadataFromXml {
 
   // Build a mapping from a country calling code to the region codes which denote the country/region
   // represented by that country code. In the case of multiple countries sharing a calling code,
-  // such as the NANPA countries, the one indicated with "getMainCountryForCode" in the metadata
+  // such as the NANPA countries, the one indicated with "isMainCountryForCode" in the metadata
   // should be first.
   public static Map<Integer, List<String>> buildCountryCodeToRegionCodeMap(
       PhoneMetadataCollection metadataCollection) {
@@ -99,7 +137,8 @@ public class BuildMetadataFromXml {
     return validateRE(regex, false);
   }
 
-  private static String validateRE(String regex, boolean removeWhitespace) {
+  // @VisibleForTesting
+  static String validateRE(String regex, boolean removeWhitespace) {
     // Removes all the whitespace and newline from the regexp. Not using pattern compile options to
     // make it work across programming languages.
     if (removeWhitespace) {
@@ -111,55 +150,133 @@ public class BuildMetadataFromXml {
     return regex;
   }
 
-  private static PhoneMetadata loadCountryMetadata(String regionCode, Element element) {
+  /**
+   * Returns the national prefix of the provided country element.
+   */
+  // @VisibleForTesting
+  static String getNationalPrefix(Element element) {
+    return element.hasAttribute(NATIONAL_PREFIX) ? element.getAttribute(NATIONAL_PREFIX) : "";
+  }
+
+  // @VisibleForTesting
+  static PhoneMetadata.Builder loadTerritoryTagMetadata(String regionCode, Element element,
+                                                        String nationalPrefix,
+                                                        String nationalPrefixFormattingRule) {
     PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
     metadata.setId(regionCode);
-    metadata.setCountryCode(Integer.parseInt(element.getAttribute("countryCode")));
-    if (element.hasAttribute("leadingDigits")) {
-      metadata.setLeadingDigits(validateRE(element.getAttribute("leadingDigits")));
+    metadata.setCountryCode(Integer.parseInt(element.getAttribute(COUNTRY_CODE)));
+    if (element.hasAttribute(LEADING_DIGITS)) {
+      metadata.setLeadingDigits(validateRE(element.getAttribute(LEADING_DIGITS)));
     }
-    metadata.setInternationalPrefix(validateRE(element.getAttribute("internationalPrefix")));
-    if (element.hasAttribute("preferredInternationalPrefix")) {
-      String preferredInternationalPrefix = element.getAttribute("preferredInternationalPrefix");
+    metadata.setInternationalPrefix(validateRE(element.getAttribute(INTERNATIONAL_PREFIX)));
+    if (element.hasAttribute(PREFERRED_INTERNATIONAL_PREFIX)) {
+      String preferredInternationalPrefix = element.getAttribute(PREFERRED_INTERNATIONAL_PREFIX);
       metadata.setPreferredInternationalPrefix(preferredInternationalPrefix);
     }
-    if (element.hasAttribute("nationalPrefixForParsing")) {
+    if (element.hasAttribute(NATIONAL_PREFIX_FOR_PARSING)) {
       metadata.setNationalPrefixForParsing(
-          validateRE(element.getAttribute("nationalPrefixForParsing")));
-      if (element.hasAttribute("nationalPrefixTransformRule")) {
+          validateRE(element.getAttribute(NATIONAL_PREFIX_FOR_PARSING)));
+      if (element.hasAttribute(NATIONAL_PREFIX_TRANSFORM_RULE)) {
         metadata.setNationalPrefixTransformRule(
-            validateRE(element.getAttribute("nationalPrefixTransformRule")));
+            validateRE(element.getAttribute(NATIONAL_PREFIX_TRANSFORM_RULE)));
       }
     }
-    String nationalPrefix = "";
-    String nationalPrefixFormattingRule = "";
-    if (element.hasAttribute("nationalPrefix")) {
-      nationalPrefix = element.getAttribute("nationalPrefix");
+    if (!nationalPrefix.isEmpty()) {
       metadata.setNationalPrefix(nationalPrefix);
-      nationalPrefixFormattingRule =
-          getNationalPrefixFormattingRuleFromElement(element, nationalPrefix);
-
       if (!metadata.hasNationalPrefixForParsing()) {
         metadata.setNationalPrefixForParsing(nationalPrefix);
       }
     }
-    String carrierCodeFormattingRule = "";
-    if (element.hasAttribute("carrierCodeFormattingRule")) {
-      carrierCodeFormattingRule = validateRE(
-          getDomesticCarrierCodeFormattingRuleFromElement(element, nationalPrefix));
-    }
-    if (element.hasAttribute("preferredExtnPrefix")) {
-      metadata.setPreferredExtnPrefix(element.getAttribute("preferredExtnPrefix"));
+    if (element.hasAttribute(PREFERRED_EXTN_PREFIX)) {
+      metadata.setPreferredExtnPrefix(element.getAttribute(PREFERRED_EXTN_PREFIX));
     }
-    if (element.hasAttribute("mainCountryForCode")) {
+    if (element.hasAttribute(MAIN_COUNTRY_FOR_CODE)) {
       metadata.setMainCountryForCode(true);
     }
-    if (element.hasAttribute("leadingZeroPossible")) {
+    if (element.hasAttribute(LEADING_ZERO_POSSIBLE)) {
       metadata.setLeadingZeroPossible(true);
     }
+    return metadata;
+  }
 
-    // Extract availableFormats
-    NodeList numberFormatElements = element.getElementsByTagName("numberFormat");
+  /**
+   * Extracts the pattern for international format. If there is no intlFormat, default to using the
+   * national format. If the intlFormat is set to "NA" the intlFormat should be ignored.
+   *
+   * @throws  RuntimeException if multiple intlFormats have been encountered.
+   * @return  whether an international number format is defined.
+   */
+  // @VisibleForTesting
+  static boolean loadInternationalFormat(PhoneMetadata.Builder metadata,
+                                         Element numberFormatElement,
+                                         String nationalFormat) {
+    NumberFormat.Builder intlFormat = NumberFormat.newBuilder();
+    setLeadingDigitsPatterns(numberFormatElement, intlFormat);
+    intlFormat.setPattern(numberFormatElement.getAttribute(PATTERN));
+    NodeList intlFormatPattern = numberFormatElement.getElementsByTagName(INTL_FORMAT);
+    boolean hasExplicitIntlFormatDefined = false;
+
+    if (intlFormatPattern.getLength() > 1) {
+      LOGGER.log(Level.SEVERE,
+                 "A maximum of one intlFormat pattern for a numberFormat element should be " +
+                 "defined.");
+      throw new RuntimeException("Invalid number of intlFormat patterns for country: " +
+                                 metadata.getId());
+    } else if (intlFormatPattern.getLength() == 0) {
+      // Default to use the same as the national pattern if none is defined.
+      intlFormat.setFormat(nationalFormat);
+    } else {
+      String intlFormatPatternValue = intlFormatPattern.item(0).getFirstChild().getNodeValue();
+      if (!intlFormatPatternValue.equals("NA")) {
+        intlFormat.setFormat(intlFormatPatternValue);
+      }
+      hasExplicitIntlFormatDefined = true;
+    }
+
+    if (intlFormat.hasFormat()) {
+      metadata.addIntlNumberFormat(intlFormat);
+    }
+    return hasExplicitIntlFormatDefined;
+  }
+
+  /**
+   * Extracts the pattern for the national format.
+   *
+   * @throws  RuntimeException if multiple or no formats have been encountered.
+   * @return  the national format string.
+   */
+  // @VisibleForTesting
+  static String loadNationalFormat(PhoneMetadata.Builder metadata, Element numberFormatElement,
+                                   NumberFormat.Builder format) {
+    setLeadingDigitsPatterns(numberFormatElement, format);
+    format.setPattern(validateRE(numberFormatElement.getAttribute(PATTERN)));
+
+    NodeList formatPattern = numberFormatElement.getElementsByTagName(FORMAT);
+    if (formatPattern.getLength() != 1) {
+      LOGGER.log(Level.SEVERE,
+                 "Only one format pattern for a numberFormat element should be defined.");
+      throw new RuntimeException("Invalid number of format patterns for country: " +
+                                   metadata.getId());
+    }
+    String nationalFormat = formatPattern.item(0).getFirstChild().getNodeValue();
+    format.setFormat(nationalFormat);
+    return nationalFormat;
+  }
+
+  /**
+   *  Extracts the available formats from the provided DOM element. If it does not contain any
+   *  nationalPrefixFormattingRule, the one passed-in is retained.
+   */
+  // @VisibleForTesting
+  static void loadAvailableFormats(PhoneMetadata.Builder metadata, String regionCode,
+                                   Element element, String nationalPrefix,
+                                   String nationalPrefixFormattingRule) {
+    String carrierCodeFormattingRule = "";
+    if (element.hasAttribute(CARRIER_CODE_FORMATTING_RULE)) {
+      carrierCodeFormattingRule = validateRE(
+          getDomesticCarrierCodeFormattingRuleFromElement(element, nationalPrefix));
+    }
+    NodeList numberFormatElements = element.getElementsByTagName(NUMBER_FORMAT);
     boolean hasExplicitIntlFormatDefined = false;
 
     int numOfFormatElements = numberFormatElements.getLength();
@@ -168,63 +285,25 @@ public class BuildMetadataFromXml {
         Element numberFormatElement = (Element) numberFormatElements.item(i);
         NumberFormat.Builder format = NumberFormat.newBuilder();
 
-        if (numberFormatElement.hasAttribute("nationalPrefixFormattingRule")) {
+        if (numberFormatElement.hasAttribute(NATIONAL_PREFIX_FORMATTING_RULE)) {
           format.setNationalPrefixFormattingRule(
               getNationalPrefixFormattingRuleFromElement(numberFormatElement, nationalPrefix));
         } else {
           format.setNationalPrefixFormattingRule(nationalPrefixFormattingRule);
         }
-        if (numberFormatElement.hasAttribute("carrierCodeFormattingRule")) {
+        if (numberFormatElement.hasAttribute(CARRIER_CODE_FORMATTING_RULE)) {
           format.setDomesticCarrierCodeFormattingRule(validateRE(
               getDomesticCarrierCodeFormattingRuleFromElement(numberFormatElement,
                                                               nationalPrefix)));
         } else {
           format.setDomesticCarrierCodeFormattingRule(carrierCodeFormattingRule);
         }
-
-        // Extract the pattern for the national format.
-        setLeadingDigitsPatterns(numberFormatElement, format);
-        format.setPattern(validateRE(numberFormatElement.getAttribute("pattern")));
-
-        NodeList formatPattern = numberFormatElement.getElementsByTagName("format");
-        if (formatPattern.getLength() != 1) {
-          LOGGER.log(Level.SEVERE,
-                     "Only one format pattern for a numberFormat element should be defined.");
-          throw new RuntimeException("Invalid number of format patterns for country: " +
-                                     regionCode);
-        }
-        String nationalFormat = formatPattern.item(0).getFirstChild().getNodeValue();
-        format.setFormat(nationalFormat);
+        String nationalFormat =
+            loadNationalFormat(metadata, numberFormatElement, format);
         metadata.addNumberFormat(format);
 
-        // Extract the pattern for international format. If there is no intlFormat, default to
-        // using the national format. If the intlFormat is set to "NA" the intlFormat should be
-        // ignored.
-        NumberFormat.Builder intlFormat = NumberFormat.newBuilder();
-        setLeadingDigitsPatterns(numberFormatElement, intlFormat);
-        intlFormat.setPattern(numberFormatElement.getAttribute("pattern"));
-        NodeList intlFormatPattern = numberFormatElement.getElementsByTagName("intlFormat");
-
-        if (intlFormatPattern.getLength() > 1) {
-          LOGGER.log(Level.SEVERE,
-                     "A maximum of one intlFormat pattern for a numberFormat element should be " +
-                     "defined.");
-          throw new RuntimeException("Invalid number of intlFormat patterns for country: " +
-                                     regionCode);
-        } else if (intlFormatPattern.getLength() == 0) {
-          // Default to use the same as the national pattern if none is defined.
-          intlFormat.setFormat(nationalFormat);
-        } else {
-           String intlFormatPatternValue =
-               intlFormatPattern.item(0).getFirstChild().getNodeValue();
-           if (!intlFormatPatternValue.equals("NA")) {
-             intlFormat.setFormat(intlFormatPatternValue);
-           }
-           hasExplicitIntlFormatDefined = true;
-        }
-
-        if (intlFormat.hasFormat()) {
-          metadata.addIntlNumberFormat(intlFormat);
+        if (loadInternationalFormat(metadata, numberFormatElement, nationalFormat)) {
+          hasExplicitIntlFormatDefined = true;
         }
       }
       // Only a small number of regions need to specify the intlFormats in the xml. For the majority
@@ -235,33 +314,11 @@ public class BuildMetadataFromXml {
         metadata.clearIntlNumberFormat();
       }
     }
-
-    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
-    generalDesc = processPhoneNumberDescElement(generalDesc, element, "generalDesc");
-    metadata.setGeneralDesc(generalDesc);
-    metadata.setFixedLine(processPhoneNumberDescElement(generalDesc, element, "fixedLine"));
-    metadata.setMobile(processPhoneNumberDescElement(generalDesc, element, "mobile"));
-    metadata.setTollFree(processPhoneNumberDescElement(generalDesc, element, "tollFree"));
-    metadata.setPremiumRate(processPhoneNumberDescElement(generalDesc, element, "premiumRate"));
-    metadata.setSharedCost(processPhoneNumberDescElement(generalDesc, element, "sharedCost"));
-    metadata.setVoip(processPhoneNumberDescElement(generalDesc, element, "voip"));
-    metadata.setPersonalNumber(processPhoneNumberDescElement(generalDesc, element,
-                                                             "personalNumber"));
-    metadata.setPager(processPhoneNumberDescElement(generalDesc, element, "pager"));
-    metadata.setUan(processPhoneNumberDescElement(generalDesc, element, "uan"));
-    metadata.setNoInternationalDialling(processPhoneNumberDescElement(generalDesc, element,
-                                                                      "noInternationalDialling"));
-
-    if (metadata.getMobile().getNationalNumberPattern().equals(
-        metadata.getFixedLine().getNationalNumberPattern())) {
-      metadata.setSameMobileAndFixedLinePattern(true);
-    }
-    return metadata.build();
   }
 
-  private static void setLeadingDigitsPatterns(Element numberFormatElement,
-                                               NumberFormat.Builder format) {
-    NodeList leadingDigitsPatternNodes = numberFormatElement.getElementsByTagName("leadingDigits");
+  // @VisibleForTesting
+  static void setLeadingDigitsPatterns(Element numberFormatElement, NumberFormat.Builder format) {
+    NodeList leadingDigitsPatternNodes = numberFormatElement.getElementsByTagName(LEADING_DIGITS);
     int numOfLeadingDigitsPatterns = leadingDigitsPatternNodes.getLength();
     if (numOfLeadingDigitsPatterns > 0) {
       for (int i = 0; i < numOfLeadingDigitsPatterns; i++) {
@@ -271,9 +328,10 @@ public class BuildMetadataFromXml {
     }
   }
 
-  private static String getNationalPrefixFormattingRuleFromElement(Element element,
-                                                                   String nationalPrefix) {
-    String nationalPrefixFormattingRule = element.getAttribute("nationalPrefixFormattingRule");
+  // @VisibleForTesting
+  static String getNationalPrefixFormattingRuleFromElement(Element element,
+                                                           String nationalPrefix) {
+    String nationalPrefixFormattingRule = element.getAttribute(NATIONAL_PREFIX_FORMATTING_RULE);
     // Replace $NP with national prefix and $FG with the first group ($1).
     nationalPrefixFormattingRule =
         nationalPrefixFormattingRule.replaceFirst("\\$NP", nationalPrefix)
@@ -281,15 +339,22 @@ public class BuildMetadataFromXml {
     return nationalPrefixFormattingRule;
   }
 
-  private static String getDomesticCarrierCodeFormattingRuleFromElement(Element element,
-                                                                        String nationalPrefix) {
-    String carrierCodeFormattingRule = element.getAttribute("carrierCodeFormattingRule");
+  // @VisibleForTesting
+  static String getDomesticCarrierCodeFormattingRuleFromElement(Element element,
+                                                                String nationalPrefix) {
+    String carrierCodeFormattingRule = element.getAttribute(CARRIER_CODE_FORMATTING_RULE);
     // Replace $FG with the first group ($1) and $NP with the national prefix.
     carrierCodeFormattingRule = carrierCodeFormattingRule.replaceFirst("\\$FG", "\\$1")
         .replaceFirst("\\$NP", nationalPrefix);
     return carrierCodeFormattingRule;
   }
 
+  // @VisibleForTesting
+  static boolean isValidNumberType(String numberType) {
+    return numberType.equals(FIXED_LINE) || numberType.equals(MOBILE) ||
+         numberType.equals(GENERAL_DESC);
+  }
+
   /**
    * Processes a phone number description element from the XML file and returns it as a
    * PhoneNumberDesc. If the description element is a fixed line or mobile number, the general
@@ -306,15 +371,13 @@ public class BuildMetadataFromXml {
    *                    file with information about that type
    * @return  complete description of that phone number type
    */
-  private static PhoneNumberDesc.Builder processPhoneNumberDescElement(
-          PhoneNumberDesc.Builder generalDesc,
-          Element countryElement,
-          String numberType) {
+  // @VisibleForTesting
+  static PhoneNumberDesc.Builder processPhoneNumberDescElement(PhoneNumberDesc.Builder generalDesc,
+                                                               Element countryElement,
+                                                               String numberType) {
     NodeList phoneNumberDescList = countryElement.getElementsByTagName(numberType);
     PhoneNumberDesc.Builder numberDesc = PhoneNumberDesc.newBuilder();
-    if (phoneNumberDescList.getLength() == 0 &&
-        (!numberType.equals("fixedLine") && !numberType.equals("mobile") &&
-         !numberType.equals("generalDesc"))) {
+    if (phoneNumberDescList.getLength() == 0 && !isValidNumberType(numberType)) {
       numberDesc.setNationalNumberPattern("NA");
       numberDesc.setPossibleNumberPattern("NA");
       return numberDesc;
@@ -322,20 +385,20 @@ public class BuildMetadataFromXml {
     numberDesc.mergeFrom(generalDesc.build());
     if (phoneNumberDescList.getLength() > 0) {
       Element element = (Element) phoneNumberDescList.item(0);
-      NodeList possiblePattern = element.getElementsByTagName("possibleNumberPattern");
+      NodeList possiblePattern = element.getElementsByTagName(POSSIBLE_NUMBER_PATTERN);
       if (possiblePattern.getLength() > 0) {
         numberDesc.setPossibleNumberPattern(
             validateRE(possiblePattern.item(0).getFirstChild().getNodeValue(), true));
       }
 
-      NodeList validPattern = element.getElementsByTagName("nationalNumberPattern");
+      NodeList validPattern = element.getElementsByTagName(NATIONAL_NUMBER_PATTERN);
       if (validPattern.getLength() > 0) {
         numberDesc.setNationalNumberPattern(
             validateRE(validPattern.item(0).getFirstChild().getNodeValue(), true));
       }
 
       if (!liteBuild) {
-        NodeList exampleNumber = element.getElementsByTagName("exampleNumber");
+        NodeList exampleNumber = element.getElementsByTagName(EXAMPLE_NUMBER);
         if (exampleNumber.getLength() > 0) {
           numberDesc.setExampleNumber(exampleNumber.item(0).getFirstChild().getNodeValue());
         }
@@ -343,4 +406,40 @@ public class BuildMetadataFromXml {
     }
     return numberDesc;
   }
+
+  // @VisibleForTesting
+  static void loadGeneralDesc(PhoneMetadata.Builder metadata, Element element) {
+    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+    generalDesc = processPhoneNumberDescElement(generalDesc, element, GENERAL_DESC);
+    metadata.setGeneralDesc(generalDesc);
+
+    metadata.setFixedLine(processPhoneNumberDescElement(generalDesc, element, FIXED_LINE));
+    metadata.setMobile(processPhoneNumberDescElement(generalDesc, element, MOBILE));
+    metadata.setTollFree(processPhoneNumberDescElement(generalDesc, element, TOLL_FREE));
+    metadata.setPremiumRate(processPhoneNumberDescElement(generalDesc, element, PREMIUM_RATE));
+    metadata.setSharedCost(processPhoneNumberDescElement(generalDesc, element, SHARED_COST));
+    metadata.setVoip(processPhoneNumberDescElement(generalDesc, element, VOIP));
+    metadata.setPersonalNumber(processPhoneNumberDescElement(generalDesc, element,
+                                                             PERSONAL_NUMBER));
+    metadata.setPager(processPhoneNumberDescElement(generalDesc, element, PAGER));
+    metadata.setUan(processPhoneNumberDescElement(generalDesc, element, UAN));
+    metadata.setNoInternationalDialling(processPhoneNumberDescElement(generalDesc, element,
+                                                                      NO_INTERNATIONAL_DIALLING));
+    metadata.setSameMobileAndFixedLinePattern(
+        metadata.getMobile().getNationalNumberPattern().equals(
+        metadata.getFixedLine().getNationalNumberPattern()));
+  }
+
+  public static PhoneMetadata loadCountryMetadata(String regionCode, Element element) {
+    String nationalPrefix = getNationalPrefix(element);
+    String nationalPrefixFormattingRule =
+        getNationalPrefixFormattingRuleFromElement(element, nationalPrefix);
+    PhoneMetadata.Builder metadata =
+        loadTerritoryTagMetadata(regionCode, element, nationalPrefix, nationalPrefixFormattingRule);
+
+    loadAvailableFormats(metadata, regionCode, element, nationalPrefix.toString(),
+                         nationalPrefixFormattingRule.toString());
+    loadGeneralDesc(metadata, element);
+    return metadata.build();
+  }
 }
diff --git a/tools/java/common/test/com/google/i18n/phonenumbers/tools/BuildMetadataFromXmlTest.java b/tools/java/common/test/com/google/i18n/phonenumbers/tools/BuildMetadataFromXmlTest.java
new file mode 100644 (file)
index 0000000..42fe782
--- /dev/null
@@ -0,0 +1,504 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+
+package com.google.i18n.phonenumbers.tools;
+
+import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection;
+import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.regex.PatternSyntaxException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+/**
+ * Unit tests for BuildMetadataFromXml.java
+ *
+ * @author Philippe Liard
+ */
+public class BuildMetadataFromXmlTest extends TestCase {
+
+  // Helper method that outputs a DOM element from a XML string.
+  private static Element parseXmlString(String xmlString)
+      throws ParserConfigurationException, SAXException, IOException {
+    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+    InputSource inputSource = new InputSource();
+    inputSource.setCharacterStream(new StringReader(xmlString));
+    return documentBuilder.parse(inputSource).getDocumentElement();
+  }
+
+  // Tests validateRE().
+  public void testValidateRERemovesWhiteSpaces() {
+    String input = " hello world ";
+    // Should remove all the white spaces contained in the provided string.
+    assertEquals("helloworld", BuildMetadataFromXml.validateRE(input, true));
+    // Make sure it only happens when the last parameter is set to true.
+    assertEquals(" hello world ", BuildMetadataFromXml.validateRE(input, false));
+  }
+
+  public void testValidateREThrowsException() {
+    String invalidPattern = "[";
+    // Should throw an exception when an invalid pattern is provided independently of the last
+    // parameter (remove white spaces).
+    try {
+      BuildMetadataFromXml.validateRE(invalidPattern, false);
+      fail();
+    } catch (PatternSyntaxException e) {
+      // Test passed.
+    }
+    try {
+      BuildMetadataFromXml.validateRE(invalidPattern, true);
+      fail();
+    } catch (PatternSyntaxException e) {
+      // Test passed.
+    }
+  }
+
+  public void testValidateRE() {
+    String validPattern = "[a-zA-Z]d{1,9}";
+    // The provided pattern should be left unchanged.
+    assertEquals(validPattern, BuildMetadataFromXml.validateRE(validPattern, false));
+  }
+
+  // Tests getNationalPrefix().
+  public void testGetNationalPrefix()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<territory nationalPrefix='00'/>";
+    Element territoryElement = parseXmlString(xmlInput);
+    assertEquals("00", BuildMetadataFromXml.getNationalPrefix(territoryElement));
+  }
+
+  // Tests loadTerritoryTagMetadata().
+  public void testLoadTerritoryTagMetadata()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory countryCode='33' leadingDigits='2' internationalPrefix='00'" +
+        "           preferredInternationalPrefix='0011' nationalPrefixForParsing='0'" +
+        "           nationalPrefixTransformRule='9$1'" + // nationalPrefix manually injected.
+        "           preferredExtnPrefix=' x' mainCountryForCode='true'" +
+        "           leadingZeroPossible='true'>" +
+        "</territory>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder phoneMetadata =
+        BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, "0", "");
+    assertEquals(33, phoneMetadata.getCountryCode());
+    assertEquals("2", phoneMetadata.getLeadingDigits());
+    assertEquals("00", phoneMetadata.getInternationalPrefix());
+    assertEquals("0011", phoneMetadata.getPreferredInternationalPrefix());
+    assertEquals("0", phoneMetadata.getNationalPrefixForParsing());
+    assertEquals("9$1", phoneMetadata.getNationalPrefixTransformRule());
+    assertEquals("0", phoneMetadata.getNationalPrefix());
+    assertEquals(" x", phoneMetadata.getPreferredExtnPrefix());
+    assertTrue(phoneMetadata.getMainCountryForCode());
+    assertTrue(phoneMetadata.getLeadingZeroPossible());
+  }
+
+  public void testLoadTerritoryTagMetadataSetsBooleanFieldsToFalseByDefault()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<territory countryCode='33'/>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder phoneMetadata =
+        BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, "", "");
+    assertFalse(phoneMetadata.getMainCountryForCode());
+    assertFalse(phoneMetadata.getLeadingZeroPossible());
+  }
+
+  public void testLoadTerritoryTagMetadataSetsNationalPrefixForParsingByDefault()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<territory countryCode='33'/>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder phoneMetadata =
+        BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, "00", "");
+    // When unspecified, nationalPrefixForParsing defaults to nationalPrefix.
+    assertEquals("00", phoneMetadata.getNationalPrefix());
+    assertEquals(phoneMetadata.getNationalPrefix(), phoneMetadata.getNationalPrefixForParsing());
+  }
+
+  public void testLoadTerritoryTagMetadataWithRequiredAttributesOnly()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<territory countryCode='33' internationalPrefix='00'/>";
+    Element territoryElement = parseXmlString(xmlInput);
+    // Should not throw any exception.
+    PhoneMetadata.Builder phoneMetadata =
+        BuildMetadataFromXml.loadTerritoryTagMetadata("33", territoryElement, "", "");
+  }
+
+  // Tests loadInternationalFormat().
+  public void testLoadInternationalFormat()
+      throws ParserConfigurationException, SAXException, IOException {
+    String intlFormat = "$1 $2";
+    String xmlInput = "<numberFormat><intlFormat>" + intlFormat + "</intlFormat></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    String nationalFormat = "";
+
+    assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
+                                                            nationalFormat));
+    assertEquals(intlFormat, metadata.getIntlNumberFormat(0).getFormat());
+  }
+
+  public void testLoadInternationalFormatWithBothNationalAndIntlFormatsDefined()
+      throws ParserConfigurationException, SAXException, IOException {
+    String intlFormat = "$1 $2";
+    String xmlInput = "<numberFormat><intlFormat>" + intlFormat + "</intlFormat></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    String nationalFormat = "$1";
+
+    assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
+                                                            nationalFormat));
+    assertEquals(intlFormat, metadata.getIntlNumberFormat(0).getFormat());
+  }
+
+  public void testLoadInternationalFormatExpectsOnlyOnePattern()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<numberFormat><intlFormat/><intlFormat/></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+
+    // Should throw an exception as multiple intlFormats are provided.
+    try {
+      BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, "");
+      fail();
+    } catch (RuntimeException e) {
+      // Test passed.
+    }
+  }
+
+  public void testLoadInternationalFormatUsesNationalFormatByDefault()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<numberFormat></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    String nationalFormat = "$1 $2 $3";
+
+    assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
+                                                             nationalFormat));
+    assertEquals(nationalFormat, metadata.getIntlNumberFormat(0).getFormat());
+  }
+
+  // Tests loadNationalFormat().
+  public void testLoadNationalFormat()
+      throws ParserConfigurationException, SAXException, IOException {
+    String nationalFormat = "$1 $2";
+    String xmlInput = String.format("<numberFormat><format>%s</format></numberFormat>",
+                                    nationalFormat);
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    NumberFormat.Builder numberFormat = NumberFormat.newBuilder();
+
+    assertEquals(nationalFormat,
+                 BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement,
+                                                         numberFormat));
+  }
+
+  public void testLoadNationalFormatRequiresFormat()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<numberFormat></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    NumberFormat.Builder numberFormat = NumberFormat.newBuilder();
+
+    try {
+      BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat);
+      fail();
+    } catch (RuntimeException e) {
+      // Test passed.
+    }
+  }
+
+  public void testLoadNationalFormatExpectsExactlyOneFormat()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<numberFormat><format/><format/></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    NumberFormat.Builder numberFormat = NumberFormat.newBuilder();
+
+    try {
+      BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat);
+      fail();
+    } catch (RuntimeException e) {
+      // Test passed.
+    }
+  }
+
+  // Tests loadAvailableFormats().
+  public void testLoadAvailableFormats()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory >" +
+        "  <availableFormats>" +
+        "    <numberFormat nationalPrefixFormattingRule='($FG)'" +
+        "                  carrierCodeFormattingRule='$NP $CC ($FG)'>" +
+        "      <format>$1 $2 $3</format>" +
+        "    </numberFormat>" +
+        "  </availableFormats>" +
+        "</territory>";
+    Element element = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    BuildMetadataFromXml.loadAvailableFormats(metadata, "AE", element, "0", "");
+    assertEquals("($1)", metadata.getNumberFormat(0).getNationalPrefixFormattingRule());
+    assertEquals("0 $CC ($1)", metadata.getNumberFormat(0).getDomesticCarrierCodeFormattingRule());
+    assertEquals("$1 $2 $3", metadata.getNumberFormat(0).getFormat());
+  }
+
+  public void testLoadAvailableFormatsPropagatesCarrierCodeFormattingRule()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory carrierCodeFormattingRule='$NP $CC ($FG)'>" +
+        "  <availableFormats>" +
+        "    <numberFormat nationalPrefixFormattingRule='($FG)'>" +
+        "      <format>$1 $2 $3</format>" +
+        "    </numberFormat>" +
+        "  </availableFormats>" +
+        "</territory>";
+    Element element = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    BuildMetadataFromXml.loadAvailableFormats(metadata, "AE", element, "0", "");
+    assertEquals("($1)", metadata.getNumberFormat(0).getNationalPrefixFormattingRule());
+    assertEquals("0 $CC ($1)", metadata.getNumberFormat(0).getDomesticCarrierCodeFormattingRule());
+    assertEquals("$1 $2 $3", metadata.getNumberFormat(0).getFormat());
+  }
+
+  public void testLoadAvailableFormatsSetsProvidedNationalPrefixFormattingRule()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory>" +
+        "  <availableFormats>" +
+        "    <numberFormat><format>$1 $2 $3</format></numberFormat>" +
+        "  </availableFormats>" +
+        "</territory>";
+    Element element = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    BuildMetadataFromXml.loadAvailableFormats(metadata, "AE", element, "", "($1)");
+    assertEquals("($1)", metadata.getNumberFormat(0).getNationalPrefixFormattingRule());
+  }
+
+  public void testLoadAvailableFormatsClearsIntlFormat()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory>" +
+        "  <availableFormats>" +
+        "    <numberFormat><format>$1 $2 $3</format></numberFormat>" +
+        "  </availableFormats>" +
+        "</territory>";
+    Element element = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    BuildMetadataFromXml.loadAvailableFormats(metadata, "AE", element, "0", "($1)");
+    assertEquals(0, metadata.getIntlNumberFormatCount());
+  }
+
+  public void testLoadAvailableFormatsHandlesMultipleNumberFormats()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory>" +
+        "  <availableFormats>" +
+        "    <numberFormat><format>$1 $2 $3</format></numberFormat>" +
+        "    <numberFormat><format>$1-$2</format></numberFormat>" +
+        "  </availableFormats>" +
+        "</territory>";
+    Element element = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    BuildMetadataFromXml.loadAvailableFormats(metadata, "AE", element, "0", "($1)");
+    assertEquals("$1 $2 $3", metadata.getNumberFormat(0).getFormat());
+    assertEquals("$1-$2", metadata.getNumberFormat(1).getFormat());
+  }
+
+  public void testLoadInternationalFormatDoesNotSetIntlFormatWhenNA()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<numberFormat><intlFormat>NA</intlFormat></numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    String nationalFormat = "$1 $2";
+
+    BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, nationalFormat);
+    assertEquals(0, metadata.getIntlNumberFormatCount());
+  }
+
+  // Tests setLeadingDigitsPatterns().
+  public void testSetLeadingDigitsPatterns()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<numberFormat>" +
+        "<leadingDigits>1</leadingDigits><leadingDigits>2</leadingDigits>" +
+        "</numberFormat>";
+    Element numberFormatElement = parseXmlString(xmlInput);
+    NumberFormat.Builder numberFormat = NumberFormat.newBuilder();
+    BuildMetadataFromXml.setLeadingDigitsPatterns(numberFormatElement, numberFormat);
+
+    assertEquals("1", numberFormat.getLeadingDigitsPattern(0));
+    assertEquals("2", numberFormat.getLeadingDigitsPattern(1));
+  }
+
+  // Tests getNationalPrefixFormattingRuleFromElement().
+  public void testGetNationalPrefixFormattingRuleFromElement()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<territory nationalPrefixFormattingRule='$NP$FG'/>";
+    Element element = parseXmlString(xmlInput);
+    assertEquals("0$1",
+                 BuildMetadataFromXml.getNationalPrefixFormattingRuleFromElement(element, "0"));
+  }
+
+  // Tests getDomesticCarrierCodeFormattingRuleFromElement().
+  public void testGetDomesticCarrierCodeFormattingRuleFromElement()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput = "<territory carrierCodeFormattingRule='$NP$CC $FG'/>";
+    Element element = parseXmlString(xmlInput);
+    assertEquals("0$CC $1",
+                 BuildMetadataFromXml.getDomesticCarrierCodeFormattingRuleFromElement(element,
+                                                                                      "0"));
+  }
+
+  // Tests isValidNumberType().
+  public void testIsValidNumberTypeWithInvalidInput() {
+    assertFalse(BuildMetadataFromXml.isValidNumberType("invalidType"));
+  }
+
+  // Tests processPhoneNumberDescElement().
+  public void testProcessPhoneNumberDescElementWithInvalidInput()
+      throws ParserConfigurationException, SAXException, IOException {
+    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+    Element territoryElement = parseXmlString("<territory/>");
+    PhoneNumberDesc.Builder phoneNumberDesc;
+
+    phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement(
+        generalDesc, territoryElement, "invalidType");
+    assertEquals("NA", phoneNumberDesc.getPossibleNumberPattern());
+    assertEquals("NA", phoneNumberDesc.getNationalNumberPattern());
+  }
+
+  public void testProcessPhoneNumberDescElementMergesWithGeneralDesc()
+      throws ParserConfigurationException, SAXException, IOException {
+    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+    generalDesc.setPossibleNumberPattern("\\d{6}");
+    Element territoryElement = parseXmlString("<territory><fixedLine/></territory>");
+    PhoneNumberDesc.Builder phoneNumberDesc;
+
+    phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement(
+        generalDesc, territoryElement, "fixedLine");
+    assertEquals("\\d{6}", phoneNumberDesc.getPossibleNumberPattern());
+  }
+
+  public void testProcessPhoneNumberDescElementOverridesGeneralDesc()
+      throws ParserConfigurationException, SAXException, IOException {
+    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+    generalDesc.setPossibleNumberPattern("\\d{8}");
+    String xmlInput =
+        "<territory><fixedLine>" +
+        "  <possibleNumberPattern>\\d{6}</possibleNumberPattern>" +
+        "</fixedLine></territory>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneNumberDesc.Builder phoneNumberDesc;
+
+    phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement(
+        generalDesc, territoryElement, "fixedLine");
+    assertEquals("\\d{6}", phoneNumberDesc.getPossibleNumberPattern());
+  }
+
+  public void testProcessPhoneNumberDescElementHandlesLiteBuild()
+      throws ParserConfigurationException, SAXException, IOException {
+    try {
+      BuildMetadataFromXml.setLiteBuild(true);
+      PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+      String xmlInput =
+          "<territory><fixedLine>" +
+          "  <exampleNumber>01 01 01 01</exampleNumber>" +
+          "</fixedLine></territory>";
+      Element territoryElement = parseXmlString(xmlInput);
+      PhoneNumberDesc.Builder phoneNumberDesc;
+
+      phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement(
+          generalDesc, territoryElement, "fixedLine");
+      assertEquals("", phoneNumberDesc.getExampleNumber());
+    } finally {
+      // Restore the lite build parameter to its default value (false) to avoid potential
+      // side-effects in other tests.
+      BuildMetadataFromXml.setLiteBuild(false);
+    }
+  }
+
+  public void testProcessPhoneNumberDescOutputsExampleNumberByDefault()
+      throws ParserConfigurationException, SAXException, IOException {
+    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+    String xmlInput =
+        "<territory><fixedLine>" +
+         "  <exampleNumber>01 01 01 01</exampleNumber>" +
+         "</fixedLine></territory>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneNumberDesc.Builder phoneNumberDesc;
+
+    phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement(
+        generalDesc, territoryElement, "fixedLine");
+    assertEquals("01 01 01 01", phoneNumberDesc.getExampleNumber());
+  }
+
+  public void testProcessPhoneNumberDescRemovesWhiteSpacesInPatterns()
+      throws ParserConfigurationException, SAXException, IOException {
+    PhoneNumberDesc.Builder generalDesc = PhoneNumberDesc.newBuilder();
+    String xmlInput =
+        "<territory><fixedLine>" +
+         "  <possibleNumberPattern>\t \\d { 6 } </possibleNumberPattern>" +
+         "</fixedLine></territory>";
+    Element countryElement = parseXmlString(xmlInput);
+    PhoneNumberDesc.Builder phoneNumberDesc;
+
+    phoneNumberDesc = BuildMetadataFromXml.processPhoneNumberDescElement(
+        generalDesc, countryElement, "fixedLine");
+    assertEquals("\\d{6}", phoneNumberDesc.getPossibleNumberPattern());
+  }
+
+  // Tests loadGeneralDesc().
+  public void testLoadGeneralDescSetsSameMobileAndFixedLinePattern()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory countryCode=\"33\">" +
+        "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>" +
+        "  <mobile><nationalNumberPattern>\\d{6}</nationalNumberPattern></mobile>" +
+        "</territory>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    // Should set sameMobileAndFixedPattern to true.
+    BuildMetadataFromXml.loadGeneralDesc(metadata, territoryElement);
+    assertTrue(metadata.getSameMobileAndFixedLinePattern());
+  }
+
+  public void testLoadGeneralDescSetsAllDescriptions()
+      throws ParserConfigurationException, SAXException, IOException {
+    String xmlInput =
+        "<territory countryCode=\"33\">" +
+        "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>" +
+        "  <mobile><nationalNumberPattern>\\d{2}</nationalNumberPattern></mobile>" +
+        "  <pager><nationalNumberPattern>\\d{3}</nationalNumberPattern></pager>" +
+        "  <tollFree><nationalNumberPattern>\\d{4}</nationalNumberPattern></tollFree>" +
+        "  <premiumRate><nationalNumberPattern>\\d{5}</nationalNumberPattern></premiumRate>" +
+        "  <sharedCost><nationalNumberPattern>\\d{6}</nationalNumberPattern></sharedCost>" +
+        "  <personalNumber><nationalNumberPattern>\\d{7}</nationalNumberPattern></personalNumber>" +
+        "  <voip><nationalNumberPattern>\\d{8}</nationalNumberPattern></voip>" +
+        "  <uan><nationalNumberPattern>\\d{9}</nationalNumberPattern></uan>" +
+        "  <shortCode><nationalNumberPattern>\\d{10}</nationalNumberPattern></shortCode>" +
+         "</territory>";
+    Element territoryElement = parseXmlString(xmlInput);
+    PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
+    BuildMetadataFromXml.loadGeneralDesc(metadata, territoryElement);
+    assertEquals("\\d{1}", metadata.getFixedLine().getNationalNumberPattern());
+    assertEquals("\\d{2}", metadata.getMobile().getNationalNumberPattern());
+    assertEquals("\\d{3}", metadata.getPager().getNationalNumberPattern());
+    assertEquals("\\d{4}", metadata.getTollFree().getNationalNumberPattern());
+    assertEquals("\\d{5}", metadata.getPremiumRate().getNationalNumberPattern());
+    assertEquals("\\d{6}", metadata.getSharedCost().getNationalNumberPattern());
+    assertEquals("\\d{7}", metadata.getPersonalNumber().getNationalNumberPattern());
+    assertEquals("\\d{8}", metadata.getVoip().getNationalNumberPattern());
+    assertEquals("\\d{9}", metadata.getUan().getNationalNumberPattern());
+  }
+}
index f9db26e592f61150b50b449490e01202149b9e93..f042be7400a4dd41a3f7109cb61a07d16e45462a 100644 (file)
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
index 426827c81d9cc25d2cb7aadfb92d2e65ed5900cb..b66b4a354e5420587aed23a8a8d0191f2d88f68c 100644 (file)
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