Browse Source

JAVA: libphonenumber 5.1: AYTF changes and metadata updates.

pull/567/head
Lara Scheidegger 13 years ago
committed by Mihaela Rosca
parent
commit
fc1adde81a
33 changed files with 699 additions and 153 deletions
  1. +18
    -3
      java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
  2. +92
    -32
      java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
  3. +13
    -0
      java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
  4. +1
    -0
      java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java
  5. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
  6. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
  7. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG
  8. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN
  9. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO
  10. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ
  11. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC
  12. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA
  13. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT
  14. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP
  15. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW
  16. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX
  17. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF
  18. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU
  19. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM
  20. +212
    -4
      java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
  21. +6
    -2
      java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
  22. +1
    -0
      java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java
  23. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR
  24. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BY
  25. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX
  26. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US
  27. +13
    -5
      java/release_notes.txt
  28. +270
    -80
      resources/PhoneNumberMetaData.xml
  29. +35
    -3
      resources/PhoneNumberMetaDataForTesting.xml
  30. +7
    -11
      tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java
  31. +31
    -13
      tools/java/common/test/com/google/i18n/phonenumbers/BuildMetadataFromXmlTest.java
  32. BIN
      tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar
  33. BIN
      tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar

+ 18
- 3
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java View File

@ -17,6 +17,7 @@
package com.google.i18n.phonenumbers.geocoding;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import java.io.IOException;
@ -148,7 +149,9 @@ public class PhoneNumberOfflineGeocoder {
* name of the geographical area the phone number is from if more detailed information is
* available.
*
* <p>This method assumes the validity of the number passed in has already been checked.
* <p>This method assumes the validity of the number passed in has already been checked, and that
* the number is suitable for geocoding. We consider fixed-line and mobile numbers possible
* candidates for geocoding.
*
* @param number a valid phone number for which we want to get a text description
* @param languageCode the language code for which the description should be written
@ -211,8 +214,11 @@ public class PhoneNumberOfflineGeocoder {
* string if the number passed in is invalid
*/
public String getDescriptionForNumber(PhoneNumber number, Locale languageCode) {
if (!phoneUtil.isValidNumber(number)) {
PhoneNumberType numberType = phoneUtil.getNumberType(number);
if (numberType == PhoneNumberType.UNKNOWN) {
return "";
} else if (!canBeGeocoded(numberType)) {
return getCountryNameForNumber(number, languageCode);
}
return getDescriptionForValidNumber(number, languageCode);
}
@ -231,12 +237,21 @@ public class PhoneNumberOfflineGeocoder {
*/
public String getDescriptionForNumber(PhoneNumber number, Locale languageCode,
String userRegion) {
if (!phoneUtil.isValidNumber(number)) {
PhoneNumberType numberType = phoneUtil.getNumberType(number);
if (numberType == PhoneNumberType.UNKNOWN) {
return "";
} else if (!canBeGeocoded(numberType)) {
return getCountryNameForNumber(number, languageCode);
}
return getDescriptionForValidNumber(number, languageCode, userRegion);
}
private boolean canBeGeocoded(PhoneNumberType numberType) {
return (numberType == PhoneNumberType.FIXED_LINE ||
numberType == PhoneNumberType.MOBILE ||
numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE);
}
/**
* Returns an area-level text description in the given language for the given phone number.
*


+ 92
- 32
java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java View File

@ -50,11 +50,17 @@ public class AsYouTypeFormatter {
// Set to true when users enter their own formatting. AsYouTypeFormatter will do no formatting at
// all when this is set to true.
private boolean inputHasFormatting = false;
private boolean isInternationalFormatting = false;
// This is set to true when we know the user is entering a full national significant number, since
// we have either detected a national prefix or an international dialing prefix. When this is
// true, we will no longer use local number formatting patterns.
private boolean isCompleteNumber = false;
private boolean isExpectingCountryCallingCode = false;
private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
private String defaultCountry;
// Character used when appropriate to separate a prefix, such as a long NDD or a country calling
// code, from the national number.
private static final char SEPARATOR_BEFORE_NATIONAL_NUMBER = ' ';
private static final PhoneMetadata EMPTY_METADATA =
new PhoneMetadata().setInternationalPrefix("NA");
private PhoneMetadata defaultMetaData;
@ -78,6 +84,9 @@ public class AsYouTypeFormatter {
private static final Pattern ELIGIBLE_FORMAT_PATTERN =
Pattern.compile("[" + PhoneNumberUtil.VALID_PUNCTUATION + "]*" +
"(\\$\\d" + "[" + PhoneNumberUtil.VALID_PUNCTUATION + "]*)+");
// A set of characters that, if found in a national prefix formatting rules, are an indicator to
// us that we should separate the national prefix from the number when formatting.
private static final Pattern NATIONAL_PREFIX_SEPARATORS_PATTERN = Pattern.compile("[- ]");
// This is the minimum length of national number accrued that is required to trigger the
// formatter. The first element of the leadingDigitsPattern of each numberFormat contains a
@ -86,8 +95,8 @@ public class AsYouTypeFormatter {
// The digits that have not been entered yet will be represented by a \u2008, the punctuation
// space.
private String digitPlaceholder = "\u2008";
private Pattern digitPattern = Pattern.compile(digitPlaceholder);
private static final String DIGIT_PLACEHOLDER = "\u2008";
private static final Pattern DIGIT_PATTERN = Pattern.compile(DIGIT_PLACEHOLDER);
private int lastMatchPosition = 0;
// The position of a digit upon which inputDigitAndRememberPosition is most recently invoked, as
// found in the original sequence of characters the user entered.
@ -99,6 +108,7 @@ public class AsYouTypeFormatter {
// and it is formatted (e.g. with space inserted). For example, this can contain IDD, country
// code, and/or NDD, etc.
private StringBuilder prefixBeforeNationalNumber = new StringBuilder();
private boolean shouldAddSpaceAfterNationalPrefix = false;
// This contains the national prefix that has been extracted. It contains only digits without
// formatting.
private String nationalPrefixExtracted = "";
@ -147,6 +157,9 @@ public class AsYouTypeFormatter {
}
if (createFormattingTemplate(numberFormat)) {
currentFormattingPattern = pattern;
shouldAddSpaceAfterNationalPrefix =
NATIONAL_PREFIX_SEPARATORS_PATTERN.matcher(
numberFormat.getNationalPrefixFormattingRule()).find();
// With a new formatting template, the matched position using the old template needs to be
// reset.
lastMatchPosition = 0;
@ -161,12 +174,15 @@ public class AsYouTypeFormatter {
private void getAvailableFormats(String leadingThreeDigits) {
List<NumberFormat> formatList =
(isInternationalFormatting && currentMetaData.intlNumberFormatSize() > 0)
(isCompleteNumber && currentMetaData.intlNumberFormatSize() > 0)
? currentMetaData.intlNumberFormats()
: currentMetaData.numberFormats();
for (NumberFormat format : formatList) {
if (isFormatEligible(format.getFormat())) {
possibleFormats.add(format);
if (isCompleteNumber || format.isNationalPrefixOptionalWhenFormatting() ||
phoneUtil.formattingRuleHasFirstGroupOnly(format.getNationalPrefixFormattingRule())) {
if (isFormatEligible(format.getFormat())) {
possibleFormats.add(format);
}
}
}
narrowDownPossibleFormats(leadingThreeDigits);
@ -233,8 +249,8 @@ public class AsYouTypeFormatter {
}
// Formats the number according to numberFormat
String template = aPhoneNumber.replaceAll(numberPattern, numberFormat);
// Replaces each digit with character digitPlaceholder
template = template.replaceAll("9", digitPlaceholder);
// Replaces each digit with character DIGIT_PLACEHOLDER
template = template.replaceAll("9", DIGIT_PLACEHOLDER);
return template;
}
@ -255,9 +271,10 @@ public class AsYouTypeFormatter {
inputHasFormatting = false;
positionToRemember = 0;
originalPosition = 0;
isInternationalFormatting = false;
isCompleteNumber = false;
isExpectingCountryCallingCode = false;
possibleFormats.clear();
shouldAddSpaceAfterNationalPrefix = false;
if (!currentMetaData.equals(defaultMetaData)) {
currentMetaData = getMetadataForRegion(defaultCountry);
}
@ -314,8 +331,9 @@ public class AsYouTypeFormatter {
}
} else if (ableToExtractLongerNdd()) {
// Add an additional space to separate long NDD and national significant number for
// readability.
prefixBeforeNationalNumber.append(" ");
// readability. We don't set shouldAddSpaceAfterNationalPrefix to true, since we don't want
// this to change later when we choose formatting templates.
prefixBeforeNationalNumber.append(SEPARATOR_BEFORE_NATIONAL_NUMBER);
return attemptToChoosePatternWithPrefixExtracted();
}
return accruedInput.toString();
@ -355,7 +373,7 @@ public class AsYouTypeFormatter {
return inputAccruedNationalNumber();
}
return ableToFormat
? prefixBeforeNationalNumber + tempNationalNumber
? appendNationalNumber(tempNationalNumber)
: accruedInput.toString();
} else {
return attemptToChooseFormattingPattern();
@ -391,12 +409,19 @@ public class AsYouTypeFormatter {
PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(Character.toString(nextChar)).matches());
}
/**
* Check to see if there is an exact pattern match for these digits. If so, we should use this
* instead of any other formatting template whose leadingDigitsPattern also matches the input.
*/
String attemptToFormatAccruedDigits() {
for (NumberFormat numFormat : possibleFormats) {
Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber);
for (NumberFormat numberFormat : possibleFormats) {
Matcher m = regexCache.getPatternForRegex(numberFormat.getPattern()).matcher(nationalNumber);
if (m.matches()) {
String formattedNumber = m.replaceAll(numFormat.getFormat());
return prefixBeforeNationalNumber + formattedNumber;
shouldAddSpaceAfterNationalPrefix =
NATIONAL_PREFIX_SEPARATORS_PATTERN.matcher(
numberFormat.getNationalPrefixFormattingRule()).find();
String formattedNumber = m.replaceAll(numberFormat.getFormat());
return appendNationalNumber(formattedNumber);
}
}
return "";
@ -421,8 +446,30 @@ public class AsYouTypeFormatter {
return currentOutputIndex;
}
// Attempts to set the formatting template and returns a string which contains the formatted
// version of the digits entered so far.
/**
* Combines the national number with any prefix (IDD/+ and country code or national prefix) that
* was collected. A space will be inserted between them if the current formatting template
* indicates this to be suitable.
*/
private String appendNationalNumber(String nationalNumber) {
int prefixBeforeNationalNumberLength = prefixBeforeNationalNumber.length();
if (shouldAddSpaceAfterNationalPrefix && prefixBeforeNationalNumberLength > 0 &&
prefixBeforeNationalNumber.charAt(prefixBeforeNationalNumberLength - 1)
!= SEPARATOR_BEFORE_NATIONAL_NUMBER) {
// We want to add a space after the national prefix if the national prefix formatting rule
// indicates that this would normally be done, with the exception of the case where we already
// appended a space because the NDD was surprisingly long.
return new String(prefixBeforeNationalNumber) + SEPARATOR_BEFORE_NATIONAL_NUMBER
+ nationalNumber;
} else {
return prefixBeforeNationalNumber + nationalNumber;
}
}
/**
* Attempts to set the formatting template and returns a string which contains the formatted
* version of the digits entered so far.
*/
private String attemptToChooseFormattingPattern() {
// We start to attempt to format only when as least MIN_LEADING_DIGITS_LENGTH digits of national
// number (excluding national prefix) have been entered.
@ -430,12 +477,14 @@ public class AsYouTypeFormatter {
getAvailableFormats(nationalNumber.substring(0, MIN_LEADING_DIGITS_LENGTH));
return maybeCreateNewTemplate() ? inputAccruedNationalNumber() : accruedInput.toString();
} else {
return prefixBeforeNationalNumber + nationalNumber.toString();
return appendNationalNumber(nationalNumber.toString());
}
}
// Invokes inputDigitHelper on each digit of the national number accrued, and returns a formatted
// string in the end.
/**
* Invokes inputDigitHelper on each digit of the national number accrued, and returns a formatted
* string in the end.
*/
private String inputAccruedNationalNumber() {
int lengthOfNationalNumber = nationalNumber.length();
if (lengthOfNationalNumber > 0) {
@ -443,21 +492,32 @@ public class AsYouTypeFormatter {
for (int i = 0; i < lengthOfNationalNumber; i++) {
tempNationalNumber = inputDigitHelper(nationalNumber.charAt(i));
}
return ableToFormat
? prefixBeforeNationalNumber + tempNationalNumber
: accruedInput.toString();
return ableToFormat ? appendNationalNumber(tempNationalNumber) : accruedInput.toString();
} else {
return prefixBeforeNationalNumber.toString();
}
}
/**
* Returns true if the current country is a NANPA country and the national number begins with
* the national prefix.
*/
private boolean isNanpaNumberWithNationalPrefix() {
// For NANPA numbers beginning with 1[2-9], treat the 1 as the national prefix. The reason is
// that national significant numbers in NANPA always start with [2-9] after the national prefix.
// Numbers beginning with 1[01] can only be short/emergency numbers, which don't need the
// national prefix.
return (currentMetaData.getCountryCode() == 1) && (nationalNumber.charAt(0) == '1') &&
(nationalNumber.charAt(1) != '0') && (nationalNumber.charAt(1) != '1');
}
// Returns the national prefix extracted, or an empty string if it is not present.
private String removeNationalPrefixFromNationalNumber() {
int startOfNationalNumber = 0;
if (currentMetaData.getCountryCode() == 1 && nationalNumber.charAt(0) == '1') {
if (isNanpaNumberWithNationalPrefix()) {
startOfNationalNumber = 1;
prefixBeforeNationalNumber.append("1 ");
isInternationalFormatting = true;
prefixBeforeNationalNumber.append('1').append(SEPARATOR_BEFORE_NATIONAL_NUMBER);
isCompleteNumber = true;
} else if (currentMetaData.hasNationalPrefixForParsing()) {
Pattern nationalPrefixForParsing =
regexCache.getPatternForRegex(currentMetaData.getNationalPrefixForParsing());
@ -466,7 +526,7 @@ public class AsYouTypeFormatter {
// When the national prefix is detected, we use international formatting rules instead of
// national ones, because national formatting rules could contain local formatting rules
// for numbers entered without area code.
isInternationalFormatting = true;
isCompleteNumber = true;
startOfNationalNumber = m.end();
prefixBeforeNationalNumber.append(nationalNumber.substring(0, startOfNationalNumber));
}
@ -489,7 +549,7 @@ public class AsYouTypeFormatter {
currentMetaData.getInternationalPrefix());
Matcher iddMatcher = internationalPrefix.matcher(accruedInputWithoutFormatting);
if (iddMatcher.lookingAt()) {
isInternationalFormatting = true;
isCompleteNumber = true;
int startOfCountryCallingCode = iddMatcher.end();
nationalNumber.setLength(0);
nationalNumber.append(accruedInputWithoutFormatting.substring(startOfCountryCallingCode));
@ -497,7 +557,7 @@ public class AsYouTypeFormatter {
prefixBeforeNationalNumber.append(
accruedInputWithoutFormatting.substring(0, startOfCountryCallingCode));
if (accruedInputWithoutFormatting.charAt(0) != PhoneNumberUtil.PLUS_SIGN) {
prefixBeforeNationalNumber.append(" ");
prefixBeforeNationalNumber.append(SEPARATOR_BEFORE_NATIONAL_NUMBER);
}
return true;
}
@ -529,7 +589,7 @@ public class AsYouTypeFormatter {
currentMetaData = getMetadataForRegion(newRegionCode);
}
String countryCodeString = Integer.toString(countryCode);
prefixBeforeNationalNumber.append(countryCodeString).append(" ");
prefixBeforeNationalNumber.append(countryCodeString).append(SEPARATOR_BEFORE_NATIONAL_NUMBER);
return true;
}
@ -556,7 +616,7 @@ public class AsYouTypeFormatter {
}
private String inputDigitHelper(char nextChar) {
Matcher digitMatcher = digitPattern.matcher(formattingTemplate);
Matcher digitMatcher = DIGIT_PATTERN.matcher(formattingTemplate);
if (digitMatcher.find(lastMatchPosition)) {
String tempTemplate = digitMatcher.replaceFirst(Character.toString(nextChar));
formattingTemplate.replace(0, tempTemplate.length(), tempTemplate);


+ 13
- 0
java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java View File

@ -348,6 +348,11 @@ public class PhoneNumberUtil {
private static final Pattern FG_PATTERN = Pattern.compile("\\$FG");
private static final Pattern CC_PATTERN = Pattern.compile("\\$CC");
// A pattern that is used to determine if the national prefix formatting rule has the first group
// only, i.e., does not start with the national prefix. Note that the pattern explicitly allows
// for unbalanced parentheses.
private static final Pattern FIRST_GROUP_ONLY_PREFIX_PATTERN = Pattern.compile("\\(?\\$1\\)?");
private static PhoneNumberUtil instance = null;
// A mapping from a region code to the PhoneMetadata for that region.
@ -922,6 +927,14 @@ public class PhoneNumberUtil {
return instance;
}
/**
* Helper function to check if the national prefix formatting rule has the first group only, i.e.,
* does not start with the national prefix.
*/
static boolean formattingRuleHasFirstGroupOnly(String nationalPrefixFormattingRule) {
return FIRST_GROUP_ONLY_PREFIX_PATTERN.matcher(nationalPrefixFormattingRule).matches();
}
/**
* Helper function to check region code is not unknown or null.
*/


+ 1
- 0
java/libphonenumber/src/com/google/i18n/phonenumbers/Phonemetadata.java View File

@ -43,6 +43,7 @@ public final class Phonemetadata {
return this;
}
}
public static Builder newBuilder() {
return new Builder();
}


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CO View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DZ View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MX View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PF View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RU View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SM View File


+ 212
- 4
java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java View File

@ -88,6 +88,35 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase {
assertEquals("+819012345678901", formatter.inputDigit('1'));
}
public void testCountryWithSpaceInNationalPrefixFormattingRule() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.BY);
assertEquals("8", formatter.inputDigit('8'));
assertEquals("88", formatter.inputDigit('8'));
assertEquals("881", formatter.inputDigit('1'));
assertEquals("8 819", formatter.inputDigit('9'));
assertEquals("8 8190", formatter.inputDigit('0'));
// The formatting rule for 5 digit numbers states that no space should be present after the
// national prefix.
assertEquals("881 901", formatter.inputDigit('1'));
assertEquals("8 819 012", formatter.inputDigit('2'));
// Too long, no formatting rule applies.
assertEquals("88190123", formatter.inputDigit('3'));
}
public void testCountryWithSpaceInNationalPrefixFormattingRuleAndLongNdd() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.BY);
assertEquals("9", formatter.inputDigit('9'));
assertEquals("99", formatter.inputDigit('9'));
assertEquals("999", formatter.inputDigit('9'));
assertEquals("9999", formatter.inputDigit('9'));
assertEquals("99999 ", formatter.inputDigit('9'));
assertEquals("99999 1", formatter.inputDigit('1'));
assertEquals("99999 12", formatter.inputDigit('2'));
assertEquals("99999 123", formatter.inputDigit('3'));
assertEquals("99999 1234", formatter.inputDigit('4'));
assertEquals("99999 12 345", formatter.inputDigit('5'));
}
public void testAYTFUS() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
assertEquals("6", formatter.inputDigit('6'));
@ -753,7 +782,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase {
}
public void testAYTFLongIDD_AU() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("AU");
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.AU);
// 0011 1 650 253 2250
assertEquals("0", formatter.inputDigit('0'));
assertEquals("00", formatter.inputDigit('0'));
@ -810,7 +839,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase {
}
public void testAYTFLongIDD_KR() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR");
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR);
// 00300 1 650 253 2222
assertEquals("0", formatter.inputDigit('0'));
assertEquals("00", formatter.inputDigit('0'));
@ -831,7 +860,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase {
}
public void testAYTFLongNDD_KR() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("KR");
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR);
// 08811-9876-7890
assertEquals("0", formatter.inputDigit('0'));
assertEquals("08", formatter.inputDigit('8'));
@ -867,7 +896,7 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase {
}
public void testAYTFLongNDD_SG() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("SG");
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.SG);
// 777777 9876 7890
assertEquals("7", formatter.inputDigit('7'));
assertEquals("77", formatter.inputDigit('7'));
@ -884,4 +913,183 @@ public class AsYouTypeFormatterTest extends TestMetadataTestCase {
assertEquals("777777 9876 789", formatter.inputDigit('9'));
assertEquals("777777 9876 7890", formatter.inputDigit('0'));
}
public void testAYTFShortNumberFormattingFix_AU() {
// For Australia, the national prefix is not optional when formatting.
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.AU);
// 1234567890 - For leading digit 1, the national prefix formatting rule has first group only.
assertEquals("1", formatter.inputDigit('1'));
assertEquals("12", formatter.inputDigit('2'));
assertEquals("123", formatter.inputDigit('3'));
assertEquals("1234", formatter.inputDigit('4'));
assertEquals("1234 5", formatter.inputDigit('5'));
assertEquals("1234 56", formatter.inputDigit('6'));
assertEquals("1234 567", formatter.inputDigit('7'));
assertEquals("1234 567 8", formatter.inputDigit('8'));
assertEquals("1234 567 89", formatter.inputDigit('9'));
assertEquals("1234 567 890", formatter.inputDigit('0'));
// +61 1234 567 890 - Test the same number, but with the country code.
formatter.clear();
assertEquals("+", formatter.inputDigit('+'));
assertEquals("+6", formatter.inputDigit('6'));
assertEquals("+61 ", formatter.inputDigit('1'));
assertEquals("+61 1", formatter.inputDigit('1'));
assertEquals("+61 12", formatter.inputDigit('2'));
assertEquals("+61 123", formatter.inputDigit('3'));
assertEquals("+61 1234", formatter.inputDigit('4'));
assertEquals("+61 1234 5", formatter.inputDigit('5'));
assertEquals("+61 1234 56", formatter.inputDigit('6'));
assertEquals("+61 1234 567", formatter.inputDigit('7'));
assertEquals("+61 1234 567 8", formatter.inputDigit('8'));
assertEquals("+61 1234 567 89", formatter.inputDigit('9'));
assertEquals("+61 1234 567 890", formatter.inputDigit('0'));
// 212345678 - For leading digit 2, the national prefix formatting rule puts the national prefix
// before the first group.
formatter.clear();
assertEquals("0", formatter.inputDigit('0'));
assertEquals("02", formatter.inputDigit('2'));
assertEquals("021", formatter.inputDigit('1'));
assertEquals("02 12", formatter.inputDigit('2'));
assertEquals("02 123", formatter.inputDigit('3'));
assertEquals("02 1234", formatter.inputDigit('4'));
assertEquals("02 1234 5", formatter.inputDigit('5'));
assertEquals("02 1234 56", formatter.inputDigit('6'));
assertEquals("02 1234 567", formatter.inputDigit('7'));
assertEquals("02 1234 5678", formatter.inputDigit('8'));
// 212345678 - Test the same number, but without the leading 0.
formatter.clear();
assertEquals("2", formatter.inputDigit('2'));
assertEquals("21", formatter.inputDigit('1'));
assertEquals("212", formatter.inputDigit('2'));
assertEquals("2123", formatter.inputDigit('3'));
assertEquals("21234", formatter.inputDigit('4'));
assertEquals("212345", formatter.inputDigit('5'));
assertEquals("2123456", formatter.inputDigit('6'));
assertEquals("21234567", formatter.inputDigit('7'));
assertEquals("212345678", formatter.inputDigit('8'));
// +61 2 1234 5678 - Test the same number, but with the country code.
formatter.clear();
assertEquals("+", formatter.inputDigit('+'));
assertEquals("+6", formatter.inputDigit('6'));
assertEquals("+61 ", formatter.inputDigit('1'));
assertEquals("+61 2", formatter.inputDigit('2'));
assertEquals("+61 21", formatter.inputDigit('1'));
assertEquals("+61 2 12", formatter.inputDigit('2'));
assertEquals("+61 2 123", formatter.inputDigit('3'));
assertEquals("+61 2 1234", formatter.inputDigit('4'));
assertEquals("+61 2 1234 5", formatter.inputDigit('5'));
assertEquals("+61 2 1234 56", formatter.inputDigit('6'));
assertEquals("+61 2 1234 567", formatter.inputDigit('7'));
assertEquals("+61 2 1234 5678", formatter.inputDigit('8'));
}
public void testAYTFShortNumberFormattingFix_KR() {
// For Korea, the national prefix is not optional when formatting, and the national prefix
// formatting rule doesn't consist of only the first group.
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.KR);
// 111
assertEquals("1", formatter.inputDigit('1'));
assertEquals("11", formatter.inputDigit('1'));
assertEquals("111", formatter.inputDigit('1'));
// 114
formatter.clear();
assertEquals("1", formatter.inputDigit('1'));
assertEquals("11", formatter.inputDigit('1'));
assertEquals("114", formatter.inputDigit('4'));
// 13121234 - Test a mobile number without the national prefix. Even though it is not an
// emergency number, it should be formatted as a block.
formatter.clear();
assertEquals("1", formatter.inputDigit('1'));
assertEquals("13", formatter.inputDigit('3'));
assertEquals("131", formatter.inputDigit('1'));
assertEquals("1312", formatter.inputDigit('2'));
assertEquals("13121", formatter.inputDigit('1'));
assertEquals("131212", formatter.inputDigit('2'));
assertEquals("1312123", formatter.inputDigit('3'));
assertEquals("13121234", formatter.inputDigit('4'));
// +82 131-2-1234 - Test the same number, but with the country code.
formatter.clear();
assertEquals("+", formatter.inputDigit('+'));
assertEquals("+8", formatter.inputDigit('8'));
assertEquals("+82 ", formatter.inputDigit('2'));
assertEquals("+82 1", formatter.inputDigit('1'));
assertEquals("+82 13", formatter.inputDigit('3'));
assertEquals("+82 131", formatter.inputDigit('1'));
assertEquals("+82 131-2", formatter.inputDigit('2'));
assertEquals("+82 131-2-1", formatter.inputDigit('1'));
assertEquals("+82 131-2-12", formatter.inputDigit('2'));
assertEquals("+82 131-2-123", formatter.inputDigit('3'));
assertEquals("+82 131-2-1234", formatter.inputDigit('4'));
}
public void testAYTFShortNumberFormattingFix_MX() {
// For Mexico, the national prefix is optional when formatting.
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.MX);
// 911
assertEquals("9", formatter.inputDigit('9'));
assertEquals("91", formatter.inputDigit('1'));
assertEquals("911", formatter.inputDigit('1'));
// 800 123 4567 - Test a toll-free number, which should have a formatting rule applied to it
// even though it doesn't begin with the national prefix.
formatter.clear();
assertEquals("8", formatter.inputDigit('8'));
assertEquals("80", formatter.inputDigit('0'));
assertEquals("800", formatter.inputDigit('0'));
assertEquals("800 1", formatter.inputDigit('1'));
assertEquals("800 12", formatter.inputDigit('2'));
assertEquals("800 123", formatter.inputDigit('3'));
assertEquals("800 123 4", formatter.inputDigit('4'));
assertEquals("800 123 45", formatter.inputDigit('5'));
assertEquals("800 123 456", formatter.inputDigit('6'));
assertEquals("800 123 4567", formatter.inputDigit('7'));
// +52 800 123 4567 - Test the same number, but with the country code.
formatter.clear();
assertEquals("+", formatter.inputDigit('+'));
assertEquals("+5", formatter.inputDigit('5'));
assertEquals("+52 ", formatter.inputDigit('2'));
assertEquals("+52 8", formatter.inputDigit('8'));
assertEquals("+52 80", formatter.inputDigit('0'));
assertEquals("+52 800", formatter.inputDigit('0'));
assertEquals("+52 800 1", formatter.inputDigit('1'));
assertEquals("+52 800 12", formatter.inputDigit('2'));
assertEquals("+52 800 123", formatter.inputDigit('3'));
assertEquals("+52 800 123 4", formatter.inputDigit('4'));
assertEquals("+52 800 123 45", formatter.inputDigit('5'));
assertEquals("+52 800 123 456", formatter.inputDigit('6'));
assertEquals("+52 800 123 4567", formatter.inputDigit('7'));
}
public void testAYTFShortNumberFormattingFix_US() {
// For the US, an initial 1 is treated specially.
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
// 101 - Test that the initial 1 is not treated as a national prefix.
assertEquals("1", formatter.inputDigit('1'));
assertEquals("10", formatter.inputDigit('0'));
assertEquals("101", formatter.inputDigit('1'));
// 112 - Test that the initial 1 is not treated as a national prefix.
formatter.clear();
assertEquals("1", formatter.inputDigit('1'));
assertEquals("11", formatter.inputDigit('1'));
assertEquals("112", formatter.inputDigit('2'));
// 122 - Test that the initial 1 is treated as a national prefix.
formatter.clear();
assertEquals("1", formatter.inputDigit('1'));
assertEquals("12", formatter.inputDigit('2'));
assertEquals("1 22", formatter.inputDigit('2'));
}
}

+ 6
- 2
java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java View File

@ -31,10 +31,10 @@ public class CountryCodeToRegionCodeMapForTesting {
// countries sharing a calling code, such as the NANPA countries, the one
// indicated with "isMainCountryForCode" in the metadata should be first.
static Map<Integer, List<String>> getCountryCodeToRegionCodeMap() {
// The capacity is set to 24 as there are 18 different country codes,
// The capacity is set to 25 as there are 19 different country codes,
// and this offers a load factor of roughly 0.75.
Map<Integer, List<String>> countryCodeToRegionCodeMap =
new HashMap<Integer, List<String>>(24);
new HashMap<Integer, List<String>>(25);
ArrayList<String> listWithRegionCode;
@ -100,6 +100,10 @@ public class CountryCodeToRegionCodeMapForTesting {
listWithRegionCode.add("YT");
countryCodeToRegionCodeMap.put(262, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("BY");
countryCodeToRegionCodeMap.put(375, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("AD");
countryCodeToRegionCodeMap.put(376, listWithRegionCode);


+ 1
- 0
java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java View File

@ -29,6 +29,7 @@ final class RegionCode {
static final String AU = "AU";
static final String BR = "BR";
static final String BS = "BS";
static final String BY = "BY";
static final String CA = "CA";
static final String CN = "CN";
static final String CS = "CS";


BIN
java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_AR View File


BIN
java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BY View File


BIN
java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_MX View File


BIN
java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US View File


+ 13
- 5
java/release_notes.txt View File

@ -1,3 +1,11 @@
Sep 3, 2012: libphonenumber-5.1
* Code changes:
- Inserting a space after the national prefix in the AsYouTypeFormatter when formatting numbers in
national format, if the formatting rules for that country dictate that a space is appropriate.
- Format emergency numbers and short-codes as a block in the AsYouTypeFormatter.
* Metadata changes:
- Updated metadata for region code(s): BF, BG, DZ, GA, IT, JP, KW, PF
Aug 20, 2012: libphonenumber-5.0.3
* Metadata changes:
- New alternate formatting data for country calling code(s): 43
@ -19,13 +27,13 @@ July 26th, 2012: libphonenumber-5.0.1
July 12th, 2012: libphonenumber-5.0
* Code changes:
- Support for alternate formats when finding phone numbers.
- Allowing two-digit numbers to be parsed if they are entered in national-format with no
punctuation
- Support for alternate formats when finding phone numbers.
- Allowing two-digit numbers to be parsed if they are entered in national-format with no
punctuation
* Metadata changes
- IL, GA
- IL, GA
* Other
- Reflowed this file to 100 char width to make it unambiguous as to what the standard should be.
- Reflowed this file to 100 char width to make it unambiguous as to what the standard should be.
July 6th, 2012: libphonenumber-4.9.1
* Metadata changes


+ 270
- 80
resources/PhoneNumberMetaData.xml View File

@ -22,7 +22,7 @@
official short names in English according to ISO 3166-1.
For more information on what each element represents, see
resources/phonemetadata.proto
java/com/google/i18n/phonenumbers/phonemetadata.proto
Note that if you want to add validation metadata, the generalDesc nationalNumberPattern and
possibleNumberPattern must be provided. If this is missing, then the country will be
@ -2471,13 +2471,14 @@
<mobile>
<!-- Including the whole range of 75 despite the document restricting it to only a few,
since diallable numbers have been found outside the range that the document specifies.
Including 716 as well since many numbers seem to have this prefix. -->
Including 716 as well since many numbers seem to have this prefix. Including 65 as a
prefix for Airtel, since they have informed us they are using it. -->
<nationalNumberPattern>
(?:
6(?:
0\d|
[05]\d|
1[01]|
6[0-4]|
6[0-7]|
8[0-2]
)|
7(?:
@ -2503,27 +2504,30 @@
<territory id="BG" countryCode="359" internationalPrefix="00"
nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
<availableFormats>
<!-- Formatting rules follow the conventions seen in web-search results. A space has been
used to separate the area code from the rest of the number, based on sites like
http://www.goldenpages.bg. -->
<numberFormat pattern="(2)(\d{5})">
<leadingDigits>29</leadingDigits>
<format>$1/$2</format>
<format>$1 $2</format>
</numberFormat>
<numberFormat pattern="(2)(\d{3})(\d{3,4})">
<leadingDigits>2</leadingDigits>
<format>$1/$2 $3</format>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{4})">
<leadingDigits>
43[124-7]|
70[1-9]
</leadingDigits>
<format>$1/$2</format>
<format>$1 $2</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{3})(\d{2})">
<leadingDigits>
43[124-7]|
70[1-9]
</leadingDigits>
<format>$1/$2 $3</format>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{2})(\d{3})">
<leadingDigits>[78]00</leadingDigits>
@ -2536,7 +2540,7 @@
8[1-6]|
9[1-7]
</leadingDigits>
<format>$1/$2 $3</format>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{2})(\d{3})(\d{3,4})">
<leadingDigits>
@ -2549,8 +2553,8 @@
</availableFormats>
<generalDesc>
<nationalNumberPattern>
[23567]\d{5,7}|
[489]\d{6,8}
[23567]\d{5,7}|
[489]\d{6,8}
</nationalNumberPattern>
<possibleNumberPattern>\d{5,9}</possibleNumberPattern>
</generalDesc>
@ -5978,13 +5982,17 @@
<exampleNumber>12345678</exampleNumber>
</fixedLine>
<mobile>
<!-- Adding 65 and 78 from numbers found online. -->
<!-- Adding 65 and 78 from numbers found online. Also, prefix 670 is added since the carrier
Mobilis Algeria provided it.-->
<nationalNumberPattern>
(?:
5[56]|
6[569]|
7[7-9]
)\d{7}
)\d{7}|
6(?:
[569]\d|
70
)\d{6}
</nationalNumberPattern>
<possibleNumberPattern>\d{9}</possibleNumberPattern>
<exampleNumber>551234567</exampleNumber>
@ -7152,26 +7160,32 @@
<!-- Gabon -->
<!-- http://www.itu.int/oth/T020200004E/en -->
<territory id="GA" countryCode="241" internationalPrefix="00"
nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
<territory id="GA" countryCode="241" internationalPrefix="00" leading_zero_possible="true"
nationalPrefix="0">
<availableFormats>
<numberFormat pattern="(\d)(\d{2})(\d{2})(\d{2})">
<numberFormat pattern="(1)(\d{2})(\d{2})(\d{2})" nationalPrefixFormattingRule="$NP$FG">
<leadingDigits>1</leadingDigits>
<format>$1 $2 $3 $4</format>
</numberFormat>
<numberFormat pattern="(0\d)(\d{2})(\d{2})(\d{2})">
<leadingDigits>0</leadingDigits>
<format>$1 $2 $3 $4</format>
</numberFormat>
</availableFormats>
<generalDesc>
<nationalNumberPattern>[1-7]\d{6}</nationalNumberPattern>
<possibleNumberPattern>\d{7}</possibleNumberPattern>
<nationalNumberPattern>[01]\d{6,7}</nationalNumberPattern>
<possibleNumberPattern>\d{7,8}</possibleNumberPattern>
</generalDesc>
<!-- A 7-digit fixed-line plan was implemented as of June 17, 2012. (The doc refers to an
8-digit plan since it counts the initial 0.) -->
<!-- A 7-digit fixed-line plan was scheduled to be implemented on June 17, 2012 to unify fixed
line and mobile numbering. However the change to remove the leading '0' from mobile NDCs
has not gone through. This is now scheduled to happen on October 28, 2012. -->
<fixedLine>
<nationalNumberPattern>1\d{6}</nationalNumberPattern>
<exampleNumber>1441234</exampleNumber>
</fixedLine>
<mobile>
<nationalNumberPattern>[2-7]\d{6}</nationalNumberPattern>
<exampleNumber>6031234</exampleNumber>
<nationalNumberPattern>0[2-7]\d{6}</nationalNumberPattern>
<exampleNumber>06031234</exampleNumber>
</mobile>
<emergency>
<nationalNumberPattern>
@ -11234,8 +11248,11 @@
<availableFormats>
<!-- The leading zero for fixed numbers will be prepended before the matching of these
regular expressions. -->
<numberFormat pattern="(0[26])(\d{3,4})(\d{4})">
<leadingDigits>0[26]</leadingDigits>
<numberFormat pattern="(\d{2})(\d{3,4})(\d{4})">
<leadingDigits>
0[26]|
55
</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(0[26])(\d{4})(\d{5})">
@ -11250,15 +11267,33 @@
<leadingDigits>0[13-57-9][0159]</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(0\d{2})(\d{4,6})">
<leadingDigits>0[13-57-9][0159]</leadingDigits>
<numberFormat pattern="(\d{3})(\d{3,6})">
<leadingDigits>
0[13-57-9][0159]|
8(?:
03|
4[17]|
9[245]
)
</leadingDigits>
<leadingDigits>
0[13-57-9][0159]|
8(?:
03|
4[17]|
9(?:
2|
[45][0-4]
)
)
</leadingDigits>
<format>$1 $2</format>
</numberFormat>
<numberFormat pattern="(0\d{3})(\d{3})(\d{4})">
<leadingDigits>0[13-57-9][2-46-8]</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(0\d{3})(\d{4,6})">
<numberFormat pattern="(0\d{3})(\d{2,6})">
<leadingDigits>0[13-57-9][2-46-8]</leadingDigits>
<format>$1 $2</format>
</numberFormat>
@ -11267,29 +11302,36 @@
[13]|
8(?:
00|
4[78]|
99
4[08]|
9[59]
)
</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{4})(\d{4})">
<leadingDigits>3</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{3,6})">
<leadingDigits>
[13]|
8(?:
03|
92
00|
4[08]|
9(?:
5[5-9]|
9
)
)
</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{4})(\d{4})">
<leadingDigits>894</leadingDigits>
<leadingDigits>894[5-9]</leadingDigits>
<format>$1 $2</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{4})(\d{4})">
<leadingDigits>3</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
</availableFormats>
<generalDesc>
<nationalNumberPattern>
[0189]\d{5,10}|
[01589]\d{5,10}|
3(?:
[12457-9]\d{8}|
[36]\d{7,9}
@ -11298,18 +11340,75 @@
<possibleNumberPattern>\d{6,11}</possibleNumberPattern>
</generalDesc>
<noInternationalDialling>
<nationalNumberPattern>848\d{6,7}</nationalNumberPattern>
<possibleNumberPattern>\d{9,10}</possibleNumberPattern>
<exampleNumber>8481234567</exampleNumber>
<nationalNumberPattern>848\d{6}</nationalNumberPattern>
<possibleNumberPattern>\d{9}</possibleNumberPattern>
<exampleNumber>848123456</exampleNumber>
</noInternationalDialling>
<fixedLine>
<!-- Maximum lengths in the ITU document are 10, but it states above that for numbers
starting with 01, the maximum length is in fact 11. In fact, online, numbers can be
found with other prefixes that are 11 digits long as well, so we allow it for all the
three and four digit area codes. -->
<nationalNumberPattern>
0(?:
[26]\d{4,9}|
[13-57-9](?:
[0159]\d{4,8}|
[2-46-8]\d{5,8}
)
(?:
1(?:
[0159]\d|
[27][1-5]|
31|
4[1-4]|
6[1356]|
8[2-57]
)|
3(?:
[0159]\d|
2[1-4]|
3[12]|
[48][1-6]|
6[2-59]|
7[1-7]
)|
4(?:
[0159]\d|
[23][1-9]|
4[245]|
6[1-5]|
7[1-4]|
81
)|
5(?:
[0159]\d|
2[1-5]|
3[2-6]|
4[1-79]|
6[4-6]|
7[1-578]|
8[3-8]
)|
7(?:
[0159]\d|
2[12]|
3[1-7]|
4[2346]|
6[13569]|
7[13-6]|
8[1-59]
)|
8(?:
[0159]\d|
2[34578]|
3[1-356]|
[6-8][1-5]
)|
9(?:
[0159]\d|
[238][1-5]|
4[12]|
6[1-8]|
7[1-6]
)
)\d{2,7}
)
</nationalNumberPattern>
<possibleNumberPattern>\d{6,11}</possibleNumberPattern>
@ -11352,26 +11451,80 @@
)\d{6}|
89(?:
2\d{3}|
4(?:
[0-4]\d{2}|
[5-9]\d{4}
)|
5(?:
[0-4]\d{2}|
[5-9]\d{6}
)|
9\d{6}
)
</nationalNumberPattern>
<possibleNumberPattern>\d{6,9}</possibleNumberPattern>
<possibleNumberPattern>\d{6,10}</possibleNumberPattern>
<exampleNumber>899123456</exampleNumber>
</premiumRate>
<sharedCost>
<nationalNumberPattern>84[78]\d{6,7}</nationalNumberPattern>
<possibleNumberPattern>\d{9,10}</possibleNumberPattern>
<exampleNumber>8481234567</exampleNumber>
<nationalNumberPattern>
84(?:
[08]\d{6}|
[17]\d{3}
)
</nationalNumberPattern>
<possibleNumberPattern>\d{6,9}</possibleNumberPattern>
<exampleNumber>848123456</exampleNumber>
</sharedCost>
<!-- The plan says these should be 6 digits long, but when you go to telephone companies in
Italy, such as http://www.gnetwork.it/EmailServizi/Numerazioni178/tabid/91/Default.aspx
and when you search for 178 numbers, they seem to all be 7 digits, so we cover both
lengths here. -->
<personalNumber>
<nationalNumberPattern>178\d{6,7}</nationalNumberPattern>
<nationalNumberPattern>
1(?:
78\d|
99
)\d{6}
</nationalNumberPattern>
<possibleNumberPattern>\d{9,10}</possibleNumberPattern>
<exampleNumber>1781234567</exampleNumber>
</personalNumber>
<voip>
<nationalNumberPattern>55\d{8}</nationalNumberPattern>
<possibleNumberPattern>\d{10}</possibleNumberPattern>
<exampleNumber>5512345678</exampleNumber>
</voip>
<shortCode>
<!-- Later, when we have better support for short-codes, we could add the codes
used for MMS and SMS services here too. -->
<nationalNumberPattern>
1(?:
1(?:
[47]|
6\d{3}
)|
2\d{2}|
4(?:
82|
9\d{1,3}
)|
5(?:
00|
1[58]|
2[25]|
3[03]|
44
)|
86|
9(?:
2(?:
[01]\d{2}|
[2-9]\d
)|
4\d|
696
)
)
</nationalNumberPattern>
<possibleNumberPattern>\d{3,6}</possibleNumberPattern>
<exampleNumber>114</exampleNumber>
</shortCode>
<emergency>
<nationalNumberPattern>11[2358]</nationalNumberPattern>
<possibleNumberPattern>\d{3}</possibleNumberPattern>
@ -11909,8 +12062,40 @@
<leadingDigits>088</leadingDigits>
<format>$1-$2-$3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{4})(\d{4})">
<leadingDigits>037</leadingDigits>
<numberFormat pattern="(\d{3})(\d{3})(\d{3,4})">
<leadingDigits>
0(?:
37|
66
)
</leadingDigits>
<format>$1-$2-$3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{4})(\d{4,5})">
<leadingDigits>
0(?:
37|
66
)
</leadingDigits>
<format>$1-$2-$3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{5})(\d{5,6})">
<leadingDigits>
0(?:
37|
66
)
</leadingDigits>
<format>$1-$2-$3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{6})(\d{6,7})">
<leadingDigits>
0(?:
37|
66
)
</leadingDigits>
<format>$1-$2-$3</format>
</numberFormat>
<!-- Some leading digits are explicitly reserved for a particular purpose.
@ -12078,7 +12263,7 @@
9[1-578]
)|
2(?:
2[03-9]|
2[03-689]|
3[3-58]|
4[0-468]|
5[04-8]|
@ -12147,7 +12332,7 @@
)|
2(?:
2(?:
[04-9]|
[04-689]|
3[23]
)|
3[3-58]|
@ -12265,7 +12450,7 @@
)|
2(?:
2(?:
[04-9]|
[04-689]|
3[23]
)|
3[3-58]|
@ -12404,7 +12589,7 @@
)|
2(?:
2(?:
[04-9]|
[04-689]|
3[23]
)|
3[3-58]|
@ -12537,7 +12722,7 @@
<leadingDigits>
1|
2(?:
23|
2[37]|
5[5-9]|
64|
78|
@ -12567,7 +12752,7 @@
<leadingDigits>
1|
2(?:
23|
2[37]|
5(?:
[57]|
[68]0|
@ -12605,7 +12790,7 @@
<leadingDigits>
1|
2(?:
23|
2[37]|
5(?:
[57]|
[68]0|
@ -12681,18 +12866,19 @@
<nationalNumberPattern>
[1-9]\d{8,9}|
0(?:
3\d{9}|
[36]\d{7,14}|
7\d{5,7}|
8\d{7}
)
</nationalNumberPattern>
<possibleNumberPattern>\d{7,11}</possibleNumberPattern>
<possibleNumberPattern>\d{7,16}</possibleNumberPattern>
</generalDesc>
<noInternationalDialling>
<!-- Toll-free numbers with a leading "00" cannot be dialled internationally. -->
<nationalNumberPattern>
0(?:
37\d{8}|
37\d{6,13}|
66\d{6,13}|
777(?:
[01]\d{2}|
5\d{3}|
@ -12701,7 +12887,7 @@
882[1245]\d{4}
)
</nationalNumberPattern>
<possibleNumberPattern>\d{7,11}</possibleNumberPattern>
<possibleNumberPattern>\d{7,16}</possibleNumberPattern>
<exampleNumber>0777012</exampleNumber>
</noInternationalDialling>
<fixedLine>
@ -12767,11 +12953,20 @@
</pager>
<tollFree>
<!-- http://www.kddi.com/english/business/free_call_dx/number.html and
http://tm.softbank.jp/english/business/phone_service/freecall_sp/index.html -->
http://tm.softbank.jp/english/business/phone_service/freecall_sp/index.html
http://eonet.jp/home/denwa/service/access.html
http://ci.fusioncom.co.jp/feature/
http://www.auhikari.jp/service/tel/connection/index.html -->
<!-- Note that in fact, the number length for 0037 and 0066 numbers should extend to 21
digits, confirmed with Yahoo JP. However, this extends well beyond the maximum number
length allowed by ITU and hence our library, so we only allow numbers up to 17 digits
for now (including both leading 00s). -->
<nationalNumberPattern>
120\d{6}|
800\d{7}|
0(?:
37\d{6,13}|
66\d{6,13}|
777(?:
[01]\d{2}|
5\d{3}|
@ -12780,7 +12975,7 @@
882[1245]\d{4}
)
</nationalNumberPattern>
<possibleNumberPattern>\d{7,10}</possibleNumberPattern>
<possibleNumberPattern>\d{7,16}</possibleNumberPattern>
<exampleNumber>120123456</exampleNumber>
</tollFree>
<premiumRate>
@ -12794,13 +12989,8 @@
<exampleNumber>601234567</exampleNumber>
</personalNumber>
<voip>
<nationalNumberPattern>
(?:
037|
50
)\d{8}
</nationalNumberPattern>
<possibleNumberPattern>\d{10,11}</possibleNumberPattern>
<nationalNumberPattern>50\d{8}</nationalNumberPattern>
<possibleNumberPattern>\d{10}</possibleNumberPattern>
<exampleNumber>5012345678</exampleNumber>
</voip>
<!-- Storing "unified number service" as UAN. -->
@ -13634,7 +13824,7 @@
<nationalNumberPattern>
(?:
5(?:
0[0-2568]|
0[0-25-9]|
11|
5\d
)|
@ -18338,7 +18528,7 @@
<nationalNumberPattern>
(?:
[27]\d{2}|
3[0-59]\d|
3[0-79]\d|
411
)\d{3}
</nationalNumberPattern>


+ 35
- 3
resources/PhoneNumberMetaDataForTesting.xml View File

@ -177,6 +177,39 @@
</premiumRate>
</territory>
<!-- Belarus -->
<!-- This country has been coopted to test the case of a national prefix formatting rule with a
space in it. -->
<territory id="BY" countryCode="375" internationalPrefix="810" nationalPrefix="8"
nationalPrefixForParsing="80?|99999" nationalPrefixFormattingRule="$NP $FG">
<availableFormats>
<!-- We make some bogus formatting templates that differ only in length to check that
switching formatting patterns works as expected.-->
<numberFormat pattern="(\d{4})">
<leadingDigits>[1-8]</leadingDigits>
<format>$1</format>
</numberFormat>
<!-- This pattern has an override to remove the space after the national prefix. -->
<numberFormat pattern="(\d{2})(\d{3})" nationalPrefixFormattingRule="$NP$FG">
<leadingDigits>[1-8]</leadingDigits>
<format>$1 $2</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{3})">
<leadingDigits>[1-8]</leadingDigits>
<format>$1 $2</format>
</numberFormat>
</availableFormats>
<generalDesc>
<!-- This numbering plan is completely bogus, but is used to test the AYTF logic. For that
reason, it is kept very simple. -->
<nationalNumberPattern>[1-9]\d{5}</nationalNumberPattern>
<possibleNumberPattern>\d{6}</possibleNumberPattern>
</generalDesc>
<fixedLine>
<exampleNumber>112345</exampleNumber>
</fixedLine>
</territory>
<!-- Germany -->
<territory id="DE" countryCode="49" internationalPrefix="00"
nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
@ -701,11 +734,10 @@
<!-- United States -->
<!-- http://www.nanpa.com/reports/reports_npa.html -->
<!-- For testing purposes, numbers starting with 24 are not considered US
numbers.-->
<!-- For testing purposes, numbers starting with 24 are not considered US numbers.-->
<territory id="US" countryCode="1" internationalPrefix="011"
preferredExtnPrefix=" extn. " nationalPrefix="1"
mainCountryForCode="true" >
mainCountryForCode="true" nationalPrefixOptionalWhenFormatting="true">
<availableFormats>
<numberFormat pattern="(\d{3})(\d{4})">
<format>$1 $2</format>


+ 7
- 11
tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java View File

@ -211,7 +211,7 @@ public class BuildMetadataFromXml {
// @VisibleForTesting
static boolean loadInternationalFormat(PhoneMetadata.Builder metadata,
Element numberFormatElement,
String nationalFormat) {
NumberFormat nationalFormat) {
NumberFormat.Builder intlFormat = NumberFormat.newBuilder();
setLeadingDigitsPatterns(numberFormatElement, intlFormat);
intlFormat.setPattern(numberFormatElement.getAttribute(PATTERN));
@ -226,7 +226,7 @@ public class BuildMetadataFromXml {
metadata.getId());
} else if (intlFormatPattern.getLength() == 0) {
// Default to use the same as the national pattern if none is defined.
intlFormat.setFormat(nationalFormat);
intlFormat.mergeFrom(nationalFormat);
} else {
String intlFormatPatternValue = intlFormatPattern.item(0).getFirstChild().getNodeValue();
if (!intlFormatPatternValue.equals("NA")) {
@ -245,11 +245,10 @@ public class BuildMetadataFromXml {
* 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) {
static void loadNationalFormat(PhoneMetadata.Builder metadata, Element numberFormatElement,
NumberFormat.Builder format) {
setLeadingDigitsPatterns(numberFormatElement, format);
format.setPattern(validateRE(numberFormatElement.getAttribute(PATTERN)));
@ -260,9 +259,7 @@ public class BuildMetadataFromXml {
throw new RuntimeException("Invalid number of format patterns for country: " +
metadata.getId());
}
String nationalFormat = formatPattern.item(0).getFirstChild().getNodeValue();
format.setFormat(nationalFormat);
return nationalFormat;
format.setFormat(formatPattern.item(0).getFirstChild().getNodeValue());
}
/**
@ -306,11 +303,10 @@ public class BuildMetadataFromXml {
} else {
format.setDomesticCarrierCodeFormattingRule(carrierCodeFormattingRule);
}
String nationalFormat =
loadNationalFormat(metadata, numberFormatElement, format);
loadNationalFormat(metadata, numberFormatElement, format);
metadata.addNumberFormat(format);
if (loadInternationalFormat(metadata, numberFormatElement, nationalFormat)) {
if (loadInternationalFormat(metadata, numberFormatElement, format.build())) {
hasExplicitIntlFormatDefined = true;
}
}


+ 31
- 13
tools/java/common/test/com/google/i18n/phonenumbers/BuildMetadataFromXmlTest.java View File

@ -153,7 +153,7 @@ public class BuildMetadataFromXmlTest extends TestCase {
String xmlInput = "<numberFormat><intlFormat>" + intlFormat + "</intlFormat></numberFormat>";
Element numberFormatElement = parseXmlString(xmlInput);
PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
String nationalFormat = "";
NumberFormat nationalFormat = NumberFormat.newBuilder().build();
assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
nationalFormat));
@ -166,10 +166,11 @@ public class BuildMetadataFromXmlTest extends TestCase {
String xmlInput = "<numberFormat><intlFormat>" + intlFormat + "</intlFormat></numberFormat>";
Element numberFormatElement = parseXmlString(xmlInput);
PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
String nationalFormat = "$1";
NumberFormat.Builder nationalFormat = NumberFormat.newBuilder();
nationalFormat.setFormat("$1");
assertTrue(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
nationalFormat));
nationalFormat.build()));
assertEquals(intlFormat, metadata.getIntlNumberFormat(0).getFormat());
}
@ -181,7 +182,8 @@ public class BuildMetadataFromXmlTest extends TestCase {
// Should throw an exception as multiple intlFormats are provided.
try {
BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, "");
BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
NumberFormat.newBuilder().build());
fail();
} catch (RuntimeException e) {
// Test passed.
@ -193,14 +195,29 @@ public class BuildMetadataFromXmlTest extends TestCase {
String xmlInput = "<numberFormat></numberFormat>";
Element numberFormatElement = parseXmlString(xmlInput);
PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
String nationalFormat = "$1 $2 $3";
NumberFormat.Builder nationalFormat = NumberFormat.newBuilder();
String nationalPattern = "$1 $2 $3";
nationalFormat.setFormat(nationalPattern);
assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
nationalFormat.build()));
assertEquals(nationalPattern, metadata.getIntlNumberFormat(0).getFormat());
}
public void testLoadInternationalFormatCopiesNationalFormatData()
throws ParserConfigurationException, SAXException, IOException {
String xmlInput = "<numberFormat></numberFormat>";
Element numberFormatElement = parseXmlString(xmlInput);
PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
NumberFormat.Builder nationalFormat = NumberFormat.newBuilder();
nationalFormat.setFormat("$1-$2");
nationalFormat.setNationalPrefixOptionalWhenFormatting(true);
assertFalse(BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
nationalFormat));
assertEquals(nationalFormat, metadata.getIntlNumberFormat(0).getFormat());
nationalFormat.build()));
assertTrue(metadata.getIntlNumberFormat(0).isNationalPrefixOptionalWhenFormatting());
}
// Tests loadNationalFormat().
public void testLoadNationalFormat()
throws ParserConfigurationException, SAXException, IOException {
String nationalFormat = "$1 $2";
@ -210,9 +227,8 @@ public class BuildMetadataFromXmlTest extends TestCase {
PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
NumberFormat.Builder numberFormat = NumberFormat.newBuilder();
assertEquals(nationalFormat,
BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement,
numberFormat));
BuildMetadataFromXml.loadNationalFormat(metadata, numberFormatElement, numberFormat);
assertEquals(nationalFormat, numberFormat.getFormat());
}
public void testLoadNationalFormatRequiresFormat()
@ -337,9 +353,11 @@ public class BuildMetadataFromXmlTest extends TestCase {
String xmlInput = "<numberFormat><intlFormat>NA</intlFormat></numberFormat>";
Element numberFormatElement = parseXmlString(xmlInput);
PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
String nationalFormat = "$1 $2";
NumberFormat.Builder nationalFormat = NumberFormat.newBuilder();
nationalFormat.setFormat("$1 $2");
BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement, nationalFormat);
BuildMetadataFromXml.loadInternationalFormat(metadata, numberFormatElement,
nationalFormat.build());
assertEquals(0, metadata.intlNumberFormatSize());
}


BIN
tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar View File


BIN
tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar View File


Loading…
Cancel
Save