Browse Source

Replacing some public APIs that take phone numbers as strings with CharSequence. Removed two private methods that were unused (leftover from a previous commit). (#1847)

pull/790/merge
lararennie 9 years ago
committed by Keghani Kouzoujian
parent
commit
7e6feaeeea
5 changed files with 115 additions and 142 deletions
  1. +10
    -10
      java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java
  2. +81
    -113
      java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
  3. +6
    -7
      java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java
  4. +8
    -12
      java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
  5. +10
    -0
      pending_code_changes.txt

+ 10
- 10
java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java View File

@ -326,15 +326,14 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
}
// Try to come up with a valid match given the entire candidate.
String rawString = candidate.toString();
PhoneNumberMatch match = parseAndVerify(rawString, offset);
PhoneNumberMatch match = parseAndVerify(candidate, offset);
if (match != null) {
return match;
}
// If that failed, try to find an "inner match" - there might be a phone number within this
// candidate.
return extractInnerMatch(rawString, offset);
return extractInnerMatch(candidate, offset);
}
/**
@ -345,7 +344,7 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
* @param offset the current offset of {@code candidate} within {@link #text}
* @return the match found, null if none can be found
*/
private PhoneNumberMatch extractInnerMatch(String candidate, int offset) {
private PhoneNumberMatch extractInnerMatch(CharSequence candidate, int offset) {
for (Pattern possibleInnerMatch : INNER_MATCHES) {
Matcher groupMatcher = possibleInnerMatch.matcher(candidate);
boolean isFirstMatch = true;
@ -354,8 +353,8 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
// We should handle any group before this one too.
CharSequence group = trimAfterFirstMatch(
PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN,
candidate.substring(0, groupMatcher.start()));
PhoneNumberMatch match = parseAndVerify(group.toString(), offset);
candidate.subSequence(0, groupMatcher.start()));
PhoneNumberMatch match = parseAndVerify(group, offset);
if (match != null) {
return match;
}
@ -364,7 +363,7 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
}
CharSequence group = trimAfterFirstMatch(
PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN, groupMatcher.group(1));
PhoneNumberMatch match = parseAndVerify(group.toString(), offset + groupMatcher.start(1));
PhoneNumberMatch match = parseAndVerify(group, offset + groupMatcher.start(1));
if (match != null) {
return match;
}
@ -383,7 +382,7 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
* @param offset the offset of {@code candidate} within {@link #text}
* @return the parsed and validated phone number match, or null
*/
private PhoneNumberMatch parseAndVerify(String candidate, int offset) {
private PhoneNumberMatch parseAndVerify(CharSequence candidate, int offset) {
try {
// Check the candidate doesn't contain any formatting which would indicate that it really
// isn't a phone number.
@ -440,7 +439,7 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
number.clearCountryCodeSource();
number.clearRawInput();
number.clearPreferredDomesticCarrierCode();
return new PhoneNumberMatch(offset, candidate, number);
return new PhoneNumberMatch(offset, candidate.toString(), number);
}
} catch (NumberParseException e) {
// ignore and continue
@ -572,7 +571,8 @@ final class PhoneNumberMatcher implements Iterator<PhoneNumberMatch> {
}
static boolean checkNumberGroupingIsValid(
PhoneNumber number, String candidate, PhoneNumberUtil util, NumberGroupingChecker checker) {
PhoneNumber number, CharSequence candidate, PhoneNumberUtil util,
NumberGroupingChecker checker) {
// TODO: Evaluate how this works for other locales (testing has been limited to NANPA regions)
// and optimise if necessary.
StringBuilder normalizedCandidate =


+ 81
- 113
java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java View File

@ -363,9 +363,11 @@ public class PhoneNumberUtil {
// correctly. Therefore, we use \d, so that the first group actually used in the pattern will be
// matched.
private static final Pattern FIRST_GROUP_PATTERN = Pattern.compile("(\\$\\d)");
private static final Pattern NP_PATTERN = Pattern.compile("\\$NP");
private static final Pattern FG_PATTERN = Pattern.compile("\\$FG");
private static final Pattern CC_PATTERN = Pattern.compile("\\$CC");
// Constants used in the formatting rules to represent the national prefix, first group and
// carrier code respectively.
private static final String NP_STRING = "$NP";
private static final String FG_STRING = "$FG";
private static final String CC_STRING = "$CC";
// A pattern that is used to determine if the national prefix formatting rule has the first group
// only, i.e., does not start with the national prefix. Note that the pattern explicitly allows
@ -478,7 +480,7 @@ public class PhoneNumberUtil {
*/
POSSIBLE {
@Override
boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) {
boolean verify(PhoneNumber number, CharSequence candidate, PhoneNumberUtil util) {
return util.isPossibleNumber(number);
}
},
@ -490,9 +492,9 @@ public class PhoneNumberUtil {
*/
VALID {
@Override
boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) {
boolean verify(PhoneNumber number, CharSequence candidate, PhoneNumberUtil util) {
if (!util.isValidNumber(number)
|| !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate, util)) {
|| !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate.toString(), util)) {
return false;
}
return PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util);
@ -512,10 +514,11 @@ public class PhoneNumberUtil {
*/
STRICT_GROUPING {
@Override
boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) {
boolean verify(PhoneNumber number, CharSequence candidate, PhoneNumberUtil util) {
String candidateString = candidate.toString();
if (!util.isValidNumber(number)
|| !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate, util)
|| PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)
|| !PhoneNumberMatcher.containsOnlyValidXChars(number, candidateString, util)
|| PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidateString)
|| !PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util)) {
return false;
}
@ -544,10 +547,11 @@ public class PhoneNumberUtil {
*/
EXACT_GROUPING {
@Override
boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util) {
boolean verify(PhoneNumber number, CharSequence candidate, PhoneNumberUtil util) {
String candidateString = candidate.toString();
if (!util.isValidNumber(number)
|| !PhoneNumberMatcher.containsOnlyValidXChars(number, candidate, util)
|| PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)
|| !PhoneNumberMatcher.containsOnlyValidXChars(number, candidateString, util)
|| PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidateString)
|| !PhoneNumberMatcher.isNationalPrefixPresentIfRequired(number, util)) {
return false;
}
@ -565,7 +569,7 @@ public class PhoneNumberUtil {
};
/** Returns true if {@code number} is a verified number according to this leniency. */
abstract boolean verify(PhoneNumber number, String candidate, PhoneNumberUtil util);
abstract boolean verify(PhoneNumber number, CharSequence candidate, PhoneNumberUtil util);
}
// A source of metadata for different regions.
@ -644,20 +648,20 @@ public class PhoneNumberUtil {
* string if no character used to start phone numbers (such as + or any digit) is found in the
* number
*/
static String extractPossibleNumber(String number) {
static CharSequence extractPossibleNumber(CharSequence number) {
Matcher m = VALID_START_CHAR_PATTERN.matcher(number);
if (m.find()) {
number = number.substring(m.start());
number = number.subSequence(m.start(), number.length());
// Remove trailing non-alpha non-numerical characters.
Matcher trailingCharsMatcher = UNWANTED_END_CHAR_PATTERN.matcher(number);
if (trailingCharsMatcher.find()) {
number = number.substring(0, trailingCharsMatcher.start());
number = number.subSequence(0, trailingCharsMatcher.start());
logger.log(Level.FINER, "Stripped trailing characters: " + number);
}
// Check for extra numbers at the end.
Matcher secondNumber = SECOND_NUMBER_START_PATTERN.matcher(number);
if (secondNumber.find()) {
number = number.substring(0, secondNumber.start());
number = number.subSequence(0, secondNumber.start());
}
return number;
} else {
@ -676,7 +680,7 @@ public class PhoneNumberUtil {
* @return true if the number could be a phone number of some sort, otherwise false
*/
// @VisibleForTesting
static boolean isViablePhoneNumber(String number) {
static boolean isViablePhoneNumber(CharSequence number) {
if (number.length() < MIN_LENGTH_FOR_NSN) {
return false;
}
@ -687,38 +691,27 @@ public class PhoneNumberUtil {
/**
* Normalizes a string of characters representing a phone number. This performs the following
* conversions:
* Punctuation is stripped.
* - Punctuation is stripped.
* For ALPHA/VANITY numbers:
* Letters are converted to their numeric representation on a telephone keypad. The keypad
* used here is the one defined in ITU Recommendation E.161. This is only done if there are
* 3 or more letters in the number, to lessen the risk that such letters are typos.
* - Letters are converted to their numeric representation on a telephone keypad. The keypad
* used here is the one defined in ITU Recommendation E.161. This is only done if there are 3
* or more letters in the number, to lessen the risk that such letters are typos.
* For other numbers:
* Wide-ascii digits are converted to normal ASCII (European) digits.
* Arabic-Indic numerals are converted to European numerals.
* Spurious alpha characters are stripped.
* - Wide-ascii digits are converted to normal ASCII (European) digits.
* - Arabic-Indic numerals are converted to European numerals.
* - Spurious alpha characters are stripped.
*
* @param number a string of characters representing a phone number
* @return the normalized string version of the phone number
* @param number a StringBuilder of characters representing a phone number that will be
* normalized in place
*/
static String normalize(String number) {
static StringBuilder normalize(StringBuilder number) {
Matcher m = VALID_ALPHA_PHONE_PATTERN.matcher(number);
if (m.matches()) {
return normalizeHelper(number, ALPHA_PHONE_MAPPINGS, true);
number.replace(0, number.length(), normalizeHelper(number, ALPHA_PHONE_MAPPINGS, true));
} else {
return normalizeDigitsOnly(number);
number.replace(0, number.length(), normalizeDigitsOnly(number));
}
}
/**
* Normalizes a string of characters representing a phone number. This is a wrapper for
* normalize(String number) but does in-place normalization of the StringBuilder provided.
*
* @param number a StringBuilder of characters representing a phone number that will be
* normalized in place
*/
static void normalize(StringBuilder number) {
String normalizedNumber = normalize(number.toString());
number.replace(0, number.length(), normalizedNumber);
return number;
}
/**
@ -728,13 +721,14 @@ public class PhoneNumberUtil {
* @param number a string of characters representing a phone number
* @return the normalized string version of the phone number
*/
public static String normalizeDigitsOnly(String number) {
public static String normalizeDigitsOnly(CharSequence number) {
return normalizeDigits(number, false /* strip non-digits */).toString();
}
static StringBuilder normalizeDigits(String number, boolean keepNonDigits) {
static StringBuilder normalizeDigits(CharSequence number, boolean keepNonDigits) {
StringBuilder normalizedDigits = new StringBuilder(number.length());
for (char c : number.toCharArray()) {
for (int i = 0; i < number.length(); i++) {
char c = number.charAt(i);
int digit = Character.digit(c, 10);
if (digit != -1) {
normalizedDigits.append(digit);
@ -752,7 +746,7 @@ public class PhoneNumberUtil {
* @param number a string of characters representing a phone number
* @return the normalized string version of the phone number
*/
public static String normalizeDiallableCharsOnly(String number) {
public static String normalizeDiallableCharsOnly(CharSequence number) {
return normalizeHelper(number, DIALLABLE_CHAR_MAPPINGS, true /* remove non matches */);
}
@ -760,7 +754,7 @@ public class PhoneNumberUtil {
* Converts all alpha characters in a number to their respective digits on a keypad, but retains
* existing formatting.
*/
public static String convertAlphaCharactersInNumber(String number) {
public static String convertAlphaCharactersInNumber(CharSequence number) {
return normalizeHelper(number, ALPHA_PHONE_MAPPINGS, false);
}
@ -930,7 +924,7 @@ public class PhoneNumberUtil {
* be stripped from the number. If this is false, they will be left unchanged in the number.
* @return the normalized string version of the phone number
*/
private static String normalizeHelper(String number,
private static String normalizeHelper(CharSequence number,
Map<Character, Character> normalizationReplacements,
boolean removeNonMatches) {
StringBuilder normalizedNumber = new StringBuilder(number.length());
@ -1267,9 +1261,8 @@ public class PhoneNumberUtil {
if (nationalPrefix.length() > 0) {
// Replace $NP with national prefix and $FG with the first group ($1).
nationalPrefixFormattingRule =
NP_PATTERN.matcher(nationalPrefixFormattingRule).replaceFirst(nationalPrefix);
nationalPrefixFormattingRule =
FG_PATTERN.matcher(nationalPrefixFormattingRule).replaceFirst("\\$1");
nationalPrefixFormattingRule.replace(NP_STRING, nationalPrefix);
nationalPrefixFormattingRule = nationalPrefixFormattingRule.replace(FG_STRING, "$1");
numFormatCopy.setNationalPrefixFormattingRule(nationalPrefixFormattingRule);
} else {
// We don't want to have a rule for how to format the national prefix if there isn't one.
@ -1295,7 +1288,7 @@ public class PhoneNumberUtil {
* @return the formatted phone number in national format for dialing using the carrier as
* specified in the {@code carrierCode}
*/
public String formatNationalNumberWithCarrierCode(PhoneNumber number, String carrierCode) {
public String formatNationalNumberWithCarrierCode(PhoneNumber number, CharSequence carrierCode) {
int countryCallingCode = number.getCountryCode();
String nationalSignificantNumber = getNationalSignificantNumber(number);
if (!hasValidCountryCallingCode(countryCallingCode)) {
@ -1343,7 +1336,7 @@ public class PhoneNumberUtil {
* none is found
*/
public String formatNationalNumberWithPreferredCarrierCode(PhoneNumber number,
String fallbackCarrierCode) {
CharSequence fallbackCarrierCode) {
return formatNationalNumberWithCarrierCode(number,
// Historically, we set this to an empty string when parsing with raw input if none was
// found in the input string. However, this doesn't result in a number we can dial. For this
@ -1658,14 +1651,6 @@ public class PhoneNumberUtil {
return false;
}
/**
* Returns true if a number is from a region whose national significant number couldn't contain a
* leading zero, but has the italian_leading_zero field set to true.
*/
private boolean hasUnexpectedItalianLeadingZero(PhoneNumber number) {
return number.isItalianLeadingZero() && !isLeadingZeroPossible(number.getCountryCode());
}
private boolean hasFormattingPatternForNumber(PhoneNumber number) {
int countryCallingCode = number.getCountryCode();
String phoneNumberRegion = getRegionCodeForCountryCode(countryCallingCode);
@ -1849,7 +1834,7 @@ public class PhoneNumberUtil {
private String formatNsn(String number,
PhoneMetadata metadata,
PhoneNumberFormat numberFormat,
String carrierCode) {
CharSequence 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.
@ -1891,7 +1876,7 @@ public class PhoneNumberUtil {
private String formatNsnUsingPattern(String nationalNumber,
NumberFormat formattingPattern,
PhoneNumberFormat numberFormat,
String carrierCode) {
CharSequence carrierCode) {
String numberFormatRule = formattingPattern.getFormat();
Matcher m =
regexCache.getPatternForRegex(formattingPattern.getPattern()).matcher(nationalNumber);
@ -1901,8 +1886,7 @@ public class PhoneNumberUtil {
&& formattingPattern.getDomesticCarrierCodeFormattingRule().length() > 0) {
// Replace the $CC in the formatting rule with the desired carrier code.
String carrierCodeFormattingRule = formattingPattern.getDomesticCarrierCodeFormattingRule();
carrierCodeFormattingRule =
CC_PATTERN.matcher(carrierCodeFormattingRule).replaceFirst(carrierCode);
carrierCodeFormattingRule = carrierCodeFormattingRule.replace(CC_STRING, 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)
@ -2427,21 +2411,6 @@ public class PhoneNumberUtil {
return nanpaRegions.contains(regionCode);
}
/**
* Checks whether the country calling code is from a region whose national significant number
* could contain a leading zero. An example of such a region is Italy. Returns false if no
* metadata for the country is found.
*/
boolean isLeadingZeroPossible(int countryCallingCode) {
PhoneMetadata mainMetadataForCallingCode =
getMetadataForRegionOrCallingCode(countryCallingCode,
getRegionCodeForCountryCode(countryCallingCode));
if (mainMetadataForCallingCode == null) {
return false;
}
return mainMetadataForCallingCode.isLeadingZeroPossible();
}
/**
* Checks if the number is a valid vanity (alpha) number such as 800 MICROSOFT. A valid vanity
* number will start with at least 3 digits and will have three or more alpha characters. This
@ -2452,7 +2421,7 @@ public class PhoneNumberUtil {
* @param number the number that needs to be checked
* @return true if the number is a valid vanity number
*/
public boolean isAlphaNumber(String number) {
public boolean isAlphaNumber(CharSequence number) {
if (!isViablePhoneNumber(number)) {
// Number is too short, or doesn't match the basic phone number pattern.
return false;
@ -2503,7 +2472,7 @@ public class PhoneNumberUtil {
* number pattern suggests that numbers of length 7 and 10 are possible, and a number in between
* these possible lengths is entered, such as of length 8, this will return TOO_LONG.
*/
private ValidationResult testNumberLength(String number, PhoneMetadata metadata) {
private ValidationResult testNumberLength(CharSequence number, PhoneMetadata metadata) {
return testNumberLength(number, metadata, PhoneNumberType.UNKNOWN);
}
@ -2514,7 +2483,7 @@ public class PhoneNumberUtil {
* entered, such as of length 8, this will return TOO_LONG.
*/
private ValidationResult testNumberLength(
String number, PhoneMetadata metadata, PhoneNumberType type) {
CharSequence number, PhoneMetadata metadata, PhoneNumberType type) {
PhoneNumberDesc descForType = getNumberDescByType(metadata, type);
// There should always be "possibleLengths" set for every element. This is declared in the XML
// schema which is verified by PhoneNumberMetadataSchemaTest.
@ -2662,7 +2631,7 @@ public class PhoneNumberUtil {
* <p>This method first parses the number, then invokes {@link #isPossibleNumber(PhoneNumber)}
* with the resultant PhoneNumber object.
*
* @param number the number that needs to be checked, in the form of a string
* @param number the number that needs to be checked
* @param regionDialingFrom the region that we are expecting the number to be dialed from.
* Note this is different from the region where the number belongs. For example, the number
* +1 650 253 0000 is a number that belongs to US. When written in this form, it can be
@ -2673,7 +2642,7 @@ public class PhoneNumberUtil {
* specific).
* @return true if the number is possible
*/
public boolean isPossibleNumber(String number, String regionDialingFrom) {
public boolean isPossibleNumber(CharSequence number, String regionDialingFrom) {
try {
return isPossibleNumber(parse(number, regionDialingFrom));
} catch (NumberParseException e) {
@ -2771,7 +2740,7 @@ public class PhoneNumberUtil {
* @return the country calling code extracted or 0 if none could be extracted
*/
// @VisibleForTesting
int maybeExtractCountryCode(String number, PhoneMetadata defaultRegionMetadata,
int maybeExtractCountryCode(CharSequence number, PhoneMetadata defaultRegionMetadata,
StringBuilder nationalNumber, boolean keepRawInput,
PhoneNumber phoneNumber)
throws NumberParseException {
@ -2824,8 +2793,7 @@ public class PhoneNumberUtil {
// keep that instead.
if ((!matcherApi.matchNationalNumber(fullNumber, generalDesc, false)
&& matcherApi.matchNationalNumber(potentialNationalNumber, generalDesc, false))
|| testNumberLength(fullNumber.toString(), defaultRegionMetadata)
== ValidationResult.TOO_LONG) {
|| testNumberLength(fullNumber, defaultRegionMetadata) == ValidationResult.TOO_LONG) {
nationalNumber.append(potentialNationalNumber);
if (keepRawInput) {
phoneNumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
@ -2991,7 +2959,7 @@ public class PhoneNumberUtil {
* parse starts with a + symbol so that we can attempt to infer the region from the number.
* Returns false if it cannot use the region provided and the region cannot be inferred.
*/
private boolean checkRegionForParsing(String numberToParse, String defaultRegion) {
private boolean checkRegionForParsing(CharSequence numberToParse, String defaultRegion) {
if (!isValidRegionCode(defaultRegion)) {
// If the number is null or empty, we can't infer the region.
if ((numberToParse == null) || (numberToParse.length() == 0)
@ -3035,7 +3003,7 @@ public class PhoneNumberUtil {
* too few or too many digits) or if no default region was supplied and the number is not in
* international format (does not start with +)
*/
public PhoneNumber parse(String numberToParse, String defaultRegion)
public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)
throws NumberParseException {
PhoneNumber phoneNumber = new PhoneNumber();
parse(numberToParse, defaultRegion, phoneNumber);
@ -3043,10 +3011,10 @@ public class PhoneNumberUtil {
}
/**
* Same as {@link #parse(String, String)}, but accepts mutable PhoneNumber as a parameter to
* decrease object creation when invoked many times.
* Same as {@link #parse(CharSequence, String)}, but accepts mutable PhoneNumber as a
* parameter to decrease object creation when invoked many times.
*/
public void parse(String numberToParse, String defaultRegion, PhoneNumber phoneNumber)
public void parse(CharSequence numberToParse, String defaultRegion, PhoneNumber phoneNumber)
throws NumberParseException {
parseHelper(numberToParse, defaultRegion, false, true, phoneNumber);
}
@ -3065,7 +3033,7 @@ public class PhoneNumberUtil {
* @throws NumberParseException if the string is not considered to be a viable phone number or if
* no default region was supplied
*/
public PhoneNumber parseAndKeepRawInput(String numberToParse, String defaultRegion)
public PhoneNumber parseAndKeepRawInput(CharSequence numberToParse, String defaultRegion)
throws NumberParseException {
PhoneNumber phoneNumber = new PhoneNumber();
parseAndKeepRawInput(numberToParse, defaultRegion, phoneNumber);
@ -3073,10 +3041,10 @@ public class PhoneNumberUtil {
}
/**
* Same as{@link #parseAndKeepRawInput(String, String)}, but accepts a mutable PhoneNumber as
* a parameter to decrease object creation when invoked many times.
* Same as{@link #parseAndKeepRawInput(CharSequence, String)}, but accepts a mutable
* PhoneNumber as a parameter to decrease object creation when invoked many times.
*/
public void parseAndKeepRawInput(String numberToParse, String defaultRegion,
public void parseAndKeepRawInput(CharSequence numberToParse, String defaultRegion,
PhoneNumber phoneNumber)
throws NumberParseException {
parseHelper(numberToParse, defaultRegion, true, true, phoneNumber);
@ -3126,7 +3094,8 @@ public class PhoneNumberUtil {
/**
* A helper function to set the values related to leading zeros in a PhoneNumber.
*/
static void setItalianLeadingZerosForPhoneNumber(String nationalNumber, PhoneNumber phoneNumber) {
static void setItalianLeadingZerosForPhoneNumber(CharSequence nationalNumber,
PhoneNumber phoneNumber) {
if (nationalNumber.length() > 1 && nationalNumber.charAt(0) == '0') {
phoneNumber.setItalianLeadingZero(true);
int numberOfLeadingZeros = 1;
@ -3151,8 +3120,8 @@ public class PhoneNumberUtil {
* Note if any new field is added to this method that should always be filled in, even when
* keepRawInput is false, it should also be handled in the copyCoreFieldsOnly() method.
*/
private void parseHelper(String numberToParse, String defaultRegion, boolean keepRawInput,
boolean checkRegion, PhoneNumber phoneNumber)
private void parseHelper(CharSequence numberToParse, String defaultRegion,
boolean keepRawInput, boolean checkRegion, PhoneNumber phoneNumber)
throws NumberParseException {
if (numberToParse == null) {
throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER,
@ -3163,22 +3132,23 @@ public class PhoneNumberUtil {
}
StringBuilder nationalNumber = new StringBuilder();
buildNationalNumberForParsing(numberToParse, nationalNumber);
String numberBeingParsed = numberToParse.toString();
buildNationalNumberForParsing(numberBeingParsed, nationalNumber);
if (!isViablePhoneNumber(nationalNumber.toString())) {
if (!isViablePhoneNumber(nationalNumber)) {
throw new NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER,
"The string supplied did not seem to be a phone number.");
}
// Check the region supplied is valid, or that the extracted number starts with some sort of +
// sign so the number's region can be determined.
if (checkRegion && !checkRegionForParsing(nationalNumber.toString(), defaultRegion)) {
if (checkRegion && !checkRegionForParsing(nationalNumber, defaultRegion)) {
throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
"Missing or invalid default region.");
}
if (keepRawInput) {
phoneNumber.setRawInput(numberToParse);
phoneNumber.setRawInput(numberBeingParsed);
}
// Attempt to parse extension first, since it doesn't require region-specific data and we want
// to have the non-normalised number here.
@ -3196,10 +3166,10 @@ public class PhoneNumberUtil {
// TODO: This method should really just take in the string buffer that has already
// been created, and just remove the prefix, rather than taking in a string and then
// outputting a string buffer.
countryCode = maybeExtractCountryCode(nationalNumber.toString(), regionMetadata,
countryCode = maybeExtractCountryCode(nationalNumber, regionMetadata,
normalizedNationalNumber, keepRawInput, phoneNumber);
} catch (NumberParseException e) {
Matcher matcher = PLUS_CHARS_PATTERN.matcher(nationalNumber.toString());
Matcher matcher = PLUS_CHARS_PATTERN.matcher(nationalNumber);
if (e.getErrorType() == NumberParseException.ErrorType.INVALID_COUNTRY_CODE
&& matcher.lookingAt()) {
// Strip the plus-char, and try again.
@ -3223,8 +3193,7 @@ public class PhoneNumberUtil {
} else {
// If no extracted country calling code, use the region supplied instead. The national number
// is just the normalized version of the number we were given to parse.
normalize(nationalNumber);
normalizedNationalNumber.append(nationalNumber);
normalizedNationalNumber.append(normalize(nationalNumber));
if (defaultRegion != null) {
countryCode = regionMetadata.getCountryCode();
phoneNumber.setCountryCode(countryCode);
@ -3243,8 +3212,7 @@ public class PhoneNumberUtil {
// We require that the NSN remaining after stripping the national prefix and carrier code be
// long enough to be a possible length for the region. Otherwise, we don't do the stripping,
// since the original number could be a valid short number.
if (testNumberLength(potentialNationalNumber.toString(), regionMetadata)
!= ValidationResult.TOO_SHORT) {
if (testNumberLength(potentialNationalNumber, regionMetadata) != ValidationResult.TOO_SHORT) {
normalizedNationalNumber = potentialNationalNumber;
if (keepRawInput && carrierCode.length() > 0) {
phoneNumber.setPreferredDomesticCarrierCode(carrierCode.toString());
@ -3260,7 +3228,7 @@ public class PhoneNumberUtil {
throw new NumberParseException(NumberParseException.ErrorType.TOO_LONG,
"The string supplied is too long to be a phone number.");
}
setItalianLeadingZerosForPhoneNumber(normalizedNationalNumber.toString(), phoneNumber);
setItalianLeadingZerosForPhoneNumber(normalizedNationalNumber, phoneNumber);
phoneNumber.setNationalNumber(Long.parseLong(normalizedNationalNumber.toString()));
}
@ -3413,7 +3381,7 @@ public class PhoneNumberUtil {
* @return NOT_A_NUMBER, NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH, EXACT_MATCH. See
* {@link #isNumberMatch(PhoneNumber, PhoneNumber)} for more details.
*/
public MatchType isNumberMatch(String firstNumber, String secondNumber) {
public MatchType isNumberMatch(CharSequence firstNumber, CharSequence secondNumber) {
try {
PhoneNumber firstNumberAsProto = parse(firstNumber, UNKNOWN_REGION);
return isNumberMatch(firstNumberAsProto, secondNumber);
@ -3451,7 +3419,7 @@ public class PhoneNumberUtil {
* @return NOT_A_NUMBER, NO_MATCH, SHORT_NSN_MATCH, NSN_MATCH, EXACT_MATCH. See
* {@link #isNumberMatch(PhoneNumber, PhoneNumber)} for more details.
*/
public MatchType isNumberMatch(PhoneNumber firstNumber, String secondNumber) {
public MatchType isNumberMatch(PhoneNumber firstNumber, CharSequence secondNumber) {
// First see if the second number has an implicit country calling code, by attempting to parse
// it.
try {


+ 6
- 7
java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java View File

@ -428,14 +428,14 @@ public class ShortNumberInfo {
* @param regionCode the region where the phone number is being dialed
* @return whether the number exactly matches an emergency services number in the given region
*/
public boolean isEmergencyNumber(String number, String regionCode) {
public boolean isEmergencyNumber(CharSequence number, String regionCode) {
return matchesEmergencyNumberHelper(number, regionCode, false /* doesn't allow prefix match */);
}
private boolean matchesEmergencyNumberHelper(String number, String regionCode,
private boolean matchesEmergencyNumberHelper(CharSequence number, String regionCode,
boolean allowPrefixMatch) {
number = PhoneNumberUtil.extractPossibleNumber(number);
if (PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(number).lookingAt()) {
CharSequence possibleNumber = PhoneNumberUtil.extractPossibleNumber(number);
if (PhoneNumberUtil.PLUS_CHARS_PATTERN.matcher(possibleNumber).lookingAt()) {
// Returns false if the number starts with a plus sign. We don't believe dialing the country
// code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can
// add additional logic here to handle it.
@ -446,11 +446,10 @@ public class ShortNumberInfo {
return false;
}
String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number);
PhoneNumberDesc emergencyDesc = metadata.getEmergency();
String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(possibleNumber);
boolean allowPrefixMatchForRegion =
allowPrefixMatch && !REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.contains(regionCode);
return matcherApi.matchNationalNumber(normalizedNumber, emergencyDesc,
return matcherApi.matchNationalNumber(normalizedNumber, metadata.getEmergency(),
allowPrefixMatchForRegion);
}


+ 8
- 12
java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java View File

@ -418,33 +418,29 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase {
}
public void testNormaliseRemovePunctuation() {
String inputNumber = "034-56&+#2\u00AD34";
StringBuilder inputNumber = new StringBuilder("034-56&+#2\u00AD34");
String expectedOutput = "03456234";
assertEquals("Conversion did not correctly remove punctuation",
expectedOutput,
PhoneNumberUtil.normalize(inputNumber));
expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
}
public void testNormaliseReplaceAlphaCharacters() {
String inputNumber = "034-I-am-HUNGRY";
StringBuilder inputNumber = new StringBuilder("034-I-am-HUNGRY");
String expectedOutput = "034426486479";
assertEquals("Conversion did not correctly replace alpha characters",
expectedOutput,
PhoneNumberUtil.normalize(inputNumber));
expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
}
public void testNormaliseOtherDigits() {
String inputNumber = "\uFF125\u0665";
StringBuilder inputNumber = new StringBuilder("\uFF125\u0665");
String expectedOutput = "255";
assertEquals("Conversion did not correctly replace non-latin digits",
expectedOutput,
PhoneNumberUtil.normalize(inputNumber));
expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
// Eastern-Arabic digits.
inputNumber = "\u06F52\u06F0";
inputNumber = new StringBuilder("\u06F52\u06F0");
expectedOutput = "520";
assertEquals("Conversion did not correctly replace non-latin digits",
expectedOutput,
PhoneNumberUtil.normalize(inputNumber));
expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
}
public void testNormaliseStripAlphaCharacters() {


+ 10
- 0
pending_code_changes.txt View File

@ -8,3 +8,13 @@ Code changes:
- Documentation update for private variables VALID_PUNCTUATION and
SINGLE_INTERNATIONAL_PREFIX, also renaming the latter from
UNIQUE_INTERNATIONAL_PREFIX.
- [Java only] Changing public APIs that take in strings representing phone
numbers or parts of phone numbers to take in CharSequence instead. Updating
some of the internal methods to do the same. This affects ShortNumberInfo and
PhoneNumberUtil, namely the following methods:
- parse & parseAndKeepRawInput
- formatWithCarrierCode & formatWithPreferredCarrierCode
- isNumberMatch
- isPossibleNumber
- isAlphaNumber
- normalizeDigitsOnly & normalizeDiallableCharsOnly

Loading…
Cancel
Save