Browse Source

JAVA: libphonenumber 4.5

Review URL: http://codereview.appspot.com/5532089
pull/567/head
Shaopeng Jia 14 years ago
committed by Mihaela Rosca
parent
commit
9feb68c47a
57 changed files with 1293 additions and 274 deletions
  1. BIN
      java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/1667_en
  2. BIN
      java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/1984_en
  3. BIN
      java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/54_en
  4. BIN
      java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/config
  5. +3
    -1
      java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
  6. +22
    -2
      java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java
  7. +233
    -71
      java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
  8. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_800
  9. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_808
  10. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_883
  11. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_888
  12. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_979
  13. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AR
  14. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH
  15. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI
  16. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN
  17. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CR
  18. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE
  19. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GA
  20. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL
  21. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO
  22. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JP
  23. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KE
  24. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KZ
  25. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LB
  26. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LK
  27. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LT
  28. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MV
  29. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW
  30. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MZ
  31. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NA
  32. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NL
  33. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_NZ
  34. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PL
  35. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RO
  36. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SA
  37. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SV
  38. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TM
  39. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_UG
  40. BIN
      java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US
  41. +18
    -0
      java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
  42. +6
    -2
      java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java
  43. +38
    -7
      java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java
  44. +183
    -13
      java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
  45. +3
    -0
      java/libphonenumber/test/com/google/i18n/phonenumbers/RegionCode.java
  46. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_800
  47. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_JP
  48. +13
    -0
      java/release_notes.txt
  49. +703
    -166
      resources/PhoneNumberMetaData.xml
  50. +39
    -1
      resources/PhoneNumberMetaDataForTesting.xml
  51. +2
    -0
      resources/geocoding/en/1.txt
  52. +12
    -5
      resources/geocoding/en/54.txt
  53. +12
    -5
      resources/geocoding/es/54.txt
  54. +1
    -1
      tools/java/common/src/com/google/i18n/phonenumbers/BuildMetadataFromXml.java
  55. BIN
      tools/java/cpp-build/target/cpp-build-1.0-SNAPSHOT-jar-with-dependencies.jar
  56. +5
    -0
      tools/java/java-build/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java
  57. BIN
      tools/java/java-build/target/java-build-1.0-SNAPSHOT-jar-with-dependencies.jar

BIN
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/1667_en View File


BIN
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/1984_en View File


BIN
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/54_en View File


BIN
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/config View File


+ 3
- 1
java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java View File

@ -523,7 +523,9 @@ public class AsYouTypeFormatter {
nationalNumber.setLength(0);
nationalNumber.append(numberWithoutCountryCallingCode);
String newRegionCode = phoneUtil.getRegionCodeForCountryCode(countryCode);
if (!newRegionCode.equals(defaultCountry)) {
if (PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY.equals(newRegionCode)) {
currentMetaData = phoneUtil.getMetadataForNonGeographicalRegion(countryCode);
} else if (!newRegionCode.equals(defaultCountry)) {
currentMetaData = getMetadataForRegion(newRegionCode);
}
String countryCodeString = Integer.toString(countryCode);


+ 22
- 2
java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java View File

@ -31,10 +31,10 @@ public class CountryCodeToRegionCodeMap {
// 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 273 as there are 205 different country codes,
// The capacity is set to 280 as there are 210 different country codes,
// and this offers a load factor of roughly 0.75.
Map<Integer, List<String>> countryCodeToRegionCodeMap =
new HashMap<Integer, List<String>>(273);
new HashMap<Integer, List<String>>(280);
ArrayList<String> listWithRegionCode;
@ -773,6 +773,14 @@ public class CountryCodeToRegionCodeMap {
listWithRegionCode.add("MH");
countryCodeToRegionCodeMap.put(692, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("001");
countryCodeToRegionCodeMap.put(800, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("001");
countryCodeToRegionCodeMap.put(808, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("KP");
countryCodeToRegionCodeMap.put(850, listWithRegionCode);
@ -797,10 +805,18 @@ public class CountryCodeToRegionCodeMap {
listWithRegionCode.add("BD");
countryCodeToRegionCodeMap.put(880, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("001");
countryCodeToRegionCodeMap.put(883, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("TW");
countryCodeToRegionCodeMap.put(886, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("001");
countryCodeToRegionCodeMap.put(888, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("MV");
countryCodeToRegionCodeMap.put(960, listWithRegionCode);
@ -869,6 +885,10 @@ public class CountryCodeToRegionCodeMap {
listWithRegionCode.add("NP");
countryCodeToRegionCodeMap.put(977, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("001");
countryCodeToRegionCodeMap.put(979, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("TJ");
countryCodeToRegionCodeMap.put(992, listWithRegionCode);


+ 233
- 71
java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java View File

@ -75,9 +75,9 @@ public class PhoneNumberUtil {
private Map<Integer, List<String>> countryCallingCodeToRegionCodeMap = null;
// The set of regions the library supports.
// There are roughly 220 of them and we set the initial capacity of the HashSet to 300 to offer a
// There are roughly 240 of them and we set the initial capacity of the HashSet to 320 to offer a
// load factor of roughly 0.75.
private final Set<String> supportedRegions = new HashSet<String>(300);
private final Set<String> supportedRegions = new HashSet<String>(320);
// Region-code for the unknown region.
private static final String UNKNOWN_REGION = "ZZ";
@ -337,11 +337,19 @@ public class PhoneNumberUtil {
private final Map<String, PhoneMetadata> regionToMetadataMap =
Collections.synchronizedMap(new HashMap<String, PhoneMetadata>());
// A mapping from a country calling code for a non-geographical entity to the PhoneMetadata for
// that country calling code. Examples of the country calling codes include 800 (International
// Toll Free Service) and 808 (International Shared Cost Service).
private final Map<Integer, PhoneMetadata> countryCodeToNonGeographicalMetadataMap =
Collections.synchronizedMap(new HashMap<Integer, PhoneMetadata>());
// A cache for frequently used region-specific regular expressions.
// As most people use phone numbers primarily from one to two countries, and there are roughly 60
// regular expressions needed, the initial capacity of 100 offers a rough load factor of 0.75.
private RegexCache regexCache = new RegexCache(100);
public static final String REGION_CODE_FOR_NON_GEO_ENTITY = "001";
/**
* INTERNATIONAL and NATIONAL formats are consistent with the definition in ITU-T Recommendation
* E123. For example, the number of the Google Switzerland office will be written as
@ -667,19 +675,26 @@ public class PhoneNumberUtil {
for (List<String> regionCodes : countryCallingCodeToRegionCodeMap.values()) {
supportedRegions.addAll(regionCodes);
}
supportedRegions.remove(REGION_CODE_FOR_NON_GEO_ENTITY);
nanpaRegions.addAll(countryCallingCodeToRegionCodeMap.get(NANPA_COUNTRY_CODE));
}
private void loadMetadataForRegionFromFile(String filePrefix, String regionCode) {
InputStream source =
PhoneNumberUtil.class.getResourceAsStream(filePrefix + "_" + regionCode);
private void loadMetadataFromFile(String filePrefix, String regionCode, int countryCallingCode) {
boolean isNonGeoRegion = REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode);
InputStream source = isNonGeoRegion
? PhoneNumberUtil.class.getResourceAsStream(filePrefix + "_" + countryCallingCode)
: PhoneNumberUtil.class.getResourceAsStream(filePrefix + "_" + regionCode);
ObjectInputStream in = null;
try {
in = new ObjectInputStream(source);
PhoneMetadataCollection metadataCollection = new PhoneMetadataCollection();
metadataCollection.readExternal(in);
for (PhoneMetadata metadata : metadataCollection.getMetadataList()) {
regionToMetadataMap.put(regionCode, metadata);
if (isNonGeoRegion) {
countryCodeToNonGeographicalMetadataMap.put(countryCallingCode, metadata);
} else {
regionToMetadataMap.put(regionCode, metadata);
}
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, e.toString());
@ -854,7 +869,8 @@ public class PhoneNumberUtil {
* therefore, it doesn't guarantee the stability of the result it produces.
* <li> subscriber numbers may not be diallable from all devices (notably mobile devices, which
* typically requires the full national_number to be dialled in most regions).
* <li> most non-geographical numbers have no area codes.
* <li> most non-geographical numbers have no area codes, including numbers from non-geographical
* entities
* <li> some geographical numbers have no area codes.
* </ul>
* @param number the PhoneNumber object for which clients want to know the length of the area
@ -1029,19 +1045,10 @@ public class PhoneNumberUtil {
}
/**
* Helper function to check region code is not unknown or null and log an error message. The
* {@code countryCallingCode} and {@code number} supplied is used only for the resultant log
* message.
* Helper function to check the country calling code is valid.
*/
private boolean hasValidRegionCode(String regionCode,
int countryCallingCode, String number) {
if (!isValidRegionCode(regionCode)) {
LOGGER.log(Level.WARNING,
"Number " + number + " has invalid or missing country calling code ("
+ countryCallingCode + ")");
return false;
}
return true;
private boolean hasValidCountryCallingCode(int countryCallingCode) {
return countryCallingCodeToRegionCodeMap.containsKey(countryCallingCode);
}
/**
@ -1091,12 +1098,13 @@ public class PhoneNumberUtil {
// share a country calling code is contained by only one region for performance reasons. For
// example, for NANPA regions it will be contained in the metadata for US.
String regionCode = getRegionCodeForCountryCode(countryCallingCode);
if (!isValidRegionCode(regionCode)) {
if (!hasValidCountryCallingCode(countryCallingCode)) {
formattedNumber.append(nationalSignificantNumber);
return;
}
PhoneMetadata metadata = getMetadataForRegion(regionCode);
PhoneMetadata metadata =
getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
formattedNumber.append(formatNationalNumber(nationalSignificantNumber, metadata, numberFormat));
maybeGetFormattedExtension(number, metadata, numberFormat, formattedNumber);
formatNumberByFormat(countryCallingCode, numberFormat, formattedNumber);
@ -1122,12 +1130,13 @@ public class PhoneNumberUtil {
// share a country calling code is contained by only one region for performance reasons. For
// example, for NANPA regions it will be contained in the metadata for US.
String regionCode = getRegionCodeForCountryCode(countryCallingCode);
if (!hasValidRegionCode(regionCode, countryCallingCode, nationalSignificantNumber)) {
if (!hasValidCountryCallingCode(countryCallingCode)) {
return nationalSignificantNumber;
}
List<NumberFormat> userDefinedFormatsCopy =
new ArrayList<NumberFormat>(userDefinedFormats.size());
PhoneMetadata metadata = getMetadataForRegion(regionCode);
PhoneMetadata metadata =
getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
for (NumberFormat numFormat : userDefinedFormats) {
String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
if (nationalPrefixFormattingRule.length() > 0) {
@ -1182,12 +1191,12 @@ public class PhoneNumberUtil {
// share a country calling code is contained by only one region for performance reasons. For
// example, for NANPA regions it will be contained in the metadata for US.
String regionCode = getRegionCodeForCountryCode(countryCallingCode);
if (!hasValidRegionCode(regionCode, countryCallingCode, nationalSignificantNumber)) {
if (!hasValidCountryCallingCode(countryCallingCode)) {
return nationalSignificantNumber;
}
StringBuilder formattedNumber = new StringBuilder(20);
PhoneMetadata metadata = getMetadataForRegion(regionCode);
PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
formattedNumber.append(formatNationalNumber(nationalSignificantNumber,
metadata,
PhoneNumberFormat.NATIONAL,
@ -1197,6 +1206,13 @@ public class PhoneNumberUtil {
return formattedNumber.toString();
}
private PhoneMetadata getMetadataForRegionOrCallingCode(
int countryCallingCode, String regionCode) {
return REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode)
? getMetadataForNonGeographicalRegion(countryCallingCode)
: getMetadataForRegion(regionCode);
}
/**
* Formats a phone number in national format for dialing using the carrier as specified in the
* preferredDomesticCarrierCode field of the PhoneNumber object passed in. If that is missing,
@ -1235,8 +1251,8 @@ public class PhoneNumberUtil {
*/
public String formatNumberForMobileDialing(PhoneNumber number, String regionCallingFrom,
boolean withFormatting) {
String regionCode = getRegionCodeForCountryCode(number.getCountryCode());
if (!isValidRegionCode(regionCode)) {
int countryCallingCode = number.getCountryCode();
if (!hasValidCountryCallingCode(countryCallingCode)) {
return number.hasRawInput() ? number.getRawInput() : "";
}
@ -1244,6 +1260,7 @@ public class PhoneNumberUtil {
// Clear the extension, as that part cannot normally be dialed together with the main number.
PhoneNumber numberNoExt = new PhoneNumber().mergeFrom(number).clearExtension();
PhoneNumberType numberType = getNumberType(numberNoExt);
String regionCode = getRegionCodeForCountryCode(countryCallingCode);
if (regionCode.equals("CO") && regionCallingFrom.equals("CO")) {
if (numberType == PhoneNumberType.FIXED_LINE) {
formattedNumber =
@ -1300,9 +1317,8 @@ public class PhoneNumberUtil {
return format(number, PhoneNumberFormat.INTERNATIONAL);
}
int countryCallingCode = number.getCountryCode();
String regionCode = getRegionCodeForCountryCode(countryCallingCode);
String nationalSignificantNumber = getNationalSignificantNumber(number);
if (!hasValidRegionCode(regionCode, countryCallingCode, nationalSignificantNumber)) {
if (!hasValidCountryCallingCode(countryCallingCode)) {
return nationalSignificantNumber;
}
if (countryCallingCode == NANPA_COUNTRY_CODE) {
@ -1333,7 +1349,9 @@ public class PhoneNumberUtil {
metadataForRegionCallingFrom.getPreferredInternationalPrefix();
}
PhoneMetadata metadataForRegion = getMetadataForRegion(regionCode);
String regionCode = getRegionCodeForCountryCode(countryCallingCode);
PhoneMetadata metadataForRegion =
getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
String formattedNationalNumber =
formatNationalNumber(nationalSignificantNumber,
metadataForRegion, PhoneNumberFormat.INTERNATIONAL);
@ -1359,6 +1377,8 @@ public class PhoneNumberUtil {
* country, or we don't have a formatting pattern for the number, the method returns the raw input
* when it is available.
*
* Note this method guarantees no digit will be inserted, removed or modified as a result of
* formatting.
* @param number the phone number that needs to be formatted in its original number format
* @param regionCallingFrom the region whose IDD needs to be prefixed if the original number
* has one
@ -1374,17 +1394,94 @@ public class PhoneNumberUtil {
if (!number.hasCountryCodeSource()) {
return format(number, PhoneNumberFormat.NATIONAL);
}
String formattedNumber;
switch (number.getCountryCodeSource()) {
case FROM_NUMBER_WITH_PLUS_SIGN:
return format(number, PhoneNumberFormat.INTERNATIONAL);
formattedNumber = format(number, PhoneNumberFormat.INTERNATIONAL);
break;
case FROM_NUMBER_WITH_IDD:
return formatOutOfCountryCallingNumber(number, regionCallingFrom);
formattedNumber = formatOutOfCountryCallingNumber(number, regionCallingFrom);
break;
case FROM_NUMBER_WITHOUT_PLUS_SIGN:
return format(number, PhoneNumberFormat.INTERNATIONAL).substring(1);
formattedNumber = format(number, PhoneNumberFormat.INTERNATIONAL).substring(1);
break;
case FROM_DEFAULT_COUNTRY:
// Fall-through to default case.
default:
return format(number, PhoneNumberFormat.NATIONAL);
String regionCode = getRegionCodeForCountryCode(number.getCountryCode());
// We strip non-digits from the NDD here, and from the raw input later, so that we can
// compare them easily.
String nationalPrefix = getNddPrefixForRegion(regionCode, true /* strip non-digits */);
String nationalFormat = format(number, PhoneNumberFormat.NATIONAL);
if (nationalPrefix == null || nationalPrefix.length() == 0) {
// If the region doesn't have a national prefix at all, we can safely return the national
// format without worrying about a national prefix being added.
formattedNumber = nationalFormat;
break;
}
// Otherwise, we check if the original number was entered with a national prefix.
if (rawInputContainsNationalPrefix(
number.getRawInput(), nationalPrefix, regionCode)) {
// If so, we can safely return the national format.
formattedNumber = nationalFormat;
break;
}
PhoneMetadata metadata = getMetadataForRegion(regionCode);
String nationalNumber = getNationalSignificantNumber(number);
NumberFormat formatRule =
chooseFormattingPatternForNumber(metadata.numberFormats(), nationalNumber);
// When the format we apply to this number doesn't contain national prefix, we can just
// return the national format.
// TODO: Refactor the code below with the code in isNationalPrefixPresentIfRequired.
String candidateNationalPrefixRule = formatRule.getNationalPrefixFormattingRule();
// We assume that the first-group symbol will never be _before_ the national prefix.
int indexOfFirstGroup = candidateNationalPrefixRule.indexOf("$1");
if (indexOfFirstGroup <= 0) {
formattedNumber = nationalFormat;
break;
}
candidateNationalPrefixRule =
candidateNationalPrefixRule.substring(0, indexOfFirstGroup);
candidateNationalPrefixRule = normalizeDigitsOnly(candidateNationalPrefixRule);
if (candidateNationalPrefixRule.length() == 0) {
// National prefix not used when formatting this number.
formattedNumber = nationalFormat;
break;
}
// Otherwise, we need to remove the national prefix from our output.
formatRule.clearNationalPrefixFormattingRule();
List<NumberFormat> numberFormats = new ArrayList<NumberFormat>(1);
numberFormats.add(formatRule);
formattedNumber = formatByPattern(number, PhoneNumberFormat.NATIONAL, numberFormats);
break;
}
String rawInput = number.getRawInput();
// If no digit is inserted/removed/modified as a result of our formatting, we return the
// formatted phone number; otherwise we return the raw input the user entered.
return (formattedNumber != null &&
normalizeDigitsOnly(formattedNumber).equals(normalizeDigitsOnly(rawInput)))
? formattedNumber
: rawInput;
}
// Check if rawInput, which is assumed to be in the national format, has a national prefix. The
// national prefix is assumed to be in digits-only form.
private boolean rawInputContainsNationalPrefix(String rawInput, String nationalPrefix,
String regionCode) {
String normalizedNationalNumber = normalizeDigitsOnly(rawInput);
if (normalizedNationalNumber.startsWith(nationalPrefix)) {
try {
// Some Japanese numbers (e.g. 00777123) might be mistaken to contain the national prefix
// when written without it (e.g. 0777123) if we just do prefix matching. To tackle that, we
// check the validity of the number if the assumed national prefix is removed (777123 won't
// be valid in Japan).
return isValidNumber(
parse(normalizedNationalNumber.substring(nationalPrefix.length()), regionCode));
} catch (NumberParseException e) {
return false;
}
}
return false;
}
/**
@ -1396,8 +1493,10 @@ public class PhoneNumberUtil {
}
private boolean hasFormattingPatternForNumber(PhoneNumber number) {
String phoneNumberRegion = getRegionCodeForCountryCode(number.getCountryCode());
PhoneMetadata metadata = getMetadataForRegion(phoneNumberRegion);
int countryCallingCode = number.getCountryCode();
String phoneNumberRegion = getRegionCodeForCountryCode(countryCallingCode);
PhoneMetadata metadata =
getMetadataForRegionOrCallingCode(countryCallingCode, phoneNumberRegion);
if (metadata == null) {
return false;
}
@ -1440,8 +1539,7 @@ public class PhoneNumberUtil {
return formatOutOfCountryCallingNumber(number, regionCallingFrom);
}
int countryCode = number.getCountryCode();
String regionCode = getRegionCodeForCountryCode(countryCode);
if (!hasValidRegionCode(regionCode, countryCode, rawInput)) {
if (!hasValidCountryCallingCode(countryCode)) {
return rawInput;
}
// Strip any prefix such as country calling code, IDD, that was present. We do this by comparing
@ -1460,7 +1558,7 @@ public class PhoneNumberUtil {
rawInput = rawInput.substring(firstNationalNumberDigit);
}
}
PhoneMetadata metadata = getMetadataForRegion(regionCallingFrom);
PhoneMetadata metadataForRegionCallingFrom = getMetadataForRegion(regionCallingFrom);
if (countryCode == NANPA_COUNTRY_CODE) {
if (isNANPACountry(regionCallingFrom)) {
return countryCode + " " + rawInput;
@ -1468,8 +1566,8 @@ public class PhoneNumberUtil {
} else if (countryCode == getCountryCodeForRegion(regionCallingFrom)) {
// Here we copy the formatting rules so we can modify the pattern we expect to match against.
List<NumberFormat> availableFormats =
new ArrayList<NumberFormat>(metadata.numberFormatSize());
for (NumberFormat format : metadata.numberFormats()) {
new ArrayList<NumberFormat>(metadataForRegionCallingFrom.numberFormatSize());
for (NumberFormat format : metadataForRegionCallingFrom.numberFormats()) {
NumberFormat newFormat = new NumberFormat();
newFormat.mergeFrom(format);
// The first group is the first group of digits that the user determined.
@ -1486,20 +1584,28 @@ public class PhoneNumberUtil {
// anything, but that is not the case in the metadata to date.
return formatAccordingToFormats(rawInput, availableFormats, PhoneNumberFormat.NATIONAL);
}
String internationalPrefix = metadata.getInternationalPrefix();
// For countries that have multiple international prefixes, the international format of the
// number is returned, unless there is a preferred international prefix.
String internationalPrefixForFormatting =
UNIQUE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches()
? internationalPrefix
: metadata.getPreferredInternationalPrefix();
String internationalPrefixForFormatting = "";
// If an unsupported region-calling-from is entered, or a country with multiple international
// prefixes, the international format of the number is returned, unless there is a preferred
// international prefix.
if (metadataForRegionCallingFrom != null) {
String internationalPrefix = metadataForRegionCallingFrom.getInternationalPrefix();
internationalPrefixForFormatting =
UNIQUE_INTERNATIONAL_PREFIX.matcher(internationalPrefix).matches()
? internationalPrefix
: metadataForRegionCallingFrom.getPreferredInternationalPrefix();
}
StringBuilder formattedNumber = new StringBuilder(rawInput);
maybeGetFormattedExtension(number, getMetadataForRegion(regionCode),
String regionCode = getRegionCodeForCountryCode(countryCode);
PhoneMetadata metadataForRegion = getMetadataForRegionOrCallingCode(countryCode, regionCode);
maybeGetFormattedExtension(number, metadataForRegion,
PhoneNumberFormat.INTERNATIONAL, formattedNumber);
if (internationalPrefixForFormatting.length() > 0) {
formattedNumber.insert(0, " ").insert(0, countryCode).insert(0, " ")
.insert(0, internationalPrefixForFormatting);
} else {
// Invalid region entered as country-calling-from (so no metadata was found for it) or the
// region chosen has multiple international dialling prefixes.
formatNumberByFormat(countryCode,
PhoneNumberFormat.INTERNATIONAL,
formattedNumber);
@ -1641,7 +1747,8 @@ public class PhoneNumberUtil {
*
* @param regionCode the region for which an example number is needed
* @return a valid fixed-line number for the specified region. Returns null when the metadata
* does not contain such information.
* does not contain such information, or the region 001 is passed in. For 001 (representing
* non-geographical numbers), call {@link #getExampleNumberForNonGeoEntity} instead.
*/
public PhoneNumber getExampleNumber(String regionCode) {
return getExampleNumberForType(regionCode, PhoneNumberType.FIXED_LINE);
@ -1653,7 +1760,9 @@ public class PhoneNumberUtil {
* @param regionCode the region for which an example number is needed
* @param type the type of number that is needed
* @return a valid number for the specified region and type. Returns null when the metadata
* does not contain such information or if an invalid region was entered.
* does not contain such information or if an invalid region or region 001 was entered.
* For 001 (representing non-geographical numbers), call
* {@link #getExampleNumberForNonGeoEntity} instead.
*/
public PhoneNumber getExampleNumberForType(String regionCode, PhoneNumberType type) {
// Check the region code is valid.
@ -1672,6 +1781,29 @@ public class PhoneNumberUtil {
return null;
}
/**
* Gets a valid number for the specified country calling code for a non-geographical entity.
*
* @param countryCallingCode the country calling code for a non-geographical entity
* @return a valid number for the non-geographical entity. Returns null when the metadata
* does not contain such information, or the country calling code passed in does not belong
* to a non-geographical entity.
*/
public PhoneNumber getExampleNumberForNonGeoEntity(int countryCallingCode) {
PhoneMetadata metadata = getMetadataForNonGeographicalRegion(countryCallingCode);
if (metadata != null) {
PhoneNumberDesc desc = metadata.getGeneralDesc();
try {
if (desc.hasExampleNumber()) {
return parse("+" + countryCallingCode + desc.getExampleNumber(), "ZZ");
}
} catch (NumberParseException e) {
LOGGER.log(Level.SEVERE, e.toString());
}
}
return null;
}
/**
* Appends the formatted extension of a phone number to formattedNumber, if the phone number had
* an extension specified.
@ -1738,11 +1870,12 @@ public class PhoneNumberUtil {
*/
public PhoneNumberType getNumberType(PhoneNumber number) {
String regionCode = getRegionCodeForNumber(number);
if (!isValidRegionCode(regionCode)) {
if (!isValidRegionCode(regionCode) && !REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode)) {
return PhoneNumberType.UNKNOWN;
}
String nationalSignificantNumber = getNationalSignificantNumber(number);
return getNumberTypeHelper(nationalSignificantNumber, getMetadataForRegion(regionCode));
PhoneMetadata metadata = getMetadataForRegionOrCallingCode(number.getCountryCode(), regionCode);
return getNumberTypeHelper(nationalSignificantNumber, metadata);
}
private PhoneNumberType getNumberTypeHelper(String nationalNumber, PhoneMetadata metadata) {
@ -1801,12 +1934,26 @@ public class PhoneNumberUtil {
}
synchronized (regionToMetadataMap) {
if (!regionToMetadataMap.containsKey(regionCode)) {
loadMetadataForRegionFromFile(currentFilePrefix, regionCode);
// The regionCode here will be valid and won't be '001', so we don't need to worry about
// what to pass in for the country calling code.
loadMetadataFromFile(currentFilePrefix, regionCode, 0);
}
}
return regionToMetadataMap.get(regionCode);
}
PhoneMetadata getMetadataForNonGeographicalRegion(int countryCallingCode) {
synchronized (countryCodeToNonGeographicalMetadataMap) {
if (!countryCallingCodeToRegionCodeMap.containsKey(countryCallingCode)) {
return null;
}
if (!countryCodeToNonGeographicalMetadataMap.containsKey(countryCallingCode)) {
loadMetadataFromFile(currentFilePrefix, REGION_CODE_FOR_NON_GEO_ENTITY, countryCallingCode);
}
}
return countryCodeToNonGeographicalMetadataMap.get(countryCallingCode);
}
private boolean isNumberMatchingDesc(String nationalNumber, PhoneNumberDesc numberDesc) {
Matcher possibleNumberPatternMatcher =
regexCache.getPatternForRegex(numberDesc.getPossibleNumberPattern())
@ -1826,7 +1973,7 @@ public class PhoneNumberUtil {
*/
public boolean isValidNumber(PhoneNumber number) {
String regionCode = getRegionCodeForNumber(number);
return (isValidRegionCode(regionCode) && isValidNumberForRegion(number, regionCode));
return isValidNumberForRegion(number, regionCode);
}
/**
@ -1842,10 +1989,13 @@ public class PhoneNumberUtil {
* @return a boolean that indicates whether the number is of a valid pattern
*/
public boolean isValidNumberForRegion(PhoneNumber number, String regionCode) {
if (number.getCountryCode() != getCountryCodeForRegion(regionCode)) {
int countryCode = number.getCountryCode();
if (countryCode == 0 ||
(!REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode) &&
countryCode != getCountryCodeForRegion(regionCode))) {
return false;
}
PhoneMetadata metadata = getMetadataForRegion(regionCode);
PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode);
PhoneNumberDesc generalNumDesc = metadata.getGeneralDesc();
String nationalSignificantNumber = getNationalSignificantNumber(number);
@ -1871,6 +2021,9 @@ public class PhoneNumberUtil {
int countryCode = number.getCountryCode();
List<String> regions = countryCallingCodeToRegionCodeMap.get(countryCode);
if (regions == null) {
String numberString = getNationalSignificantNumber(number);
LOGGER.log(Level.WARNING,
"Missing/invalid country_code (" + countryCode + ") for number " + numberString);
return null;
}
if (regions.size() == 1) {
@ -1917,6 +2070,10 @@ public class PhoneNumberUtil {
*/
public int getCountryCodeForRegion(String regionCode) {
if (!isValidRegionCode(regionCode)) {
LOGGER.log(Level.SEVERE,
"Invalid or missing region code ("
+ ((regionCode == null) ? "null" : regionCode)
+ ") provided.");
return 0;
}
PhoneMetadata metadata = getMetadataForRegion(regionCode);
@ -1939,7 +2096,10 @@ public class PhoneNumberUtil {
*/
public String getNddPrefixForRegion(String regionCode, boolean stripNonDigits) {
if (!isValidRegionCode(regionCode)) {
LOGGER.log(Level.SEVERE, "Invalid or missing region code provided.");
LOGGER.log(Level.SEVERE,
"Invalid or missing region code ("
+ ((regionCode == null) ? "null" : regionCode)
+ ") provided.");
return null;
}
PhoneMetadata metadata = getMetadataForRegion(regionCode);
@ -2055,11 +2215,12 @@ public class PhoneNumberUtil {
// Russia) since the getRegionCodeForNumber will not work if the number is possible but not
// valid. This would need to be revisited if the possible number pattern ever differed between
// various regions within those plans.
String regionCode = getRegionCodeForCountryCode(countryCode);
if (!isValidRegionCode(regionCode)) {
if (!hasValidCountryCallingCode(countryCode)) {
return ValidationResult.INVALID_COUNTRY_CODE;
}
PhoneNumberDesc generalNumDesc = getMetadataForRegion(regionCode).getGeneralDesc();
String regionCode = getRegionCodeForCountryCode(countryCode);
PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode);
PhoneNumberDesc generalNumDesc = metadata.getGeneralDesc();
// Handling case of numbers with no metadata.
if (!generalNumDesc.hasNationalNumberPattern()) {
LOGGER.log(Level.FINER, "Checking if number is possible with incomplete metadata.");
@ -2607,7 +2768,7 @@ public class PhoneNumberUtil {
if (countryCode != 0) {
String phoneNumberRegion = getRegionCodeForCountryCode(countryCode);
if (!phoneNumberRegion.equals(defaultRegion)) {
regionMetadata = getMetadataForRegion(phoneNumberRegion);
regionMetadata = getMetadataForRegionOrCallingCode(countryCode, phoneNumberRegion);
}
} else {
// If no extracted country calling code, use the region supplied instead. The national number
@ -2819,23 +2980,24 @@ public class PhoneNumberUtil {
}
/**
* Returns true if the number can only be dialled from within the region. If unknown, or the
* number can be dialled from outside the region as well, returns false. Does not check the
* number is a valid number.
* TODO: Make this method public when we have enough metadata to make it worthwhile. Currently
* visible for testing purposes only.
* Returns true if the number can be dialled from outside the region, or unknown. If the number
* can only be dialled from within the region, returns false. Does not check the number is a valid
* number.
* TODO: Make this method public when we have enough metadata to make it worthwhile.
*
* @param number the phone-number for which we want to know whether it is only diallable from
* within the region
* @param number the phone-number for which we want to know whether it is diallable from
* outside the region
*/
// @VisibleForTesting
boolean canBeInternationallyDialled(PhoneNumber number) {
String regionCode = getRegionCodeForNumber(number);
String nationalSignificantNumber = getNationalSignificantNumber(number);
if (!hasValidRegionCode(regionCode, number.getCountryCode(), nationalSignificantNumber)) {
if (!isValidRegionCode(regionCode)) {
// Note numbers belonging to non-geographical entities (e.g. +800 numbers) are always
// internationally diallable, and will be caught here.
return true;
}
PhoneMetadata metadata = getMetadataForRegion(regionCode);
String nationalSignificantNumber = getNationalSignificantNumber(number);
return !isNumberMatchingDesc(nationalSignificantNumber, metadata.getNoInternationalDialling());
}
}

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


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


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


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


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


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


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


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI 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_CR View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE 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_IL View File


BIN
java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_JO 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_KE View File


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


+ 18
- 0
java/libphonenumber/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java View File

@ -685,6 +685,24 @@ public class AsYouTypeFormatterTest extends TestCase {
assertEquals("+52 1 541 234 5678", formatter.inputDigit('8'));
}
public void testAYTF_International_Toll_Free() {
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.US);
// +800 1234 5678
assertEquals("+", formatter.inputDigit('+'));
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 1234", formatter.inputDigit('4'));
assertEquals("+800 1234 5", formatter.inputDigit('5'));
assertEquals("+800 1234 56", formatter.inputDigit('6'));
assertEquals("+800 1234 567", formatter.inputDigit('7'));
assertEquals("+800 1234 5678", formatter.inputDigit('8'));
assertEquals("+800123456789", formatter.inputDigit('9'));
}
public void testAYTFMultipleLeadingDigitPatterns() {
// +81 50 2345 6789
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(RegionCode.JP);


+ 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 21 as there are 16 different country codes,
// The capacity is set to 22 as there are 17 different country codes,
// and this offers a load factor of roughly 0.75.
Map<Integer, List<String>> countryCodeToRegionCodeMap =
new HashMap<Integer, List<String>>(21);
new HashMap<Integer, List<String>>(22);
ArrayList<String> listWithRegionCode;
@ -104,6 +104,10 @@ public class CountryCodeToRegionCodeMapForTesting {
listWithRegionCode.add("AD");
countryCodeToRegionCodeMap.put(376, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("001");
countryCodeToRegionCodeMap.put(800, listWithRegionCode);
return countryCodeToRegionCodeMap;
}
}

+ 38
- 7
java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java View File

@ -369,20 +369,20 @@ public class PhoneNumberMatcherTest extends TestCase {
new NumberTest("31/8/2011", RegionCode.US),
new NumberTest("1/12/2011", RegionCode.US),
new NumberTest("10/12/82", RegionCode.DE),
new NumberTest("650x2531234", RegionCode.US),
};
/**
* Strings with number-like things that should only be found under "possible".
*/
private static final NumberTest[] POSSIBLE_ONLY_CASES = {
new NumberTest("abc8002345678", RegionCode.US),
// US numbers cannot start with 7 in the test metadata to be valid.
new NumberTest("7121115678", RegionCode.US),
// 'X' should not be found in numbers at leniencies stricter than POSSIBLE, unless it represents
// a carrier code or extension.
new NumberTest("1650 x 253 - 1234", RegionCode.US),
new NumberTest("650 x 253 - 1234", RegionCode.US),
new NumberTest("650x2531234", RegionCode.US),
new NumberTest("6502531x234", RegionCode.US),
new NumberTest("(20) 3346 1234", RegionCode.GB), // Non-optional NP omitted
};
@ -391,18 +391,19 @@ public class PhoneNumberMatcherTest extends TestCase {
* leniency level.
*/
private static final NumberTest[] VALID_CASES = {
new NumberTest("65 02 53 00 00.", RegionCode.US),
new NumberTest("65 02 53 00 00", RegionCode.US),
new NumberTest("6502 538365", RegionCode.US),
new NumberTest("650//253-1234", RegionCode.US), // 2 slashes are illegal at higher levels
new NumberTest("650/253/1234", RegionCode.US),
new NumberTest("9002309. 158", RegionCode.US),
new NumberTest("21 7/8 - 14 12/34 - 5", RegionCode.US),
new NumberTest("12 7/8 - 14 12/34 - 5", RegionCode.US),
new NumberTest("12.1 - 23.71 - 23.45", RegionCode.US),
new NumberTest("1979-2011 100%", RegionCode.US),
new NumberTest("800 234 1 111x1111", RegionCode.US),
new NumberTest("1979-2011 100", RegionCode.US),
new NumberTest("+494949-4-94", RegionCode.DE), // National number in wrong format
new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17\uFF17",
RegionCode.US),
new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17", RegionCode.US),
};
/**
@ -443,6 +444,36 @@ public class PhoneNumberMatcherTest extends TestCase {
new NumberTest("(33) 3461 2234", RegionCode.MX), // Optional NP omitted
};
public void testMatchesWithPossibleLeniency() throws Exception {
List<NumberTest> testCases = new ArrayList<NumberTest>();
testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));
testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES));
testCases.addAll(Arrays.asList(VALID_CASES));
testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES));
doTestNumberMatchesForLeniency(testCases, Leniency.POSSIBLE);
}
public void testNonMatchesWithPossibleLeniency() throws Exception {
List<NumberTest> testCases = new ArrayList<NumberTest>();
testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES));
doTestNumberNonMatchesForLeniency(testCases, Leniency.POSSIBLE);
}
public void testMatchesWithValidLeniency() throws Exception {
List<NumberTest> testCases = new ArrayList<NumberTest>();
testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));
testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES));
testCases.addAll(Arrays.asList(VALID_CASES));
doTestNumberMatchesForLeniency(testCases, Leniency.VALID);
}
public void testNonMatchesWithValidLeniency() throws Exception {
List<NumberTest> testCases = new ArrayList<NumberTest>();
testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES));
testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES));
doTestNumberNonMatchesForLeniency(testCases, Leniency.VALID);
}
public void testMatchesWithStrictGroupingLeniency() throws Exception {
List<NumberTest> testCases = new ArrayList<NumberTest>();
testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));


+ 183
- 13
java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java View File

@ -105,6 +105,10 @@ public class PhoneNumberUtilTest extends TestCase {
private static final PhoneNumber US_SPOOF_WITH_RAW_INPUT =
new PhoneNumber().setCountryCode(1).setNationalNumber(0L)
.setRawInput("000-000-0000");
private static final PhoneNumber INTERNATIONAL_TOLL_FREE =
new PhoneNumber().setCountryCode(800).setNationalNumber(12345678L);
private static final PhoneNumber INTERNATIONAL_TOLL_FREE_TOO_LONG =
new PhoneNumber().setCountryCode(800).setNationalNumber(1234567890L);
public PhoneNumberUtilTest() {
phoneUtil = initializePhoneUtilForTesting();
@ -123,7 +127,7 @@ public class PhoneNumberUtilTest extends TestCase {
public void testGetInstanceLoadUSMetadata() {
PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
assertEquals(RegionCode.US, metadata.getId());
assertEquals("US", metadata.getId());
assertEquals(1, metadata.getCountryCode());
assertEquals("011", metadata.getInternationalPrefix());
assertTrue(metadata.hasNationalPrefix());
@ -144,7 +148,7 @@ public class PhoneNumberUtilTest extends TestCase {
public void testGetInstanceLoadDEMetadata() {
PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.DE);
assertEquals(RegionCode.DE, metadata.getId());
assertEquals("DE", metadata.getId());
assertEquals(49, metadata.getCountryCode());
assertEquals("00", metadata.getInternationalPrefix());
assertEquals("0", metadata.getNationalPrefix());
@ -164,7 +168,7 @@ public class PhoneNumberUtilTest extends TestCase {
public void testGetInstanceLoadARMetadata() {
PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.AR);
assertEquals(RegionCode.AR, metadata.getId());
assertEquals("AR", metadata.getId());
assertEquals(54, metadata.getCountryCode());
assertEquals("00", metadata.getInternationalPrefix());
assertEquals("0", metadata.getNationalPrefix());
@ -178,10 +182,21 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals("$1 $2 $3 $4", metadata.getIntlNumberFormat(3).getFormat());
}
public void testGetInstanceLoadInternationalTollFreeMetadata() {
PhoneMetadata metadata = phoneUtil.getMetadataForNonGeographicalRegion(800);
assertEquals("001", metadata.getId());
assertEquals(800, metadata.getCountryCode());
assertEquals("$1 $2", metadata.getNumberFormat(0).getFormat());
assertEquals("(\\d{4})(\\d{4})", metadata.getNumberFormat(0).getPattern());
assertEquals("12345678", metadata.getGeneralDesc().getExampleNumber());
assertEquals("12345678", metadata.getTollFree().getExampleNumber());
}
public void testIsLeadingZeroPossible() {
assertTrue(phoneUtil.isLeadingZeroPossible(39)); // Italy
assertFalse(phoneUtil.isLeadingZeroPossible(1)); // USA
assertFalse(phoneUtil.isLeadingZeroPossible(800)); // Not in metadata file, just default to
assertFalse(phoneUtil.isLeadingZeroPossible(800)); // International toll free numbers
assertFalse(phoneUtil.isLeadingZeroPossible(888)); // Not in metadata file, just default to
// false.
}
@ -209,6 +224,9 @@ public class PhoneNumberUtilTest extends TestCase {
// An invalid US number (1 digit shorter), which has no area code.
assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_SHORT_BY_ONE_NUMBER));
// An international toll free number, which has no area code.
assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(INTERNATIONAL_TOLL_FREE));
}
public void testGetLengthOfNationalDestinationCode() {
@ -242,6 +260,9 @@ public class PhoneNumberUtilTest extends TestCase {
// A number containing an invalid country calling code, which shouldn't have any NDC.
PhoneNumber number = new PhoneNumber().setCountryCode(123).setNationalNumber(6502530000L);
assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
// An international toll free number, which has NDC "1234".
assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(INTERNATIONAL_TOLL_FREE));
}
public void testGetNationalSignificantNumber() {
@ -252,6 +273,8 @@ public class PhoneNumberUtilTest extends TestCase {
// An Italian fixed line number.
assertEquals("0236618300", phoneUtil.getNationalSignificantNumber(IT_NUMBER));
assertEquals("12345678", phoneUtil.getNationalSignificantNumber(INTERNATIONAL_TOLL_FREE));
}
public void testGetExampleNumber() {
@ -272,6 +295,13 @@ public class PhoneNumberUtilTest extends TestCase {
// CS is an invalid region, so we have no data for it.
assertNull(phoneUtil.getExampleNumberForType(RegionCode.CS,
PhoneNumberUtil.PhoneNumberType.MOBILE));
// RegionCode 001 is reserved for supporting non-geographical country calling code. We don't
// support getting an example number for it with this method.
assertEquals(null, phoneUtil.getExampleNumber(RegionCode.UN001));
}
public void testGetExampleNumberForNonGeoEntity() {
assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.getExampleNumberForNonGeoEntity(800));
}
public void testConvertAlphaCharactersInNumber() {
@ -469,6 +499,8 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals("011 54 9 11 8765 4321",
phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, RegionCode.US));
assertEquals("011 800 1234 5678",
phoneUtil.formatOutOfCountryCallingNumber(INTERNATIONAL_TOLL_FREE, RegionCode.US));
PhoneNumber arNumberWithExtn = new PhoneNumber().mergeFrom(AR_MOBILE).setExtension("1234");
assertEquals("011 54 9 11 8765 4321 ext. 1234",
@ -483,7 +515,10 @@ public class PhoneNumberUtilTest extends TestCase {
// AQ/Antarctica isn't a valid region code for phone number formatting,
// so this falls back to intl formatting.
assertEquals("+1 650 253 0000",
phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, "AQ"));
phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.AQ));
// For region code 001, the out-of-country format always turns into the international format.
assertEquals("+1 650 253 0000",
phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.UN001));
}
public void testFormatOutOfCountryWithPreferredIntlPrefix() {
@ -551,6 +586,9 @@ public class PhoneNumberUtilTest extends TestCase {
// Testing a region with multiple international prefixes.
assertEquals("+61 1-800-SIX-FLAG",
phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.SG));
// Testing the case of calling from a non-supported region.
assertEquals("+61 1-800-SIX-FLAG",
phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AQ));
// Testing the case with an invalid country calling code.
alphaNumericNumber.setCountryCode(0).setNationalNumber(18007493524L)
@ -564,6 +602,12 @@ public class PhoneNumberUtilTest extends TestCase {
// No country-code stripping can be done.
assertEquals("00 1 180-SIX",
phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
// Testing the case of calling from a non-supported region.
alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
// No country-code stripping can be done since the number is invalid.
assertEquals("+1 180-SIX",
phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AQ));
}
public void testFormatWithCarrierCode() {
@ -646,6 +690,11 @@ public class PhoneNumberUtilTest extends TestCase {
phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER, RegionCode.JP, false));
assertEquals("*2345",
phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER, RegionCode.JP, true));
assertEquals("+80012345678",
phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.JP, false));
assertEquals("+800 1234 5678",
phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.JP, true));
}
public void testFormatByPattern() {
@ -709,6 +758,7 @@ public class PhoneNumberUtilTest extends TestCase {
public void testFormatE164Number() {
assertEquals("+16502530000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.E164));
assertEquals("+4930123456", phoneUtil.format(DE_NUMBER, PhoneNumberFormat.E164));
assertEquals("+80012345678", phoneUtil.format(INTERNATIONAL_TOLL_FREE, PhoneNumberFormat.E164));
}
public void testFormatNumberWithExtension() {
@ -723,7 +773,7 @@ public class PhoneNumberUtilTest extends TestCase {
PhoneNumberFormat.NATIONAL));
}
public void testFormatUsingOriginalNumberFormat() throws Exception {
public void testFormatInOriginalFormat() throws Exception {
PhoneNumber number1 = phoneUtil.parseAndKeepRawInput("+442087654321", RegionCode.GB);
assertEquals("+44 20 8765 4321", phoneUtil.formatInOriginalFormat(number1, RegionCode.GB));
@ -746,17 +796,88 @@ public class PhoneNumberUtilTest extends TestCase {
// US is not a leading zero country, and the presence of the leading zero leads us to format the
// number using raw_input.
PhoneNumber number7 = phoneUtil.parseAndKeepRawInput("07345678901", RegionCode.US);
assertEquals("07345678901", phoneUtil.formatInOriginalFormat(number7, RegionCode.US));
PhoneNumber number7 = phoneUtil.parseAndKeepRawInput("0734567 8901", RegionCode.US);
assertEquals("0734567 8901", phoneUtil.formatInOriginalFormat(number7, RegionCode.US));
// This number is valid, but we don't have a formatting pattern for it. Fall back to the raw
// input.
PhoneNumber number8 = phoneUtil.parseAndKeepRawInput("02-4567-8900", RegionCode.KR);
assertEquals("02-4567-8900", phoneUtil.formatInOriginalFormat(number8, RegionCode.KR));
PhoneNumber number9 = phoneUtil.parseAndKeepRawInput("01180012345678", RegionCode.US);
assertEquals("011 800 1234 5678", phoneUtil.formatInOriginalFormat(number9, RegionCode.US));
PhoneNumber number10 = phoneUtil.parseAndKeepRawInput("+80012345678", RegionCode.KR);
assertEquals("+800 1234 5678", phoneUtil.formatInOriginalFormat(number10, RegionCode.KR));
// US local numbers are formatted correctly, as we have formatting patterns for them.
PhoneNumber localNumberUS = phoneUtil.parseAndKeepRawInput("2530000", RegionCode.US);
assertEquals("253 0000", phoneUtil.formatInOriginalFormat(localNumberUS, RegionCode.US));
PhoneNumber numberWithNationalPrefixUS =
phoneUtil.parseAndKeepRawInput("18003456789", RegionCode.US);
assertEquals("1 800 345 6789",
phoneUtil.formatInOriginalFormat(numberWithNationalPrefixUS, RegionCode.US));
PhoneNumber numberWithoutNationalPrefixGB =
phoneUtil.parseAndKeepRawInput("2087654321", RegionCode.GB);
assertEquals("20 8765 4321",
phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixGB, RegionCode.GB));
PhoneNumber numberWithNationalPrefixMX =
phoneUtil.parseAndKeepRawInput("013312345678", RegionCode.MX);
assertEquals("01 33 1234 5678",
phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX, RegionCode.MX));
PhoneNumber numberWithoutNationalPrefixMX =
phoneUtil.parseAndKeepRawInput("3312345678", RegionCode.MX);
assertEquals("33 1234 5678",
phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixMX, RegionCode.MX));
PhoneNumber italianFixedLineNumber =
phoneUtil.parseAndKeepRawInput("0212345678", RegionCode.IT);
assertEquals("02 1234 5678",
phoneUtil.formatInOriginalFormat(italianFixedLineNumber, RegionCode.IT));
PhoneNumber numberWithNationalPrefixJP =
phoneUtil.parseAndKeepRawInput("00777012", RegionCode.JP);
assertEquals("0077-7012",
phoneUtil.formatInOriginalFormat(numberWithNationalPrefixJP, RegionCode.JP));
PhoneNumber numberWithoutNationalPrefixJP =
phoneUtil.parseAndKeepRawInput("0777012", RegionCode.JP);
assertEquals("0777012",
phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixJP, RegionCode.JP));
PhoneNumber numberWithCarrierCodeBR =
phoneUtil.parseAndKeepRawInput("012 3121286979", RegionCode.BR);
assertEquals("012 3121286979",
phoneUtil.formatInOriginalFormat(numberWithCarrierCodeBR, RegionCode.BR));
// The default national prefix used in this case is 045. When a number with national prefix 044
// is entered, we return the raw input as we don't want to change the number entered.
PhoneNumber numberWithNationalPrefixMX1 =
phoneUtil.parseAndKeepRawInput("044(33)1234-5678", RegionCode.MX);
assertEquals("044(33)1234-5678",
phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX1, RegionCode.MX));
PhoneNumber numberWithNationalPrefixMX2 =
phoneUtil.parseAndKeepRawInput("045(33)1234-5678", RegionCode.MX);
assertEquals("045 33 1234 5678",
phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX2, RegionCode.MX));
// The default international prefix used in this case is 0011. When a number with international
// prefix 0012 is entered, we return the raw input as we don't want to change the number
// entered.
PhoneNumber outOfCountryNumberFromAU1 =
phoneUtil.parseAndKeepRawInput("0012 16502530000", RegionCode.AU);
assertEquals("0012 16502530000",
phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU1, RegionCode.AU));
PhoneNumber outOfCountryNumberFromAU2 =
phoneUtil.parseAndKeepRawInput("0011 16502530000", RegionCode.AU);
assertEquals("0011 1 650 253 0000",
phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU2, RegionCode.AU));
}
public void testIsPremiumRate() {
@ -804,6 +925,9 @@ public class PhoneNumberUtilTest extends TestCase {
tollFreeNumber.setCountryCode(49).setNationalNumber(8001234567L);
assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
phoneUtil.getNumberType(tollFreeNumber));
assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
phoneUtil.getNumberType(INTERNATIONAL_TOLL_FREE));
}
public void testIsMobile() {
@ -862,6 +986,7 @@ public class PhoneNumberUtilTest extends TestCase {
assertTrue(phoneUtil.isValidNumber(US_NUMBER));
assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
assertTrue(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE));
PhoneNumber nzNumber = new PhoneNumber().setCountryCode(64).setNationalNumber(21387835L);
assertTrue(phoneUtil.isValidNumber(nzNumber));
@ -898,6 +1023,8 @@ public class PhoneNumberUtilTest extends TestCase {
reNumber.setNationalNumber(800123456L);
assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
assertTrue(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE, RegionCode.UN001));
assertFalse(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE, RegionCode.US));
}
public void testIsNotValidNumber() {
@ -918,18 +1045,22 @@ public class PhoneNumberUtilTest extends TestCase {
invalidNumber.clear();
invalidNumber.setCountryCode(64).setNationalNumber(3316005L);
assertFalse(phoneUtil.isValidNumber(invalidNumber));
assertFalse(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE_TOO_LONG));
}
public void testGetRegionCodeForCountryCode() {
assertEquals(RegionCode.US, phoneUtil.getRegionCodeForCountryCode(1));
assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));
assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(800));
}
public void testGetRegionCodeForNumber() {
assertEquals(RegionCode.BS, phoneUtil.getRegionCodeForNumber(BS_NUMBER));
assertEquals(RegionCode.US, phoneUtil.getRegionCodeForNumber(US_NUMBER));
assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForNumber(GB_MOBILE));
assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForNumber(INTERNATIONAL_TOLL_FREE));
}
public void testGetCountryCodeForRegion() {
@ -937,6 +1068,7 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(64, phoneUtil.getCountryCodeForRegion(RegionCode.NZ));
assertEquals(0, phoneUtil.getCountryCodeForRegion(null));
assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.ZZ));
assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.UN001));
// CS is already deprecated so the library doesn't support it.
assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.CS));
}
@ -953,6 +1085,7 @@ public class PhoneNumberUtilTest extends TestCase {
// Test cases with invalid regions.
assertEquals(null, phoneUtil.getNddPrefixForRegion(null, false));
assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.ZZ, false));
assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.UN001, false));
// CS is already deprecated so the library doesn't support it.
assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.CS, false));
}
@ -962,6 +1095,7 @@ public class PhoneNumberUtilTest extends TestCase {
assertTrue(phoneUtil.isNANPACountry(RegionCode.BS));
assertFalse(phoneUtil.isNANPACountry(RegionCode.DE));
assertFalse(phoneUtil.isNANPACountry(RegionCode.ZZ));
assertFalse(phoneUtil.isNANPACountry(RegionCode.UN001));
assertFalse(phoneUtil.isNANPACountry(null));
}
@ -969,6 +1103,7 @@ public class PhoneNumberUtilTest extends TestCase {
assertTrue(phoneUtil.isPossibleNumber(US_NUMBER));
assertTrue(phoneUtil.isPossibleNumber(US_LOCAL_NUMBER));
assertTrue(phoneUtil.isPossibleNumber(GB_NUMBER));
assertTrue(phoneUtil.isPossibleNumber(INTERNATIONAL_TOLL_FREE));
assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.US));
assertTrue(phoneUtil.isPossibleNumber("+1 650 GOO OGLE", RegionCode.US));
@ -979,6 +1114,7 @@ public class PhoneNumberUtilTest extends TestCase {
assertTrue(phoneUtil.isPossibleNumber("(020) 7031 3000", RegionCode.GB));
assertTrue(phoneUtil.isPossibleNumber("7031 3000", RegionCode.GB));
assertTrue(phoneUtil.isPossibleNumber("3331 6005", RegionCode.NZ));
assertTrue(phoneUtil.isPossibleNumber("+800 1234 5678", RegionCode.UN001));
}
public void testIsPossibleNumberWithReason() {
@ -1007,6 +1143,9 @@ public class PhoneNumberUtilTest extends TestCase {
assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
phoneUtil.isPossibleNumberWithReason(number));
assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
phoneUtil.isPossibleNumberWithReason(INTERNATIONAL_TOLL_FREE_TOO_LONG));
// Try with number that we don't have metadata for.
PhoneNumber adNumber = new PhoneNumber();
adNumber.setCountryCode(376).setNationalNumber(12345L);
@ -1022,6 +1161,7 @@ public class PhoneNumberUtilTest extends TestCase {
public void testIsNotPossibleNumber() {
assertFalse(phoneUtil.isPossibleNumber(US_LONG_NUMBER));
assertFalse(phoneUtil.isPossibleNumber(INTERNATIONAL_TOLL_FREE_TOO_LONG));
PhoneNumber number = new PhoneNumber();
number.setCountryCode(1).setNationalNumber(253000L);
@ -1030,20 +1170,16 @@ public class PhoneNumberUtilTest extends TestCase {
number.clear();
number.setCountryCode(44).setNationalNumber(300L);
assertFalse(phoneUtil.isPossibleNumber(number));
assertFalse(phoneUtil.isPossibleNumber("+1 650 253 00000", RegionCode.US));
assertFalse(phoneUtil.isPossibleNumber("(650) 253-00000", RegionCode.US));
assertFalse(phoneUtil.isPossibleNumber("I want a Pizza", RegionCode.US));
assertFalse(phoneUtil.isPossibleNumber("253-000", RegionCode.US));
assertFalse(phoneUtil.isPossibleNumber("1 3000", RegionCode.GB));
assertFalse(phoneUtil.isPossibleNumber("+44 300", RegionCode.GB));
assertFalse(phoneUtil.isPossibleNumber("+800 1234 5678 9", RegionCode.UN001));
}
public void testTruncateTooLongNumber() {
// US number 650-253-0000, but entered with one additional digit at the end.
assertTrue(phoneUtil.truncateTooLongNumber(US_LONG_NUMBER));
assertEquals(US_NUMBER, US_LONG_NUMBER);
// GB number 080 1234 5678, but entered with 4 extra digits at the end.
PhoneNumber tooLongNumber = new PhoneNumber();
tooLongNumber.setCountryCode(44).setNationalNumber(80123456780123L);
@ -1060,6 +1196,17 @@ public class PhoneNumberUtilTest extends TestCase {
assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
assertEquals(validNumber, tooLongNumber);
// US number 650-253-0000, but entered with one additional digit at the end.
tooLongNumber.clear();
tooLongNumber.mergeFrom(US_LONG_NUMBER);
assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
assertEquals(US_NUMBER, tooLongNumber);
tooLongNumber.clear();
tooLongNumber.mergeFrom(INTERNATIONAL_TOLL_FREE_TOO_LONG);
assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
assertEquals(INTERNATIONAL_TOLL_FREE, tooLongNumber);
// Tests what happens when a valid number is passed in.
PhoneNumber validNumberCopy = new PhoneNumber().mergeFrom(validNumber);
assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
@ -1275,6 +1422,20 @@ public class PhoneNumberUtilTest extends TestCase {
fail("Should not have thrown an exception: " + e.toString());
}
number.clear();
try {
String phoneNumber = "+80012345678";
int countryCallingCode = 800;
StringBuilder numberToFill = new StringBuilder();
assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
countryCallingCode,
phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
number));
assertEquals("Did not figure out CountryCodeSource correctly",
CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
} catch (NumberParseException e) {
fail("Should not have thrown an exception: " + e.toString());
}
number.clear();
try {
String phoneNumber = "2345-6789";
StringBuilder numberToFill = new StringBuilder();
@ -1407,6 +1568,7 @@ public class PhoneNumberUtilTest extends TestCase {
public void testParseWithInternationalPrefixes() throws Exception {
assertEquals(US_NUMBER, phoneUtil.parse("+1 (650) 253-0000", RegionCode.NZ));
assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.parse("011 800 1234 5678", RegionCode.US));
assertEquals(US_NUMBER, phoneUtil.parse("1-650-253-0000", RegionCode.US));
// Calling the US number from Singapore by using different service providers
// 1st test: calling using SingTel IDD service (IDD is 001)
@ -1685,6 +1847,7 @@ public class PhoneNumberUtilTest extends TestCase {
// Test with normal plus but leading characters that need to be stripped.
assertEquals(NZ_NUMBER, phoneUtil.parse("Tel: +64 3 331 6005", RegionCode.ZZ));
assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", null));
assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.parse("+800 1234 5678", null));
// It is important that we set the carrier code to an empty string, since we used
// ParseAndKeepRawInput and no carrier code was found.
@ -1839,6 +2002,8 @@ public class PhoneNumberUtilTest extends TestCase {
// has been specified.
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
phoneUtil.isNumberMatch("+64 3 331 6005", "+64 03 331 6005"));
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
phoneUtil.isNumberMatch("+800 1234 5678", "+80012345678"));
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
phoneUtil.isNumberMatch("+64 03 331-6005", "+64 03331 6005"));
assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
@ -1886,6 +2051,8 @@ public class PhoneNumberUtilTest extends TestCase {
// Non-matches.
assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
phoneUtil.isNumberMatch("03 331 6005", "03 331 6006"));
assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
phoneUtil.isNumberMatch("+800 1234 5678", "+1 800 1234 5678"));
// Different country calling code, partial number match.
assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
phoneUtil.isNumberMatch("+64 3 331-6005", "+16433316005"));
@ -1993,12 +2160,15 @@ public class PhoneNumberUtilTest extends TestCase {
// We have no data for NZ - should return true.
assertTrue(phoneUtil.canBeInternationallyDialled(NZ_NUMBER));
assertTrue(phoneUtil.canBeInternationallyDialled(INTERNATIONAL_TOLL_FREE));
}
public void testIsAlphaNumber() throws Exception {
assertTrue(phoneUtil.isAlphaNumber("1800 six-flags"));
assertTrue(phoneUtil.isAlphaNumber("1800 six-flags ext. 1234"));
assertTrue(phoneUtil.isAlphaNumber("+800 six-flags"));
assertFalse(phoneUtil.isAlphaNumber("1800 123-1234"));
assertFalse(phoneUtil.isAlphaNumber("1800 123-1234 extension: 1234"));
assertFalse(phoneUtil.isAlphaNumber("+800 1234-1234"));
}
}

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

@ -20,8 +20,11 @@ package com.google.i18n.phonenumbers;
* Class containing string constants of region codes for easier testing.
*/
final class RegionCode {
// Region code for global networks (e.g. +800 numbers).
static final String UN001 = "001";
static final String AD = "AD";
static final String AO = "AO";
static final String AQ = "AQ";
static final String AR = "AR";
static final String AU = "AU";
static final String BR = "BR";


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


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


+ 13
- 0
java/release_notes.txt View File

@ -1,3 +1,16 @@
January 19th, 2012: libphonenumber-4.5
* Code changes
- Support for non-geographical country calling codes (e.g. +800).
- Modify formatInOriginalFormat to not insert/remove/modify digits in the original number passed
in.
- Fix formatOutOfCountryKeepingAlphaChars to not throw a NPE.
* Metadata changes
- Updates for AR, BH, CI, CN, CR, DE, GA, IL, JO, JP, KE, KZ, LB, LK, LT, MV, MW, MZ, NA, NL, NZ,
PL, RO, SA, SV, TM, UG, US
- New country calling codes: 800, 808, 883, 888, 979
- Geocoding data updates: AR, US
December 9th, 2011: libphonenumber-4.4
* Code changes
- Support for Voicemail numbers


+ 703
- 166
resources/PhoneNumberMetaData.xml
File diff suppressed because it is too large
View File


+ 39
- 1
resources/PhoneNumberMetaDataForTesting.xml View File

@ -335,7 +335,7 @@
patterns as digits beyond the third one are entered. As a result, only a few fake
formatting rules are added. -->
<territory id="JP" countryCode="81" internationalPrefix="010"
nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG">
nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG" leadingZeroPossible="true">
<availableFormats>
<numberFormat pattern="(\d{2})(\d{4})(\d{4})">
<leadingDigits>[57-9]0</leadingDigits>
@ -362,6 +362,10 @@
<leadingDigits>[23]</leadingDigits>
<format>$1 $2 $3</format>
</numberFormat>
<numberFormat pattern="(\d{3})(\d{4})">
<leadingDigits>077</leadingDigits>
<format>$1-$2</format>
</numberFormat>
<!-- The following numberFormat is added to test that the format containing the star sign is
not used by the AYTF. -->
<numberFormat nationalPrefixFormattingRule="$FG" pattern="(\d{4})">
@ -373,6 +377,15 @@
<nationalNumberPattern>[23]\d{3}</nationalNumberPattern>
<possibleNumberPattern>\d{4}</possibleNumberPattern>
</noInternationalDialling>
<generalDesc>
<nationalNumberPattern>07\d{5}|[1-357-9]\d{3,10}</nationalNumberPattern>
<possibleNumberPattern>\d{4,11}</possibleNumberPattern>
</generalDesc>
<tollFree>
<nationalNumberPattern>0777[01]\d{2}</nationalNumberPattern>
<possibleNumberPattern>\d{7}</possibleNumberPattern>
<exampleNumber>0777012</exampleNumber>
</tollFree>
</territory>
<!-- Korea (Rep. of) -->
@ -753,5 +766,30 @@
<exampleNumber>801234567</exampleNumber>
</tollFree>
</territory>
<!-- International Toll Free numbers -->
<territory id="001" countryCode="800">
<availableFormats>
<numberFormat pattern="(\d{4})(\d{4})">
<format>$1 $2</format>
</numberFormat>
</availableFormats>
<generalDesc>
<nationalNumberPattern>\d{8}</nationalNumberPattern>
<possibleNumberPattern>\d{8}</possibleNumberPattern>
<exampleNumber>12345678</exampleNumber>
</generalDesc>
<fixedLine>
<nationalNumberPattern>NA</nationalNumberPattern>
<possibleNumberPattern>NA</possibleNumberPattern>
</fixedLine>
<mobile>
<nationalNumberPattern>NA</nationalNumberPattern>
<possibleNumberPattern>NA</possibleNumberPattern>
</mobile>
<tollFree>
<nationalNumberPattern>\d{8}</nationalNumberPattern>
</tollFree>
</territory>
</territories>
</phoneNumberMetadata>

+ 2
- 0
resources/geocoding/en/1.txt View File

@ -14123,6 +14123,7 @@
1662963|Nettleton, MS
1662983|Bruce, MS
1662993|Ripley, MS
1667|Maryland
1678|Georgia
1678339|Alpharetta, GA
1678493|Canton, GA
@ -23247,6 +23248,7 @@
1979968|La Grange, TX
1980|North Carolina
1980207|Charlotte, NC
1984|North Carolina
1985|Louisiana
1985223|Houma, LA
1985229|Kentwood, LA


+ 12
- 5
resources/geocoding/en/54.txt View File

@ -89,16 +89,19 @@
542475|Rojas, Buenos Aires
542477|Pergamino
542478|Arrecifes, Buenos Aires
54260|San Rafael
54261|Mendoza, Capital
542622|Tunuyán, Mendoza
542623|San Martin
542625|General Alvear, Mendoza
542627|San Rafael
54263|San Martin
54264|San Juan, Capital
542646|Valle Fértil
542652|San Luis, La Capital
542656|Merlo, San Luis
542657|Villa Mercedes, General Pedernera
54266|San Luis, La Capital
54280|Trelew, Rawson
542901|Ushuaia
542902|El Calafate, Lago Argentino
54291|Bahía Blanca
@ -114,21 +117,22 @@
542932|Punta Alta, Buenos Aires
542934|San Antonio Oeste, Río Negro
542936|Buenos Aires Province
542941|Confluencia
54294|San Carlos de Bariloche, Río Negro
542940|Ingeniero Jacobacci, Río Negro
542942|Zapala
542944|San Carlos de Bariloche, Río Negro
542945|Esquel, Futaleufú
542946|Choele-choel, Río Negro
542946|Choele Choel, Río Negro
542948|Chos Malal, Neuquén
542952|General Acha, La Pampa
542953|Macachín, La Pampa
542954|Santa Rosa, La Pampa
542962|Puerto San Julián, Santa Cruz
542964|Río Grande
542965|Trelew, Rawson
542966|Río Gallegos, Ger Aike
54297|Comodoro Rivadavia, Escalante
542972|San Martín de los Andes
54298|General Roca, Río Negro
542983|Tres Arroyos
54299|Neuquén, Confluencia
543327|López Camelo, Buenos Aires
@ -193,6 +197,8 @@
543573|Villa del Rosario, Córdoba
543576|Córdoba
54358|Río Cuarto
54362|Resistencia, San Fernando
54364|Presidencia Roque Sáenz Pena, Chaco
543717|Formosa
543718|Clorinda, Formosa
543722|Resistencia, San Fernando
@ -203,18 +209,19 @@
543735|Villa Angela, Mayor Luis Fonta
543743|Puerto Rico, Misiones
543751|El Dorado, Misiones
543752|Posadas, Capital
543754|Leandro N. Alem, Misiones
543755|Oberá, Misiones
543756|Santo Tomé, Corrientes
543757|Puerto Iguazú, Misiones
543758|Apóstoles, Misiones
54376|Posadas, Capital
543772|Paso de Los Libres, Corrientes/Resistencia
543773|Mercedes, Corrientes
543774|Curuzú Cuatiá, Corrientes
543775|Monte Caseros, Corrientes
543777|Goya, Corrientes
543783|Corrientes, Capital
54379|Corrientes, Capital
54381|San Miguel de Tucumán, Capital
543822|La Rioja, Capital
543825|Chilecito, La Rioja


+ 12
- 5
resources/geocoding/es/54.txt View File

@ -91,16 +91,19 @@
542475|Rojas, Buenos Aires
542477|Pergamino
542478|Arrecifes, Buenos Aires
54260|San Rafael
54261|Mendoza, Capital
542622|Tunuyán, Mendoza
542623|San Martin
542625|General Alvear, Mendoza
542627|San Rafael
54263|San Martin
54264|San Juan, Capital
542646|Valle Fértil
542652|San Luis, La Capital
542656|Merlo, San Luis
542657|Villa Mercedes, General Pedernera
54266|San Luis, La Capital
54280|Trelew, Rawson
542901|Ushuaia
542902|El Calafate, Lago Argentino
54291|Bahía Blanca
@ -116,21 +119,22 @@
542932|Punta Alta, Buenos Aires
542934|San Antonio Oeste, Río Negro
542936|Buenos Aires
542941|Confluencia
54294|San Carlos de Bariloche, Río Negro
542940|Ingeniero Jacobacci, Río Negro
542942|Zapala
542944|San Carlos de Bariloche, Río Negro
542945|Esquel, Futaleufú
542946|Choele-choel, Río Negro
542946|Choele Choel, Río Negro
542948|Chos Malal, Neuquén
542952|General Acha, La Pampa
542953|Macachín, La Pampa
542954|Santa Rosa, La Pampa
542962|Puerto San Julián, Santa Cruz
542964|Río Grande
542965|Trelew, Rawson
542966|Río Gallegos, Ger Aike
54297|Comodoro Rivadavia, Escalante
542972|San Martín de los Andes
54298|General Roca, Río Negro
542983|Tres Arroyos
54299|Neuquén, Confluencia
543327|López Camelo, Buenos Aires
@ -195,6 +199,8 @@
543573|Villa del Rosario, Córdoba
543576|Córdoba
54358|Río Cuarto
54362|Resistencia, San Fernando
54364|Presidencia Roque Sáenz Pena, Chaco
543717|Formosa
543718|Clorinda, Formosa
543722|Resistencia, San Fernando
@ -205,18 +211,19 @@
543735|Villa Angela, Mayor Luis Fonta
543743|Puerto Rico, Misiones
543751|El Dorado, Misiones
543752|Posadas, Capital
543754|Leandro N. Alem, Misiones
543755|Oberá, Misiones
543756|Santo Tomé, Corrientes
543757|Puerto Iguazú, Misiones
543758|Apóstoles, Misiones
54376|Posadas, Capital
543772|Paso de Los Libres, Corrientes/Resistencia
543773|Mercedes, Corrientes
543774|Curuzú Cuatiá, Corrientes
543775|Monte Caseros, Corrientes
543777|Goya, Corrientes
543783|Corrientes, Capital
54379|Corrientes, Capital
54381|San Miguel de Tucumán, Capital
543822|La Rioja, Capital
543825|Chilecito, La Rioja


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

@ -183,7 +183,7 @@ public class BuildMetadataFromXml {
}
if (element.hasAttribute(NATIONAL_PREFIX_FOR_PARSING)) {
metadata.setNationalPrefixForParsing(
validateRE(element.getAttribute(NATIONAL_PREFIX_FOR_PARSING)));
validateRE(element.getAttribute(NATIONAL_PREFIX_FOR_PARSING), true));
if (element.hasAttribute(NATIONAL_PREFIX_TRANSFORM_RULE)) {
metadata.setNationalPrefixTransformRule(
validateRE(element.getAttribute(NATIONAL_PREFIX_TRANSFORM_RULE)));


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


+ 5
- 0
tools/java/java-build/src/com/google/i18n/phonenumbers/BuildMetadataProtoFromXml.java View File

@ -102,6 +102,11 @@ public class BuildMetadataProtoFromXml extends Command {
for (PhoneMetadata metadata : metadataCollection.getMetadataList()) {
String regionCode = metadata.getId();
// For non-geographical country calling codes (e.g. +800), use the country calling codes
// instead of the region code to form the file name.
if (regionCode.equals("001")) {
regionCode = Integer.toString(metadata.getCountryCode());
}
PhoneMetadataCollection outMetadataCollection = new PhoneMetadataCollection();
outMetadataCollection.addMetadata(metadata);
FileOutputStream outputForRegion = new FileOutputStream(filePrefix + "_" + regionCode);


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


Loading…
Cancel
Save