コード例 #1
0
        // Helper method to get the region code for a given phone number, from a list of possible region
        // codes. If the list contains more than one region, the first region for which the number is
        // valid is returned.
        private String getRegionCodeForShortNumberFromRegionList(PhoneNumber number,
                                                                 List <String> regionCodes)
        {
            if (regionCodes.size() == 0)
            {
                return(null);
            }
            else if (regionCodes.size() == 1)
            {
                return(regionCodes.get(0));
            }
            String nationalNumber = phoneUtil.getNationalSignificantNumber(number);

            foreach (String regionCode in regionCodes)
            {
                PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);
                if (phoneMetadata != null &&
                    phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getShortCode()))
                {
                    // The number is valid for this region.
                    return(regionCode);
                }
            }
            return(null);
        }
コード例 #2
0
        /**
         * Gets the expected cost category of a short number (however, nothing is implied about its
         * validity). If it is important that the number is valid, then its validity must first be checked
         * using {@link isValidShortNumber}. Note that emergency numbers are always considered toll-free.
         * Example usage:
         * <pre>{@code
         * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
         * ShortNumberInfo shortInfo = ShortNumberInfo.getInstance();
         * PhoneNumber number = phoneUtil.parse("110", "FR");
         * if (shortInfo.isValidShortNumber(number)) {
         *   ShortNumberInfo.ShortNumberCost cost = shortInfo.getExpectedCost(number);
         *   // Do something with the cost information here.
         * }}</pre>
         *
         * @param number the short number for which we want to know the expected cost category
         * @return the expected cost category of the short number. Returns UNKNOWN_COST if the number does
         *     not match a cost category. Note that an invalid number may match any cost category.
         */
        public ShortNumberCost getExpectedCost(PhoneNumber number)
        {
            List <String> regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
            String        regionCode  = getRegionCodeForShortNumberFromRegionList(number, regionCodes);

            // Note that regionCode may be null, in which case phoneMetadata will also be null.
            PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);

            if (phoneMetadata == null)
            {
                return(ShortNumberCost.UNKNOWN_COST);
            }
            String nationalNumber = phoneUtil.getNationalSignificantNumber(number);

            // The cost categories are tested in order of decreasing expense, since if for some reason the
            // patterns overlap the most expensive matching cost category should be returned.
            if (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getPremiumRate()))
            {
                return(ShortNumberCost.PREMIUM_RATE);
            }
            if (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getStandardRate()))
            {
                return(ShortNumberCost.STANDARD_RATE);
            }
            if (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getTollFree()))
            {
                return(ShortNumberCost.TOLL_FREE);
            }
            if (isEmergencyNumber(nationalNumber, regionCode))
            {
                // Emergency numbers are implicitly toll-free.
                return(ShortNumberCost.TOLL_FREE);
            }
            return(ShortNumberCost.UNKNOWN_COST);
        }
コード例 #3
0
 internal static boolean containsOnlyValidXChars(
     PhoneNumber number, String candidate, PhoneNumberUtil util)
 {
     // The characters 'x' and 'X' can be (1) a carrier code, in which case they always precede the
     // national significant number or (2) an extension sign, in which case they always precede the
     // extension number. We assume a carrier code is more than 1 digit, so the first case has to
     // have more than 1 consecutive 'x' or 'X', whereas the second case can only have exactly 1 'x'
     // or 'X'. We ignore the character if it appears as the last character of the string.
     for (int index = 0; index < candidate.length() - 1; index++)
     {
         char charAtIndex = candidate.charAt(index);
         if (charAtIndex == 'x' || charAtIndex == 'X')
         {
             char charAtNextIndex = candidate.charAt(index + 1);
             if (charAtNextIndex == 'x' || charAtNextIndex == 'X')
             {
                 // This is the carrier code case, in which the 'X's always precede the national
                 // significant number.
                 index++;
                 if (util.isNumberMatch(number, candidate.substring(index)) != MatchType.NSN_MATCH)
                 {
                     return(false);
                 }
                 // This is the extension sign case, in which the 'x' or 'X' should always precede the
                 // extension number.
             }
             else if (!PhoneNumberUtil.normalizeDigitsOnly(candidate.substring(index)).equals(
                          number.getExtension()))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
コード例 #4
0
        /**
         * Returns the description of the geographical area the {@code number} corresponds to. This method
         * distinguishes the case of an invalid prefix and a prefix for which the name is not available in
         * the current language. If the description is not available in the current language an empty
         * string is returned. If no description was found for the provided number, null is returned.
         *
         * @param number  the phone number to look up
         * @return  the description of the geographical area
         */
        internal String lookup(PhoneNumber number)
        {
            int numOfEntries = areaCodeMapStorage.getNumOfEntries();

            if (numOfEntries == 0)
            {
                return(null);
            }
            long phonePrefix =
                Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number));
            int currentIndex = numOfEntries - 1;
            SortedSet <Integer> currentSetOfLengths = areaCodeMapStorage.getPossibleLengths();

            while (currentSetOfLengths.size() > 0)
            {
                Integer possibleLength = currentSetOfLengths.last();
                String  phonePrefixStr = String.valueOf(phonePrefix);
                if (phonePrefixStr.length() > possibleLength)
                {
                    phonePrefix = Long.parseLong(phonePrefixStr.substring(0, possibleLength));
                }
                currentIndex = binarySearch(0, currentIndex, phonePrefix);
                if (currentIndex < 0)
                {
                    return(null);
                }
                int currentPrefix = areaCodeMapStorage.getPrefix(currentIndex);
                if (phonePrefix == currentPrefix)
                {
                    return(areaCodeMapStorage.getDescription(currentIndex));
                }
                currentSetOfLengths = currentSetOfLengths.headSet(possibleLength);
            }
            return(null);
        }
コード例 #5
0
 /**
  * Helper method to get the national-number part of a number, formatted without any national
  * prefix, and return it as a set of digit blocks that would be formatted together.
  */
 private static String[] getNationalNumberGroups(PhoneNumberUtil util, PhoneNumber number,
                                                 NumberFormat formattingPattern)
 {
     if (formattingPattern == null)
     {
         // This will be in the format +CC-DG;ext=EXT where DG represents groups of digits.
         String rfc3966Format = util.format(number, PhoneNumberFormat.RFC3966);
         // We remove the extension part from the formatted string before splitting it into different
         // groups.
         int endIndex = rfc3966Format.indexOf(';');
         if (endIndex < 0)
         {
             endIndex = rfc3966Format.length();
         }
         // The country-code will have a '-' following it.
         int startIndex = rfc3966Format.indexOf('-') + 1;
         return(rfc3966Format.substring(startIndex, endIndex).split("-"));
     }
     else
     {
         // We format the NSN only, and split that according to the separator.
         String nationalSignificantNumber = util.getNationalSignificantNumber(number);
         return(util.formatNsnUsingPattern(nationalSignificantNumber,
                                           formattingPattern, PhoneNumberFormat.RFC3966).split("-"));
     }
 }
コード例 #6
0
 /**
  * @param exampleNumberRequestedType  type we are requesting an example number for
  * @param possibleExpectedTypes       acceptable types that this number should match, such as
  *     FIXED_LINE and FIXED_LINE_OR_MOBILE for a fixed line example number.
  */
 private void checkNumbersValidAndCorrectType(PhoneNumberType exampleNumberRequestedType,
                                              Set <PhoneNumberType> possibleExpectedTypes)
 {
     foreach (String regionCode in phoneNumberUtil.getSupportedRegions())
     {
         PhoneNumber exampleNumber =
             phoneNumberUtil.getExampleNumberForType(regionCode, exampleNumberRequestedType);
         if (exampleNumber != null)
         {
             if (!phoneNumberUtil.isValidNumber(exampleNumber))
             {
                 invalidCases.add(exampleNumber);
                 LOGGER.log(Level.SEVERE, "Failed validation for " + exampleNumber.toString());
             }
             else
             {
                 // We know the number is valid, now we check the type.
                 PhoneNumberType exampleNumberType = phoneNumberUtil.getNumberType(exampleNumber);
                 if (!possibleExpectedTypes.contains(exampleNumberType))
                 {
                     wrongTypeCases.add(exampleNumber);
                     LOGGER.log(Level.SEVERE, "Wrong type for " +
                                exampleNumber.toString() +
                                ": got " + exampleNumberType);
                     LOGGER.log(Level.WARNING, "Expected types: ");
                     foreach (PhoneNumberType type in possibleExpectedTypes)
                     {
                         LOGGER.log(Level.WARNING, type.ToString());
                     }
                 }
             }
         }
     }
 }
コード例 #7
0
        /**
         * Returns an area-level text description in the given language for the given phone number.
         *
         * @param number  the phone number for which we want to get a text description
         * @param lang  two-letter lowercase ISO language codes as defined by ISO 639-1
         * @param script  four-letter titlecase (the first letter is uppercase and the rest of the letters
         *     are lowercase) ISO script codes as defined in ISO 15924
         * @param region  two-letter uppercase ISO country codes as defined by ISO 3166-1
         * @return  an area-level text description in the given language for the given phone number, or an
         *     empty string if such a description is not available
         */
        private String getAreaDescriptionForNumber(
            PhoneNumber number, String lang, String script, String region)
        {
            int countryCallingCode = number.getCountryCode();
            // As the NANPA data is split into multiple files covering 3-digit areas, use a phone number
            // prefix of 4 digits for NANPA instead, e.g. 1650.
            int phonePrefix = (countryCallingCode != 1) ?
                              countryCallingCode : (1000 + (int)(number.getNationalNumber() / 10000000));
            AreaCodeMap phonePrefixDescriptions =
                getPhonePrefixDescriptions(phonePrefix, lang, script, region);
            String description = (phonePrefixDescriptions != null)
        ? phonePrefixDescriptions.lookup(number)
        : null;

            // When a location is not available in the requested language, fall back to English.
            if ((description == null || description.length() == 0) && mayFallBackToEnglish(lang))
            {
                AreaCodeMap defaultMap = getPhonePrefixDescriptions(phonePrefix, "en", "", "");
                if (defaultMap == null)
                {
                    return("");
                }
                description = defaultMap.lookup(number);
            }
            return(description != null ? (string)description : "");
        }
コード例 #8
0
        internal static boolean containsMoreThanOneSlashInNationalNumber(PhoneNumber number, String candidate)
        {
            int firstSlashInBodyIndex = candidate.indexOf('/');

            if (firstSlashInBodyIndex < 0)
            {
                // No slashes, this is okay.
                return(false);
            }
            // Now look for a second one.
            int secondSlashInBodyIndex = candidate.indexOf('/', firstSlashInBodyIndex + 1);

            if (secondSlashInBodyIndex < 0)
            {
                // Only one slash, this is okay.
                return(false);
            }

            // If the first slash is after the country calling code, this is permitted.
            boolean candidateHasCountryCode =
                (number.getCountryCodeSource() == CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN ||
                 number.getCountryCodeSource() == CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);

            if (candidateHasCountryCode &&
                PhoneNumberUtil.normalizeDigitsOnly(candidate.substring(0, firstSlashInBodyIndex))
                .equals(Integer.toString(number.getCountryCode())))
            {
                // Any more slashes and this is illegal.
                return(candidate.substring(secondSlashInBodyIndex + 1).contains("/"));
            }
            return(true);
        }
コード例 #9
0
        internal static boolean checkNumberGroupingIsValid(
            PhoneNumber number, String 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 =
                PhoneNumberUtil.normalizeDigits(candidate, true /* keep non-digits */);

            String[] formattedNumberGroups = getNationalNumberGroups(util, number, null);
            if (checker.checkGroups(util, number, normalizedCandidate, formattedNumberGroups))
            {
                return(true);
            }
            // If this didn't pass, see if there are any alternate formats, and try them instead.
            PhoneMetadata alternateFormats =
                MetadataManager.getAlternateFormatsForCountry(number.getCountryCode());

            if (alternateFormats != null)
            {
                foreach (NumberFormat alternateFormat in alternateFormats.numberFormats())
                {
                    formattedNumberGroups = getNationalNumberGroups(util, number, alternateFormat);
                    if (checker.checkGroups(util, number, normalizedCandidate, formattedNumberGroups))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #10
0
 [TestMethod] public void testEveryRegionHasAnExampleNumber()
 {
     foreach (String regionCode in phoneNumberUtil.getSupportedRegions())
     {
         PhoneNumber exampleNumber = phoneNumberUtil.getExampleNumber(regionCode);
         assertNotNull("None found for region " + regionCode, exampleNumber);
     }
 }
コード例 #11
0
        /**
         * Given a valid short number, determines whether it is carrier-specific (however, nothing is
         * implied about its validity). If it is important that the number is valid, then its validity
         * must first be checked using {@link isValidShortNumber}.
         *
         * @param number the valid short number to check
         * @return whether the short number is carrier-specific (assuming the input was a valid short
         *     number).
         */
        public boolean isCarrierSpecific(PhoneNumber number)
        {
            List <String> regionCodes    = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
            String        regionCode     = getRegionCodeForShortNumberFromRegionList(number, regionCodes);
            String        nationalNumber = phoneUtil.getNationalSignificantNumber(number);
            PhoneMetadata phoneMetadata  = MetadataManager.getShortNumberMetadataForRegion(regionCode);

            return((phoneMetadata != null) &&
                   (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getCarrierSpecific())));
        }
コード例 #12
0
        public void testEqualSimpleNumber()
        {
            PhoneNumber numberA = new PhoneNumber();
            numberA.setCountryCode(1).setNationalNumber(6502530000L);

            PhoneNumber numberB = new PhoneNumber();
            numberB.setCountryCode(1).setNationalNumber(6502530000L);

            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #13
0
 public void testEqualWithCountryCodeSourceSet()
 {
     PhoneNumber numberA = new PhoneNumber();
     numberA.setRawInput("+1 650 253 00 00").
     setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
     PhoneNumber numberB = new PhoneNumber();
     numberB.setRawInput("+1 650 253 00 00").
     setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
     assertEquals(numberA, numberB);
     assertEquals(numberA.hashCode(), numberB.hashCode());
 }
コード例 #14
0
        /**
         * Returns a text description for the given phone number, in the language provided. The
         * description might consist of the name of the country where the phone number is from, or the
         * name of the geographical area the phone number is from if more detailed information is
         * available.
         *
         * <p>This method assumes the validity of the number passed in has already been checked, and that
         * the number is suitable for geocoding. We consider fixed-line and mobile numbers possible
         * candidates for geocoding.
         *
         * @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
         */
        public String getDescriptionForValidNumber(PhoneNumber number, Locale languageCode)
        {
            String langStr   = languageCode.getLanguage();
            String scriptStr = ""; // No script is specified
            String regionStr = languageCode.getCountry();

            String areaDescription =
                getAreaDescriptionForNumber(number, langStr, scriptStr, regionStr);

            return((areaDescription.length() > 0)
        ? areaDescription : getCountryNameForNumber(number, languageCode));
        }
コード例 #15
0
 /**
    * Creates a new match.
    *
    * @param start  the start index into the target text
    * @param rawString  the matched substring of the target text
    * @param number  the matched phone number
    */
 internal PhoneNumberMatch(int start, String rawString, PhoneNumber number)
 {
     if (start < 0) {
       throw new IllegalArgumentException("Start index must be >= 0.");
     }
     if (rawString == null || number == null) {
       throw new NullPointerException();
     }
     this._start = start;
     this._rawString = rawString;
     this._number = number;
 }
コード例 #16
0
        /**
         * Parses a phone number from the {@code candidate} using {@link PhoneNumberUtil#parse} and
         * verifies it matches the requested {@link #leniency}. If parsing and verification succeed, a
         * corresponding {@link PhoneNumberMatch} is returned, otherwise this method returns null.
         *
         * @param candidate  the candidate match
         * @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)
        {
            try {
                // Check the candidate doesn't contain any formatting which would indicate that it really
                // isn't a phone number.
                if (!MATCHING_BRACKETS.matcher(candidate).matches())
                {
                    return(null);
                }

                // If leniency is set to VALID or stricter, we also want to skip numbers that are surrounded
                // by Latin alphabetic characters, to skip cases like abc8005001234 or 8005001234def.
                if (leniency.compareTo(Leniency.VALID) >= 0)
                {
                    // If the candidate is not at the start of the text, and does not start with phone-number
                    // punctuation, check the previous character.
                    if (offset > 0 && !LEAD_CLASS.matcher(candidate).lookingAt())
                    {
                        char previousChar = text.charAt(offset - 1);
                        // We return null if it is a latin letter or an invalid punctuation symbol.
                        if (isInvalidPunctuationSymbol(previousChar) || isLatinLetter(previousChar))
                        {
                            return(null);
                        }
                    }
                    int lastCharIndex = offset + candidate.length();
                    if (lastCharIndex < text.length())
                    {
                        char nextChar = text.charAt(lastCharIndex);
                        if (isInvalidPunctuationSymbol(nextChar) || isLatinLetter(nextChar))
                        {
                            return(null);
                        }
                    }
                }

                PhoneNumber number = phoneUtil.parseAndKeepRawInput(candidate, preferredRegion);
                if (leniency.verify(number, candidate, phoneUtil))
                {
                    // We used parseAndKeepRawInput to create this number, but for now we don't return the extra
                    // values parsed. TODO: stop clearing all values here and switch all users over
                    // to using rawInput() rather than the rawString() of PhoneNumberMatch.
                    number.clearCountryCodeSource();
                    number.clearRawInput();
                    number.clearPreferredDomesticCarrierCode();
                    return(new PhoneNumberMatch(offset, candidate, number));
                }
            } catch (NumberParseException) {
                // ignore and continue
            }
            return(null);
        }
コード例 #17
0
        [TestMethod] public void testEqualWithPreferredDomesticCarrierCodeSetToDefault()
        {
            PhoneNumber numberA = new PhoneNumber();

            numberA.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");

            PhoneNumber numberB = new PhoneNumber();

            numberB.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");

            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #18
0
        [TestMethod] public void testEqualSimpleNumber()
        {
            PhoneNumber numberA = new PhoneNumber();

            numberA.setCountryCode(1).setNationalNumber(6502530000L);

            PhoneNumber numberB = new PhoneNumber();

            numberB.setCountryCode(1).setNationalNumber(6502530000L);

            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #19
0
        [TestMethod] public void testEqualWithCountryCodeSourceSet()
        {
            PhoneNumber numberA = new PhoneNumber();

            numberA.setRawInput("+1 650 253 00 00").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
            PhoneNumber numberB = new PhoneNumber();

            numberB.setRawInput("+1 650 253 00 00").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #20
0
        [TestMethod] public void testNonEqualWithItalianLeadingZeroSetToTrue()
        {
            PhoneNumber numberA = new PhoneNumber();

            numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(true);

            PhoneNumber numberB = new PhoneNumber();

            numberB.setCountryCode(1).setNationalNumber(6502530000L);

            assertFalse(numberA.equals(numberB));
            assertFalse(numberA.hashCode() == numberB.hashCode());
        }
コード例 #21
0
        [TestMethod] public void testEqualWithItalianLeadingZeroSetToDefault()
        {
            PhoneNumber numberA = new PhoneNumber();

            numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(false);

            PhoneNumber numberB = new PhoneNumber();

            numberB.setCountryCode(1).setNationalNumber(6502530000L);

            // These should still be equal, since the default value for this field is false.
            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #22
0
        /**
         * Check whether a short number is a possible number. This provides a more lenient check than
         * {@link #isValidShortNumber}. See {@link #isPossibleShortNumber(String, String)} for
         * details.
         *
         * @param number the short number to check
         * @return whether the number is a possible short number
         */
        public boolean isPossibleShortNumber(PhoneNumber number)
        {
            List <String> regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
            String        shortNumber = phoneUtil.getNationalSignificantNumber(number);
            String        regionCode  = getRegionCodeForShortNumberFromRegionList(number, regionCodes);

            if (regionCodes.size() > 1 && regionCode != null)
            {
                // If a matching region had been found for the phone number from among two or more regions,
                // then we have already implicitly verified its validity for that region.
                return(true);
            }
            return(isPossibleShortNumber(shortNumber, regionCode));
        }
コード例 #23
0
        [TestMethod] public void testIsPossibleShortNumber()
        {
            PhoneNumber possibleNumber = new PhoneNumber();

            possibleNumber.setCountryCode(33).setNationalNumber(123456L);
            assertTrue(shortInfo.isPossibleShortNumber(possibleNumber));
            assertTrue(shortInfo.isPossibleShortNumber("123456", RegionCode.FR));

            PhoneNumber impossibleNumber = new PhoneNumber();

            impossibleNumber.setCountryCode(33).setNationalNumber(9L);
            assertFalse(shortInfo.isPossibleShortNumber(impossibleNumber));
            assertFalse(shortInfo.isPossibleShortNumber("9", RegionCode.FR));
        }
コード例 #24
0
        /**
         * As per {@link #getDescriptionForValidNumber(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
         */
        public String getDescriptionForNumber(PhoneNumber number, Locale languageCode)
        {
            PhoneNumberType numberType = phoneUtil.getNumberType(number);

            if (numberType == PhoneNumberType.UNKNOWN)
            {
                return("");
            }
            else if (!canBeGeocoded(numberType))
            {
                return(getCountryNameForNumber(number, languageCode));
            }
            return(getDescriptionForValidNumber(number, languageCode));
        }
コード例 #25
0
 /**
  * Creates a new match.
  *
  * @param start  the start index into the target text
  * @param rawString  the matched substring of the target text
  * @param number  the matched phone number
  */
 internal PhoneNumberMatch(int start, String rawString, PhoneNumber number)
 {
     if (start < 0)
     {
         throw new IllegalArgumentException("Start index must be >= 0.");
     }
     if (rawString == null || number == null)
     {
         throw new NullPointerException();
     }
     this._start     = start;
     this._rawString = rawString;
     this._number    = number;
 }
コード例 #26
0
        /**
         * Tests the value type semantics. Equality and hash code must be based on the covered range and
         * corresponding phone number. Range and number correctness are tested by
         * {@link PhoneNumberMatcherTest}.
         */
        [TestMethod] public void testValueTypeSemantics()
        {
            PhoneNumber      number = new PhoneNumber();
            PhoneNumberMatch match1 = new PhoneNumberMatch(10, "1 800 234 45 67", number);
            PhoneNumberMatch match2 = new PhoneNumberMatch(10, "1 800 234 45 67", number);

            assertEquals(match1, match2);
            assertEquals(match1.hashCode(), match2.hashCode());
            assertEquals(match1.start(), match2.start());
            assertEquals(match1.end(), match2.end());
            assertEquals(match1.number(), match2.number());
            assertEquals(match1.rawString(), match2.rawString());
            assertEquals("1 800 234 45 67", match1.rawString());
        }
コード例 #27
0
 [TestMethod] public void testGlobalNetworkNumbers()
 {
     foreach (Integer callingCode in phoneNumberUtil.getSupportedGlobalNetworkCallingCodes())
     {
         PhoneNumber exampleNumber =
             phoneNumberUtil.getExampleNumberForNonGeoEntity(callingCode);
         assertNotNull("No example phone number for calling code " + callingCode, exampleNumber);
         if (!phoneNumberUtil.isValidNumber(exampleNumber))
         {
             invalidCases.add(exampleNumber);
             LOGGER.log(Level.SEVERE, "Failed validation for " + exampleNumber.toString());
         }
     }
     assertEquals(0, invalidCases.size());
 }
コード例 #28
0
        [TestMethod] public void testGetExpectedCost()
        {
            PhoneNumber premiumRateNumber = new PhoneNumber();

            premiumRateNumber.setCountryCode(33).setNationalNumber(
                Integer.parseInt(shortInfo.getExampleShortNumberForCost(
                                     RegionCode.FR, ShortNumberInfo.ShortNumberCost.PREMIUM_RATE)));
            assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE,
                         shortInfo.getExpectedCost(premiumRateNumber));

            PhoneNumber standardRateNumber = new PhoneNumber();

            standardRateNumber.setCountryCode(33).setNationalNumber(
                Integer.parseInt(shortInfo.getExampleShortNumberForCost(
                                     RegionCode.FR, ShortNumberInfo.ShortNumberCost.STANDARD_RATE)));
            assertEquals(ShortNumberInfo.ShortNumberCost.STANDARD_RATE,
                         shortInfo.getExpectedCost(standardRateNumber));

            PhoneNumber tollFreeNumber = new PhoneNumber();

            tollFreeNumber.setCountryCode(33).setNationalNumber(
                Integer.parseInt(shortInfo.getExampleShortNumberForCost(
                                     RegionCode.FR, ShortNumberInfo.ShortNumberCost.TOLL_FREE)));
            assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE,
                         shortInfo.getExpectedCost(tollFreeNumber));

            PhoneNumber unknownCostNumber = new PhoneNumber();

            unknownCostNumber.setCountryCode(33).setNationalNumber(12345L);
            assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST,
                         shortInfo.getExpectedCost(unknownCostNumber));

            // Test that an invalid number may nevertheless have a cost other than UNKNOWN_COST.
            PhoneNumber invalidNumber = new PhoneNumber();

            invalidNumber.setCountryCode(33).setNationalNumber(116123L);
            assertFalse(shortInfo.isValidShortNumber(invalidNumber));
            assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE,
                         shortInfo.getExpectedCost(invalidNumber));

            // Test a non-existent country code.
            unknownCostNumber.clear();
            unknownCostNumber.setCountryCode(123).setNationalNumber(911L);
            assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST,
                         shortInfo.getExpectedCost(unknownCostNumber));
        }
コード例 #29
0
        /**
         * As per {@link #getDescriptionForValidNumber(PhoneNumber, Locale)} but also considers the
         * region of the user. If the phone number is from the same region as the user, only a lower-level
         * description will be returned, if one exists. Otherwise, the phone number's region will be
         * returned, with optionally some more detailed information.
         *
         * <p>For example, for a user from the region "US" (United States), we would show "Mountain View,
         * CA" for a particular number, omitting the United States from the description. For a user from
         * the United Kingdom (region "GB"), for the same number we may show "Mountain View, CA, United
         * States" or even just "United States".
         *
         * <p>This method assumes the validity of the number passed in has already been checked.
         *
         * @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
         * @param userRegion  the region code for a given user. This region will be omitted from the
         *     description if the phone number comes from this region. It is a two-letter uppercase ISO
         *     country code as defined by ISO 3166-1.
         * @return  a text description for the given language code for the given phone number, or empty
         *     string if the number passed in is invalid
         */
        public String getDescriptionForValidNumber(PhoneNumber number, Locale languageCode,
                                                   String userRegion)
        {
            // If the user region matches the number's region, then we just show the lower-level
            // description, if one exists - if no description exists, we will show the region(country) name
            // for the number.
            String regionCode = phoneUtil.getRegionCodeForNumber(number);

            if (userRegion.equals(regionCode))
            {
                return(getDescriptionForValidNumber(number, languageCode));
            }
            // Otherwise, we just show the region(country) name for now.
            return(getRegionDisplayName(regionCode, languageCode));
            // TODO: Concatenate the lower-level and country-name information in an appropriate
            // way for each language.
        }
コード例 #30
0
        [TestMethod] public void testNonEqualWithDifferingRawInput()
        {
            PhoneNumber numberA = new PhoneNumber();

            numberA.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1 650 253 00 00").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);

            PhoneNumber numberB = new PhoneNumber();

            // Although these numbers would pass an isNumberMatch test, they are not considered "equal" as
            // objects, since their raw input is different.
            numberB.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1-650-253-00-00").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);

            assertFalse(numberA.equals(numberB));
            assertFalse(numberA.hashCode() == numberB.hashCode());
        }
コード例 #31
0
        internal static boolean isNationalPrefixPresentIfRequired(PhoneNumber number, PhoneNumberUtil util)
        {
            // First, check how we deduced the country code. If it was written in international format, then
            // the national prefix is not required.
            if (number.getCountryCodeSource() != CountryCodeSource.FROM_DEFAULT_COUNTRY)
            {
                return(true);
            }
            String phoneNumberRegion =
                util.getRegionCodeForCountryCode(number.getCountryCode());
            PhoneMetadata metadata = util.getMetadataForRegion(phoneNumberRegion);

            if (metadata == null)
            {
                return(true);
            }
            // Check if a national prefix should be present when formatting this number.
            String       nationalNumber = util.getNationalSignificantNumber(number);
            NumberFormat formatRule     =
                util.chooseFormattingPatternForNumber(metadata.numberFormats(), nationalNumber);

            // To do this, we check that a national prefix formatting rule was present and that it wasn't
            // just the first-group symbol ($1) with punctuation.
            if ((formatRule != null) && formatRule.getNationalPrefixFormattingRule().length() > 0)
            {
                if (formatRule.isNationalPrefixOptionalWhenFormatting())
                {
                    // The national-prefix is optional in these cases, so we don't need to check if it was
                    // present.
                    return(true);
                }
                if (PhoneNumberUtil.formattingRuleHasFirstGroupOnly(
                        formatRule.getNationalPrefixFormattingRule()))
                {
                    // National Prefix not needed for this number.
                    return(true);
                }
                // Normalize the remainder.
                String        rawInputCopy = PhoneNumberUtil.normalizeDigitsOnly(number.getRawInput());
                StringBuilder rawInput     = new StringBuilder(rawInputCopy);
                // Check if we found a national prefix and/or carrier code at the start of the raw input, and
                // return the result.
                return(util.maybeStripNationalPrefixAndCarrierCode(rawInput, metadata, null));
            }
            return(true);
        }
コード例 #32
0
        [TestMethod] public void testShortNumbersValidAndCorrectCost()
        {
            List <String> invalidStringCases = new ArrayList <String>();

            foreach (String regionCode in shortNumberInfo.getSupportedRegions())
            {
                if (regionCode == RegionCode.PG)
                {
                    // The only short number for Papua New Guinea is 000, which fails the test, since the
                    // national prefix is 0. This needs to be fixed.
                    continue;
                }
                String exampleShortNumber = shortNumberInfo.getExampleShortNumber(regionCode);
                if (!shortNumberInfo.isValidShortNumber(exampleShortNumber, regionCode))
                {
                    String invalidStringCase = "region_code: " + regionCode + ", national_number: " +
                                               exampleShortNumber;
                    invalidStringCases.add(invalidStringCase);
                    LOGGER.log(Level.SEVERE, "Failed validation for string " + invalidStringCase);
                }
                PhoneNumber phoneNumber = phoneNumberUtil.parse(exampleShortNumber, regionCode);
                if (!shortNumberInfo.isValidShortNumber(phoneNumber))
                {
                    invalidCases.add(phoneNumber);
                    LOGGER.log(Level.SEVERE, "Failed validation for " + phoneNumber.toString());
                }

                foreach (ShortNumberInfo.ShortNumberCost cost in System.Enum.GetValues(typeof(ShortNumberInfo.ShortNumberCost)))
                {
                    exampleShortNumber = shortNumberInfo.getExampleShortNumberForCost(regionCode, cost);
                    if (!exampleShortNumber.equals(""))
                    {
                        phoneNumber = phoneNumberUtil.parse(exampleShortNumber, regionCode);
                        if (cost != shortNumberInfo.getExpectedCost(phoneNumber))
                        {
                            wrongTypeCases.add(phoneNumber);
                            LOGGER.log(Level.SEVERE, "Wrong cost for " + phoneNumber.toString());
                        }
                    }
                }
            }
            assertEquals(0, invalidStringCases.size());
            assertEquals(0, invalidCases.size());
            assertEquals(0, wrongTypeCases.size());
        }
コード例 #33
0
        internal static boolean allNumberGroupsRemainGrouped(PhoneNumberUtil util,
                                                             PhoneNumber number,
                                                             StringBuilder normalizedCandidate,
                                                             String[] formattedNumberGroups)
        {
            int fromIndex = 0;

            // Check each group of consecutive digits are not broken into separate groupings in the
            // {@code normalizedCandidate} string.
            for (int i = 0; i < formattedNumberGroups.length(); i++)
            {
                // Fails if the substring of {@code normalizedCandidate} starting from {@code fromIndex}
                // doesn't contain the consecutive digits in formattedNumberGroups[i].
                fromIndex = normalizedCandidate.indexOf(formattedNumberGroups[i], fromIndex);
                if (fromIndex < 0)
                {
                    return(false);
                }
                // Moves {@code fromIndex} forward.
                fromIndex += formattedNumberGroups[i].length();
                if (i == 0 && fromIndex < normalizedCandidate.length())
                {
                    // We are at the position right after the NDC. We get the region used for formatting
                    // information based on the country code in the phone number, rather than the number itself,
                    // as we do not need to distinguish between different countries with the same country
                    // calling code and this is faster.
                    String region = util.getRegionCodeForCountryCode(number.getCountryCode());
                    if (util.getNddPrefixForRegion(region, true) != null &&
                        Character.isDigit(normalizedCandidate.charAt(fromIndex)))
                    {
                        // This means there is no formatting symbol after the NDC. In this case, we only
                        // accept the number if there is no formatting symbol at all in the number, except
                        // for extensions. This is only important for countries with national prefixes.
                        String nationalSignificantNumber = util.getNationalSignificantNumber(number);
                        return(normalizedCandidate.substring(fromIndex - formattedNumberGroups[i].length())
                               .startsWith(nationalSignificantNumber));
                    }
                }
            }
            // The check here makes sure that we haven't mistakenly already used the extension to
            // match the last group of the subscriber number. Note the extension cannot have
            // formatting in-between digits.
            return(normalizedCandidate.substring(fromIndex).contains(number.getExtension()));
        }
コード例 #34
0
        public void testParseNumbersMexico()
        {
            // Test parsing fixed-line numbers of Mexico.
            PhoneNumber mxNumber = new PhoneNumber();
            mxNumber.setCountryCode(52).setNationalNumber(4499780001L);
            assertEquals(mxNumber, phoneUtil.parse("+52 (449)978-0001", RegionCode.MX));
            assertEquals(mxNumber, phoneUtil.parse("01 (449)978-0001", RegionCode.MX));
            assertEquals(mxNumber, phoneUtil.parse("(449)978-0001", RegionCode.MX));

            // Test parsing mobile numbers of Mexico.
            mxNumber.clear();
            mxNumber.setCountryCode(52).setNationalNumber(13312345678L);
            assertEquals(mxNumber, phoneUtil.parse("+52 1 33 1234-5678", RegionCode.MX));
            assertEquals(mxNumber, phoneUtil.parse("044 (33) 1234-5678", RegionCode.MX));
            assertEquals(mxNumber, phoneUtil.parse("045 33 1234-5678", RegionCode.MX));
        }
コード例 #35
0
        public void testFormatOutOfCountryCallingNumber()
        {
            assertEquals("00 1 900 253 0000",
                 phoneUtil.formatOutOfCountryCallingNumber(US_PREMIUM, RegionCode.DE));

            assertEquals("1 650 253 0000",
                 phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.BS));

            assertEquals("00 1 650 253 0000",
                 phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.PL));

            assertEquals("011 44 7912 345 678",
                 phoneUtil.formatOutOfCountryCallingNumber(GB_MOBILE, RegionCode.US));

            assertEquals("00 49 1234",
                 phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.GB));
            // Note this number is correctly formatted without national prefix. Most of the numbers that
            // are treated as invalid numbers by the library are short numbers, and they are usually not
            // dialed with national prefix.
            assertEquals("1234", phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.DE));

            assertEquals("011 39 02 3661 8300",
                 phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.US));
            assertEquals("02 3661 8300",
                 phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.IT));
            assertEquals("+39 02 3661 8300",
                 phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.SG));

            assertEquals("6521 8000",
                 phoneUtil.formatOutOfCountryCallingNumber(SG_NUMBER, RegionCode.SG));

            assertEquals("011 54 9 11 8765 4321",
                 phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, RegionCode.US));
            assertEquals("011 800 1234 5678",
                 phoneUtil.formatOutOfCountryCallingNumber(INTERNATIONAL_TOLL_FREE, RegionCode.US));

            PhoneNumber arNumberWithExtn = new PhoneNumber().mergeFrom(AR_MOBILE).setExtension("1234");
            assertEquals("011 54 9 11 8765 4321 ext. 1234",
                 phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.US));
            assertEquals("0011 54 9 11 8765 4321 ext. 1234",
                 phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AU));
            assertEquals("011 15 8765-4321 ext. 1234",
                 phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AR));
        }
コード例 #36
0
        public void testParseNumbersWithPlusWithNoRegion()
        {
            // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country calling code
            // can be calculated.
            assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.ZZ));
            // Test with full-width plus.
            assertEquals(NZ_NUMBER, phoneUtil.parse("\uFF0B64 3 331 6005", RegionCode.ZZ));
            // Test with normal plus but leading characters that need to be stripped.
            assertEquals(NZ_NUMBER, phoneUtil.parse("Tel: +64 3 331 6005", RegionCode.ZZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", null));
            assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.parse("+800 1234 5678", null));
            assertEquals(UNIVERSAL_PREMIUM_RATE, phoneUtil.parse("+979 123 456 789", null));

            // Test parsing RFC3966 format with a phone context.
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;phone-context=+64", RegionCode.ZZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("  tel:03-331-6005;phone-context=+64", RegionCode.ZZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;isub=12345;phone-context=+64",
            RegionCode.ZZ));

            // It is important that we set the carrier code to an empty string, since we used
            // ParseAndKeepRawInput and no carrier code was found.
            PhoneNumber nzNumberWithRawInput = new PhoneNumber().mergeFrom(NZ_NUMBER).
            setRawInput("+64 3 331 6005").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).
            setPreferredDomesticCarrierCode("");
            assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005",
                                                                      RegionCode.ZZ));
            // Null is also allowed for the region code in these cases.
            assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", null));
        }
コード例 #37
0
        public void testFormatOutOfCountryKeepingAlphaChars()
        {
            PhoneNumber alphaNumericNumber = new PhoneNumber();
            alphaNumericNumber.setCountryCode(1).setNationalNumber(8007493524L)
            .setRawInput("1800 six-flag");
            assertEquals("0011 1 800 SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            alphaNumericNumber.setRawInput("1-800-SIX-flag");
            assertEquals("0011 1 800-SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            alphaNumericNumber.setRawInput("Call us from UK: 00 1 800 SIX-flag");
            assertEquals("0011 1 800 SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            alphaNumericNumber.setRawInput("800 SIX-flag");
            assertEquals("0011 1 800 SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            // Formatting from within the NANPA region.
            assertEquals("1 800 SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.US));

            assertEquals("1 800 SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.BS));

            // Testing that if the raw input doesn't exist, it is formatted using
            // formatOutOfCountryCallingNumber.
            alphaNumericNumber.clearRawInput();
            assertEquals("00 1 800 749 3524",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));

            // Testing AU alpha number formatted from Australia.
            alphaNumericNumber.setCountryCode(61).setNationalNumber(827493524L)
            .setRawInput("+61 82749-FLAG");
            // This number should have the national prefix fixed.
            assertEquals("082749-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            alphaNumericNumber.setRawInput("082749-FLAG");
            assertEquals("082749-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            alphaNumericNumber.setNationalNumber(18007493524L).setRawInput("1-800-SIX-flag");
            // This number should not have the national prefix prefixed, in accordance with the override for
            // this specific formatting rule.
            assertEquals("1-800-SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));

            // The metadata should not be permanently changed, since we copied it before modifying patterns.
            // Here we check this.
            alphaNumericNumber.setNationalNumber(1800749352L);
            assertEquals("1800 749 352",
                 phoneUtil.formatOutOfCountryCallingNumber(alphaNumericNumber, RegionCode.AU));

            // Testing a region with multiple international prefixes.
            assertEquals("+61 1-800-SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.SG));
            // Testing the case of calling from a non-supported region.
            assertEquals("+61 1-800-SIX-FLAG",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AQ));

            // Testing the case with an invalid country calling code.
            alphaNumericNumber.setCountryCode(0).setNationalNumber(18007493524L)
            .setRawInput("1-800-SIX-flag");
            // Uses the raw input only.
            assertEquals("1-800-SIX-flag",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));

            // Testing the case of an invalid alpha number.
            alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
            // No country-code stripping can be done.
            assertEquals("00 1 180-SIX",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));

            // Testing the case of calling from a non-supported region.
            alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
            // No country-code stripping can be done since the number is invalid.
            assertEquals("+1 180-SIX",
                 phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AQ));
        }
コード例 #38
0
 /**
    * Returns the description of the geographical area the {@code number} corresponds to. This method
    * distinguishes the case of an invalid prefix and a prefix for which the name is not available in
    * the current language. If the description is not available in the current language an empty
    * string is returned. If no description was found for the provided number, null is returned.
    *
    * @param number  the phone number to look up
    * @return  the description of the geographical area
    */
 internal String lookup(PhoneNumber number)
 {
     int numOfEntries = areaCodeMapStorage.getNumOfEntries();
     if (numOfEntries == 0) {
       return null;
     }
     long phonePrefix =
     Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number));
     int currentIndex = numOfEntries - 1;
     SortedSet<Integer> currentSetOfLengths = areaCodeMapStorage.getPossibleLengths();
     while (currentSetOfLengths.size() > 0) {
       Integer possibleLength = currentSetOfLengths.last();
       String phonePrefixStr = String.valueOf(phonePrefix);
       if (phonePrefixStr.length() > possibleLength) {
     phonePrefix = Long.parseLong(phonePrefixStr.substring(0, possibleLength));
       }
       currentIndex = binarySearch(0, currentIndex, phonePrefix);
       if (currentIndex < 0) {
     return null;
       }
       int currentPrefix = areaCodeMapStorage.getPrefix(currentIndex);
       if (phonePrefix == currentPrefix) {
     return areaCodeMapStorage.getDescription(currentIndex);
       }
       currentSetOfLengths = currentSetOfLengths.headSet(possibleLength);
     }
     return null;
 }
コード例 #39
0
        public void testTruncateTooLongNumber()
        {
            // GB number 080 1234 5678, but entered with 4 extra digits at the end.
            PhoneNumber tooLongNumber = new PhoneNumber();
            tooLongNumber.setCountryCode(44).setNationalNumber(80123456780123L);
            PhoneNumber validNumber = new PhoneNumber();
            validNumber.setCountryCode(44).setNationalNumber(8012345678L);
            assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
            assertEquals(validNumber, tooLongNumber);

            // IT number 022 3456 7890, but entered with 3 extra digits at the end.
            tooLongNumber.clear();
            tooLongNumber.setCountryCode(39).setNationalNumber(2234567890123L).setItalianLeadingZero(true);
            validNumber.clear();
            validNumber.setCountryCode(39).setNationalNumber(2234567890L).setItalianLeadingZero(true);
            assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
            assertEquals(validNumber, tooLongNumber);

            // US number 650-253-0000, but entered with one additional digit at the end.
            tooLongNumber.clear();
            tooLongNumber.mergeFrom(US_LONG_NUMBER);
            assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
            assertEquals(US_NUMBER, tooLongNumber);

            tooLongNumber.clear();
            tooLongNumber.mergeFrom(INTERNATIONAL_TOLL_FREE_TOO_LONG);
            assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
            assertEquals(INTERNATIONAL_TOLL_FREE, tooLongNumber);

            // Tests what happens when a valid number is passed in.
            PhoneNumber validNumberCopy = new PhoneNumber().mergeFrom(validNumber);
            assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
            // Tests the number is not modified.
            assertEquals(validNumberCopy, validNumber);

            // Tests what happens when a number with invalid prefix is passed in.
            PhoneNumber numberWithInvalidPrefix = new PhoneNumber();
            // The test metadata says US numbers cannot have prefix 240.
            numberWithInvalidPrefix.setCountryCode(1).setNationalNumber(2401234567L);
            PhoneNumber invalidNumberCopy = new PhoneNumber().mergeFrom(numberWithInvalidPrefix);
            assertFalse(phoneUtil.truncateTooLongNumber(numberWithInvalidPrefix));
            // Tests the number is not modified.
            assertEquals(invalidNumberCopy, numberWithInvalidPrefix);

            // Tests what happens when a too short number is passed in.
            PhoneNumber tooShortNumber = new PhoneNumber().setCountryCode(1).setNationalNumber(1234L);
            PhoneNumber tooShortNumberCopy = new PhoneNumber().mergeFrom(tooShortNumber);
            assertFalse(phoneUtil.truncateTooLongNumber(tooShortNumber));
            // Tests the number is not modified.
            assertEquals(tooShortNumberCopy, tooShortNumber);
        }
コード例 #40
0
        public void testParseNationalNumberArgentina()
        {
            // Test parsing mobile numbers of Argentina.
            PhoneNumber arNumber = new PhoneNumber();
            arNumber.setCountryCode(54).setNationalNumber(93435551212L);
            assertEquals(arNumber, phoneUtil.parse("+54 9 343 555 1212", RegionCode.AR));
            assertEquals(arNumber, phoneUtil.parse("0343 15 555 1212", RegionCode.AR));

            arNumber.clear();
            arNumber.setCountryCode(54).setNationalNumber(93715654320L);
            assertEquals(arNumber, phoneUtil.parse("+54 9 3715 65 4320", RegionCode.AR));
            assertEquals(arNumber, phoneUtil.parse("03715 15 65 4320", RegionCode.AR));
            assertEquals(AR_MOBILE, phoneUtil.parse("911 876 54321", RegionCode.AR));

            // Test parsing fixed-line numbers of Argentina.
            assertEquals(AR_NUMBER, phoneUtil.parse("+54 11 8765 4321", RegionCode.AR));
            assertEquals(AR_NUMBER, phoneUtil.parse("011 8765 4321", RegionCode.AR));

            arNumber.clear();
            arNumber.setCountryCode(54).setNationalNumber(3715654321L);
            assertEquals(arNumber, phoneUtil.parse("+54 3715 65 4321", RegionCode.AR));
            assertEquals(arNumber, phoneUtil.parse("03715 65 4321", RegionCode.AR));

            arNumber.clear();
            arNumber.setCountryCode(54).setNationalNumber(2312340000L);
            assertEquals(arNumber, phoneUtil.parse("+54 23 1234 0000", RegionCode.AR));
            assertEquals(arNumber, phoneUtil.parse("023 1234 0000", RegionCode.AR));
        }
コード例 #41
0
        public void testNonEqualWithDifferingRawInput()
        {
            PhoneNumber numberA = new PhoneNumber();
            numberA.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1 650 253 00 00").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);

            PhoneNumber numberB = new PhoneNumber();
            // Although these numbers would pass an isNumberMatch test, they are not considered "equal" as
            // objects, since their raw input is different.
            numberB.setCountryCode(1).setNationalNumber(6502530000L).setRawInput("+1-650-253-00-00").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);

            assertFalse(numberA.equals(numberB));
            assertFalse(numberA.hashCode() == numberB.hashCode());
        }
コード例 #42
0
 public void testMaybeExtractCountryCode()
 {
     PhoneNumber number = new PhoneNumber();
     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
     // Note that for the US, the IDD is 011.
     try {
       String phoneNumber = "011112-3456789";
       String strippedNumber = "123456789";
       int countryCallingCode = 1;
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
            countryCallingCode,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
                                              number));
       assertEquals("Did not figure out CountryCodeSource correctly",
            CountryCodeSource.FROM_NUMBER_WITH_IDD, number.getCountryCodeSource());
       // Should strip and normalize national significant number.
       assertEquals("Did not strip off the country calling code correctly.",
            strippedNumber,
            numberToFill.toString());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "+6423456789";
       int countryCallingCode = 64;
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
            countryCallingCode,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
                                              number));
       assertEquals("Did not figure out CountryCodeSource correctly",
            CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "+80012345678";
       int countryCallingCode = 800;
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
            countryCallingCode,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
                                              number));
       assertEquals("Did not figure out CountryCodeSource correctly",
            CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "2345-6789";
       StringBuilder numberToFill = new StringBuilder();
       assertEquals(
       "Should not have extracted a country calling code - no international prefix present.",
       0,
       phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number));
       assertEquals("Did not figure out CountryCodeSource correctly",
            CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "0119991123456789";
       StringBuilder numberToFill = new StringBuilder();
       phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number);
       fail("Should have thrown an exception, no valid country calling code present.");
     } catch (NumberParseException e) {
       // Expected.
       assertEquals("Wrong error type stored in exception.",
            NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
            e.getErrorType());
     }
     number.clear();
     try {
       String phoneNumber = "(1 610) 619 4466";
       int countryCallingCode = 1;
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Should have extracted the country calling code of the region passed in",
            countryCallingCode,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
                                              number));
       assertEquals("Did not figure out CountryCodeSource correctly",
            CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN,
            number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "(1 610) 619 4466";
       int countryCallingCode = 1;
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Should have extracted the country calling code of the region passed in",
            countryCallingCode,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
                                              number));
       assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "(1 610) 619 446";
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Should not have extracted a country calling code - invalid number after " +
            "extraction of uncertain country calling code.",
            0,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
                                              number));
       assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
     number.clear();
     try {
       String phoneNumber = "(1 610) 619";
       StringBuilder numberToFill = new StringBuilder();
       assertEquals("Should not have extracted a country calling code - too short number both " +
            "before and after extraction of uncertain country calling code.",
            0,
            phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
                                              number));
       assertEquals("Did not figure out CountryCodeSource correctly",
            CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
     } catch (NumberParseException e) {
       fail("Should not have thrown an exception: " + e.toString());
     }
 }
コード例 #43
0
        public void testParseNationalNumber()
        {
            // National prefix attached.
            assertEquals(NZ_NUMBER, phoneUtil.parse("033316005", RegionCode.NZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("33316005", RegionCode.NZ));
            // National prefix attached and some formatting present.
            assertEquals(NZ_NUMBER, phoneUtil.parse("03-331 6005", RegionCode.NZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("03 331 6005", RegionCode.NZ));
            // Test parsing RFC3966 format with a phone context.
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;phone-context=+64", RegionCode.NZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:331-6005;phone-context=+64-3", RegionCode.NZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:331-6005;phone-context=+64-3", RegionCode.US));
            // Test parsing RFC3966 format with optional user-defined parameters. The parameters will appear
            // after the context if present.
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;phone-context=+64;a=%A1",
            RegionCode.NZ));
            // Test parsing RFC3966 with an ISDN subaddress.
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;isub=12345;phone-context=+64",
            RegionCode.NZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("tel:+64-3-331-6005;isub=12345", RegionCode.NZ));
            // Testing international prefixes.
            // Should strip country calling code.
            assertEquals(NZ_NUMBER, phoneUtil.parse("0064 3 331 6005", RegionCode.NZ));
            // Try again, but this time we have an international number with Region Code US. It should
            // recognise the country calling code and parse accordingly.
            assertEquals(NZ_NUMBER, phoneUtil.parse("01164 3 331 6005", RegionCode.US));
            assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.US));
            // We should ignore the leading plus here, since it is not followed by a valid country code but
            // instead is followed by the IDD for the US.
            assertEquals(NZ_NUMBER, phoneUtil.parse("+01164 3 331 6005", RegionCode.US));
            assertEquals(NZ_NUMBER, phoneUtil.parse("+0064 3 331 6005", RegionCode.NZ));
            assertEquals(NZ_NUMBER, phoneUtil.parse("+ 00 64 3 331 6005", RegionCode.NZ));

            assertEquals(US_LOCAL_NUMBER,
            phoneUtil.parse("tel:253-0000;phone-context=www.google.com", RegionCode.US));
            assertEquals(US_LOCAL_NUMBER,
            phoneUtil.parse("tel:253-0000;isub=12345;phone-context=www.google.com", RegionCode.US));
            // This is invalid because no "+" sign is present as part of phone-context. The phone context
            // is simply ignored in this case just as if it contains a domain.
            assertEquals(US_LOCAL_NUMBER,
            phoneUtil.parse("tel:2530000;isub=12345;phone-context=1-650", RegionCode.US));
            assertEquals(US_LOCAL_NUMBER,
            phoneUtil.parse("tel:2530000;isub=12345;phone-context=1234.com", RegionCode.US));

            PhoneNumber nzNumber = new PhoneNumber();
            nzNumber.setCountryCode(64).setNationalNumber(64123456L);
            assertEquals(nzNumber, phoneUtil.parse("64(0)64123456", RegionCode.NZ));
            // Check that using a "/" is fine in a phone number.
            assertEquals(DE_NUMBER, phoneUtil.parse("301/23456", RegionCode.DE));

            PhoneNumber usNumber = new PhoneNumber();
            // Check it doesn't use the '1' as a country calling code when parsing if the phone number was
            // already possible.
            usNumber.setCountryCode(1).setNationalNumber(1234567890L);
            assertEquals(usNumber, phoneUtil.parse("123-456-7890", RegionCode.US));

            // Test star numbers. Although this is not strictly valid, we would like to make sure we can
            // parse the output we produce when formatting the number.
            assertEquals(JP_STAR_NUMBER, phoneUtil.parse("+81 *2345", RegionCode.JP));

            PhoneNumber shortNumber = new PhoneNumber();
            shortNumber.setCountryCode(64).setNationalNumber(12L);
            assertEquals(shortNumber, phoneUtil.parse("12", RegionCode.NZ));
        }
コード例 #44
0
        public void testEqualWithPreferredDomesticCarrierCodeSetToDefault()
        {
            PhoneNumber numberA = new PhoneNumber();
            numberA.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");

            PhoneNumber numberB = new PhoneNumber();
            numberB.setCountryCode(1).setNationalNumber(6502530000L).setPreferredDomesticCarrierCode("");

            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #45
0
        public void testEqualWithItalianLeadingZeroSetToDefault()
        {
            PhoneNumber numberA = new PhoneNumber();
            numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(false);

            PhoneNumber numberB = new PhoneNumber();
            numberB.setCountryCode(1).setNationalNumber(6502530000L);

            // These should still be equal, since the default value for this field is false.
            assertEquals(numberA, numberB);
            assertEquals(numberA.hashCode(), numberB.hashCode());
        }
コード例 #46
0
 public void testParseWithXInNumber()
 {
     // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
     assertEquals(AR_NUMBER, phoneUtil.parse("01187654321", RegionCode.AR));
     assertEquals(AR_NUMBER, phoneUtil.parse("(0) 1187654321", RegionCode.AR));
     assertEquals(AR_NUMBER, phoneUtil.parse("0 1187654321", RegionCode.AR));
     assertEquals(AR_NUMBER, phoneUtil.parse("(0xx) 1187654321", RegionCode.AR));
     PhoneNumber arFromUs = new PhoneNumber();
     arFromUs.setCountryCode(54).setNationalNumber(81429712L);
     // This test is intentionally constructed such that the number of digit after xx is larger than
     // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
     // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
     // code is written in the form of xx have a national significant number of length larger than 7.
     assertEquals(arFromUs, phoneUtil.parse("011xx5481429712", RegionCode.US));
 }
コード例 #47
0
 public void testFormatNumberWithExtension()
 {
     PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("1234");
     // Uses default extension prefix:
     assertEquals("03-331 6005 ext. 1234", phoneUtil.format(nzNumber, PhoneNumberFormat.NATIONAL));
     // Uses RFC 3966 syntax.
     assertEquals("tel:+64-3-331-6005;ext=1234",
     phoneUtil.format(nzNumber, PhoneNumberFormat.RFC3966));
     // Extension prefix overridden in the territory information for the US:
     PhoneNumber usNumberWithExtension = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("4567");
     assertEquals("650 253 0000 extn. 4567", phoneUtil.format(usNumberWithExtension,
                                                      PhoneNumberFormat.NATIONAL));
 }
コード例 #48
0
        public void testFormatDENumber()
        {
            PhoneNumber deNumber = new PhoneNumber();
            deNumber.setCountryCode(49).setNationalNumber(301234L);
            assertEquals("030/1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
            assertEquals("+49 30/1234", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
            assertEquals("tel:+49-30-1234", phoneUtil.format(deNumber, PhoneNumberFormat.RFC3966));

            deNumber.clear();
            deNumber.setCountryCode(49).setNationalNumber(291123L);
            assertEquals("0291 123", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
            assertEquals("+49 291 123", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));

            deNumber.clear();
            deNumber.setCountryCode(49).setNationalNumber(29112345678L);
            assertEquals("0291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
            assertEquals("+49 291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));

            deNumber.clear();
            deNumber.setCountryCode(49).setNationalNumber(912312345L);
            assertEquals("09123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
            assertEquals("+49 9123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
            deNumber.clear();
            deNumber.setCountryCode(49).setNationalNumber(80212345L);
            assertEquals("08021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
            assertEquals("+49 8021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
            // Note this number is correctly formatted without national prefix. Most of the numbers that
            // are treated as invalid numbers by the library are short numbers, and they are usually not
            // dialed with national prefix.
            assertEquals("1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.NATIONAL));
            assertEquals("+49 1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.INTERNATIONAL));

            deNumber.clear();
            deNumber.setCountryCode(49).setNationalNumber(41341234);
            assertEquals("04134 1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
        }
コード例 #49
0
        public void testFormatNumberForMobileDialing()
        {
            // Numbers are normally dialed in national format in-country, and international format from
            // outside the country.
            assertEquals("030123456",
            phoneUtil.formatNumberForMobileDialing(DE_NUMBER, RegionCode.DE, false));
            assertEquals("+4930123456",
            phoneUtil.formatNumberForMobileDialing(DE_NUMBER, RegionCode.CH, false));
            PhoneNumber deNumberWithExtn = new PhoneNumber().mergeFrom(DE_NUMBER).setExtension("1234");
            assertEquals("030123456",
            phoneUtil.formatNumberForMobileDialing(deNumberWithExtn, RegionCode.DE, false));
            assertEquals("+4930123456",
            phoneUtil.formatNumberForMobileDialing(deNumberWithExtn, RegionCode.CH, false));

            // US toll free numbers are marked as noInternationalDialling in the test metadata for testing
            // purposes. For such numbers, we expect nothing to be returned when the region code is not the
            // same one.
            assertEquals("800 253 0000",
            phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US,
                                               true /*  keep formatting */));
            assertEquals("", phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, true));
            assertEquals("+1 650 253 0000",
            phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, true));
            PhoneNumber usNumberWithExtn = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("1234");
            assertEquals("+1 650 253 0000",
            phoneUtil.formatNumberForMobileDialing(usNumberWithExtn, RegionCode.US, true));

            assertEquals("8002530000",
            phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US,
                                               false /* remove formatting */));
            assertEquals("", phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, false));
            assertEquals("+16502530000",
            phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, false));
            assertEquals("+16502530000",
            phoneUtil.formatNumberForMobileDialing(usNumberWithExtn, RegionCode.US, false));

            // An invalid US number, which is one digit too long.
            assertEquals("+165025300001",
            phoneUtil.formatNumberForMobileDialing(US_LONG_NUMBER, RegionCode.US, false));
            assertEquals("+1 65025300001",
            phoneUtil.formatNumberForMobileDialing(US_LONG_NUMBER, RegionCode.US, true));

            // Star numbers. In real life they appear in Israel, but we have them in JP in our test
            // metadata.
            assertEquals("*2345",
            phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER, RegionCode.JP, false));
            assertEquals("*2345",
            phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER, RegionCode.JP, true));

            assertEquals("+80012345678",
            phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.JP, false));
            assertEquals("+800 1234 5678",
            phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.JP, true));

            // UAE numbers beginning with 600 (classified as UAN) need to be dialled without +971 locally.
            assertEquals("+971600123456",
            phoneUtil.formatNumberForMobileDialing(AE_UAN, RegionCode.JP, false));
            assertEquals("600123456",
            phoneUtil.formatNumberForMobileDialing(AE_UAN, RegionCode.AE, false));

            assertEquals("+523312345678",
            phoneUtil.formatNumberForMobileDialing(MX_NUMBER1, RegionCode.MX, false));
            assertEquals("+523312345678",
            phoneUtil.formatNumberForMobileDialing(MX_NUMBER1, RegionCode.US, false));

            // Non-geographical numbers should always be dialed in international format.
            assertEquals("+80012345678",
            phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.US, false));
            assertEquals("+80012345678",
            phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.UN001, false));
        }
コード例 #50
0
 public void testParseNumberWithAlphaCharacters()
 {
     // Test case with alpha characters.
     PhoneNumber tollfreeNumber = new PhoneNumber();
     tollfreeNumber.setCountryCode(64).setNationalNumber(800332005L);
     assertEquals(tollfreeNumber, phoneUtil.parse("0800 DDA 005", RegionCode.NZ));
     PhoneNumber premiumNumber = new PhoneNumber();
     premiumNumber.setCountryCode(64).setNationalNumber(9003326005L);
     assertEquals(premiumNumber, phoneUtil.parse("0900 DDA 6005", RegionCode.NZ));
     // Not enough alpha characters for them to be considered intentional, so they are stripped.
     assertEquals(premiumNumber, phoneUtil.parse("0900 332 6005a", RegionCode.NZ));
     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600a5", RegionCode.NZ));
     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600A5", RegionCode.NZ));
     assertEquals(premiumNumber, phoneUtil.parse("0900 a332 600A5", RegionCode.NZ));
 }
コード例 #51
0
        /**
           * Gets the expected cost category of a short number (however, nothing is implied about its
           * validity). If it is important that the number is valid, then its validity must first be checked
           * using {@link isValidShortNumber}. Note that emergency numbers are always considered toll-free.
           * Example usage:
           * <pre>{@code
           * PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
           * ShortNumberInfo shortInfo = ShortNumberInfo.getInstance();
           * PhoneNumber number = phoneUtil.parse("110", "FR");
           * if (shortInfo.isValidShortNumber(number)) {
           *   ShortNumberInfo.ShortNumberCost cost = shortInfo.getExpectedCost(number);
           *   // Do something with the cost information here.
           * }}</pre>
           *
           * @param number the short number for which we want to know the expected cost category
           * @return the expected cost category of the short number. Returns UNKNOWN_COST if the number does
           *     not match a cost category. Note that an invalid number may match any cost category.
           */
        public ShortNumberCost getExpectedCost(PhoneNumber number)
        {
            List<String> regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
            String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes);

            // Note that regionCode may be null, in which case phoneMetadata will also be null.
            PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);
            if (phoneMetadata == null) {
              return ShortNumberCost.UNKNOWN_COST;
            }
            String nationalNumber = phoneUtil.getNationalSignificantNumber(number);

            // The cost categories are tested in order of decreasing expense, since if for some reason the
            // patterns overlap the most expensive matching cost category should be returned.
            if (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getPremiumRate())) {
              return ShortNumberCost.PREMIUM_RATE;
            }
            if (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getStandardRate())) {
              return ShortNumberCost.STANDARD_RATE;
            }
            if (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getTollFree())) {
              return ShortNumberCost.TOLL_FREE;
            }
            if (isEmergencyNumber(nationalNumber, regionCode)) {
              // Emergency numbers are implicitly toll-free.
              return ShortNumberCost.TOLL_FREE;
            }
            return ShortNumberCost.UNKNOWN_COST;
        }
コード例 #52
0
        public void testNonEqualWithItalianLeadingZeroSetToTrue()
        {
            PhoneNumber numberA = new PhoneNumber();
            numberA.setCountryCode(1).setNationalNumber(6502530000L).setItalianLeadingZero(true);

            PhoneNumber numberB = new PhoneNumber();
            numberB.setCountryCode(1).setNationalNumber(6502530000L);

            assertFalse(numberA.equals(numberB));
            assertFalse(numberA.hashCode() == numberB.hashCode());
        }
コード例 #53
0
        public void testParseExtensions()
        {
            PhoneNumber nzNumber = new PhoneNumber();
            nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("3456");
            assertEquals(nzNumber, phoneUtil.parse("03 331 6005 ext 3456", RegionCode.NZ));
            assertEquals(nzNumber, phoneUtil.parse("03-3316005x3456", RegionCode.NZ));
            assertEquals(nzNumber, phoneUtil.parse("03-3316005 int.3456", RegionCode.NZ));
            assertEquals(nzNumber, phoneUtil.parse("03 3316005 #3456", RegionCode.NZ));
            // Test the following do not extract extensions:
            assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 six-flags", RegionCode.US));
            assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 SIX FLAGS", RegionCode.US));
            assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("0~0 1800 7493 5247", RegionCode.PL));
            assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("(1800) 7493.5247", RegionCode.US));
            // Check that the last instance of an extension token is matched.
            PhoneNumber extnNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).setExtension("1234");
            assertEquals(extnNumber, phoneUtil.parse("0~0 1800 7493 5247 ~1234", RegionCode.PL));
            // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
            // extracting the extension. Also verifying a few different cases of extensions.
            PhoneNumber ukNumber = new PhoneNumber();
            ukNumber.setCountryCode(44).setNationalNumber(2034567890L).setExtension("456");
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.NZ));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X 456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X  456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x 456  ", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44 2034567890  X 456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("+44-2034567890;ext=456", RegionCode.GB));
            assertEquals(ukNumber, phoneUtil.parse("tel:2034567890;ext=456;phone-context=+44",
                                           RegionCode.ZZ));
            // Full-width extension, "extn" only.
            assertEquals(ukNumber, phoneUtil.parse("+442034567890\uFF45\uFF58\uFF54\uFF4E456",
                                           RegionCode.GB));
            // "xtn" only.
            assertEquals(ukNumber, phoneUtil.parse("+442034567890\uFF58\uFF54\uFF4E456",
                                           RegionCode.GB));
            // "xt" only.
            assertEquals(ukNumber, phoneUtil.parse("+442034567890\uFF58\uFF54456",
                                           RegionCode.GB));

            PhoneNumber usWithExtension = new PhoneNumber();
            usWithExtension.setCountryCode(1).setNationalNumber(8009013355L).setExtension("7246433");
            assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 x 7246433", RegionCode.US));
            assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , ext 7246433", RegionCode.US));
            assertEquals(usWithExtension,
                 phoneUtil.parse("(800) 901-3355 ,extension 7246433", RegionCode.US));
            assertEquals(usWithExtension,
                 phoneUtil.parse("(800) 901-3355 ,extensi\u00F3n 7246433", RegionCode.US));
            // Repeat with the small letter o with acute accent created by combining characters.
            assertEquals(usWithExtension,
                 phoneUtil.parse("(800) 901-3355 ,extensio\u0301n 7246433", RegionCode.US));
            assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , 7246433", RegionCode.US));
            assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ext: 7246433", RegionCode.US));

            // Test that if a number has two extensions specified, we ignore the second.
            PhoneNumber usWithTwoExtensionsNumber = new PhoneNumber();
            usWithTwoExtensionsNumber.setCountryCode(1).setNationalNumber(2121231234L).setExtension("508");
            assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/x1234",
                                                            RegionCode.US));
            assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/ x1234",
                                                            RegionCode.US));
            assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508\\x1234",
                                                            RegionCode.US));

            // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
            // the # are an extension.
            usWithExtension.clear();
            usWithExtension.setCountryCode(1).setNationalNumber(6451231234L).setExtension("910");
            assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234-910#", RegionCode.US));
            // Retry with the same number in a slightly different format.
            assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234 ext. 910#", RegionCode.US));
        }
コード例 #54
0
 /**
    * Given a valid short number, determines whether it is carrier-specific (however, nothing is
    * implied about its validity). If it is important that the number is valid, then its validity
    * must first be checked using {@link isValidShortNumber}.
    *
    * @param number the valid short number to check
    * @return whether the short number is carrier-specific (assuming the input was a valid short
    *     number).
    */
 public boolean isCarrierSpecific(PhoneNumber number)
 {
     List<String> regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
     String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes);
     String nationalNumber = phoneUtil.getNationalSignificantNumber(number);
     PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);
     return (phoneMetadata != null) &&
     (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getCarrierSpecific()));
 }
コード例 #55
0
        public void testParseAndKeepRaw()
        {
            PhoneNumber alphaNumericNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).
            setRawInput("800 six-flags").
            setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
            setPreferredDomesticCarrierCode("");
            assertEquals(alphaNumericNumber,
                 phoneUtil.parseAndKeepRawInput("800 six-flags", RegionCode.US));

            PhoneNumber shorterAlphaNumber = new PhoneNumber().
            setCountryCode(1).setNationalNumber(8007493524L).
            setRawInput("1800 six-flag").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN).
            setPreferredDomesticCarrierCode("");
            assertEquals(shorterAlphaNumber,
                 phoneUtil.parseAndKeepRawInput("1800 six-flag", RegionCode.US));

            shorterAlphaNumber.setRawInput("+1800 six-flag").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
            assertEquals(shorterAlphaNumber,
                 phoneUtil.parseAndKeepRawInput("+1800 six-flag", RegionCode.NZ));

            shorterAlphaNumber.setRawInput("001800 six-flag").
            setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_IDD);
            assertEquals(shorterAlphaNumber,
                 phoneUtil.parseAndKeepRawInput("001800 six-flag", RegionCode.NZ));

            // Invalid region code supplied.
            try {
              phoneUtil.parseAndKeepRawInput("123 456 7890", RegionCode.CS);
              fail("Deprecated region code not allowed: should fail.");
            } catch (NumberParseException e) {
              // Expected this exception.
              assertEquals("Wrong error type stored in exception.",
                   NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
                   e.getErrorType());
            }

            PhoneNumber koreanNumber = new PhoneNumber();
            koreanNumber.setCountryCode(82).setNationalNumber(22123456).setRawInput("08122123456").
            setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
            setPreferredDomesticCarrierCode("81");
            assertEquals(koreanNumber, phoneUtil.parseAndKeepRawInput("08122123456", RegionCode.KR));
        }
コード例 #56
0
 /**
    * Tests whether a short number matches a valid pattern. Note that this doesn't verify the number
    * is actually in use, which is impossible to tell by just looking at the number itself. See
    * {@link #isValidShortNumber(String, String)} for details.
    *
    * @param number the short number for which we want to test the validity
    * @return whether the short number matches a valid pattern
    */
 public boolean isValidShortNumber(PhoneNumber number)
 {
     List<String> regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
     String shortNumber = phoneUtil.getNationalSignificantNumber(number);
     String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes);
     if (regionCodes.size() > 1 && regionCode != null) {
       // If a matching region had been found for the phone number from among two or more regions,
       // then we have already implicitly verified its validity for that region.
       return true;
     }
     return isValidShortNumber(shortNumber, regionCode);
 }
コード例 #57
0
 public void testIsVoip()
 {
     PhoneNumber gbNumber = new PhoneNumber();
     gbNumber.setCountryCode(44).setNationalNumber(5631231234L);
     assertEquals(PhoneNumberUtil.PhoneNumberType.VOIP, phoneUtil.getNumberType(gbNumber));
 }
コード例 #58
0
 // Helper method to get the region code for a given phone number, from a list of possible region
 // codes. If the list contains more than one region, the first region for which the number is
 // valid is returned.
 private String getRegionCodeForShortNumberFromRegionList(PhoneNumber number,
                                                    List<String> regionCodes)
 {
     if (regionCodes.size() == 0) {
       return null;
     } else if (regionCodes.size() == 1) {
       return regionCodes.get(0);
     }
     String nationalNumber = phoneUtil.getNationalSignificantNumber(number);
     foreach (String regionCode in regionCodes) {
       PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);
       if (phoneMetadata != null &&
       phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getShortCode())) {
     // The number is valid for this region.
     return regionCode;
       }
     }
     return null;
 }
コード例 #59
0
        public void testValueTypeSemantics()
        {
            PhoneNumber number = new PhoneNumber();
            PhoneNumberMatch match1 = new PhoneNumberMatch(10, "1 800 234 45 67", number);
            PhoneNumberMatch match2 = new PhoneNumberMatch(10, "1 800 234 45 67", number);

            assertEquals(match1, match2);
            assertEquals(match1.hashCode(), match2.hashCode());
            assertEquals(match1.start(), match2.start());
            assertEquals(match1.end(), match2.end());
            assertEquals(match1.number(), match2.number());
            assertEquals(match1.rawString(), match2.rawString());
            assertEquals("1 800 234 45 67", match1.rawString());
        }
コード例 #60
0
        public void testFormatAUNumber()
        {
            assertEquals("02 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.NATIONAL));
            assertEquals("+61 2 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.INTERNATIONAL));
            assertEquals("+61236618300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.E164));

            PhoneNumber auNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(1800123456L);
            assertEquals("1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.NATIONAL));
            assertEquals("+61 1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.INTERNATIONAL));
            assertEquals("+611800123456", phoneUtil.format(auNumber, PhoneNumberFormat.E164));
        }