1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.common.util;
21  
22  import java.util.MissingResourceException;
23  import java.util.ResourceBundle;
24  
25  import org.crosswire.jsword.internationalisation.LocaleProviderManager;
26  
27  /**
28   * A utility class that converts ISO-3166 codes or locales to their "friendly"
29   * country name.
30   * 
31   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
32   * @author DM Smith
33   */
34  public final class Countries {
35      /**
36       * Make the class a true utility class by having a private constructor.
37       */
38      private Countries() {
39      }
40  
41      /**
42       * Determine whether the country code is valid. The code is valid if it is
43       * null or empty. The code is valid if it is in iso3166.properties. If a
44       * locale is used for the iso3166Code, it will use the part after the '_'.
45       * Thus, this code does not support dialects.
46       * 
47       * @param iso3166Code the country code
48       * @return true if the country is valid.
49       */
50      public static boolean isValidCountry(String iso3166Code) {
51          String lookup = iso3166Code;
52          if (lookup == null || lookup.length() == 0) {
53              return true;
54          }
55  
56          if (lookup.indexOf('_') != -1) {
57              String[] locale = StringUtil.split(lookup, '_');
58              return isValidCountry(locale[1]);
59          }
60  
61          if (lookup.length() > 2) {
62              return false;
63          }
64  
65          try {
66              getLocalisedCountries().getString(lookup);
67              return true;
68          } catch (MissingResourceException e) {
69              return false;
70          }
71      }
72  
73      /**
74       * Get the country name from the country code. If the code is null or empty
75       * then it is considered to be DEFAULT_COUNTRY_CODE (that is, US).
76       * Otherwise, it will generate a log message and return unknown. If a locale
77       * is used for the iso3166Code, it will use the part before the '_'. Thus,
78       * this code does not support dialects, except as found in the iso3166.
79       * 
80       * @param iso3166Code the country code
81       * @return the name of the country
82       */
83      public static String getCountry(String iso3166Code) {
84          String lookup = iso3166Code;
85          if (lookup == null || lookup.length() == 0) {
86              return getCountry(DEFAULT_COUNTRY_CODE);
87          }
88  
89          if (lookup.indexOf('_') != -1) {
90              String[] locale = StringUtil.split(lookup, '_');
91              return getCountry(locale[1]);
92          }
93  
94          try {
95              return getLocalisedCountries().getString(lookup);
96          } catch (MissingResourceException e) {
97              return getCountry(UNKNOWN_COUNTRY_CODE);
98          }
99      }
100 
101     /**
102      * Gets the localised countries.
103      *
104      * @return the localised countries
105      */
106     private static ResourceBundle getLocalisedCountries() {
107         return ResourceBundle.getBundle("iso3166", LocaleProviderManager.getLocale(), CWClassLoader.instance());
108     }
109 
110     public static final String DEFAULT_COUNTRY_CODE = "US";
111     private static final String UNKNOWN_COUNTRY_CODE = "XX";
112 }
113