@ -1818,6 +1818,62 @@ public class PhoneNumberUtil {
return getExampleNumberForType ( regionCode , PhoneNumberType . FIXED_LINE ) ;
return getExampleNumberForType ( regionCode , PhoneNumberType . FIXED_LINE ) ;
}
}
/ * *
* Gets an invalid number for the specified region . This is useful for unit - testing purposes ,
* where you want to test what will happen with an invalid number . Note that the number that is
* returned will always be able to be parsed and will have the correct country code . It may also
* be a valid * short * number / code for this region . Validity checking such numbers is handled with
* { @link com . google . i18n . phonenumbers . ShortNumberInfo } .
*
* @param regionCode the region for which an example number is needed
* @return an invalid number for the specified region . Returns null when an unsupported region or
* the region 001 ( Earth ) is passed in .
* /
public PhoneNumber getInvalidExampleNumber ( String regionCode ) {
if ( ! isValidRegionCode ( regionCode ) ) {
logger . log ( Level . WARNING , "Invalid or unknown region code provided: " + regionCode ) ;
return null ;
}
/ / We start off with a valid fixed - line number since every country supports this . Alternatively
/ / we could start with a different number type , since fixed - line numbers typically have a wide
/ / breadth of valid number lengths and we may have to make it very short before we get an
/ / invalid number .
PhoneNumberDesc desc = getNumberDescByType ( getMetadataForRegion ( regionCode ) ,
PhoneNumberType . FIXED_LINE ) ;
if ( desc . exampleNumber . equals ( "" ) ) {
/ / This shouldn ' t happen ; we have a test for this .
return null ;
}
String exampleNumber = desc . exampleNumber ;
/ / Try and make the number invalid . We do this by changing the length . We try reducing the
/ / length of the number , since currently no region has a number that is the same length as
/ / MIN_LENGTH_FOR_NSN . This is probably quicker than making the number longer , which is another
/ / alternative . We could also use the possible number pattern to extract the possible lengths of
/ / the number to make this faster , but this method is only for unit - testing so simplicity is
/ / preferred to performance . We don ' t want to return a number that can ' t be parsed , so we check
/ / the number is long enough . We try all possible lengths because phone number plans often have
/ / overlapping prefixes so the number 123456 might be valid as a fixed - line number , and 12345 as
/ / a mobile number . It would be faster to loop in a different order , but we prefer numbers that
/ / look closer to real numbers ( and it gives us a variety of different lengths for the resulting
/ / phone numbers - otherwise they would all be MIN_LENGTH_FOR_NSN digits long . )
for ( int phoneNumberLength = exampleNumber . length ( ) - 1 ;
phoneNumberLength > = MIN_LENGTH_FOR_NSN ;
phoneNumberLength - - ) {
String numberToTry = exampleNumber . substring ( 0 , phoneNumberLength ) ;
try {
PhoneNumber possiblyValidNumber = parse ( numberToTry , regionCode ) ;
if ( ! isValidNumber ( possiblyValidNumber ) ) {
return possiblyValidNumber ;
}
} catch ( NumberParseException e ) {
/ / Shouldn ' t happen : we have already checked the length , we know example numbers have
/ / only valid digits , and we know the region code is fine .
}
}
/ / We have a test to check that this doesn ' t happen for any of our supported regions .
return null ;
}
/ * *
/ * *
* Gets a valid number for the specified region and number type .
* Gets a valid number for the specified region and number type .
*
*
@ -1845,6 +1901,37 @@ public class PhoneNumberUtil {
return null ;
return null ;
}
}
/ * *
* Gets a valid number for the specified number type ( it may belong to any country ) .
*
* @param type the type of number that is needed
* @return a valid number for the specified type . Returns null when the metadata
* does not contain such information . This should only happen when no numbers of this type are
* allocated anywhere in the world anymore .
* /
public PhoneNumber getExampleNumberForType ( PhoneNumberType type ) {
for ( String regionCode : getSupportedRegions ( ) ) {
PhoneNumber exampleNumber = getExampleNumberForType ( regionCode , type ) ;
if ( exampleNumber ! = null ) {
return exampleNumber ;
}
}
/ / If there wasn ' t an example number for a region , try the non - geographical entities .
for ( int countryCallingCode : getSupportedGlobalNetworkCallingCodes ( ) ) {
PhoneNumberDesc desc = getNumberDescByType (
getMetadataForNonGeographicalRegion ( countryCallingCode ) , type ) ;
try {
if ( ! desc . exampleNumber . equals ( "" ) ) {
return parse ( "+" + countryCallingCode + desc . exampleNumber , UNKNOWN_REGION ) ;
}
} catch ( NumberParseException e ) {
logger . log ( Level . SEVERE , e . toString ( ) ) ;
}
}
/ / There are no example numbers of this type for any country in the library .
return null ;
}
/ * *
/ * *
* Gets a valid number for the specified country calling code for a non - geographical entity .
* Gets a valid number for the specified country calling code for a non - geographical entity .
*
*
@ -1859,7 +1946,7 @@ public class PhoneNumberUtil {
PhoneNumberDesc desc = metadata . generalDesc ;
PhoneNumberDesc desc = metadata . generalDesc ;
try {
try {
if ( ! desc . exampleNumber . equals ( "" ) ) {
if ( ! desc . exampleNumber . equals ( "" ) ) {
return parse ( "+" + countryCallingCode + desc . exampleNumber , "ZZ" ) ;
return parse ( "+" + countryCallingCode + desc . exampleNumber , UNKNOWN_REGION ) ;
}
}
} catch ( NumberParseException e ) {
} catch ( NumberParseException e ) {
logger . log ( Level . SEVERE , e . toString ( ) ) ;
logger . log ( Level . SEVERE , e . toString ( ) ) ;
@ -2670,10 +2757,18 @@ public class PhoneNumberUtil {
}
}
/ * *
/ * *
* Parses a string and returns it in proto buffer format . This method will throw a
* { @link com . google . i18n . phonenumbers . NumberParseException } if the number is not considered to be
* a possible number . Note that validation of whether the number is actually a valid number for a
* particular region is not performed . This can be done separately with { @link # isValidNumber } .
* Parses a string and returns it as a phone number in proto buffer format . The method is quite
* lenient and looks for a number in the input text ( raw input ) and does not check whether the
* string is definitely only a phone number . To do this , it ignores punctuation and white - space ,
* as well as any text before the number ( e . g . a leading “ Tel : ” ) and trims the non - number bits .
* It will accept a number in any format ( E164 , national , international etc ) , assuming it can be
* interpreted with the defaultRegion supplied . It also attempts to convert any alpha characters
* into digits if it thinks this is a vanity number of the type "1800 MICROSOFT" .
*
* < p > This method will throw a { @link com . google . i18n . phonenumbers . NumberParseException } if the
* number is not considered to be a possible number . Note that validation of whether the number
* is actually a valid number for a particular region is not performed . This can be done
* separately with { @link # isValidNumber } .
*
*
* @param numberToParse number that we are attempting to parse . This can contain formatting
* @param numberToParse number that we are attempting to parse . This can contain formatting
* such as + , ( and - , as well as a phone number extension . It can also
* such as + , ( and - , as well as a phone number extension . It can also
@ -2685,9 +2780,10 @@ public class PhoneNumberUtil {
* start with a '+' followed by the country calling code , then
* start with a '+' followed by the country calling code , then
* "ZZ" or null can be supplied .
* "ZZ" or null can be supplied .
* @return a phone number proto buffer filled with the parsed number
* @return a phone number proto buffer filled with the parsed number
* @throws NumberParseException if the string is not considered to be a viable phone number or if
* no default region was supplied and the number is not in
* international format ( does not start with + )
* @throws NumberParseException if the string is not considered to be a viable phone number ( e . g .
* 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 ( String numberToParse , String defaultRegion )
throws NumberParseException {
throws NumberParseException {