001/*
002 *  Copyright 2012 Christopher Pheby
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.jadira.cdt.country;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import com.google.i18n.phonenumbers.PhoneNumberUtil;
022
023import org.jadira.cdt.country.CountryCode;
024
025/**
026* Enumeration of ISO <a href="http://en.wikipedia.org/wiki/ISO_3166-1">ISO 3166-1</a>
027* country codes.
028* <p>
029* The Enum names of this enumeration themselves are represented by
030* <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a>
031* codes. 
032* Instance methods return country name (getName()), 
033* <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3" >ISO 3166-1 alpha-3</a> codes ({@link ISOCountryCode#getAlpha3Code()}),
034* <a href="http://en.wikipedia.org/wiki/ISO_3166-1_numericCode">ISO 3166-1 numericCode</a> codes ({@link ISOCountryCode#getNumericCode()}),
035* <a href="http://en.wikipedia.org/wiki/E.164">and E.164 the dialling region</a> code ({@link ISOCountryCode#getDiallingRegionCode()})
036* Static factory methods can retrieve ISOCountryCode instances that
037* corresponds to a given code.
038* </p>
039* <p>
040* To update this class, populate using countrynames.txt, downloadable from <a href="http://opengeocode.org/download/countrynames.txt">OpenGeoCode</a>.
041* For the purpose of FMPP, all but one line of header must be removed. 
042* 
043*/
044public enum ISOCountryCode implements CountryCode {
045
046    AF("Afghanistan", "AFG", 4),
047    AX("Aland Islands", "ALA", 248),
048    AL("Albania", "ALB", 8),
049    DZ("Algeria", "DZA", 12),
050    AS("American Samoa", "ASM", 16),
051    AD("Andorra", "AND", 20),
052    AO("Angola", "AGO", 24),
053    AI("Anguilla", "AIA", 660),
054    AQ("Antarctica", "ATA", 10),
055    AG("Antigua and Barbuda", "ATG", 28),
056    AR("Argentina", "ARG", 32),
057    AM("Armenia", "ARM", 51),
058    AW("Aruba", "ABW", 533),
059    AU("Australia", "AUS", 36),
060    AT("Austria", "AUT", 40),
061    AZ("Azerbaijan", "AZE", 31),
062    BS("Bahamas", "BHS", 44),
063    BH("Bahrain", "BHR", 48),
064    BD("Bangladesh", "BGD", 50),
065    BB("Barbados", "BRB", 52),
066    BY("Belarus", "BLR", 112),
067    BE("Belgium", "BEL", 56),
068    BZ("Belize", "BLZ", 84),
069    BJ("Benin", "BEN", 204),
070    BM("Bermuda", "BMU", 60),
071    BT("Bhutan", "BTN", 64),
072    BO("Plurinational State of Bolivia", "BOL", 68),
073    BQ("Bonaire, Sint Eustatius and Saba", "BES", 535),
074    BA("Bosnia and Herzegovina", "BIH", 70),
075    BW("Botswana", "BWA", 72),
076    BV("Bouvet Island", "BVT", 74),
077    BR("Brazil", "BRA", 76),
078    IO("British Indian Ocean Territory", "IOT", 86),
079    BN("Brunei Darussalam", "BRN", 96),
080    BG("Bulgaria", "BGR", 100),
081    BF("Burkina Faso", "BFA", 854),
082    BI("Burundi", "BDI", 108),
083    KH("Cambodia", "KHM", 116),
084    CM("Cameroon", "CMR", 120),
085    CA("Canada", "CAN", 124),
086    CV("Cape Verde", "CPV", 132),
087    KY("Cayman Islands", "CYM", 136),
088    CF("Central African Republic", "CAF", 140),
089    TD("Chad", "TCD", 148),
090    CL("Chile", "CHL", 152),
091    CN("China", "CHN", 156),
092    CX("Christmas Island", "CXR", 162),
093    CC("Cocos (Keeling) Islands", "CCK", 166),
094    CO("Colombia", "COL", 170),
095    KM("Comoros", "COM", 174),
096    CG("Congo", "COG", 178),
097    CD("The Democratic Republic of the Congo", "COD", 180),
098    CK("Cook Islands", "COK", 184),
099    CR("Costa Rica", "CRI", 188),
100    CI("Cote d'Ivoire", "CIV", 384),
101    HR("Croatia", "HRV", 191),
102    CU("Cuba", "CUB", 192),
103    CW("Curacao", "CUW", 531),
104    CY("Cyprus", "CYP", 196),
105    CZ("Czech Republic", "CZE", 203),
106    DK("Denmark", "DNK", 208),
107    DJ("Djibouti", "DJI", 262),
108    DM("Dominica", "DMA", 212),
109    DO("Dominican Republic", "DOM", 214),
110    EC("Ecuador", "ECU", 218),
111    EG("Egypt", "EGY", 818),
112    SV("El Salvador", "SLV", 222),
113    GQ("Equatorial Guinea", "GNQ", 226),
114    ER("Eritrea", "ERI", 232),
115    EE("Estonia", "EST", 233),
116    ET("Ethiopia", "ETH", 231),
117    FK("Falkland Islands (Malvinas)", "FLK", 238),
118    FO("Faroe Islands", "534", 703),
119    FJ("Fiji", "FJI", 242),
120    FI("Finland", "FIN", 246),
121    FR("France", "FRA", 250),
122    GF("French Guiana", "GUF", 254),
123    PF("French Polynesia", "PYF", 258),
124    TF("French Southern Territories", "ATF", 260),
125    GA("Gabon", "GAB", 266),
126    GM("Gambia", "GMB", 270),
127    GE("Georgia", "GEO", 268),
128    DE("Germany", "DEU", 276),
129    GH("Ghana", "GHA", 288),
130    GI("Gibraltar", "GIB", 292),
131    GR("Greece", "GRC", 300),
132    GL("Greenland", "GRL", 304),
133    GD("Grenada", "GRD", 308),
134    GP("Guadeloupe", "GLP", 312),
135    GU("Guam", "GUM", 316),
136    GT("Guatemala", "GTM", 320),
137    GG("Guernsey", "GGY", 831),
138    GN("Guinea", "GIN", 324),
139    GW("Guinea-Bissau", "GNB", 624),
140    GY("Guyana", "GUY", 328),
141    HT("Haiti", "HTI", 332),
142    HM("Heard Island and McDonald Islands", "HMD", 334),
143    VA("Holy See (Vatican City State)", "VAT", 336),
144    HN("Honduras", "HND", 340),
145    HK("Hong Kong", "HKG", 344),
146    HU("Hungary", "HUN", 348),
147    IS("Iceland", "ISL", 352),
148    IN("India", "IND", 356),
149    ID("Indonesia", "IDN", 360),
150    IR("Islamic Republic of Iran", "IRN", 364),
151    IQ("Iraq", "IRQ", 368),
152    IE("Ireland", "IRL", 372),
153    IM("Isle of Man", "IMN", 833),
154    IL("Israel", "ISR", 376),
155    IT("Italy", "ITA", 380),
156    JM("Jamaica", "JAM", 388),
157    JP("Japan", "JPN", 392),
158    JE("Jersey", "JEY", 832),
159    JO("Jordan", "JOR", 400),
160    KZ("Kazakhstan", "KAZ", 398),
161    KE("Kenya", "KEN", 404),
162    KI("Kiribati", "KIR", 296),
163    KP("Democratic People's Republic of Korea", "PRK", 408),
164    KR("Republic of Korea", "KOR", 410),
165    KW("Kuwait", "KWT", 414),
166    KG("Kyrgyzstan", "KGZ", 417),
167    LA("Lao People's Democratic Republic", "LAO", 418),
168    LV("Latvia", "LVA", 428),
169    LB("Lebanon", "LBN", 422),
170    LS("Lesotho", "LSO", 426),
171    LR("Liberia", "LBR", 430),
172    LY("Libyan Arab Jamahiriya", "LBY", 434),
173    LI("Liechtenstein", "LIE", 438),
174    LT("Lithuania", "LTU", 440),
175    LU("Luxembourg", "LUX", 442),
176    MO("Macao", "MAC", 446),
177    MK("The Former Yugoslav Republic of Macedonia", "MKD", 807),
178    MG("Madagascar", "MDG", 450),
179    MW("Malawi", "MWI", 454),
180    MY("Malaysia", "MYS", 458),
181    MV("Maldives", "MDV", 462),
182    ML("Mali", "MLI", 466),
183    MT("Malta", "MLT", 470),
184    MH("Marshall Islands", "MHL", 584),
185    MQ("Martinique", "MTQ", 474),
186    MR("Mauritania", "MRT", 478),
187    MU("Mauritius", "MUS", 480),
188    YT("Mayotte", "MYT", 175),
189    MX("Mexico", "MEX", 484),
190    FM("Federated States of Micronesia", "FSM", 583),
191    MD("Republic of Moldova", "MDA", 498),
192    MC("Monaco", "MCO", 492),
193    MN("Mongolia", "MNG", 496),
194    ME("Montenegro", "MNE", 499),
195    MS("Montserrat", "MSR", 500),
196    MA("Morocco", "MAR", 504),
197    MZ("Mozambique", "MOZ", 508),
198    MM("Myanmar", "MMR", 104),
199    NA("Namibia", "NAM", 516),
200    NR("Nauru", "NRU", 520),
201    NP("Nepal", "NPL", 524),
202    NL("Netherlands", "NLD", 528),
203    NC("New Caledonia", "NCL", 540),
204    NZ("New Zealand", "NZL", 554),
205    NI("Nicaragua", "NIC", 558),
206    NE("Niger", "NER", 562),
207    NG("Nigeria", "NGA", 566),
208    NU("Niue", "NIU", 570),
209    NF("Norfolk Island", "NFK", 574),
210    MP("Northern Mariana Islands", "MNP", 580),
211    NO("Norway", "NOR", 578),
212    PS("Occupied Palestinian Territory", "PSE", 275),
213    OM("Oman", "OMN", 512),
214    PK("Pakistan", "PAK", 586),
215    PW("Palau", "PLW", 585),
216    PA("Panama", "PAN", 591),
217    PG("Papua New Guinea", "PNG", 598),
218    PY("Paraguay", "PRY", 600),
219    PE("Peru", "PER", 604),
220    PH("Philippines", "PHL", 608),
221    PN("Pitcairn", "PCN", 612),
222    PL("Poland", "POL", 616),
223    PT("Portugal", "PRT", 620),
224    PR("Puerto Rico", "PRI", 630),
225    QA("Qatar", "QAT", 634),
226    RE("Reunion", "REU", 638),
227    RO("Romania", "ROU", 642),
228    RU("Russian Federation", "RUS", 643),
229    RW("Rwanda", "RWA", 646),
230    BL("Saint Barthelemy", "534", 703),
231    SH("Saint Helena, Ascension and Tristan da Cunha", "SHN", 654),
232    KN("Saint Kitts and Nevis", "KNA", 659),
233    LC("Saint Lucia", "LCA", 662),
234    MF("Saint Martin (French part)", "MAF", 663),
235    PM("Saint Pierre and Miquelon", "SPM", 666),
236    VC("Saint Vincent and The Grenadines", "VCT", 670),
237    WS("Samoa", "WSM", 882),
238    SM("San Marino", "SMR", 674),
239    ST("Sao Tome and Principe", "STP", 678),
240    SA("Saudi Arabia", "SAU", 682),
241    SN("Senegal", "SEN", 686),
242    RS("Serbia", "SRB", 688),
243    SC("Seychelles", "SYC", 690),
244    SL("Sierra Leone", "SLE", 694),
245    SG("Singapore", "SGP", 702),
246    SX("Sint Maarten (Dutch part)", "SXM", 534),
247    SK("Slovakia", "SVK", 703),
248    SI("Slovenia", "SVN", 705),
249    SB("Solomon Islands", "SLB", 90),
250    SO("Somalia", "SOM", 706),
251    ZA("South Africa", "ZAF", 710),
252    GS("South Georgia and the South Sandwich Islands", "SGS", 239),
253    SS("South Sudan", "SSD", 728),
254    ES("Spain", "ESP", 724),
255    LK("Sri Lanka", "LKA", 144),
256    SD("Sudan", "SDN", 729),
257    SR("Suriname", "SUR", 740),
258    SJ("Svalbard and Jan Mayen", "534", 703),
259    SZ("Swaziland", "SWZ", 748),
260    SE("Sweden", "SWE", 752),
261    CH("Switzerland", "CHE", 756),
262    SY("Syrian Arab Republic", "SYR", 760),
263    TW("Taiwan, Province of China", "TWN", 158),
264    TJ("Tajikistan", "TJK", 762),
265    TZ("United Republic of Tanzania", "TZA", 834),
266    TH("Thailand", "THA", 764),
267    TL("Timor-Leste", "TLS", 626),
268    TG("Togo", "TGO", 768),
269    TK("Tokelau", "TKL", 772),
270    TO("Tonga", "TON", 776),
271    TT("Trinidad and Tobago", "TTO", 780),
272    TN("Tunisia", "TUN", 788),
273    TR("Turkey", "TUR", 792),
274    TM("Turkmenistan", "TKM", 795),
275    TC("Turks and Caicos Islands", "TCA", 796),
276    TV("Tuvalu", "TUV", 798),
277    UG("Uganda", "UGA", 800),
278    UA("Ukraine", "UKR", 804),
279    AE("United Arab Emirates", "ARE", 784),
280    GB("United Kingdom", "GBR", 826),
281    US("United States", "USA", 840),
282    UM("United States Minor Outlying Islands", "UMI", 581),
283    UY("Uruguay", "URY", 858),
284    UZ("Uzbekistan", "UZB", 860),
285    VU("Vanuatu", "VUT", 548),
286    VE("Bolivarian Republic of Venezuela", "VEN", 862),
287    VN("Viet Nam", "VNM", 704),
288    VG("British Virgin Islands", "VGB", 92),
289    VI("U.S. Virgin Islands", "VIR", 850),
290    WF("Wallis and Futuna", "WLF", 876),
291    EH("Western Sahara", "ESH", 732),
292    YE("Yemen", "YEM", 887),
293    ZM("Zambia", "ZMB", 894),
294    ZW("Zimbabwe", "ZWE", 716),
295;
296
297    private static final Map<String, ISOCountryCode> alpha3CodeMap = new HashMap<String, ISOCountryCode>();
298    private static final Map<Integer, ISOCountryCode> numericCodeMap = new HashMap<Integer, ISOCountryCode>();
299
300    private static final PhoneNumberUtil PHONE_NUMBER_UTIL = PhoneNumberUtil.getInstance();
301    
302    static {
303        
304        for (ISOCountryCode next : values()) {
305            alpha3CodeMap.put(next.getAlpha3Code(), next);
306            numericCodeMap.put(next.getNumericCode(), next);
307        }
308    }
309
310    private final String countryName;
311    private final String alpha3Code;
312    private final Integer numericCode;
313
314    private ISOCountryCode(String countryName, String alpha3Code, Integer numericCode) {
315        this.countryName = countryName;
316        this.alpha3Code = alpha3Code;
317        this.numericCode = numericCode;
318    }
319
320        /**
321         * Get the country name.
322         * @return The country name.
323         */
324        public String getCountryName() {
325        return countryName;
326    }
327
328        /**
329         * Get the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2" >ISO 3166-1 alpha-2</a> code.
330         * @return The <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a> code.
331         */
332        public String getAlpha2Code() {
333                return name();
334        }
335
336        /**
337         * Get the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3" >ISO 3166-1 alpha-3</a> code.
338         * @return The <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3">ISO 3166-1 alpha-3</a> code.
339         */
340        public String getAlpha3Code() {
341                return alpha3Code;
342        }
343
344        /**
345         * Get the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_numericCode" >ISO 3166-1 numericCode</a> code.
346         * @return The <a href="http://en.wikipedia.org/wiki/ISO_3166-1_numericCode">ISO 3166-1 numericCode</a> code.
347         */
348        public Integer getNumericCode() {
349                return numericCode;
350        }
351        
352        /**
353         * Gets the <a href="http://en.wikipedia.org/wiki/E.164">International Direct Dial</a> prefix for the country
354         * @return
355         */
356        public Integer getDiallingRegionCode() {
357                return PHONE_NUMBER_UTIL.getCountryCodeForRegion(this.getAlpha2Code());
358        }
359
360        /**
361         * Get a CountryCode that corresponds to a given ISO 3166-1 <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">alpha-2</a> or 
362         * <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3">alpha-3</a> code.
363         * @param code An ISO 3166-1 <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">alpha-2</a> or 
364         * <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3">alpha-3</a> code.
365         * @return A ISOCountryCode instance, or null if not found.
366         */
367        public static ISOCountryCode getByCode(String code) {
368                
369                if (code == null) {
370                        return null;
371                }
372
373                if (code.length() == 2) {
374                        return getByAlpha2Code(code);
375                } else if (code.length() == 3) {
376                        return getByAlpha3Code(code);
377                } else {
378                        return null;
379                }
380        }
381
382        /**
383         * Get a CountryCode that corresponds to a given ISO 3166-1 <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">alpha-2</a> code.
384         * @param code An ISO 3166-1 <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">alpha-2</a>.
385         * @return A ISOCountryCode instance, or null if not found.
386         */
387        public static ISOCountryCode getByAlpha2Code(String code) {
388                try {
389                        return Enum.valueOf(ISOCountryCode.class, code);
390                } catch (IllegalArgumentException e) {
391                        return null;
392                }
393        }
394
395        /**
396         * Get a CountryCode that corresponds to a given ISO 3166-1 <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3">alpha-3</a> code.
397         * @param code An ISO 3166-1 <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3">alpha-3</a> code.
398         * @return A ISOCountryCode instance, or null if not found.
399         */
400        public static ISOCountryCode getByAlpha3Code(String code) {
401                return alpha3CodeMap.get(code);
402        }
403
404        /**
405         * Get a CountryCode that corresponds to a given <a href="http://en.wikipedia.org/wiki/ISO_3166-1_numericCode">ISO 3166-1
406         * numericCode</a> code.
407         * @param code An <a href="http://en.wikipedia.org/wiki/ISO_3166-1_numericCode">ISO 3166-1 numericCode</a> code.
408         * @return A CountryCode instance, or null if not found.
409         */
410        public static ISOCountryCode getByNumericCode(Integer code) {
411                return numericCodeMap.get(code);
412        }
413
414        /**
415         * Get a CountryCode that corresponds to a given <a href="http://en.wikipedia.org/wiki/E.164">Dialling Region</a> code.
416         * @param code An <a href="http://en.wikipedia.org/wiki/E.164">E.164 Dialling Region Code</a> code.
417         * @return A CountryCode instance, or null if not found.
418         */
419        public static ISOCountryCode getByDiallingRegionCode(Integer code) {
420                return getByCode(PHONE_NUMBER_UTIL.getRegionCodeForCountryCode(code));
421        }
422}