diff --git a/java/build.xml b/java/build.xml index f8692118e..b5fc72734 100644 --- a/java/build.xml +++ b/java/build.xml @@ -35,13 +35,33 @@ + + + + + + + + + + + + + + + + + + + + @@ -61,6 +81,9 @@ + + + diff --git a/java/resources/com/google/i18n/phonenumbers/GenerateAreaCodeData.java b/java/resources/com/google/i18n/phonenumbers/GenerateAreaCodeData.java index f29f699c9..b424cb547 100644 --- a/java/resources/com/google/i18n/phonenumbers/GenerateAreaCodeData.java +++ b/java/resources/com/google/i18n/phonenumbers/GenerateAreaCodeData.java @@ -183,12 +183,15 @@ public class GenerateAreaCodeData { File[] languageDirectories = inputPath.listFiles(); for (File languageDirectory : languageDirectories) { - if (!languageDirectory.isDirectory()) { + if (!languageDirectory.isDirectory() || languageDirectory.isHidden()) { continue; } File[] countryCodeFiles = languageDirectory.listFiles(); for (File countryCodeFile : countryCodeFiles) { + if (countryCodeFile.isHidden()) { + continue; + } String countryCodeFileName = countryCodeFile.getName(); int indexOfDot = countryCodeFileName.indexOf('.'); if (indexOfDot == -1) { diff --git a/java/src/com/google/i18n/phonenumbers/AreaCodeMap.java b/java/src/com/google/i18n/phonenumbers/AreaCodeMap.java index e212fc8b4..1358b924c 100644 --- a/java/src/com/google/i18n/phonenumbers/AreaCodeMap.java +++ b/java/src/com/google/i18n/phonenumbers/AreaCodeMap.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.SortedMap; +import java.util.SortedSet; import java.util.TreeSet; /** @@ -36,7 +37,7 @@ public class AreaCodeMap implements Externalizable { private TreeSet possibleLengths = new TreeSet(); private int[] phoneNumberPrefixes; private String[] descriptions; - private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); + private PhoneNumberUtil phoneUtil; /** * Creates an empty {@link AreaCodeMap}. The default constructor is necessary for implementing @@ -44,6 +45,12 @@ public class AreaCodeMap implements Externalizable { * {@link #readAreaCodeMap(java.util.SortedMap)} or {@link #readExternal(java.io.ObjectInput)}. */ public AreaCodeMap() { + phoneUtil = PhoneNumberUtil.getInstance(); + } + + // @VisibleForTesting + AreaCodeMap(PhoneNumberUtil phoneUtil) { + this.phoneUtil = phoneUtil; } /** @@ -115,7 +122,9 @@ public class AreaCodeMap implements Externalizable { long phonePrefix = Long.parseLong(number.getCountryCode() + phoneUtil.getNationalSignificantNumber(number)); int currentIndex = numOfEntries - 1; - for (Integer possibleLength : possibleLengths.descendingSet()) { + SortedSet currentSetOfLengths = possibleLengths; + while (currentSetOfLengths.size() > 0) { + Integer possibleLength = currentSetOfLengths.last(); String phonePrefixStr = String.valueOf(phonePrefix); if (phonePrefixStr.length() > possibleLength) { phonePrefix = Long.parseLong(phonePrefixStr.substring(0, possibleLength)); @@ -127,6 +136,7 @@ public class AreaCodeMap implements Externalizable { if (phonePrefix == phoneNumberPrefixes[currentIndex]) { return descriptions[currentIndex]; } + currentSetOfLengths = possibleLengths.headSet(possibleLength); } return ""; } diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoder.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoder.java index 9e4d2e144..b4a9628cd 100644 --- a/java/src/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoder.java +++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoder.java @@ -90,7 +90,7 @@ public class PhoneNumberOfflineGeocoder { ObjectInputStream in; try { in = new ObjectInputStream(source); - AreaCodeMap map = new AreaCodeMap(); + AreaCodeMap map = new AreaCodeMap(phoneUtil); map.readExternal(in); availablePhonePrefixMaps.put(fileName, map); } catch (IOException e) { diff --git a/java/src/com/google/i18n/phonenumbers/geocoding_data/82_zh_Hans b/java/src/com/google/i18n/phonenumbers/geocoding_data/82_zh similarity index 100% rename from java/src/com/google/i18n/phonenumbers/geocoding_data/82_zh_Hans rename to java/src/com/google/i18n/phonenumbers/geocoding_data/82_zh diff --git a/java/src/com/google/i18n/phonenumbers/geocoding_data/86_zh_Hans b/java/src/com/google/i18n/phonenumbers/geocoding_data/86_zh similarity index 100% rename from java/src/com/google/i18n/phonenumbers/geocoding_data/86_zh_Hans rename to java/src/com/google/i18n/phonenumbers/geocoding_data/86_zh diff --git a/java/src/com/google/i18n/phonenumbers/geocoding_data/config b/java/src/com/google/i18n/phonenumbers/geocoding_data/config index d1601e05f..ab7f88185 100644 Binary files a/java/src/com/google/i18n/phonenumbers/geocoding_data/config and b/java/src/com/google/i18n/phonenumbers/geocoding_data/config differ diff --git a/java/test/com/google/i18n/phonenumbers/AreaCodeMapTest.java b/java/test/com/google/i18n/phonenumbers/AreaCodeMapTest.java new file mode 100644 index 000000000..c393c8919 --- /dev/null +++ b/java/test/com/google/i18n/phonenumbers/AreaCodeMapTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * 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.Phonenumber.PhoneNumber; +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Unittests for AreaCodeMap.java + * + * @author Shaopeng Jia + */ +public class AreaCodeMapTest extends TestCase { + private final AreaCodeMap areaCodeMap; + private PhoneNumber number = new PhoneNumber(); + private static final Logger LOGGER = Logger.getLogger(AreaCodeMapTest.class.getName()); + static final String TEST_META_DATA_FILE_PREFIX = + "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting"; + + public AreaCodeMapTest() { + PhoneNumberUtil.resetInstance(); + PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance( + TEST_META_DATA_FILE_PREFIX, + CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap()); + areaCodeMap = new AreaCodeMap(phoneUtil); + + SortedMap sortedMap = new TreeMap(); + sortedMap.put(1212, "New York"); + sortedMap.put(1480, "Arizona"); + sortedMap.put(1650, "California"); + sortedMap.put(1907, "Alaska"); + sortedMap.put(1201664, "Westwood, NJ"); + sortedMap.put(1480893, "Phoenix, AZ"); + sortedMap.put(1501372, "Little Rock, AR"); + sortedMap.put(1626308, "Alhambra, CA"); + sortedMap.put(1650345, "San Mateo, CA"); + sortedMap.put(1867993, "Dawson, YT"); + sortedMap.put(1972480, "Richardson, TX"); + + areaCodeMap.readAreaCodeMap(sortedMap); + } + + public void testLookupInvalidNumber_US() { + // central office code cannot start with 1. + number.setCountryCode(1).setNationalNumber(2121234567L); + assertEquals("New York", areaCodeMap.lookup(number)); + } + + public void testLookupNumber_NJ() { + number.setCountryCode(1).setNationalNumber(2016641234L); + assertEquals("Westwood, NJ", areaCodeMap.lookup(number)); + } + + public void testLookupNumber_NY() { + number.setCountryCode(1).setNationalNumber(2126641234L); + assertEquals("New York", areaCodeMap.lookup(number)); + } + + public void testLookupNumber_CA_1() { + number.setCountryCode(1).setNationalNumber(6503451234L); + assertEquals("San Mateo, CA", areaCodeMap.lookup(number)); + } + + public void testLookupNumber_CA_2() { + number.setCountryCode(1).setNationalNumber(6502531234L); + assertEquals("California", areaCodeMap.lookup(number)); + } + + public void testLookupNumberFound_TX() { + number.setCountryCode(1).setNationalNumber(9724801234L); + assertEquals("Richardson, TX", areaCodeMap.lookup(number)); + } + + public void testLookupNumberNotFound_TX() { + number.setCountryCode(1).setNationalNumber(9724811234L); + assertEquals("", areaCodeMap.lookup(number)); + } + + public void testLookupNumber_CH() { + number.setCountryCode(41).setNationalNumber(446681300L); + assertEquals("", areaCodeMap.lookup(number)); + } + + public void testReadWriteExternal() { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + areaCodeMap.writeExternal(objectOutputStream); + objectOutputStream.flush(); + + AreaCodeMap newAreaCodeMap = new AreaCodeMap(); + newAreaCodeMap.readExternal( + new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))); + + assertEquals(areaCodeMap.toString(), newAreaCodeMap.toString()); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + fail(); + } + } +} diff --git a/java/test/com/google/i18n/phonenumbers/MappingFileProviderTest.java b/java/test/com/google/i18n/phonenumbers/MappingFileProviderTest.java new file mode 100644 index 000000000..a35bc227e --- /dev/null +++ b/java/test/com/google/i18n/phonenumbers/MappingFileProviderTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * 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 junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Unittests for MappingFileProvider.java + * + * @author Shaopeng Jia + */ +public class MappingFileProviderTest extends TestCase { + private final MappingFileProvider mappingProvider = new MappingFileProvider(); + private static final Logger LOGGER = Logger.getLogger(MappingFileProviderTest.class.getName()); + + public MappingFileProviderTest() { + SortedMap> mapping = new TreeMap>(); + mapping.put(1, newHashSet("en")); + mapping.put(86, newHashSet("zh", "en", "zh_Hant")); + mapping.put(41, newHashSet("de", "fr", "it", "rm")); + mapping.put(65, newHashSet("en", "zh_Hans", "ms", "ta")); + + mappingProvider.readFileConfigs(mapping); + } + + private static HashSet newHashSet(String... strings) { + HashSet set = new HashSet(); + set.addAll(Arrays.asList(strings)); + return set; + } + + public void testReadWriteExternal() { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + mappingProvider.writeExternal(objectOutputStream); + objectOutputStream.flush(); + + MappingFileProvider newMappingProvider = new MappingFileProvider(); + newMappingProvider.readExternal( + new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))); + assertEquals(mappingProvider.toString(), newMappingProvider.toString()); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + fail(); + } + } + + public void testGetFileName() { + assertEquals("1_en", mappingProvider.getFileName(1, "en", "", "")); + assertEquals("1_en", mappingProvider.getFileName(1, "en", "", "US")); + assertEquals("1_en", mappingProvider.getFileName(1, "en", "", "GB")); + assertEquals("41_de", mappingProvider.getFileName(41, "de", "", "CH")); + assertEquals("", mappingProvider.getFileName(44, "en", "", "GB")); + assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "", "")); + assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "Hans", "")); + assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "", "CN")); + assertEquals("", mappingProvider.getFileName(86, "", "", "CN")); + assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "Hans", "CN")); + assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "Hans", "SG")); + assertEquals("86_zh", mappingProvider.getFileName(86, "zh", "", "SG")); + assertEquals("86_zh_Hant", mappingProvider.getFileName(86, "zh", "", "TW")); + assertEquals("86_zh_Hant", mappingProvider.getFileName(86, "zh", "", "HK")); + assertEquals("86_zh_Hant", mappingProvider.getFileName(86, "zh", "Hant", "TW")); + } +} diff --git a/java/test/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoderTest.java b/java/test/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoderTest.java index facd3c4ac..b577e849a 100644 --- a/java/test/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoderTest.java +++ b/java/test/com/google/i18n/phonenumbers/PhoneNumberOfflineGeocoderTest.java @@ -30,10 +30,22 @@ public class PhoneNumberOfflineGeocoderTest extends TestCase { private PhoneNumberOfflineGeocoder geocoder; static final String TEST_META_DATA_FILE_PREFIX = "/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting"; + private static final String TEST_MAPPING_DATA_DIRECTORY = + "/com/google/i18n/phonenumbers/geocoding_testing_data/"; // Set up some test numbers to re-use. + private static final PhoneNumber KO_NUMBER1 = + new PhoneNumber().setCountryCode(82).setNationalNumber(22123456L); + private static final PhoneNumber KO_NUMBER2 = + new PhoneNumber().setCountryCode(82).setNationalNumber(322123456L); + private static final PhoneNumber KO_NUMBER3 = + new PhoneNumber().setCountryCode(82).setNationalNumber(6421234567L); private static final PhoneNumber US_NUMBER1 = new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L); + private static final PhoneNumber US_NUMBER2 = + new PhoneNumber().setCountryCode(1).setNationalNumber(6509600000L); + private static final PhoneNumber US_NUMBER3 = + new PhoneNumber().setCountryCode(1).setNationalNumber(2128120000L); private static final PhoneNumber BS_NUMBER1 = new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L); private static final PhoneNumber AU_NUMBER = @@ -46,19 +58,45 @@ public class PhoneNumberOfflineGeocoderTest extends TestCase { PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance( TEST_META_DATA_FILE_PREFIX, CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap()); - geocoder = new PhoneNumberOfflineGeocoder(phoneUtil); + geocoder = new PhoneNumberOfflineGeocoder(TEST_MAPPING_DATA_DIRECTORY, phoneUtil); } - public void testGetCompactDescriptionForNumber() { - assertEquals("United States", - geocoder.getDescriptionForNumber(US_NUMBER1, Locale.ENGLISH)); + public void testGetDescriptionForNumberWithNoDataFile() { + // No data file containing mappings for US numbers is available in Chinese for the unittests. As + // a result, the country name of United States in simplified Chinese is returned. + assertEquals("\u7F8E\u56FD", + geocoder.getDescriptionForNumber(US_NUMBER1, Locale.SIMPLIFIED_CHINESE)); assertEquals("Stati Uniti", geocoder.getDescriptionForNumber(US_NUMBER1, Locale.ITALIAN)); assertEquals("Bahamas", - geocoder.getDescriptionForNumber(BS_NUMBER1, Locale.ENGLISH)); + geocoder.getDescriptionForNumber(BS_NUMBER1, new Locale("en", "US"))); assertEquals("Australia", - geocoder.getDescriptionForNumber(AU_NUMBER, Locale.ENGLISH)); + geocoder.getDescriptionForNumber(AU_NUMBER, new Locale("en", "US"))); assertEquals("", geocoder.getDescriptionForNumber(NUMBER_WITH_INVALID_COUNTRY_CODE, - Locale.ENGLISH)); + new Locale("en", "US"))); + } + + public void testGetDescriptionForNumber_en_US() { + assertEquals("CA", + geocoder.getDescriptionForNumber(US_NUMBER1, new Locale("en", "US"))); + assertEquals("Mountain View, CA", + geocoder.getDescriptionForNumber(US_NUMBER2, new Locale("en", "US"))); + assertEquals("New York, NY", + geocoder.getDescriptionForNumber(US_NUMBER3, new Locale("en", "US"))); + } + + public void testGetDescriptionForKoreanNumber() { + assertEquals("Seoul", + geocoder.getDescriptionForNumber(KO_NUMBER1, Locale.ENGLISH)); + assertEquals("Incheon", + geocoder.getDescriptionForNumber(KO_NUMBER2, Locale.ENGLISH)); + assertEquals("Jeju", + geocoder.getDescriptionForNumber(KO_NUMBER3, Locale.ENGLISH)); + assertEquals("\uC11C\uC6B8", + geocoder.getDescriptionForNumber(KO_NUMBER1, Locale.KOREAN)); + assertEquals("\uC778\uCC9C", + geocoder.getDescriptionForNumber(KO_NUMBER2, Locale.KOREAN)); + assertEquals("\uC81C\uC8FC", + geocoder.getDescriptionForNumber(KO_NUMBER3, Locale.KOREAN)); } } diff --git a/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/82_en b/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/82_en new file mode 100644 index 000000000..964e02644 Binary files /dev/null and b/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/82_en differ diff --git a/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/82_ko b/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/82_ko new file mode 100644 index 000000000..69c8afec4 Binary files /dev/null and b/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/82_ko differ diff --git a/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/config b/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/config index 0b0884db9..ab7bf471f 100644 Binary files a/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/config and b/java/test/com/google/i18n/phonenumbers/geocoding_testing_data/config differ diff --git a/resources/geocoding/zh_Hans/82.txt b/resources/geocoding/zh/82.txt similarity index 100% rename from resources/geocoding/zh_Hans/82.txt rename to resources/geocoding/zh/82.txt diff --git a/resources/geocoding/zh_Hans/86.txt b/resources/geocoding/zh/86.txt similarity index 100% rename from resources/geocoding/zh_Hans/86.txt rename to resources/geocoding/zh/86.txt diff --git a/resources/test/geocoding/zh_Hans/86.txt b/resources/test/geocoding/en/82.txt similarity index 73% rename from resources/test/geocoding/zh_Hans/86.txt rename to resources/test/geocoding/en/82.txt index a11a43145..f66e0e8c2 100644 --- a/resources/test/geocoding/zh_Hans/86.txt +++ b/resources/test/geocoding/en/82.txt @@ -12,8 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -8610|北京市 -8621|上海市 -86311|河北省石家庄市 -86551|安徽省合肥市 -86888|云南省丽江 +822|Seoul +8231|Gyeonggi +8232|Incheon +8233|Gangwon +8241|Chungnam +8242|Daejeon +8243|Chungbuk +8251|Busan +8252|Ulsan +8253|Daegu +8254|Gyeongbuk +8255|Gyeongnam +8261|Jeonnam +8262|Gwangju +8263|Jeonbuk +8264|Jeju diff --git a/resources/test/geocoding/en/86.txt b/resources/test/geocoding/ko/82.txt similarity index 75% rename from resources/test/geocoding/en/86.txt rename to resources/test/geocoding/ko/82.txt index 22c47444d..9c4162470 100644 --- a/resources/test/geocoding/en/86.txt +++ b/resources/test/geocoding/ko/82.txt @@ -12,9 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -8610|Beijing -8621|Shanghai -86311|Shijiazhuang, Hebei -86851|Guiyang, Guizhou -868029|Zhongba, Tibet -868081|Nyima, Tibet +822|서울 +8231|경기 +8232|인천 +8233|강원 +8241|충남 +8242|대전 +8243|충북 +8251|부산 +8252|울산 +8253|대구 +8254|경북 +8255|경남 +8261|전남 +8262|광주 +8263|전북 +8264|제주 diff --git a/resources/test/geocoding/zh_Hant/86.txt b/resources/test/geocoding/zh_Hant/86.txt deleted file mode 100644 index 5ba062b3c..000000000 --- a/resources/test/geocoding/zh_Hant/86.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) 2011 Google Inc. - -# 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. - -8620|廣州市 -8623|重慶市 -86311|河北省石家莊市 -86553|安徽省蕪湖市 -86888|雲南省麗江