summaryrefslogtreecommitdiffstats
path: root/java/libphonenumber/src/com/google/i18n/phonenumbers
diff options
context:
space:
mode:
authorlararennie@google.com <lararennie@google.com@ee073f10-1060-11df-b6a4-87a95322a99c>2012-02-09 15:17:29 +0000
committerlararennie@google.com <lararennie@google.com@ee073f10-1060-11df-b6a4-87a95322a99c>2012-02-09 15:17:29 +0000
commit35f0f61f256a275bba4f6ce331754602ebd13d8d (patch)
tree4bcae31bd06fbe9f8f69fd34298c42aa99a62a7d /java/libphonenumber/src/com/google/i18n/phonenumbers
parentb326557982dbdb6db73212e85199d47eaa9156dc (diff)
downloadandroid_external_libphonenumbergoogle-35f0f61f256a275bba4f6ce331754602ebd13d8d.tar.gz
android_external_libphonenumbergoogle-35f0f61f256a275bba4f6ce331754602ebd13d8d.tar.bz2
android_external_libphonenumbergoogle-35f0f61f256a275bba4f6ce331754602ebd13d8d.zip
JAVA: libphonenumber v4.6. New countries: BQ, CW, SS, metadata updates & bug fixes.
git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@426 ee073f10-1060-11df-b6a4-87a95322a99c
Diffstat (limited to 'java/libphonenumber/src/com/google/i18n/phonenumbers')
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java12
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java15
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java276
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_ANbin595 -> 293 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AXbin546 -> 657 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BFbin406 -> 418 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJbin401 -> 419 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQbin0 -> 335 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BRbin823 -> 797 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BSbin619 -> 619 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CWbin0 -> 485 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJbin313 -> 410 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FIbin763 -> 884 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_INbin3996 -> 4018 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LVbin345 -> 368 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MWbin574 -> 493 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RSbin728 -> 866 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SCbin518 -> 525 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SSbin0 -> 376 bytes
-rw-r--r--java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VNbin1000 -> 1126 bytes
20 files changed, 174 insertions, 129 deletions
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java
index 915c02b..922ab6d 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMap.java
@@ -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 280 as there are 210 different country codes,
+ // The capacity is set to 281 as there are 211 different country codes,
// and this offers a load factor of roughly 0.75.
Map<Integer, List<String>> countryCodeToRegionCodeMap =
- new HashMap<Integer, List<String>>(280);
+ new HashMap<Integer, List<String>>(281);
ArrayList<String> listWithRegionCode;
@@ -254,6 +254,10 @@ public class CountryCodeToRegionCodeMap {
countryCodeToRegionCodeMap.put(98, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode.add("SS");
+ countryCodeToRegionCodeMap.put(211, listWithRegionCode);
+
+ listWithRegionCode = new ArrayList<String>(1);
listWithRegionCode.add("MA");
countryCodeToRegionCodeMap.put(212, listWithRegionCode);
@@ -685,8 +689,10 @@ public class CountryCodeToRegionCodeMap {
listWithRegionCode.add("UY");
countryCodeToRegionCodeMap.put(598, listWithRegionCode);
- listWithRegionCode = new ArrayList<String>(1);
+ listWithRegionCode = new ArrayList<String>(3);
+ listWithRegionCode.add("CW");
listWithRegionCode.add("AN");
+ listWithRegionCode.add("BQ");
countryCodeToRegionCodeMap.put(599, listWithRegionCode);
listWithRegionCode = new ArrayList<String>(1);
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
index e0892ba..d4bc575 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
@@ -71,6 +71,14 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
Pattern.compile("(?:(?:[0-3]?\\d/[01]?\\d)|(?:[01]?\\d/[0-3]?\\d))/(?:[12]\\d)?\\d{2}");
/**
+ * Matches timestamps. Examples: "2012-01-02 08:00". Note that the reg-ex does not include the
+ * trailing ":\d\d" -- that is covered by TIME_STAMPS_SUFFIX.
+ */
+ private static final Pattern TIME_STAMPS =
+ Pattern.compile("[12]\\d{3}[-/]?[01]\\d[-/]?[0-3]\\d [0-2]\\d$");
+ private static final Pattern TIME_STAMPS_SUFFIX = Pattern.compile(":[0-5]\\d");
+
+ /**
* Pattern to check that brackets match. Opening brackets should be closed within a phone number.
* This also checks that there is something inside the brackets. Having no brackets at all is also
* fine.
@@ -310,6 +318,13 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
if (PUB_PAGES.matcher(candidate).find() || SLASH_SEPARATED_DATES.matcher(candidate).find()) {
return null;
}
+ // Skip potential time-stamps.
+ if (TIME_STAMPS.matcher(candidate).find()) {
+ String followingText = text.toString().substring(offset + candidate.length());
+ if (TIME_STAMPS_SUFFIX.matcher(followingText).lookingAt()) {
+ return null;
+ }
+ }
// Try to come up with a valid match given the entire candidate.
String rawString = candidate.toString();
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
index 76212c6..883a676 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
@@ -95,6 +95,8 @@ public class PhoneNumberUtil {
// The PLUS_SIGN signifies the international prefix.
static final char PLUS_SIGN = '+';
+ private static final char STAR_SIGN = '*';
+
private static final String RFC3966_EXTN_PREFIX = ";ext=";
// A map that contains characters that are essential when dialling. That means any of the
@@ -256,11 +258,11 @@ public class PhoneNumberUtil {
// carrier codes, for example in Brazilian phone numbers. We also allow multiple "+" characters at
// the start.
// Corresponds to the following:
- // plus_sign*([punctuation]*[digits]){3,}([punctuation]|[digits]|[alpha])*
+ // plus_sign*(([punctuation]|[star])*[digits]){3,}([punctuation]|[star]|[digits]|[alpha])*
// Note VALID_PUNCTUATION starts with a -, so must be the first in the range.
private static final String VALID_PHONE_NUMBER =
- "[" + PLUS_CHARS + "]*(?:[" + VALID_PUNCTUATION + "]*" + DIGITS + "){3,}[" +
- VALID_PUNCTUATION + VALID_ALPHA + DIGITS + "]*";
+ "[" + PLUS_CHARS + "]*(?:[" + VALID_PUNCTUATION + STAR_SIGN + "]*" + DIGITS + "){3,}[" +
+ VALID_PUNCTUATION + STAR_SIGN + VALID_ALPHA + DIGITS + "]*";
// Default extension prefix to use when formatting. This will be put in front of any extension
// component of the number, after the main national number is formatted. For example, if you wish
@@ -993,6 +995,7 @@ public class PhoneNumberUtil {
return normalizedNumber.toString();
}
+ // @VisibleForTesting
static synchronized PhoneNumberUtil getInstance(
String baseFileLocation,
Map<Integer, List<String>> countryCallingCodeToRegionCodeMap) {
@@ -1020,6 +1023,14 @@ public class PhoneNumberUtil {
}
/**
+ * Convenience method to get a list of what global network calling codes the library has metadata
+ * for.
+ */
+ public Set<Integer> getSupportedGlobalNetworkCallingCodes() {
+ return countryCodeToNonGeographicalMetadataMap.keySet();
+ }
+
+ /**
* Gets a {@link PhoneNumberUtil} instance to carry out international phone number formatting,
* parsing, or validation. The instance is loaded with phone number metadata for a number of most
* commonly used regions.
@@ -1091,23 +1102,24 @@ public class PhoneNumberUtil {
// Early exit for E164 case since no formatting of the national number needs to be applied.
// Extensions are not formatted.
formattedNumber.append(nationalSignificantNumber);
- formatNumberByFormat(countryCallingCode, PhoneNumberFormat.E164, formattedNumber);
+ prefixNumberWithCountryCallingCode(countryCallingCode, PhoneNumberFormat.E164,
+ formattedNumber);
return;
}
// Note getRegionCodeForCountryCode() is used because formatting information for regions which
// 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 (!hasValidCountryCallingCode(countryCallingCode)) {
+ if (!hasValidCountryCallingCode(countryCallingCode)) {
formattedNumber.append(nationalSignificantNumber);
return;
}
PhoneMetadata metadata =
getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
- formattedNumber.append(formatNationalNumber(nationalSignificantNumber, metadata, numberFormat));
- maybeGetFormattedExtension(number, metadata, numberFormat, formattedNumber);
- formatNumberByFormat(countryCallingCode, numberFormat, formattedNumber);
+ formattedNumber.append(formatNsn(nationalSignificantNumber, metadata, numberFormat));
+ maybeAppendFormattedExtension(number, metadata, numberFormat, formattedNumber);
+ prefixNumberWithCountryCallingCode(countryCallingCode, numberFormat, formattedNumber);
}
/**
@@ -1133,18 +1145,24 @@ public class PhoneNumberUtil {
if (!hasValidCountryCallingCode(countryCallingCode)) {
return nationalSignificantNumber;
}
- List<NumberFormat> userDefinedFormatsCopy =
- new ArrayList<NumberFormat>(userDefinedFormats.size());
PhoneMetadata metadata =
getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
- for (NumberFormat numFormat : userDefinedFormats) {
- String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
+
+ StringBuilder formattedNumber = new StringBuilder(20);
+
+ NumberFormat formattingPattern =
+ chooseFormattingPatternForNumber(userDefinedFormats, nationalSignificantNumber);
+ if (formattingPattern == null) {
+ // If no pattern above is matched, we format the number as a whole.
+ formattedNumber.append(nationalSignificantNumber);
+ } else {
+ NumberFormat numFormatCopy = new NumberFormat();
+ // Before we do a replacement of the national prefix pattern $NP with the national prefix, we
+ // need to copy the rule so that subsequent replacements for different numbers have the
+ // appropriate national prefix.
+ numFormatCopy.mergeFrom(formattingPattern);
+ String nationalPrefixFormattingRule = formattingPattern.getNationalPrefixFormattingRule();
if (nationalPrefixFormattingRule.length() > 0) {
- // Before we do a replacement of the national prefix pattern $NP with the national prefix,
- // we need to copy the rule so that subsequent replacements for different numbers have the
- // appropriate national prefix.
- NumberFormat numFormatCopy = new NumberFormat();
- numFormatCopy.mergeFrom(numFormat);
String nationalPrefix = metadata.getNationalPrefix();
if (nationalPrefix.length() > 0) {
// Replace $NP with national prefix and $FG with the first group ($1).
@@ -1157,19 +1175,12 @@ public class PhoneNumberUtil {
// We don't want to have a rule for how to format the national prefix if there isn't one.
numFormatCopy.clearNationalPrefixFormattingRule();
}
- userDefinedFormatsCopy.add(numFormatCopy);
- } else {
- // Otherwise, we just add the original rule to the modified list of formats.
- userDefinedFormatsCopy.add(numFormat);
}
+ formattedNumber.append(
+ formatNsnUsingPattern(nationalSignificantNumber, numFormatCopy, numberFormat));
}
-
- StringBuilder formattedNumber =
- new StringBuilder(formatAccordingToFormats(nationalSignificantNumber,
- userDefinedFormatsCopy,
- numberFormat));
- maybeGetFormattedExtension(number, metadata, numberFormat, formattedNumber);
- formatNumberByFormat(countryCallingCode, numberFormat, formattedNumber);
+ maybeAppendFormattedExtension(number, metadata, numberFormat, formattedNumber);
+ prefixNumberWithCountryCallingCode(countryCallingCode, numberFormat, formattedNumber);
return formattedNumber.toString();
}
@@ -1197,12 +1208,11 @@ public class PhoneNumberUtil {
StringBuilder formattedNumber = new StringBuilder(20);
PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
- formattedNumber.append(formatNationalNumber(nationalSignificantNumber,
- metadata,
- PhoneNumberFormat.NATIONAL,
- carrierCode));
- maybeGetFormattedExtension(number, metadata, PhoneNumberFormat.NATIONAL, formattedNumber);
- formatNumberByFormat(countryCallingCode, PhoneNumberFormat.NATIONAL, formattedNumber);
+ formattedNumber.append(formatNsn(nationalSignificantNumber, metadata,
+ PhoneNumberFormat.NATIONAL, carrierCode));
+ maybeAppendFormattedExtension(number, metadata, PhoneNumberFormat.NATIONAL, formattedNumber);
+ prefixNumberWithCountryCallingCode(countryCallingCode, PhoneNumberFormat.NATIONAL,
+ formattedNumber);
return formattedNumber.toString();
}
@@ -1314,6 +1324,10 @@ public class PhoneNumberUtil {
public String formatOutOfCountryCallingNumber(PhoneNumber number,
String regionCallingFrom) {
if (!isValidRegionCode(regionCallingFrom)) {
+ LOGGER.log(Level.WARNING,
+ "Trying to format number from invalid region "
+ + regionCallingFrom
+ + ". International formatting applied.");
return format(number, PhoneNumberFormat.INTERNATIONAL);
}
int countryCallingCode = number.getCountryCode();
@@ -1327,7 +1341,7 @@ public class PhoneNumberUtil {
// country calling code.
return countryCallingCode + " " + format(number, PhoneNumberFormat.NATIONAL);
}
- } else if (countryCallingCode == getCountryCodeForRegion(regionCallingFrom)) {
+ } else if (countryCallingCode == getCountryCodeForValidRegion(regionCallingFrom)) {
// For regions that share a country calling code, the country calling code need not be dialled.
// This also applies when dialling within a region, so this if clause covers both these cases.
// Technically this is the case for dialling from La Reunion to other overseas departments of
@@ -1353,18 +1367,17 @@ public class PhoneNumberUtil {
PhoneMetadata metadataForRegion =
getMetadataForRegionOrCallingCode(countryCallingCode, regionCode);
String formattedNationalNumber =
- formatNationalNumber(nationalSignificantNumber,
- metadataForRegion, PhoneNumberFormat.INTERNATIONAL);
+ formatNsn(nationalSignificantNumber, metadataForRegion, PhoneNumberFormat.INTERNATIONAL);
StringBuilder formattedNumber = new StringBuilder(formattedNationalNumber);
- maybeGetFormattedExtension(number, metadataForRegion, PhoneNumberFormat.INTERNATIONAL,
- formattedNumber);
+ maybeAppendFormattedExtension(number, metadataForRegion, PhoneNumberFormat.INTERNATIONAL,
+ formattedNumber);
if (internationalPrefixForFormatting.length() > 0) {
formattedNumber.insert(0, " ").insert(0, countryCallingCode).insert(0, " ")
.insert(0, internationalPrefixForFormatting);
} else {
- formatNumberByFormat(countryCallingCode,
- PhoneNumberFormat.INTERNATIONAL,
- formattedNumber);
+ prefixNumberWithCountryCallingCode(countryCallingCode,
+ PhoneNumberFormat.INTERNATIONAL,
+ formattedNumber);
}
return formattedNumber.toString();
}
@@ -1379,6 +1392,7 @@ public class PhoneNumberUtil {
*
* 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
@@ -1565,26 +1579,27 @@ public class PhoneNumberUtil {
if (isNANPACountry(regionCallingFrom)) {
return countryCode + " " + rawInput;
}
- } 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>(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.
- newFormat.setPattern("(\\d+)(.*)");
- // Here we just concatenate them back together after the national prefix has been fixed.
- newFormat.setFormat("$1$2");
- availableFormats.add(newFormat);
+ } else if (isValidRegionCode(regionCallingFrom) &&
+ countryCode == getCountryCodeForValidRegion(regionCallingFrom)) {
+ NumberFormat formattingPattern =
+ chooseFormattingPatternForNumber(metadataForRegionCallingFrom.numberFormats(),
+ nationalNumber);
+ if (formattingPattern == null) {
+ // If no pattern above is matched, we format the original input.
+ return rawInput;
}
- // Now we format using these patterns instead of the default pattern, but with the national
- // prefix prefixed if necessary, by choosing the format rule based on the leading digits
- // present in the unformatted national number.
+ NumberFormat newFormat = new NumberFormat();
+ newFormat.mergeFrom(formattingPattern);
+ // The first group is the first group of digits that the user wrote together.
+ newFormat.setPattern("(\\d+)(.*)");
+ // Here we just concatenate them back together after the national prefix has been fixed.
+ newFormat.setFormat("$1$2");
+ // Now we format using this pattern instead of the default pattern, but with the national
+ // prefix prefixed if necessary.
// This will not work in the cases where the pattern (and not the leading digits) decide
// whether a national prefix needs to be used, since we have overridden the pattern to match
// anything, but that is not the case in the metadata to date.
- return formatAccordingToFormats(rawInput, availableFormats, PhoneNumberFormat.NATIONAL);
+ return formatNsnUsingPattern(rawInput, newFormat, PhoneNumberFormat.NATIONAL);
}
String internationalPrefixForFormatting = "";
// If an unsupported region-calling-from is entered, or a country with multiple international
@@ -1600,15 +1615,15 @@ public class PhoneNumberUtil {
StringBuilder formattedNumber = new StringBuilder(rawInput);
String regionCode = getRegionCodeForCountryCode(countryCode);
PhoneMetadata metadataForRegion = getMetadataForRegionOrCallingCode(countryCode, regionCode);
- maybeGetFormattedExtension(number, metadataForRegion,
- PhoneNumberFormat.INTERNATIONAL, formattedNumber);
+ maybeAppendFormattedExtension(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,
+ prefixNumberWithCountryCallingCode(countryCode,
PhoneNumberFormat.INTERNATIONAL,
formattedNumber);
}
@@ -1632,9 +1647,9 @@ public class PhoneNumberUtil {
/**
* A helper function that is used by format and formatByPattern.
*/
- private void formatNumberByFormat(int countryCallingCode,
- PhoneNumberFormat numberFormat,
- StringBuilder formattedNumber) {
+ private void prefixNumberWithCountryCallingCode(int countryCallingCode,
+ PhoneNumberFormat numberFormat,
+ StringBuilder formattedNumber) {
switch (numberFormat) {
case E164:
formattedNumber.insert(0, countryCallingCode).insert(0, PLUS_SIGN);
@@ -1651,21 +1666,19 @@ public class PhoneNumberUtil {
}
}
- // Simple wrapper of formatNationalNumber for the common case of no carrier code.
- private String formatNationalNumber(String number,
- PhoneMetadata metadata,
- PhoneNumberFormat numberFormat) {
- return formatNationalNumber(number, metadata, numberFormat, null);
+ // Simple wrapper of formatNsn for the common case of no carrier code.
+ private String formatNsn(String number, PhoneMetadata metadata, PhoneNumberFormat numberFormat) {
+ return formatNsn(number, metadata, numberFormat, null);
}
// Note in some regions, the national number can be written in two completely different ways
// depending on whether it forms part of the NATIONAL format or INTERNATIONAL format. The
// numberFormat parameter here is used to specify which format to use for those cases. If a
// carrierCode is specified, this will be inserted into the formatted string to replace $CC.
- private String formatNationalNumber(String number,
- PhoneMetadata metadata,
- PhoneNumberFormat numberFormat,
- String carrierCode) {
+ private String formatNsn(String number,
+ PhoneMetadata metadata,
+ PhoneNumberFormat numberFormat,
+ String carrierCode) {
List<NumberFormat> intlNumberFormats = metadata.intlNumberFormats();
// When the intlNumberFormats exists, we use that to format national number for the
// INTERNATIONAL format instead of using the numberDesc.numberFormats.
@@ -1673,13 +1686,10 @@ public class PhoneNumberUtil {
(intlNumberFormats.size() == 0 || numberFormat == PhoneNumberFormat.NATIONAL)
? metadata.numberFormats()
: metadata.intlNumberFormats();
- String formattedNationalNumber =
- formatAccordingToFormats(number, availableFormats, numberFormat, carrierCode);
- if (numberFormat == PhoneNumberFormat.RFC3966) {
- formattedNationalNumber =
- SEPARATOR_PATTERN.matcher(formattedNationalNumber).replaceAll("-");
- }
- return formattedNationalNumber;
+ NumberFormat formattingPattern = chooseFormattingPatternForNumber(availableFormats, number);
+ return (formattingPattern == null)
+ ? number
+ : formatNsnUsingPattern(number, formattingPattern, numberFormat, carrierCode);
}
private NumberFormat chooseFormattingPatternForNumber(List<NumberFormat> availableFormats,
@@ -1698,50 +1708,58 @@ public class PhoneNumberUtil {
return null;
}
- // Simple wrapper of formatAccordingToFormats for the common case of no carrier code.
- private String formatAccordingToFormats(String nationalNumber,
- List<NumberFormat> availableFormats,
- PhoneNumberFormat numberFormat) {
- return formatAccordingToFormats(nationalNumber, availableFormats, numberFormat, null);
+ // Simple wrapper of formatNsnUsingPattern for the common case of no carrier code.
+ private String formatNsnUsingPattern(String nationalNumber,
+ NumberFormat formattingPattern,
+ PhoneNumberFormat numberFormat) {
+ return formatNsnUsingPattern(nationalNumber, formattingPattern, numberFormat, null);
}
// Note that carrierCode is optional - if NULL or an empty string, no carrier code replacement
// will take place.
- private String formatAccordingToFormats(String nationalNumber,
- List<NumberFormat> availableFormats,
- PhoneNumberFormat numberFormat,
- String carrierCode) {
- NumberFormat numFormat = chooseFormattingPatternForNumber(availableFormats, nationalNumber);
- if (numFormat == null) {
- // If no pattern above is matched, we format the number as a whole.
- return nationalNumber;
- }
- String numberFormatRule = numFormat.getFormat();
- Matcher m = regexCache.getPatternForRegex(numFormat.getPattern()).matcher(nationalNumber);
+ private String formatNsnUsingPattern(String nationalNumber,
+ NumberFormat formattingPattern,
+ PhoneNumberFormat numberFormat,
+ String carrierCode) {
+ String numberFormatRule = formattingPattern.getFormat();
+ Matcher m =
+ regexCache.getPatternForRegex(formattingPattern.getPattern()).matcher(nationalNumber);
+ String formattedNationalNumber = "";
if (numberFormat == PhoneNumberFormat.NATIONAL &&
carrierCode != null && carrierCode.length() > 0 &&
- numFormat.getDomesticCarrierCodeFormattingRule().length() > 0) {
+ formattingPattern.getDomesticCarrierCodeFormattingRule().length() > 0) {
// Replace the $CC in the formatting rule with the desired carrier code.
- String carrierCodeFormattingRule = numFormat.getDomesticCarrierCodeFormattingRule();
+ String carrierCodeFormattingRule = formattingPattern.getDomesticCarrierCodeFormattingRule();
carrierCodeFormattingRule =
CC_PATTERN.matcher(carrierCodeFormattingRule).replaceFirst(carrierCode);
// Now replace the $FG in the formatting rule with the first group and the carrier code
// combined in the appropriate way.
numberFormatRule = FIRST_GROUP_PATTERN.matcher(numberFormatRule)
.replaceFirst(carrierCodeFormattingRule);
- return m.replaceAll(numberFormatRule);
+ formattedNationalNumber = m.replaceAll(numberFormatRule);
} else {
// Use the national prefix formatting rule instead.
- String nationalPrefixFormattingRule = numFormat.getNationalPrefixFormattingRule();
+ String nationalPrefixFormattingRule = formattingPattern.getNationalPrefixFormattingRule();
if (numberFormat == PhoneNumberFormat.NATIONAL &&
nationalPrefixFormattingRule != null &&
nationalPrefixFormattingRule.length() > 0) {
Matcher firstGroupMatcher = FIRST_GROUP_PATTERN.matcher(numberFormatRule);
- return m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule));
+ formattedNationalNumber =
+ m.replaceAll(firstGroupMatcher.replaceFirst(nationalPrefixFormattingRule));
} else {
- return m.replaceAll(numberFormatRule);
+ formattedNationalNumber = m.replaceAll(numberFormatRule);
}
}
+ if (numberFormat == PhoneNumberFormat.RFC3966) {
+ // Strip any leading punctuation.
+ Matcher matcher = SEPARATOR_PATTERN.matcher(formattedNationalNumber);
+ if (matcher.lookingAt()) {
+ formattedNationalNumber = matcher.replaceFirst("");
+ }
+ // Replace the rest with a dash between each number group.
+ formattedNationalNumber = matcher.reset(formattedNationalNumber).replaceAll("-");
+ }
+ return formattedNationalNumber;
}
/**
@@ -1769,7 +1787,7 @@ public class PhoneNumberUtil {
public PhoneNumber getExampleNumberForType(String regionCode, PhoneNumberType type) {
// Check the region code is valid.
if (!isValidRegionCode(regionCode)) {
- LOGGER.log(Level.SEVERE, "Invalid or unknown region code provided: " + regionCode);
+ LOGGER.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode);
return null;
}
PhoneNumberDesc desc = getNumberDescByType(getMetadataForRegion(regionCode), type);
@@ -1802,6 +1820,9 @@ public class PhoneNumberUtil {
} catch (NumberParseException e) {
LOGGER.log(Level.SEVERE, e.toString());
}
+ } else {
+ LOGGER.log(Level.WARNING,
+ "Invalid or unknown country calling code provided: " + countryCallingCode);
}
return null;
}
@@ -1810,32 +1831,22 @@ public class PhoneNumberUtil {
* Appends the formatted extension of a phone number to formattedNumber, if the phone number had
* an extension specified.
*/
- private void maybeGetFormattedExtension(PhoneNumber number, PhoneMetadata metadata,
- PhoneNumberFormat numberFormat,
- StringBuilder formattedNumber) {
+ private void maybeAppendFormattedExtension(PhoneNumber number, PhoneMetadata metadata,
+ PhoneNumberFormat numberFormat,
+ StringBuilder formattedNumber) {
if (number.hasExtension() && number.getExtension().length() > 0) {
if (numberFormat == PhoneNumberFormat.RFC3966) {
formattedNumber.append(RFC3966_EXTN_PREFIX).append(number.getExtension());
} else {
- formatExtension(number.getExtension(), metadata, formattedNumber);
+ if (metadata.hasPreferredExtnPrefix()) {
+ formattedNumber.append(metadata.getPreferredExtnPrefix()).append(number.getExtension());
+ } else {
+ formattedNumber.append(DEFAULT_EXTN_PREFIX).append(number.getExtension());
+ }
}
}
}
- /**
- * Formats the extension part of the phone number by prefixing it with the appropriate extension
- * prefix. This will be the default extension prefix, unless overridden by a preferred
- * extension prefix for this region.
- */
- private void formatExtension(String extensionDigits, PhoneMetadata metadata,
- StringBuilder extension) {
- if (metadata.hasPreferredExtnPrefix()) {
- extension.append(metadata.getPreferredExtnPrefix()).append(extensionDigits);
- } else {
- extension.append(DEFAULT_EXTN_PREFIX).append(extensionDigits);
- }
- }
-
PhoneNumberDesc getNumberDescByType(PhoneMetadata metadata, PhoneNumberType type) {
switch (type) {
case PREMIUM_RATE:
@@ -1992,12 +2003,14 @@ public class PhoneNumberUtil {
*/
public boolean isValidNumberForRegion(PhoneNumber number, String regionCode) {
int countryCode = number.getCountryCode();
- if (countryCode == 0 ||
+ PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode);
+ if ((metadata == null) ||
(!REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode) &&
- countryCode != getCountryCodeForRegion(regionCode))) {
+ countryCode != getCountryCodeForValidRegion(regionCode))) {
+ // Either the region code was invalid, or the country calling code for this number does not
+ // match that of the region code.
return false;
}
- PhoneMetadata metadata = getMetadataForRegionOrCallingCode(countryCode, regionCode);
PhoneNumberDesc generalNumDesc = metadata.getGeneralDesc();
String nationalSignificantNumber = getNationalSignificantNumber(number);
@@ -2072,12 +2085,23 @@ public class PhoneNumberUtil {
*/
public int getCountryCodeForRegion(String regionCode) {
if (!isValidRegionCode(regionCode)) {
- LOGGER.log(Level.SEVERE,
+ LOGGER.log(Level.WARNING,
"Invalid or missing region code ("
+ ((regionCode == null) ? "null" : regionCode)
+ ") provided.");
return 0;
}
+ return getCountryCodeForValidRegion(regionCode);
+ }
+
+ /**
+ * Returns the country calling code for a specific region. For example, this would be 1 for the
+ * United States, and 64 for New Zealand. Assumes the region is already valid.
+ *
+ * @param regionCode the region that we want to get the country calling code for
+ * @return the country calling code for the region denoted by regionCode
+ */
+ private int getCountryCodeForValidRegion(String regionCode) {
PhoneMetadata metadata = getMetadataForRegion(regionCode);
return metadata.getCountryCode();
}
@@ -2098,7 +2122,7 @@ public class PhoneNumberUtil {
*/
public String getNddPrefixForRegion(String regionCode, boolean stripNonDigits) {
if (!isValidRegionCode(regionCode)) {
- LOGGER.log(Level.SEVERE,
+ LOGGER.log(Level.WARNING,
"Invalid or missing region code ("
+ ((regionCode == null) ? "null" : regionCode)
+ ") provided.");
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN
index ece2723..10f648f 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX
index 91d11b5..18ca4d0 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AX
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
index 01ca8c3..802997e 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BF
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ
index af2439c..09eee90 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQ
new file mode 100644
index 0000000..6ac0880
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BQ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
index 845377b..31ed9bc 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BR
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
index 2a8b978..d280135 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CW
new file mode 100644
index 0000000..8f4170e
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ
index 57af3c0..0683a64 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DJ
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI
index 1e7307e..9995781 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_FI
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
index 326d131..f07407a 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV
index 335c85d..fd64fb8 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW
index 2fb6952..fdb4093 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_MW
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS
index 81c0848..bf324e6 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_RS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC
index 39ee643..7f55e5a 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SC
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SS b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SS
new file mode 100644
index 0000000..a8293fd
--- /dev/null
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SS
Binary files differ
diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN
index 2d29291..d775464 100644
--- a/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN
+++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_VN
Binary files differ