summaryrefslogtreecommitdiff
path: root/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java')
-rw-r--r--libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java233
1 files changed, 0 insertions, 233 deletions
diff --git a/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java b/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java
deleted file mode 100644
index 5c072d6a..00000000
--- a/libphonenumber/src/com/google/i18n/phonenumbers/MetadataManager.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2012 The Libphonenumber Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.i18n.phonenumbers;
-
-import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
-import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Manager for loading metadata for alternate formats and short numbers. We also declare some
- * constants for phone number metadata loading, to more easily maintain all three types of metadata
- * together.
- * TODO: Consider managing phone number metadata loading here too.
- */
-final class MetadataManager {
- static final String MULTI_FILE_PHONE_NUMBER_METADATA_FILE_PREFIX =
- "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto";
- static final String SINGLE_FILE_PHONE_NUMBER_METADATA_FILE_NAME =
- "/com/google/i18n/phonenumbers/data/SingleFilePhoneNumberMetadataProto";
- private static final String ALTERNATE_FORMATS_FILE_PREFIX =
- "/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto";
- private static final String SHORT_NUMBER_METADATA_FILE_PREFIX =
- "/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto";
-
- static final MetadataLoader DEFAULT_METADATA_LOADER = new MetadataLoader() {
- @Override
- public InputStream loadMetadata(String metadataFileName) {
- return MetadataManager.class.getResourceAsStream(metadataFileName);
- }
- };
-
- private static final Logger logger = Logger.getLogger(MetadataManager.class.getName());
-
- // A mapping from a country calling code to the alternate formats for that country calling code.
- private static final ConcurrentHashMap<Integer, PhoneMetadata> alternateFormatsMap =
- new ConcurrentHashMap<Integer, PhoneMetadata>();
-
- // A mapping from a region code to the short number metadata for that region code.
- private static final ConcurrentHashMap<String, PhoneMetadata> shortNumberMetadataMap =
- new ConcurrentHashMap<String, PhoneMetadata>();
-
- // The set of country calling codes for which there are alternate formats. For every country
- // calling code in this set there should be metadata linked into the resources.
- private static final Set<Integer> alternateFormatsCountryCodes =
- AlternateFormatsCountryCodeSet.getCountryCodeSet();
-
- // The set of region codes for which there are short number metadata. For every region code in
- // this set there should be metadata linked into the resources.
- private static final Set<String> shortNumberMetadataRegionCodes =
- ShortNumbersRegionCodeSet.getRegionCodeSet();
-
- private MetadataManager() {}
-
- static PhoneMetadata getAlternateFormatsForCountry(int countryCallingCode) {
- if (!alternateFormatsCountryCodes.contains(countryCallingCode)) {
- return null;
- }
- return getMetadataFromMultiFilePrefix(countryCallingCode, alternateFormatsMap,
- ALTERNATE_FORMATS_FILE_PREFIX, DEFAULT_METADATA_LOADER);
- }
-
- static PhoneMetadata getShortNumberMetadataForRegion(String regionCode) {
- if (!shortNumberMetadataRegionCodes.contains(regionCode)) {
- return null;
- }
- return getMetadataFromMultiFilePrefix(regionCode, shortNumberMetadataMap,
- SHORT_NUMBER_METADATA_FILE_PREFIX, DEFAULT_METADATA_LOADER);
- }
-
- static Set<String> getSupportedShortNumberRegions() {
- return Collections.unmodifiableSet(shortNumberMetadataRegionCodes);
- }
-
- /**
- * @param key the lookup key for the provided map, typically a region code or a country calling
- * code
- * @param map the map containing mappings of already loaded metadata from their {@code key}. If
- * this {@code key}'s metadata isn't already loaded, it will be added to this map after
- * loading
- * @param filePrefix the prefix of the file to load metadata from
- * @param metadataLoader the metadata loader used to inject alternative metadata sources
- */
- static <T> PhoneMetadata getMetadataFromMultiFilePrefix(T key,
- ConcurrentHashMap<T, PhoneMetadata> map, String filePrefix, MetadataLoader metadataLoader) {
- PhoneMetadata metadata = map.get(key);
- if (metadata != null) {
- return metadata;
- }
- // We assume key.toString() is well-defined.
- String fileName = filePrefix + "_" + key;
- List<PhoneMetadata> metadataList = getMetadataFromSingleFileName(fileName, metadataLoader);
- if (metadataList.size() > 1) {
- logger.log(Level.WARNING, "more than one metadata in file " + fileName);
- }
- metadata = metadataList.get(0);
- PhoneMetadata oldValue = map.putIfAbsent(key, metadata);
- return (oldValue != null) ? oldValue : metadata;
- }
-
- // Loader and holder for the metadata maps loaded from a single file.
- static class SingleFileMetadataMaps {
- static SingleFileMetadataMaps load(String fileName, MetadataLoader metadataLoader) {
- List<PhoneMetadata> metadataList = getMetadataFromSingleFileName(fileName, metadataLoader);
- Map<String, PhoneMetadata> regionCodeToMetadata = new HashMap<String, PhoneMetadata>();
- Map<Integer, PhoneMetadata> countryCallingCodeToMetadata =
- new HashMap<Integer, PhoneMetadata>();
- for (PhoneMetadata metadata : metadataList) {
- String regionCode = metadata.getId();
- if (PhoneNumberUtil.REGION_CODE_FOR_NON_GEO_ENTITY.equals(regionCode)) {
- // regionCode belongs to a non-geographical entity.
- countryCallingCodeToMetadata.put(metadata.getCountryCode(), metadata);
- } else {
- regionCodeToMetadata.put(regionCode, metadata);
- }
- }
- return new SingleFileMetadataMaps(regionCodeToMetadata, countryCallingCodeToMetadata);
- }
-
- // A map from a region code to the PhoneMetadata for that region.
- // For phone number metadata, the region code "001" is excluded, since that is used for the
- // non-geographical phone number entities.
- private final Map<String, PhoneMetadata> regionCodeToMetadata;
-
- // A map from a country calling code to the PhoneMetadata for that country calling code.
- // Examples of the country calling codes include 800 (International Toll Free Service) and 808
- // (International Shared Cost Service).
- // For phone number metadata, only the non-geographical phone number entities' country calling
- // codes are present.
- private final Map<Integer, PhoneMetadata> countryCallingCodeToMetadata;
-
- private SingleFileMetadataMaps(Map<String, PhoneMetadata> regionCodeToMetadata,
- Map<Integer, PhoneMetadata> countryCallingCodeToMetadata) {
- this.regionCodeToMetadata = Collections.unmodifiableMap(regionCodeToMetadata);
- this.countryCallingCodeToMetadata = Collections.unmodifiableMap(countryCallingCodeToMetadata);
- }
-
- PhoneMetadata get(String regionCode) {
- return regionCodeToMetadata.get(regionCode);
- }
-
- PhoneMetadata get(int countryCallingCode) {
- return countryCallingCodeToMetadata.get(countryCallingCode);
- }
- }
-
- // Manages the atomic reference lifecycle of a SingleFileMetadataMaps encapsulation.
- static SingleFileMetadataMaps getSingleFileMetadataMaps(
- AtomicReference<SingleFileMetadataMaps> ref, String fileName, MetadataLoader metadataLoader) {
- SingleFileMetadataMaps maps = ref.get();
- if (maps != null) {
- return maps;
- }
- maps = SingleFileMetadataMaps.load(fileName, metadataLoader);
- ref.compareAndSet(null, maps);
- return ref.get();
- }
-
- private static List<PhoneMetadata> getMetadataFromSingleFileName(String fileName,
- MetadataLoader metadataLoader) {
- InputStream source = metadataLoader.loadMetadata(fileName);
- if (source == null) {
- // Sanity check; this would only happen if we packaged jars incorrectly.
- throw new IllegalStateException("missing metadata: " + fileName);
- }
- PhoneMetadataCollection metadataCollection = loadMetadataAndCloseInput(source);
- List<PhoneMetadata> metadataList = metadataCollection.getMetadataList();
- if (metadataList.size() == 0) {
- // Sanity check; this should not happen since we build with non-empty metadata.
- throw new IllegalStateException("empty metadata: " + fileName);
- }
- return metadataList;
- }
-
- /**
- * Loads and returns the metadata from the given stream and closes the stream.
- *
- * @param source the non-null stream from which metadata is to be read
- * @return the loaded metadata
- */
- private static PhoneMetadataCollection loadMetadataAndCloseInput(InputStream source) {
- ObjectInputStream ois = null;
- try {
- try {
- ois = new ObjectInputStream(source);
- } catch (IOException e) {
- throw new RuntimeException("cannot load/parse metadata", e);
- }
- PhoneMetadataCollection metadataCollection = new PhoneMetadataCollection();
- try {
- metadataCollection.readExternal(ois);
- } catch (IOException e) {
- throw new RuntimeException("cannot load/parse metadata", e);
- }
- return metadataCollection;
- } finally {
- try {
- if (ois != null) {
- // This will close all underlying streams as well, including source.
- ois.close();
- } else {
- source.close();
- }
- } catch (IOException e) {
- logger.log(Level.WARNING, "error closing input stream (ignored)", e);
- }
- }
- }
-}