14b867acb917b73e699a596df94445c634c916519Shaopeng Jia/* 24b867acb917b73e699a596df94445c634c916519Shaopeng Jia * Copyright (C) 2012 The Libphonenumber Authors 34b867acb917b73e699a596df94445c634c916519Shaopeng Jia * 44b867acb917b73e699a596df94445c634c916519Shaopeng Jia * Licensed under the Apache License, Version 2.0 (the "License"); 54b867acb917b73e699a596df94445c634c916519Shaopeng Jia * you may not use this file except in compliance with the License. 64b867acb917b73e699a596df94445c634c916519Shaopeng Jia * You may obtain a copy of the License at 74b867acb917b73e699a596df94445c634c916519Shaopeng Jia * 84b867acb917b73e699a596df94445c634c916519Shaopeng Jia * http://www.apache.org/licenses/LICENSE-2.0 94b867acb917b73e699a596df94445c634c916519Shaopeng Jia * 104b867acb917b73e699a596df94445c634c916519Shaopeng Jia * Unless required by applicable law or agreed to in writing, software 114b867acb917b73e699a596df94445c634c916519Shaopeng Jia * distributed under the License is distributed on an "AS IS" BASIS, 124b867acb917b73e699a596df94445c634c916519Shaopeng Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b867acb917b73e699a596df94445c634c916519Shaopeng Jia * See the License for the specific language governing permissions and 144b867acb917b73e699a596df94445c634c916519Shaopeng Jia * limitations under the License. 154b867acb917b73e699a596df94445c634c916519Shaopeng Jia */ 164b867acb917b73e699a596df94445c634c916519Shaopeng Jia 174b867acb917b73e699a596df94445c634c916519Shaopeng Jiapackage com.android.i18n.phonenumbers; 184b867acb917b73e699a596df94445c634c916519Shaopeng Jia 194b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport com.android.i18n.phonenumbers.Phonemetadata.PhoneMetadata; 204b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport com.android.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection; 214b867acb917b73e699a596df94445c634c916519Shaopeng Jia 224b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.io.IOException; 234b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.io.InputStream; 244b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.io.ObjectInputStream; 254b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.Collections; 264b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.HashMap; 274b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.Iterator; 28bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jiaimport java.util.List; 294b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.Map; 304b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.Set; 314b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.logging.Level; 324b867acb917b73e699a596df94445c634c916519Shaopeng Jiaimport java.util.logging.Logger; 334b867acb917b73e699a596df94445c634c916519Shaopeng Jia 344b867acb917b73e699a596df94445c634c916519Shaopeng Jia/** 354b867acb917b73e699a596df94445c634c916519Shaopeng Jia * Class encapsulating loading of PhoneNumber Metadata information. Currently this is used only for 364b867acb917b73e699a596df94445c634c916519Shaopeng Jia * additional data files such as PhoneNumberAlternateFormats, but in the future it is envisaged it 37bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia * would handle the main metadata file (PhoneNumberMetadata.xml) as well. 384b867acb917b73e699a596df94445c634c916519Shaopeng Jia */ 394b867acb917b73e699a596df94445c634c916519Shaopeng Jiaclass MetadataManager { 404b867acb917b73e699a596df94445c634c916519Shaopeng Jia private static final String ALTERNATE_FORMATS_FILE_PREFIX = 414b867acb917b73e699a596df94445c634c916519Shaopeng Jia "/com/android/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto"; 42bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private static final String SHORT_NUMBER_METADATA_FILE_PREFIX = 43bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia "/com/android/i18n/phonenumbers/data/ShortNumberMetadataProto"; 444b867acb917b73e699a596df94445c634c916519Shaopeng Jia 454b867acb917b73e699a596df94445c634c916519Shaopeng Jia private static final Logger LOGGER = Logger.getLogger(MetadataManager.class.getName()); 464b867acb917b73e699a596df94445c634c916519Shaopeng Jia 474b867acb917b73e699a596df94445c634c916519Shaopeng Jia private static final Map<Integer, PhoneMetadata> callingCodeToAlternateFormatsMap = 484b867acb917b73e699a596df94445c634c916519Shaopeng Jia Collections.synchronizedMap(new HashMap<Integer, PhoneMetadata>()); 49bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private static final Map<String, PhoneMetadata> regionCodeToShortNumberMetadataMap = 50bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia Collections.synchronizedMap(new HashMap<String, PhoneMetadata>()); 514b867acb917b73e699a596df94445c634c916519Shaopeng Jia 524b867acb917b73e699a596df94445c634c916519Shaopeng Jia // A set of which country calling codes there are alternate format data for. If the set has an 534b867acb917b73e699a596df94445c634c916519Shaopeng Jia // entry for a code, then there should be data for that code linked into the resources. 544b867acb917b73e699a596df94445c634c916519Shaopeng Jia private static final Set<Integer> countryCodeSet = 554b867acb917b73e699a596df94445c634c916519Shaopeng Jia AlternateFormatsCountryCodeSet.getCountryCodeSet(); 564b867acb917b73e699a596df94445c634c916519Shaopeng Jia 57bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // A set of which region codes there are short number data for. If the set has an entry for a 58bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // code, then there should be data for that code linked into the resources. 59bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private static final Set<String> regionCodeSet = ShortNumbersRegionCodeSet.getRegionCodeSet(); 60bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 614b867acb917b73e699a596df94445c634c916519Shaopeng Jia private MetadataManager() { 624b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 634b867acb917b73e699a596df94445c634c916519Shaopeng Jia 644b867acb917b73e699a596df94445c634c916519Shaopeng Jia private static void close(InputStream in) { 654b867acb917b73e699a596df94445c634c916519Shaopeng Jia if (in != null) { 664b867acb917b73e699a596df94445c634c916519Shaopeng Jia try { 674b867acb917b73e699a596df94445c634c916519Shaopeng Jia in.close(); 684b867acb917b73e699a596df94445c634c916519Shaopeng Jia } catch (IOException e) { 694b867acb917b73e699a596df94445c634c916519Shaopeng Jia LOGGER.log(Level.WARNING, e.toString()); 704b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 714b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 724b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 734b867acb917b73e699a596df94445c634c916519Shaopeng Jia 74bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private static void loadAlternateFormatsMetadataFromFile(int countryCallingCode) { 754b867acb917b73e699a596df94445c634c916519Shaopeng Jia InputStream source = PhoneNumberMatcher.class.getResourceAsStream( 764b867acb917b73e699a596df94445c634c916519Shaopeng Jia ALTERNATE_FORMATS_FILE_PREFIX + "_" + countryCallingCode); 774b867acb917b73e699a596df94445c634c916519Shaopeng Jia ObjectInputStream in = null; 784b867acb917b73e699a596df94445c634c916519Shaopeng Jia try { 794b867acb917b73e699a596df94445c634c916519Shaopeng Jia in = new ObjectInputStream(source); 804b867acb917b73e699a596df94445c634c916519Shaopeng Jia PhoneMetadataCollection alternateFormats = new PhoneMetadataCollection(); 814b867acb917b73e699a596df94445c634c916519Shaopeng Jia alternateFormats.readExternal(in); 824b867acb917b73e699a596df94445c634c916519Shaopeng Jia for (PhoneMetadata metadata : alternateFormats.getMetadataList()) { 834b867acb917b73e699a596df94445c634c916519Shaopeng Jia callingCodeToAlternateFormatsMap.put(metadata.getCountryCode(), metadata); 844b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 854b867acb917b73e699a596df94445c634c916519Shaopeng Jia } catch (IOException e) { 864b867acb917b73e699a596df94445c634c916519Shaopeng Jia LOGGER.log(Level.WARNING, e.toString()); 874b867acb917b73e699a596df94445c634c916519Shaopeng Jia } finally { 884b867acb917b73e699a596df94445c634c916519Shaopeng Jia close(in); 894b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 904b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 914b867acb917b73e699a596df94445c634c916519Shaopeng Jia 924b867acb917b73e699a596df94445c634c916519Shaopeng Jia static PhoneMetadata getAlternateFormatsForCountry(int countryCallingCode) { 934b867acb917b73e699a596df94445c634c916519Shaopeng Jia if (!countryCodeSet.contains(countryCallingCode)) { 944b867acb917b73e699a596df94445c634c916519Shaopeng Jia return null; 954b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 964b867acb917b73e699a596df94445c634c916519Shaopeng Jia synchronized (callingCodeToAlternateFormatsMap) { 974b867acb917b73e699a596df94445c634c916519Shaopeng Jia if (!callingCodeToAlternateFormatsMap.containsKey(countryCallingCode)) { 98bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia loadAlternateFormatsMetadataFromFile(countryCallingCode); 994b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 1004b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 1014b867acb917b73e699a596df94445c634c916519Shaopeng Jia return callingCodeToAlternateFormatsMap.get(countryCallingCode); 1024b867acb917b73e699a596df94445c634c916519Shaopeng Jia } 103bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 104bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private static void loadShortNumberMetadataFromFile(String regionCode) { 105bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia InputStream source = PhoneNumberMatcher.class.getResourceAsStream( 106bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia SHORT_NUMBER_METADATA_FILE_PREFIX + "_" + regionCode); 107bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia ObjectInputStream in = null; 108bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia try { 109bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia in = new ObjectInputStream(source); 110bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia PhoneMetadataCollection shortNumberMetadata = new PhoneMetadataCollection(); 111bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia shortNumberMetadata.readExternal(in); 112bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia for (PhoneMetadata metadata : shortNumberMetadata.getMetadataList()) { 113bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia regionCodeToShortNumberMetadataMap.put(regionCode, metadata); 114bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 115bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } catch (IOException e) { 116bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia LOGGER.log(Level.WARNING, e.toString()); 117bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } finally { 118bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia close(in); 119bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 120bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 121bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 122bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // @VisibleForTesting 123bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia static Set<String> getShortNumberMetadataSupportedRegions() { 124bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia return regionCodeSet; 125bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 126bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 127bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia static PhoneMetadata getShortNumberMetadataForRegion(String regionCode) { 128bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia if (!regionCodeSet.contains(regionCode)) { 129bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia return null; 130bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 131bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia synchronized (regionCodeToShortNumberMetadataMap) { 132bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia if (!regionCodeToShortNumberMetadataMap.containsKey(regionCode)) { 133bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia loadShortNumberMetadataFromFile(regionCode); 134bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 135bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 136bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia return regionCodeToShortNumberMetadataMap.get(regionCode); 137bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 1384b867acb917b73e699a596df94445c634c916519Shaopeng Jia} 139