diff --git a/java/carrier/src/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapper.java b/java/carrier/src/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapper.java index 3b97f75dc..201062d9b 100644 --- a/java/carrier/src/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapper.java +++ b/java/carrier/src/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapper.java @@ -57,20 +57,20 @@ public class PhoneNumberToCarrierMapper { } /** - * Returns a text description for the given phone number, in the language provided. The - * description consists of the name of the carrier the number was originally allocated to, however - * if the country supports mobile number portability the number might not belong to the returned - * carrier anymore. If no mapping is found an empty string is returned. + * Returns a carrier name for the given phone number, in the language provided. The carrier name + * is the one the number was originally allocated to, however if the country supports mobile + * number portability the number might not belong to the returned carrier anymore. If no mapping + * is found an empty string is returned. * *

This method assumes the validity of the number passed in has already been checked, and that * the number is suitable for carrier lookup. We consider mobile and pager numbers possible * candidates for carrier lookup. * - * @param number a valid phone number for which we want to get a text description - * @param languageCode the language code for which the description should be written - * @return a text description for the given language code for the given phone number + * @param number a valid phone number for which we want to get a carrier name + * @param languageCode the language code in which the name should be written + * @return a carrier name for the given phone number */ - public String getDescriptionForValidNumber(PhoneNumber number, Locale languageCode) { + public String getNameForValidNumber(PhoneNumber number, Locale languageCode) { String langStr = languageCode.getLanguage(); String scriptStr = ""; // No script is specified String regionStr = languageCode.getCountry(); @@ -79,22 +79,40 @@ public class PhoneNumberToCarrierMapper { } /** - * As per {@link #getDescriptionForValidNumber(PhoneNumber, Locale)} but explicitly checks - * the validity of the number passed in. + * Gets the name of the carrier for the given phone number, in the language provided. As per + * {@link #getNameForValidNumber(PhoneNumber, Locale)} but explicitly checks the validity of + * the number passed in. * - * @param number the phone number for which we want to get a text description - * @param languageCode the language code for which the description should be written - * @return a text description for the given language code for the given phone number, or empty - * string if the number passed in is invalid + * @param number the phone number for which we want to get a carrier name + * @param languageCode the language code in which the name should be written + * @return a carrier name for the given phone number, or empty string if the number passed in is + * invalid */ - public String getDescriptionForNumber(PhoneNumber number, Locale languageCode) { + public String getNameForNumber(PhoneNumber number, Locale languageCode) { PhoneNumberType numberType = phoneUtil.getNumberType(number); if (isMobile(numberType)) { - return getDescriptionForValidNumber(number, languageCode); + return getNameForValidNumber(number, languageCode); } return ""; } + /** + * Gets the name of the carrier for the given phone number only when it is 'safe' to display to + * users. A carrier name is considered safe if the number is valid and for a region that doesn't + * support + * {@linkplain http://en.wikipedia.org/wiki/Mobile_number_portability mobile number portability}. + * + * @param number the phone number for which we want to get a carrier name + * @param languageCode the language code in which the name should be written + * @return a carrier name that is safe to display to users, or the empty string + */ + public String getSafeDisplayName(PhoneNumber number, Locale languageCode) { + if (phoneUtil.isMobileNumberPortableRegion(phoneUtil.getRegionCodeForNumber(number))) { + return ""; + } + return getNameForNumber(number, languageCode); + } + /** * Checks if the supplied number type supports carrier lookup. */ diff --git a/java/carrier/test/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapperTest.java b/java/carrier/test/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapperTest.java index 9592679cb..8f4654053 100644 --- a/java/carrier/test/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapperTest.java +++ b/java/carrier/test/com/google/i18n/phonenumbers/PhoneNumberToCarrierMapperTest.java @@ -61,57 +61,61 @@ public class PhoneNumberToCarrierMapperTest extends TestCase { private static final PhoneNumber INTERNATIONAL_TOLL_FREE = new PhoneNumber().setCountryCode(800).setNationalNumber(12345678L); - public void testGetDescriptionForMobilePortableRegion() { + public void testGetNameForMobilePortableRegion() { assertEquals("British carrier", - carrierMapper.getDescriptionForNumber(UK_MOBILE1, Locale.ENGLISH)); + carrierMapper.getNameForNumber(UK_MOBILE1, Locale.ENGLISH)); assertEquals("Brittisk operatör", - carrierMapper.getDescriptionForNumber(UK_MOBILE1, new Locale("sv", "SE"))); + carrierMapper.getNameForNumber(UK_MOBILE1, new Locale("sv", "SE"))); assertEquals("British carrier", - carrierMapper.getDescriptionForNumber(UK_MOBILE1, Locale.FRENCH)); + carrierMapper.getNameForNumber(UK_MOBILE1, Locale.FRENCH)); + // Returns an empty string because the UK implements mobile number portability. + assertEquals("", carrierMapper.getSafeDisplayName(UK_MOBILE1, Locale.ENGLISH)); } - public void testGetDescriptionForNonMobilePortableRegion() { + public void testGetNameForNonMobilePortableRegion() { assertEquals("Angolan carrier", - carrierMapper.getDescriptionForNumber(AO_MOBILE1, Locale.ENGLISH)); + carrierMapper.getNameForNumber(AO_MOBILE1, Locale.ENGLISH)); + assertEquals("Angolan carrier", + carrierMapper.getSafeDisplayName(AO_MOBILE1, Locale.ENGLISH)); } - public void testGetDescriptionForFixedLineNumber() { - assertEquals("", carrierMapper.getDescriptionForNumber(AO_FIXED1, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForNumber(UK_FIXED1, Locale.ENGLISH)); + public void testGetNameForFixedLineNumber() { + assertEquals("", carrierMapper.getNameForNumber(AO_FIXED1, Locale.ENGLISH)); + assertEquals("", carrierMapper.getNameForNumber(UK_FIXED1, Locale.ENGLISH)); // If the carrier information is present in the files and the method that assumes a valid // number is used, a carrier is returned. assertEquals("Angolan fixed line carrier", - carrierMapper.getDescriptionForValidNumber(AO_FIXED2, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForValidNumber(UK_FIXED2, Locale.ENGLISH)); + carrierMapper.getNameForValidNumber(AO_FIXED2, Locale.ENGLISH)); + assertEquals("", carrierMapper.getNameForValidNumber(UK_FIXED2, Locale.ENGLISH)); } - public void testGetDescriptionForFixedOrMobileNumber() { - assertEquals("US carrier", carrierMapper.getDescriptionForNumber(US_FIXED_OR_MOBILE, + public void testGetNameForFixedOrMobileNumber() { + assertEquals("US carrier", carrierMapper.getNameForNumber(US_FIXED_OR_MOBILE, Locale.ENGLISH)); } - public void testGetDescriptionForPagerNumber() { - assertEquals("British pager", carrierMapper.getDescriptionForNumber(UK_PAGER, Locale.ENGLISH)); + public void testGetNameForPagerNumber() { + assertEquals("British pager", carrierMapper.getNameForNumber(UK_PAGER, Locale.ENGLISH)); } - public void testGetDescriptionForNumberWithNoDataFile() { - assertEquals("", carrierMapper.getDescriptionForNumber(NUMBER_WITH_INVALID_COUNTRY_CODE, + public void testGetNameForNumberWithNoDataFile() { + assertEquals("", carrierMapper.getNameForNumber(NUMBER_WITH_INVALID_COUNTRY_CODE, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForNumber(INTERNATIONAL_TOLL_FREE, + assertEquals("", carrierMapper.getNameForNumber(INTERNATIONAL_TOLL_FREE, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForValidNumber(NUMBER_WITH_INVALID_COUNTRY_CODE, + assertEquals("", carrierMapper.getNameForValidNumber(NUMBER_WITH_INVALID_COUNTRY_CODE, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForValidNumber(INTERNATIONAL_TOLL_FREE, + assertEquals("", carrierMapper.getNameForValidNumber(INTERNATIONAL_TOLL_FREE, Locale.ENGLISH)); } - public void testGetDescriptionForNumberWithMissingPrefix() { - assertEquals("", carrierMapper.getDescriptionForNumber(UK_MOBILE2, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForNumber(AO_MOBILE2, Locale.ENGLISH)); + public void testGetNameForNumberWithMissingPrefix() { + assertEquals("", carrierMapper.getNameForNumber(UK_MOBILE2, Locale.ENGLISH)); + assertEquals("", carrierMapper.getNameForNumber(AO_MOBILE2, Locale.ENGLISH)); } - public void testGetDescriptionForInvalidNumber() { - assertEquals("", carrierMapper.getDescriptionForNumber(UK_INVALID_NUMBER, Locale.ENGLISH)); - assertEquals("", carrierMapper.getDescriptionForNumber(AO_INVALID_NUMBER, Locale.ENGLISH)); + public void testGetNameForInvalidNumber() { + assertEquals("", carrierMapper.getNameForNumber(UK_INVALID_NUMBER, Locale.ENGLISH)); + assertEquals("", carrierMapper.getNameForNumber(AO_INVALID_NUMBER, Locale.ENGLISH)); } } diff --git a/java/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java b/java/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java index 77fa2a96e..4a329ba13 100644 --- a/java/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java +++ b/java/demo/src/com/google/phonenumbers/PhoneNumberParserServlet.java @@ -283,7 +283,7 @@ public class PhoneNumberParserServlet extends HttpServlet { output.append("PhoneNumberToCarrierMapper Results"); appendLine( "Carrier", - PhoneNumberToCarrierMapper.getInstance().getDescriptionForNumber( + PhoneNumberToCarrierMapper.getInstance().getNameForNumber( number, new Locale(languageCode, regionCode)), output); output.append(""); diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java index 8ad8b808e..93c56e480 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java @@ -3132,4 +3132,20 @@ public class PhoneNumberUtil { String nationalSignificantNumber = getNationalSignificantNumber(number); return !isNumberMatchingDesc(nationalSignificantNumber, metadata.getNoInternationalDialling()); } + + /** + * Returns true if the supplied region supports mobile number portability. Returns false for + * invalid, unknown or regions that don't support mobile number portability. + * + * @param regionCode the region for which we want to know whether it supports mobile number + * portability or not. + */ + public boolean isMobileNumberPortableRegion(String regionCode) { + PhoneMetadata metadata = getMetadataForRegion(regionCode); + if (metadata == null) { + logger.log(Level.WARNING, "Invalid or unknown region code provided: " + regionCode); + return false; + } + return metadata.isMobileNumberPortableRegion(); + } } diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java index 3207709c9..b4759ec68 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java @@ -2473,4 +2473,11 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase { assertFalse(phoneUtil.isAlphaNumber("1800 123-1234 extension: 1234")); assertFalse(phoneUtil.isAlphaNumber("+800 1234-1234")); } + + public void testIsMobileNumberPortableRegion() { + assertTrue(phoneUtil.isMobileNumberPortableRegion(RegionCode.US)); + assertTrue(phoneUtil.isMobileNumberPortableRegion(RegionCode.GB)); + assertFalse(phoneUtil.isMobileNumberPortableRegion(RegionCode.AE)); + assertFalse(phoneUtil.isMobileNumberPortableRegion(RegionCode.BS)); + } } diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB index 883dde391..27a746d7b 100644 Binary files a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_GB differ diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US index de2108278..6058300b6 100644 Binary files a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US and b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_US differ diff --git a/java/release_notes.txt b/java/release_notes.txt index 336ef2807..a5fe8da81 100644 --- a/java/release_notes.txt +++ b/java/release_notes.txt @@ -1,3 +1,9 @@ +Oct 8, 2013: libphonenumber-5.8.7 +* Code changes: + - New method in the PhoneNumberUtil API - isMobileNumberPortableRegion. + - Carrier mapper: Updated API and added a getSafeDisplayName method that only returns the carrier + if it's safe to display to the user. + Oct 7, 2013: * Code changes: - Added PhoneNumberToTimeZonesMapper including unittests to the geocoder maven project. diff --git a/resources/PhoneNumberMetadataForTesting.xml b/resources/PhoneNumberMetadataForTesting.xml index 94fa98655..04d5729c4 100644 --- a/resources/PhoneNumberMetadataForTesting.xml +++ b/resources/PhoneNumberMetadataForTesting.xml @@ -282,7 +282,8 @@ + nationalPrefix="0" nationalPrefixFormattingRule="($NP$FG)" + mobileNumberPortableRegion="true"> [1-59]|[78]0 @@ -757,7 +758,8 @@ + mainCountryForCode="true" nationalPrefixOptionalWhenFormatting="true" + mobileNumberPortableRegion="true"> $1 $2