Exemple #1
0
        private bool matchesEmergencyNumberHelper(String number, String regionCode,
                                                  bool allowPrefixMatch)
        {
            number = PhoneNumberUtil.extractPossibleNumber(number);
            if (PhoneNumberUtil.PLUS_CHARS_PATTERN.MatchBeginning(number).Success)
            {
                // Returns false if the number starts with a plus sign. We don't believe dialing the country
                // code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can
                // add additional logic here to handle it.
                return(false);
            }
            PhoneMetadata metadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);

            if (metadata == null || !metadata.HasEmergency())
            {
                return(false);
            }
            var emergencyNumberPattern =
                new JavaRegex(metadata.getEmergency().getNationalNumberPattern());
            String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number);

            return((!allowPrefixMatch || REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.Contains(regionCode))
        ? emergencyNumberPattern.MatchWhole(normalizedNumber).Success
        : emergencyNumberPattern.MatchBeginning(normalizedNumber).Success);
        }
Exemple #2
0
        internal static bool 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);
        }
Exemple #3
0
        /**
         * Gets a valid short number for the specified cost category.
         *
         * @param regionCode the region for which an example short number is needed
         * @param cost the cost category of number that is needed
         * @return a valid short number for the specified region and cost category. Returns an empty
         *     string when the metadata does not contain such information, or the cost is UNKNOWN_COST.
         */
        // @VisibleForTesting
        internal String getExampleShortNumberForCost(String regionCode, ShortNumberCost cost)
        {
            PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);

            if (phoneMetadata == null)
            {
                return("");
            }
            PhoneNumberDesc desc = null;

            switch (cost)
            {
            case ShortNumberCost.TOLL_FREE:
                desc = phoneMetadata.getTollFree();
                break;

            case ShortNumberCost.STANDARD_RATE:
                desc = phoneMetadata.getStandardRate();
                break;

            case ShortNumberCost.PREMIUM_RATE:
                desc = phoneMetadata.getPremiumRate();
                break;

            default:
                // UNKNOWN_COST numbers are computed by the process of elimination from the other cost
                // categories.
                break;
            }
            if (desc != null && desc.HasExampleNumber())
            {
                return(desc.getExampleNumber());
            }
            return("");
        }
Exemple #4
0
        /**
         * Extracts the country calling code from the beginning of nationalNumber to
         * prefixBeforeNationalNumber when they are available, and places the remaining input into
         * nationalNumber.
         *
         * @return  true when a valid country calling code can be found.
         */

        private bool attemptToExtractCountryCallingCode()
        {
            if (nationalNumber.Length == 0)
            {
                return(false);
            }
            StringBuilder numberWithoutCountryCallingCode = new StringBuilder();
            int           countryCode = phoneUtil.extractCountryCode(nationalNumber, numberWithoutCountryCallingCode);

            if (countryCode == 0)
            {
                return(false);
            }
            nationalNumber.Length = 0;
            nationalNumber.Append(numberWithoutCountryCallingCode);
            String newRegionCode = phoneUtil.getRegionCodeForCountryCode(countryCode);

            if (PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY.Equals(newRegionCode))
            {
                currentMetadata = phoneUtil.getMetadataForNonGeographicalRegion(countryCode);
            }
            else if (!newRegionCode.Equals(defaultCountry))
            {
                currentMetadata = getMetadataForRegion(newRegionCode);
            }
            String countryCodeString = countryCode.ToString();

            prefixBeforeNationalNumber.Append(countryCodeString).Append(SEPARATOR_BEFORE_NATIONAL_NUMBER);
            // When we have successfully extracted the IDD, the previously extracted NDD should be cleared
            // because it is no longer valid.
            extractedNationalPrefix = "";
            return(true);
        }
Exemple #5
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.Count == 0)
            {
                return(null);
            }
            else if (regionCodes.Count == 1)
            {
                return(regionCodes[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);
        }
Exemple #6
0
        /**
         * Gets the expected cost category of a short number when dialled from a region (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 isValidShortNumberForRegion}. Note that emergency numbers
         * are always considered toll-free. Example usage:
         * <pre>{@code
         * ShortNumberInfo shortInfo = ShortNumberInfo.getInstance();
         * String shortNumber = "110";
         * String regionCode = "FR";
         * if (shortInfo.isValidShortNumberForRegion(shortNumber, regionCode)) {
         *   ShortNumberInfo.ShortNumberCost cost = shortInfo.getExpectedCostForRegion(shortNumber,
         *       regionCode);
         *   // Do something with the cost information here.
         * }}</pre>
         *
         * @param shortNumber the short number for which we want to know the expected cost category,
         *     as a string
         * @param regionDialingFrom the region from which the number is dialed
         * @return the expected cost category for that region 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 getExpectedCostForRegion(String shortNumber, String regionDialingFrom)
        {
            // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null.
            PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(
                regionDialingFrom);

            if (phoneMetadata == null)
            {
                return(ShortNumberCost.UNKNOWN_COST);
            }

            // 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(shortNumber, phoneMetadata.getPremiumRate()))
            {
                return(ShortNumberCost.PREMIUM_RATE);
            }
            if (phoneUtil.isNumberMatchingDesc(shortNumber, phoneMetadata.getStandardRate()))
            {
                return(ShortNumberCost.STANDARD_RATE);
            }
            if (phoneUtil.isNumberMatchingDesc(shortNumber, phoneMetadata.getTollFree()))
            {
                return(ShortNumberCost.TOLL_FREE);
            }
            if (isEmergencyNumber(shortNumber, regionDialingFrom))
            {
                // Emergency numbers are implicitly toll-free.
                return(ShortNumberCost.TOLL_FREE);
            }
            return(ShortNumberCost.UNKNOWN_COST);
        }
Exemple #7
0
        /**
         * Tests whether a short number matches a valid pattern in a region. Note that this doesn't verify
         * the number is actually in use, which is impossible to tell by just looking at the number
         * itself.
         *
         * @param shortNumber the short number to check as a string
         * @param regionDialingFrom the region from which the number is dialed
         * @return whether the short number matches a valid pattern
         */
        public bool isValidShortNumberForRegion(String shortNumber, String regionDialingFrom)
        {
            PhoneMetadata phoneMetadata =
                MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom);

            if (phoneMetadata == null)
            {
                return(false);
            }
            PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc();

            if (!generalDesc.HasNationalNumberPattern() ||
                !phoneUtil.isNumberMatchingDesc(shortNumber, generalDesc))
            {
                return(false);
            }
            PhoneNumberDesc shortNumberDesc = phoneMetadata.getShortCode();

            if (!shortNumberDesc.HasNationalNumberPattern())
            {
                logger.log(Level.WARNING, "No short code national number pattern found for region: " +
                           regionDialingFrom);
                return(false);
            }
            return(phoneUtil.isNumberMatchingDesc(shortNumber, shortNumberDesc));
        }
Exemple #8
0
 public PhoneMetadataCollection addMetadata(PhoneMetadata value)
 {
     if (value == null)
     {
         throw new NullReferenceException();
     }
     metadata_.Add(value);
     return(this);
 }
Exemple #9
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} or
         * {@link #isValidShortNumberForRegion}.
         *
         * @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 bool 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())));
        }
Exemple #10
0
        public void readExternal(BinaryReader objectInput)
        {
            int size = objectInput.readInt();

            for (int i = 0; i < size; i++)
            {
                PhoneMetadata metadata = new PhoneMetadata();
                metadata.readExternal(objectInput);
                metadata_.Add(metadata);
            }
        }
Exemple #11
0
        /**
         * Check whether a short number is a possible number when dialled from a region, given the number
         * in the form of a string, and the region where the number is dialed from. This provides a more
         * lenient check than {@link #isValidShortNumberForRegion}.
         *
         * @param shortNumber the short number to check as a string
         * @param regionDialingFrom the region from which the number is dialed
         * @return whether the number is a possible short number
         */
        public bool isPossibleShortNumberForRegion(String shortNumber, String regionDialingFrom)
        {
            PhoneMetadata phoneMetadata =
                MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom);

            if (phoneMetadata == null)
            {
                return(false);
            }
            PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc();

            return(phoneUtil.isNumberPossibleForDesc(shortNumber, generalDesc));
        }
Exemple #12
0
        // The metadata needed by this class is the same for all regions sharing the same country calling
        // code. Therefore, we return the metadata for "main" region for this country calling code.
        private PhoneMetadata getMetadataForRegion(String regionCode)
        {
            int           countryCallingCode = phoneUtil.getCountryCodeForRegion(regionCode);
            String        mainCountry        = phoneUtil.getRegionCodeForCountryCode(countryCallingCode);
            PhoneMetadata metadata           = phoneUtil.getMetadataForRegion(mainCountry);

            if (metadata != null)
            {
                return(metadata);
            }
            // Set to a default instance of the metadata. This allows us to function with an incorrect
            // region code, even if formatting only works for numbers specified with "+".
            return(EMPTY_METADATA);
        }
Exemple #13
0
        /**
         * Check whether a short number is a possible number. If a country calling code is shared by
         * multiple regions, this returns true if it's possible in any of them. This provides a more
         * lenient check than {@link #isValidShortNumber}. See {@link
         * #isPossibleShortNumberForRegion(String, String)} for details.
         *
         * @param number the short number to check
         * @return whether the number is a possible short number
         */
        public bool isPossibleShortNumber(PhoneNumber number)
        {
            List <String> regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode());
            String        shortNumber = phoneUtil.getNationalSignificantNumber(number);

            foreach (String region in regionCodes)
            {
                PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(region);
                if (phoneUtil.isNumberPossibleForDesc(shortNumber, phoneMetadata.getGeneralDesc()))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #14
0
        /**
         * Gets a valid short number for the specified region.
         *
         * @param regionCode the region for which an example short number is needed
         * @return a valid short number for the specified region. Returns an empty string when the
         *     metadata does not contain such information.
         */
        // @VisibleForTesting
        internal String getExampleShortNumber(String regionCode)
        {
            PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode);

            if (phoneMetadata == null)
            {
                return("");
            }
            PhoneNumberDesc desc = phoneMetadata.getShortCode();

            if (desc.HasExampleNumber())
            {
                return(desc.getExampleNumber());
            }
            return("");
        }
Exemple #15
0
        internal static bool 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() != PhoneNumber.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.chooseFormattingRegexForNumber(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);
        }
Exemple #16
0
        /**
         * Clears the internal state of the formatter, so it can be reused.
         */

        public void clear()
        {
            currentOutput = "";
            accruedInput.Clear();
            accruedInputWithoutFormatting.Clear();
            formattingTemplate.Clear();
            lastMatchPosition        = 0;
            currentFormattingPattern = "";
            prefixBeforeNationalNumber.Clear();
            extractedNationalPrefix = "";
            nationalNumber.Clear();
            ableToFormat                  = true;
            inputHasFormatting            = false;
            positionToRemember            = 0;
            originalPosition              = 0;
            isCompleteNumber              = false;
            isExpectingCountryCallingCode = false;
            possibleFormats.Clear();
            shouldAddSpaceAfterNationalPrefix = false;
            if (!currentMetadata.Equals(defaultMetadata))
            {
                currentMetadata = getMetadataForRegion(defaultCountry);
            }
        }
Exemple #17
0
        /**
         * Constructs an as-you-type formatter. Should be obtained from {@link
         * PhoneNumberUtil#getAsYouTypeFormatter}.
         *
         * @param regionCode  the country/region where the phone number is being entered
         */

        internal AsYouTypeFormatter(String regionCode)
        {
            defaultCountry  = regionCode;
            currentMetadata = getMetadataForRegion(defaultCountry);
            defaultMetadata = currentMetadata;
        }