/[classpath]/classpath/java/util/Locale.java
ViewVC logotype

Diff of /classpath/java/util/Locale.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by ericb, Thu Mar 21 23:01:27 2002 UTC revision 1.13 by ericb, Sun Mar 24 23:42:38 2002 UTC
# Line 1  Line 1 
1  /* Locale.java -- i18n locales  /* Locale.java -- i18n locales
2     Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
6  GNU Classpath is free software; you can redistribute it and/or modify  GNU Classpath is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)  the Free Software Foundation; either version 2, or (at your option)
9  any later version.  any later version.
10    
11  GNU Classpath is distributed in the hope that it will be useful, but  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  General Public License for more details.  General Public License for more details.
15    
16  You should have received a copy of the GNU General Public License  You should have received a copy of the GNU General Public License
17  along with GNU Classpath; see the file COPYING.  If not, write to the  along with GNU Classpath; see the file COPYING.  If not, write to the
18  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19  02111-1307 USA.  02111-1307 USA.
20    
21  Linking this library statically or dynamically with other modules is  Linking this library statically or dynamically with other modules is
22  making a combined work based on this library.  Thus, the terms and  making a combined work based on this library.  Thus, the terms and
23  conditions of the GNU General Public License cover the whole  conditions of the GNU General Public License cover the whole
# Line 37  exception statement from your version. * Line 37  exception statement from your version. *
37    
38  package java.util;  package java.util;
39    
40    import java.io.IOException;
41    import java.io.ObjectInputStream;
42    import java.io.ObjectOutputStream;
43    import java.io.Serializable;
44    
45  /**  /**
46   * Locales represent a specific country and culture.   * Locales represent a specific country and culture. Classes which can be
47   * <br><br>   * passed a Locale object tailor their information for a given locale. For
48   * Classes which can be passed a Locale object tailor their information   * instance, currency number formatting is handled differently for the USA
49   * for a given locale.  For instance, currency number formatting is   * and France.
50   * handled differently for the USA and France.   *
51   * <br><br>   * <p>Locales are made up of a language code, a country code, and an optional
52   * Locales are made up of a language code, a country code, and an optional   * set of variant strings. Language codes are represented by
53   * set of variant strings.   * <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
54   * <br><br>   * ISO 639:1988</a> w/ additions from ISO 639/RA Newsletter No. 1/1989
55   * Language codes are represented by   * and a decision of the Advisory Committee of ISO/TC39 on August 8, 1997.
56   * <a href="http://www.indigo.ie/egt/standards/iso639/iso639-1-en.html">ISO 639:1988</a>   *
57   * w/ additions from ISO 639/RA Newsletter No. 1/1989   * <p>Country codes are represented by
58   * and a decision of the Advisory Committee of ISO/TC39 on   * <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">
59   * August 8, 1997.   * ISO 3166</a>. Variant strings are vendor and browser specific. Standard
60   * <br><br>   * variant strings include "POSIX" for POSIX, "WIN" for MS-Windows, and
61   * Country codes are represented by   * "MAC" for Macintosh. When there is more than one variant string, they must
  * <a href="ftp://ftp.ripe.net/iso3166-countrycodes">ISO 3166</a>.  
  * <br><br>  
  * Variant strings are vendor and browser specific.  Standard variant  
  * strings include "POSIX" for POSIX, "WIN" for MS-Windows, and "MAC" for  
  * Macintosh.  When there is more than one variant string, they must  
62   * be separated by an underscore (U+005F).   * be separated by an underscore (U+005F).
63   * <br><br>   *
64   * The default locale is determined by the values of the system properties   * <p>The default locale is determined by the values of the system properties
65   * user.language, user.region, and user.variant.   * user.language, user.region, and user.variant, defaulting to "en". Note that
66     * the locale does NOT contain the conversion and formatting capabilities (for
67     * that, use ResourceBundle and java.text). Rather, it is an immutable tag
68     * object for identifying a given locale, which is referenced by these other
69     * classes when they must make locale-dependent decisions.
70     *
71   * @see ResourceBundle   * @see ResourceBundle
72   * @see java.text.Format   * @see java.text.Format
73   * @see java.text.NumberFormat   * @see java.text.NumberFormat
74   * @see java.text.Collator   * @see java.text.Collator
75   * @author Jochen Hoenicke   * @author Jochen Hoenicke
76   * @author Paul Fisher   * @author Paul Fisher
77     * @author Eric Blake <ebb9@email.byu.edu>
78     * @since 1.1
79     * @status updated to 1.4
80   */   */
81  public final class Locale implements java.io.Serializable, Cloneable  public final class Locale implements Serializable, Cloneable
82  {  {
83    // NOTE: These static finals must be initialized with the trusted    /** Locale which represents the English language. */
84    // constructor to avoid bootstrap cycles with String.toUpperCase.    public static final Locale ENGLISH = new Locale("en");
85    
86      /** Locale which represents the French language. */
87      public static final Locale FRENCH = new Locale("fr");
88    
89      /** Locale which represents the German language. */
90      public static final Locale GERMAN = new Locale("de");
91    
92      /** Locale which represents the Italian language. */
93      public static final Locale ITALIAN = new Locale("it");
94    
95      /** Locale which represents the Japanese language. */
96      public static final Locale JAPANESE = new Locale("ja");
97    
98      /** Locale which represents the Korean language. */
99      public static final Locale KOREAN = new Locale("ko");
100    
101      /** Locale which represents the Chinese language. */
102      public static final Locale CHINESE = new Locale("zh");
103    
104      /** Locale which represents the Chinese language as used in China. */
105      public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN");
106    
   /**  
    * Locale which represents the English language.  
    */  
   public static final Locale ENGLISH = new Locale("en", "", true);  
   /**  
    * Locale which represents the English language.  
    */  
   public static final Locale FRENCH = new Locale("fr", "", true);  
   /**  
    * Locale which represents the German language.  
    */  
   public static final Locale GERMAN = new Locale("de", "", true);  
   /**  
    * Locale which represents the Italian language.  
    */  
   public static final Locale ITALIAN = new Locale("it", "", true);  
   /**  
    * Locale which represents the Japanese language.  
    */  
   public static final Locale JAPANESE = new Locale("ja", "", true);  
   /**  
    * Locale which represents the Korean language.  
    */  
   public static final Locale KOREAN = new Locale("ko", "", true);  
   /**  
    * Locale which represents the Chinese language.  
    */  
   public static final Locale CHINESE = new Locale("zh", "", true);  
   /**  
    * Locale which represents the Chinese language as used in China.  
    */  
   public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN", true);  
107    /**    /**
108     * Locale which represents the Chinese language as used in Taiwan.     * Locale which represents the Chinese language as used in Taiwan.
109     * Same as TAIWAN Locale.     * Same as TAIWAN Locale.
110     */     */
111    public static final Locale TRADITIONAL_CHINESE = new Locale("zh", "TW", true);    public static final Locale TRADITIONAL_CHINESE = new Locale("zh", "TW");
112    /**  
113     * Locale which represents France.    /** Locale which represents France. */
114     */    public static final Locale FRANCE = new Locale("fr", "FR");
115    public static final Locale FRANCE = new Locale("fr", "FR", true);  
116    /**    /** Locale which represents Germany. */
117     * Locale which represents Germany.    public static final Locale GERMANY = new Locale("de", "DE");
118     */  
119    public static final Locale GERMANY = new Locale("de", "DE", true);    /** Locale which represents Italy. */
120    /**    public static final Locale ITALY = new Locale("it", "IT");
121     * Locale which represents Italy.  
122     */    /** Locale which represents Japan. */
123    public static final Locale ITALY = new Locale("it", "IT", true);    public static final Locale JAPAN = new Locale("ja", "JP");
124    /**  
125     * Locale which represents Japan.    /** Locale which represents Korea. */
126     */    public static final Locale KOREA = new Locale("ko", "KR");
127    public static final Locale JAPAN = new Locale("ja", "JP", true);  
   /**  
    * Locale which represents Korea.  
    */  
   public static final Locale KOREA = new Locale("ko", "KR", true);  
128    /**    /**
129     * Locale which represents China.     * Locale which represents China.
130     * Same as SIMPLIFIED_CHINESE Locale.     * Same as SIMPLIFIED_CHINESE Locale.
131     */     */
132    public static final Locale CHINA = SIMPLIFIED_CHINESE;    public static final Locale CHINA = SIMPLIFIED_CHINESE;
133    
134    /**    /**
135     * Locale which represents the People's Republic of China.     * Locale which represents the People's Republic of China.
136     * Same as CHINA Locale.     * Same as CHINA Locale.
137     */     */
138    public static final Locale PRC = CHINA;    public static final Locale PRC = CHINA;
139    
140    /**    /**
141     * Locale which represents Taiwan.     * Locale which represents Taiwan.
142     * Same as TRADITIONAL_CHINESE Locale.     * Same as TRADITIONAL_CHINESE Locale.
143     */     */
144    public static final Locale TAIWAN = TRADITIONAL_CHINESE;    public static final Locale TAIWAN = TRADITIONAL_CHINESE;
145    /**  
146     * Locale which represents the United Kingdom.    /** Locale which represents the United Kingdom. */
147     */    public static final Locale UK = new Locale("en", "GB");
148    public static final Locale UK = new Locale("en", "GB", true);  
149    /**    /** Locale which represents the United States. */
150     * Locale which represents the United States.    public static final Locale US = new Locale("en", "US");
151     */  
152    public static final Locale US = new Locale("en", "US", true);    /** Locale which represents the English speaking portion of Canada. */
153    /**    public static final Locale CANADA = new Locale("en", "CA");
154     * Locale which represents the English speaking portion of Canada.  
155     */    /** Locale which represents the French speaking portion of Canada. */
156    public static final Locale CANADA = new Locale("en", "CA", true);    public static final Locale CANADA_FRENCH = new Locale("fr", "CA");
   /**  
    * Locale which represents the French speaking portion of Canada.  
    */  
   public static final Locale CANADA_FRENCH = new Locale("fr", "CA", true);  
157    
158    /**    /**
159     * We are compatible to sun's Locale.     * Compatible with JDK 1.1+.
160     */     */
161    private static final long serialVersionUID = 9149081749638150636L;    private static final long serialVersionUID = 9149081749638150636L;
162    
163    /**    /**
164     * The language code, as returned by getLanguage().     * The language code, as returned by getLanguage().
165     * @serial     *
166       * @serial the languange, possibly ""
167     */     */
168    private String language;    private String language;
169    
170    /**    /**
171     * The country code, as returned by getCountry().     * The country code, as returned by getCountry().
172     * @serial     *
173       * @serial the country, possibly ""
174     */     */
175    private String country;    private String country;
176    
177    /**    /**
178     * The variant code, as returned by getVariant().     * The variant code, as returned by getVariant().
179     * @serial     *
180       * @serial the variant, possibly ""
181     */     */
182    private String variant;    private String variant;
183    
184    /**    /**
185     * This is the cached hashcode.  When writing to stream, we write -1.     * This is the cached hashcode. When writing to stream, we write -1.
186     * @serial     *
187       * @serial should be -1 in serial streams
188     */     */
189    private int hashcode;    private int hashcode;
190    
191    /**    /**
192     * Convert old iso639 codes to the new ones.     * The default locale. Except for during bootstrapping, this should never be
193       * null. Note the logic in the main constructor, to detect when
194       * bootstrapping has completed.
195       */
196      private static Locale defaultLocale =
197        new Locale(System.getProperty("user.language", "en"),
198                   System.getProperty("user.region", ""),
199                   System.getProperty("user.variant", ""));
200    
201      /**
202       * Convert new iso639 codes to the old ones.
203       *
204       * @param language the language to check
205       * @return the appropriate code
206     */     */
207    private String convertLanguage(String language)    private String convertLanguage(String language)
208    {    {
209      if (language.equals(""))      if (language.equals(""))
210        return language;        return language;
   
211      language = language.toLowerCase();      language = language.toLowerCase();
212      int index = "iw,in,ji".indexOf(language);      int index = "he,id,yi".indexOf(language);
213      if (index != -1)      if (index != -1)
214        return "he,id,yi".substring(index, index + 2);        return "iw,in,ji".substring(index, index + 2);
215      return language;      return language;
216    }    }
217    
218    /**    /**
219     * Creates a new locale for the given language and country.     * Creates a new locale for the given language and country.
220     * @param language lowercase two-letter ISO-639 A2 language code.     *
221     * @param country uppercase two-letter ISO-3166 A2 contry code.     * @param language lowercase two-letter ISO-639 A2 language code
222     * @param variant vendor and browser specific.     * @param country uppercase two-letter ISO-3166 A2 contry code
223       * @param variant vendor and browser specific
224       * @throws NullPointerException if any argument is null
225     */     */
226    public Locale(String language, String country, String variant)    public Locale(String language, String country, String variant)
227    {    {
228      this.language = convertLanguage(language);      // During bootstrap, we already know the strings being passed in are
229      this.country = country.toUpperCase();      // the correct capitalization, and not null. We can't call
230      this.variant = variant.toUpperCase();      // String.toUpperCase during this time, since that depends on the
231      this.hashcode = (this.language.hashCode() ^ this.country.hashCode()      // default locale.
232                       ^ this.variant.hashCode());      if (defaultLocale != null)
233          {
234            language = convertLanguage(language);
235            country = country.toUpperCase();
236            variant = variant.toUpperCase();
237          }
238        this.language = language;
239        this.country = country;
240        this.variant = variant;
241        hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
242    }    }
243    
244    /**    /**
245     * Creates a new locale for the given language and country.     * Creates a new locale for the given language and country.
246     * @param language lowercase two-letter ISO-639 A2 language code.     *
247     * @param country uppercase two-letter ISO-3166 A2 country code.     * @param language lowercase two-letter ISO-639 A2 language code
248       * @param country uppercase two-letter ISO-3166 A2 country code
249       * @throws NullPointerException if either argument is null
250     */     */
251    public Locale(String language, String country)    public Locale(String language, String country)
252    {    {
# Line 231  public final class Locale implements jav Line 254  public final class Locale implements jav
254    }    }
255    
256    /**    /**
257     * Creates a new locale with trusted versions of the strings. This is     * Creates a new locale for a language.
    * necessary to avoid bootstrap cycles with String.toUpperCase.  
258     *     *
259     * @param language lowercase two-letter ISO-639 A2 language code     * @param language lowercase two-letter ISO-639 A2 language code
260     * @param country uppercase two-letter ISO-3166 A2 contry code     * @throws NullPointerException if either argument is null
261     * @param ignored just for the type signature     * @since 1.4
    *  
262     */     */
263    private Locale(String language, String country, boolean ignored)    public Locale(String language)
264    {    {
265      this.language = language;      this(language, "", "");
     this.country = country;  
     variant = "";  
     hashcode = language.hashCode() ^ country.hashCode();  
266    }    }
267    
   private static Locale defaultLocale =  
     new Locale(System.getProperty("user.language", ""),  
                System.getProperty("user.region", ""), true);  
   
268    /**    /**
269     * Returns the default Locale.  The default locale is generally     * Returns the default Locale. The default locale is generally once set
270     * once set on start up and then never changed.  Normally you     * on start up and then never changed. Normally you should use this locale
271     * should use this locale for everywhere you need a locale.     * for everywhere you need a locale. The initial setting matches the
272     * The initial setting matches the default locale, the user has     * default locale, the user has chosen.
273     * chosen.     *
274       * @return the default locale for this virtual machine
275     */     */
276    public static Locale getDefault()    public static Locale getDefault()
277    {    {
# Line 264  public final class Locale implements jav Line 279  public final class Locale implements jav
279    }    }
280    
281    /**    /**
282     * Changes the default locale.  Normally only called on program     * Changes the default locale. Normally only called on program start up.
283     * start up.  Note that this doesn't change the locale for other     * Note that this doesn't change the locale for other programs. This has
284     * programs.       * a security check,
285       * <code>PropertyPermission("user.language", "write")</code>, because of
286       * its potential impact to running code.
287       *
288       * @param newLocale the new default locale
289       * @throws NullPointerException if newLocale is null
290       * @throws SecurityException if permission is denied
291     */     */
292    public static void setDefault(Locale newLocale)    public static void setDefault(Locale newLocale)
293    {    {
294        if (newLocale == null)
295          throw new NullPointerException();
296        SecurityManager sm = System.getSecurityManager();
297        if (sm != null)
298          sm.checkPermission(new PropertyPermission("user.language", "write"));
299      defaultLocale = newLocale;      defaultLocale = newLocale;
300    }    }
301    
302    /**    /**
303     * Returns the list of available locales.     * Returns the list of available locales.
304       *
305       * @return the installed locales
306     */     */
307    public static Locale[] getAvailableLocales()    public static Locale[] getAvailableLocales()
308    {    {
309      /* I only return those for which localized language      /* I only return those for which localized language
310       * or country information exists.       * or country information exists.
311       * XXX - remove hard coded list.       * XXX - remove hard coded list, and implement more locales (Sun's JDK 1.4
312         * has 148 installed locales!).
313       */       */
314      return new Locale[]      return new Locale[]
315      {      {
# Line 290  public final class Locale implements jav Line 319  public final class Locale implements jav
319    
320    /**    /**
321     * Returns a list of all 2-letter uppercase country codes as defined     * Returns a list of all 2-letter uppercase country codes as defined
322     * in ISO 3166     * in ISO 3166.
323       *
324       * @return a list of acceptible country codes
325     */     */
326    public static String[] getISOCountries()    public static String[] getISOCountries()
327    {    {
328      return new String[]      return new String[]
329      {      {
330         "AF", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG",        "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS",
331         "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD",        "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI",
332         "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BA",        "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA",
333         "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH",        "CC", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU",
334         "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX",        "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE",
335         "CC", "CO", "KM", "CG", "CK", "CR", "CI", "HR", "CU",        "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX",
336         "CY", "CZ", "DK", "DJ", "DM", "DO", "TP", "EC", "EG",        "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ",
337         "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI",        "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU",
338         "FR", "FX", "GF", "PF", "TF", "GA", "GM", "GE", "DE",        "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP",
339         "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GN",        "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA",
340         "GW", "GY", "HT", "HM", "HN", "HK", "HU", "IS", "IN",        "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC",
341         "ID", "IR", "IQ", "IE", "IL", "IT", "JM", "JP", "JO",        "MD", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS",
342         "KZ", "KE", "KI", "KP", "KR", "KW", "KG", "LA", "LV",        "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG",
343         "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK",        "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG",
344         "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR",        "PH", "PK", "PL", "PM", "PN", "PR", "PT", "PW", "PY", "QA", "RE", "RO",
345         "MU", "YT", "MX", "FM", "MD", "MC", "MN", "MS", "MA",        "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK",
346         "MZ", "MM", "NA", "NR", "NP", "NL", "AN", "NC", "NZ",        "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", "TF",
347         "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK",        "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW",
348         "PW", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT",        "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI",
349         "PR", "QA", "RE", "RO", "RU", "RW", "KN", "LC", "VC",        "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZR", "ZW"
350         "WS", "SM", "ST", "SA", "SN", "SC", "SL", "SG", "SK",      };
        "SI", "SB", "SO", "ZA", "GS", "ES", "LK", "SH", "PM",  
        "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ",  
        "TZ", "TH", "TG", "TK", "TO", "TT", "TN", "TR", "TM",  
        "TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY",  
        "UZ", "VU", "VA", "VE", "VN", "VG", "VI", "WF", "EH",  
        "YE", "YU", "ZR", "ZM", "ZW"};  
351    }    }
352    
353    /**    /**
354     * Returns a list of all 2-letter lowercase language codes as defined     * Returns a list of all 2-letter lowercase language codes as defined
355     * in ISO 639 (both old and new variant).     * in ISO 639 (both old and new variant).
356       *
357       * @return a list of acceptable language codes
358     */     */
359    public static String[] getISOLanguages()    public static String[] getISOLanguages()
360    {    {
361      return new String[]      return new String[]
362      {      {
363          "aa", "ab", "af", "am", "ar", "as", "ay", "az", "ba",        "aa", "ab", "af", "am", "ar", "as", "ay", "az", "ba", "be", "bg", "bh",
364          "be", "bg", "bh", "bi", "bn", "bo", "br", "ca", "co",        "bi", "bn", "bo", "br", "ca", "co", "cs", "cy", "da", "de", "dz", "el",
365          "cs", "cy", "da", "de", "dz", "el", "en", "eo", "es",        "en", "eo", "es", "et", "eu", "fa", "fi", "fj", "fo", "fr", "fy", "ga",
366          "et", "eu", "fa", "fi", "fj", "fo", "fr", "fy", "ga",        "gd", "gl", "gn", "gu", "ha", "he", "hi", "hr", "hu", "hy", "ia", "id",
367          "gd", "gl", "gn", "gu", "ha", "iw", "he", "hi", "hr",        "ie", "ik", "in", "is", "it", "iu", "iw", "ja", "ji", "jw", "ka", "kk",
368          "hu", "hy", "ia", "in", "id", "ie", "ik", "is", "it",        "kl", "km", "kn", "ko", "ks", "ku", "ky", "la", "ln", "lo", "lt", "lv",
369          "iu", "ja", "jw", "ka", "kk", "kl", "km", "kn", "ko",        "mg", "mi", "mk", "ml", "mn", "mo", "mr", "ms", "mt", "my", "na", "ne",
370          "ks", "ku", "ky", "la", "ln", "lo", "lt", "lv", "mg",        "nl", "no", "oc", "om", "or", "pa", "pl", "ps", "pt", "qu", "rm", "rn",
371          "mi", "mk", "ml", "mn", "mo", "mr", "ms", "mt", "my",        "ro", "ru", "rw", "sa", "sd", "sg", "sh", "si", "sk", "sl", "sm", "sn",
372          "na", "ne", "nl", "no", "oc", "om", "or", "pa", "pl",        "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta", "te", "tg", "th",
373          "ps", "pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa",        "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ug", "uk", "ur",
374          "sd", "sg", "sh", "si", "sk", "sl", "sm", "sn", "so",        "uz", "vi", "vo", "wo", "xh", "yi", "yo", "za", "zh", "zu"
375          "sq", "sr", "ss", "st", "su", "sv", "sw", "ta", "te",      };
         "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts",  
         "tt", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wo",  
         "xh", "ji", "yi", "yo", "za", "zh", "zu"};  
376    }    }
377    
378    /**    /**
379     * Returns the language code of this locale.     * Returns the language code of this locale. Some language codes have changed
380     * @return language code portion of this locale, or an empty String if     * as ISO 639 has evolved; this returns the old name, even if you built
381     * none exists     * the locale with the new one.
382       *
383       * @return language code portion of this locale, or an empty String
384     */     */
385    public String getLanguage()    public String getLanguage()
386    {    {
# Line 363  public final class Locale implements jav Line 389  public final class Locale implements jav
389    
390    /**    /**
391     * Returns the country code of this locale.     * Returns the country code of this locale.
392     * @return country code portion of this locale, or an empty String if     *
393     * none exists     * @return country code portion of this locale, or an empty String
394     */     */
395    public String getCountry()    public String getCountry()
396    {    {
# Line 373  public final class Locale implements jav Line 399  public final class Locale implements jav
399    
400    /**    /**
401     * Returns the variant code of this locale.     * Returns the variant code of this locale.
402       *
403       * @return the variant code portion of this locale, or an empty String
404     */     */
405    public String getVariant()    public String getVariant()
406    {    {
# Line 380  public final class Locale implements jav Line 408  public final class Locale implements jav
408    }    }
409    
410    /**    /**
411     * Gets the string representation of the current locale.  This     * Gets the string representation of the current locale. This consists of
412     * consists of the language, the country, and the variant,     * the language, the country, and the variant, separated by an underscore.
413     * separated by an underscore.  If one of this three component is     * The variant is listed only if there is a language or country. Examples:
414     * missing the underscore will also disappear.       * "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr__MAC".
415     * @return the string representation of this Locale.     *
416       * @return the string representation of this Locale
417       * @see #getDisplayName()
418     */     */
419    public final String toString()    public final String toString()
420    {    {
421        if (language.length() == 0 && country.length() == 0)
422          return "";
423      StringBuffer result = new StringBuffer(language);      StringBuffer result = new StringBuffer(language);
424      String underscore = "";      result.append('_').append(country);
     if (language.length() != 0)  
       underscore = "_";  
     if (country.length() != 0)  
       {  
         result.append(underscore);  
         result.append(country);  
         underscore = "_";  
       }  
425      if (variant.length() != 0)      if (variant.length() != 0)
426        {        result.append('_').append(variant);
         result.append(underscore);  
         result.append(variant);  
       }  
427      return result.toString();      return result.toString();
428    }    }
429    
430    /**    /**
431     * Returns the three-letter ISO language abbrevation of this locale.     * Returns the three-letter ISO language abbrevation of this locale.
432     * @exception MissingResourceException if the three-letter code is not     *
433     * known.       * @throws MissingResourceException if the three-letter code is not known
434     */     */
435    public String getISO3Language() throws MissingResourceException    public String getISO3Language()
436    {    {
437      int index =      if ("".equals(language))
438        ("aa,ab,af,am,ar,as,ay,az,ba,be,bg,bh,bi,bn,bo,br,ca,co,cs,cy," +        return "";
439         "da,de,dz,el,en,eo,es,et,eu,fa,fi,fj,fo,fr,fy,ga,gd,gl,gn,gu," +      int index
440         "gv,ha,hi,hr,hu,hy,ia,ie,ik,id,is,it,iu,he,ja,yi,jw,ka,kk,kl," +        = ("aa,ab,af,am,ar,as,ay,az,ba,be,bg,bh,bi,bn,bo,br,ca,co,cs,cy,da,"
441         "km,kn,ko,ks,ku,kw,ky,la,lb,ln,lo,lt,lv,mg,mi,mk,ml,mn,mo,mr," +           + "de,dz,el,en,eo,es,et,eu,fa,fi,fj,fo,fr,fy,ga,gd,gl,gn,gu,ha,iw,"
442         "ms,mt,my,na,ne,nl,no,oc,om,or,pa,pl,ps,pt,qu,rm,rn,ro,ru,rw," +           + "hi,hr,hu,hy,ia,in,ie,ik,in,is,it,iu,iw,ja,ji,jw,ka,kk,kl,km,kn,"
443         "sa,sd,se,sg,sh,si,sk,sl,sm,sn,so,sq,sr,ss,st,su,sv,sw,ta,te," +           + "ko,ks,ku,ky,la,ln,lo,lt,lv,mg,mi,mk,ml,mn,mo,mr,ms,mt,my,na,ne,"
444         "tg,th,ti,tk,tl,tn,to,tr,ts,tt,tw,ug,uk,ur,uz,vi,vo,wo,xh,yo," +           + "nl,no,oc,om,or,pa,pl,ps,pt,qu,rm,rn,ro,ru,rw,sa,sd,sg,sh,si,sk,"
445         "za,zh,zu,").indexOf(language + ",");           + "sl,sm,sn,so,sq,sr,ss,st,su,sv,sw,ta,te,tg,th,ti,tk,tl,tn,to,tr,"
446                   + "ts,tt,tw,ug,uk,ur,uz,vi,vo,wo,xh,ji,yo,za,zh,zu")
447      if (index == -1 || language.length() != 2)        .indexOf(language);
448    
449        if (index % 3 != 0 || language.length() != 2)
450        throw new MissingResourceException        throw new MissingResourceException
451          ("Can't find ISO3 language for " + language,          ("Can't find ISO3 language for " + language,
452           "java.util.Locale", language);           "java.util.Locale", language);
453    
454      /* Don't read this aloud.  This are the three letter language codes      // Don't read this aloud. These are the three letter language codes.
      */  
455      return      return
456        ("aarabkaframharaasmaymazebakbelbulbihbisbenbodbrecatcoscescym" +        ("aarabkaframharaasmaymazebakbelbulbihbisbenbodbrecatcoscescymdandeu"
457         "dandeudzoellengepospaesteusfasfinfijfaofrafrygaigdhglggrnguj" +         + "dzoellengepospaesteusfasfinfijfaofrafrygaigdhglggrngujhauhebhinhrv"
458         "maxhauhinhrvhunhyeinaileipkindislitaikuhebjpnyidjawkatkazkal" +         + "hunhyeinaindileipkindislitaikuhebjpnyidjawkatkazkalkhmkankorkaskur"
459         "khmkankorkaskurcorkirlatltzlinlaolitlavmlgmrimkdmalmonmolmar" +         + "kirlatlinlaolitlavmlgmrimkdmalmonmolmarmsamltmyanaunepnldnorociorm"
460         "msamltmyanaunepnldnorociormoripanpolpusporquerohrunronruskin" +         + "oripanpolpusporquerohrunronruskinsansndsagsrpsinslkslvsmosnasomsqi"
461         "sansndsmisagsrpsinslkslvsmosnasomsqisrpsswsotsunsweswatamtel" +         + "srpsswsotsunsweswatamteltgkthatirtuktgltsntonturtsotattwiuigukrurd"
462         "tgkthatirtuktgltsntonturtsotattwiuigukrurduzbvievolwolxhoyor" +         + "uzbvievolwolxhoyidyorzhazhozul")
463         "zhazhozul").substring(index, index + 3);        .substring(index, index + 3);
464    }    }
465    
466    /**    /**
467     * Returns the three-letter ISO country abbrevation of the locale.     * Returns the three-letter ISO country abbrevation of the locale.
468     * @exception MissingResourceException if the three-letter code is not     *
469     * known.     * @throws MissingResourceException if the three-letter code is not known
470     */     */
471    public String getISO3Country() throws MissingResourceException    public String getISO3Country()
472    {    {
473      int index =      if ("".equals(country))
474        ("AF,AL,DZ,AS,AD,AO,AI,AQ,AG,AR,AM,AW,AU,AT,AZ,BS,BH,BD,BB,BY,BE," +        return "";
475         "BZ,BJ,BM,BT,BO,BA,BW,BV,BR,IO,BN,BG,BF,BI,KH,CM,CA,CV,KY,CF,TD," +      int index
476         "CL,CN,CX,CC,CO,KM,CG,CD,CK,CR,CI,HR,CU,CY,CZ,DK,DJ,DM,DO,TP,EC," +        = ("AD,AE,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AT,AU,AW,AZ,BA,BB,BD,BE,BF,"
477         "EG,SV,GQ,ER,EE,ET,FK,FO,FJ,FI,FR,FX,GF,PF,TF,GA,GM,GE,DE,GH,GI," +           + "BG,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CA,CC,CF,CG,CH,CI,CK,"
478         "GR,GL,GD,GP,GU,GT,GN,GW,GY,HT,HM,VA,HN,HK,HU,IS,IN,ID,IR,IQ,IE," +           + "CL,CM,CN,CO,CR,CU,CV,CX,CY,CZ,DE,DJ,DK,DM,DO,DZ,EC,EE,EG,EH,ER,"
479         "IL,IT,JM,JP,JO,KZ,KE,KI,KP,KR,KW,KG,LA,LV,LB,LS,LR,LY,LI,LT,LU," +           + "ES,ET,FI,FJ,FK,FM,FO,FR,FX,GA,GB,GD,GE,GF,GH,GI,GL,GM,GN,GP,GQ,"
480         "MO,MK,MG,MW,MY,MV,ML,MT,MH,MQ,MR,MU,YT,MX,FM,MD,MC,MN,MS,MA,MZ," +           + "GR,GS,GT,GU,GW,GY,HK,HM,HN,HR,HT,HU,ID,IE,IL,IN,IO,IQ,IR,IS,IT,"
481         "MM,NA,NR,NP,NL,AN,NC,NZ,NI,NE,NG,NU,NF,MP,NO,OM,PK,PW,PA,PG,PY," +           + "JM,JO,JP,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,"
482         "PE,PH,PN,PL,PT,PR,QA,RE,RO,RU,RW,KN,LC,VC,WS,SM,ST,SA,SN,SC,SL," +           + "LT,LU,LV,LY,MA,MC,MD,MG,MH,MK,ML,MM,MN,MO,MP,MQ,MR,MS,MT,MU,MV,"
483         "SG,SK,SI,SB,SO,ZA,GS,ES,LK,SH,PM,SD,SR,SJ,SZ,SE,CH,SY,TW,TJ,TZ," +           + "MW,MX,MY,MZ,NA,NC,NE,NF,NG,NI,NL,NO,NP,NR,NU,NZ,OM,PA,PE,PF,PG,"
484         "TH,TG,TK,TO,TT,TN,TR,TM,TC,TV,UG,UA,AE,GB,US,UM,UY,UZ,VU,VE,VN," +           + "PH,PK,PL,PM,PN,PR,PT,PW,PY,QA,RE,RO,RU,RW,SA,SB,SC,SD,SE,SG,SH,"
485         "VG,VI,WF,EH,YE,YU,ZM,ZW,").indexOf(country + ",");           + "SI,SJ,SK,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TM,TN,"
486                   + "TO,TP,TR,TT,TV,TW,TZ,UA,UG,UM,US,UY,UZ,VA,VC,VE,VG,VI,VN,VU,WF,"
487      if (index == -1 || language.length() != 2)           + "WS,YE,YT,YU,ZA,ZM,ZR,ZW")
488          .indexOf(country);
489    
490        if (index % 3 != 0 || language.length() != 2)
491        throw new MissingResourceException        throw new MissingResourceException
492          ("Can't find ISO3 country for " + country,          ("Can't find ISO3 country for " + country,
493           "java.util.Locale", country);           "java.util.Locale", country);
494    
495      /* Don't read this aloud.  This are the three letter country codes      // Don't read this aloud. These are the three letter country codes.
      */  
496      return      return
497        ("AFGALBDZAASMANDAGOAIAATAATGARGARMABWAUSAUTAZEBHSBHRBGDBRBBLRBEL" +        ("ANDAREAFGATGAIAALBARMANTAGOATAARGASMAUTAUSABWAZEBIHBRBBGDBELBFABGR"
498         "BLZBENBMUBTNBOLBIHBWABVTBRAIOTBRNBGRBFABDIKHMCMRCANCPVCYMCAFTCD" +         + "BHRBDIBENBMUBRNBOLBRABHSBTNBVTBWABLRBLZCANCCKCAFCOGCHECIVCOKCHLCMR"
499         "CHLCHNCXRCCKCOLCOMCOGCODCOKCRICIVHRVCUBCYPCZEDNKDJIDMADOMTMPECU" +         + "CHNCOLCRICUBCPVCXRCYPCZEDEUDJIDNKDMADOMDZAECUESTEGYESHERIESPETHFIN"
500         "EGYSLVGNQERIESTETHFLKFROFJIFINFRAFXXGUFPYFATFGABGMBGEODEUGHAGIB" +         + "FJIFLKFSMFROFRAFXXGABGBRGRDGEOGUFGHAGIBGRLGMBGINGLPGNQGRCSGSGTMGUM"
501         "GRCGRLGRDGLPGUMGTMGINGNBGUYHTIHMDVATHNDHKGHUNISLINDIDNIRNIRQIRL" +         + "GNBGUYHKGHMDHNDHRVHTIHUNIDNIRLISRINDIOTIRQIRNISLITAJAMJORJPNKENKGZ"
502         "ISRITAJAMJPNJORKAZKENKIRPRKKORKWTKGZLAOLVALBNLSOLBRLBYLIELTULUX" +         + "KHMKIRCOMKNAPRKKORKWTCYMKAZLAOLBNLCALIELKALBRLSOLTULUXLVALBYMARMCO"
503         "MACMKDMDGMWIMYSMDVMLIMLTMHLMTQMRTMUSMYTMEXFSMMDAMCOMNGMSRMARMOZ" +         + "MDAMDGMHLMKDMLIMMRMNGMACMNPMTQMRTMSRMLTMUSMDVMWIMEXMYSMOZNAMNCLNER"
504         "MMRNAMNRUNPLNLDANTNCLNZLNICNERNGANIUNFKMNPNOROMNPAKPLWPANPNGPRY" +         + "NFKNGANICNLDNORNPLNRUNIUNZLOMNPANPERPYFPNGPHLPAKPOLSPMPCNPRIPRTPLW"
505         "PERPHLPCNPOLPRTPRIQATREUROMRUSRWAKNALCAVCTWSMSMRSTPSAUSENSYCSLE" +         + "PRYQATREUROMRUSRWASAUSLBSYCSDNSWESGPSHNSVNSJMSVKSLESMRSENSOMSURSTP"
506         "SGPSVKSVNSLBSOMZAFSGSESPLKASHNSPMSDNSURSJMSWZSWECHESYRTWNTJKTZA" +         + "SLVSYRSWZTCATCDATFTGOTHATJKTKLTKMTUNTONTMPTURTTOTUVTWNTZAUKRUGAUMI"
507         "THATGOTKLTONTTOTUNTURTKMTCATUVUGAUKRAREGBRUSAUMIURYUZBVUTVENVNM" +         + "USAURYUZBVATVCTVENVGBVIRVNMVUTWLFWSMYEMMYTYUGZAFZMBZARZWE")
508         "VGBVIRWLFESHYEMYUGZMBZWE").substring(index, index + 3);        .substring(index, index + 3);
509    }    }
510    
511    /**    /**
512     * Gets the country name suitable for display to the user, formatted     * Gets the country name suitable for display to the user, formatted
513     * for the default locale.  This has the same effect as     * for the default locale.  This has the same effect as
514     * <pre>     * <pre>
515     * getDisplayLanguage(Locale.getDefault());     * getDisplayLanguage(Locale.getDefault());
516     * </pre>     * </pre>
517     *     *
518     * @return the language name of this locale localized to the     * @return the language name of this locale localized to the default locale,
519     * default locale.  If the localized is not found, the ISO code     *         with the ISO code as backup
    * is returned.  
520     */     */
521    public String getDisplayLanguage()    public String getDisplayLanguage()
522    {    {
523      return getDisplayLanguage(getDefault());      return getDisplayLanguage(defaultLocale);
524    }    }
525    
526    /**    /**
527     * Gets the language name suitable for display to the user, formatted     * Gets the language name suitable for display to the user, formatted
528     * for a specified locale.     * for a specified locale.
529       *
530     * @param locale locale to use for formatting     * @param locale locale to use for formatting
531     * @return the language name of this locale localized to the     * @return the language name of this locale localized to the given locale,
532     * given locale.  If the localized is not found, the ISO code     *         with the ISO code as backup
    * is returned.  
533     */     */
534    public String getDisplayLanguage(Locale locale)    public String getDisplayLanguage(Locale locale)
535    {    {
536      try      try
537        {        {
538          ResourceBundle bundle          ResourceBundle bundle
539            = ResourceBundle.getBundle("gnu.java.locale.iso639", locale);            = ResourceBundle.getBundle("gnu.java.locale.iso639", locale);
540          return bundle.getString(language);          return bundle.getString(language);
541        }        }
542      catch (MissingResourceException ex)      catch (MissingResourceException ex)
543        {        {
544          return language;          return language;
545        }        }
546    }    }
547    
548    /**    /**
549     * Returns the country name of this locale localized to the     * Returns the country name of this locale localized to the
550     * default locale.  If the localized is not found, the ISO code     * default locale. If the localized is not found, the ISO code
551     * is returned.  This has the same effect as     * is returned. This has the same effect as
552     * <pre>     * <pre>
553     * getDisplayCountry(Locale.getDefault());     * getDisplayCountry(Locale.getDefault());
554     * </pre>     * </pre>
555       *
556       * @return the country name of this locale localized to the given locale,
557       *         with the ISO code as backup
558     */     */
559    public String getDisplayCountry()    public String getDisplayCountry()
560    {    {
561      return getDisplayCountry(getDefault());      return getDisplayCountry(defaultLocale);
562    }    }
563    
564    /**    /**
565     * Gets the country name suitable for display to the user, formatted     * Gets the country name suitable for display to the user, formatted
566     * for a specified locale.     * for a specified locale.
567     *     *
568     * @param locale locale to use for formatting     * @param locale locale to use for formatting
569     * @return the country name of this locale localized to the given     * @return the country name of this locale localized to the given locale,
570     * locale.  If the localized is not found, the ISO country code is     *         with the ISO code as backup
571     * returned.  */     */
572    public String getDisplayCountry(Locale locale)    public String getDisplayCountry(Locale locale)
573    {    {
574      try      try
575        {        {
576          ResourceBundle bundle =          ResourceBundle bundle =
577            ResourceBundle.getBundle("gnu.java.locale.iso3166", locale);            ResourceBundle.getBundle("gnu.java.locale.iso3166", locale);
578          return bundle.getString(country);          return bundle.getString(country);
579        }        }
580      catch (MissingResourceException ex)      catch (MissingResourceException ex)
581        {        {
582          return country;          return country;
583        }        }
584    }    }
585    
586    /**    /**
587     * Returns the variant name of this locale localized to the     * Returns the variant name of this locale localized to the
588     * default locale.  If the localized is not found, the variant code     * default locale. If the localized is not found, the variant code
589     * itself is returned.  This has the same effect as     * itself is returned. This has the same effect as
590     * <pre>     * <pre>
591     * getDisplayVariant(Locale.getDefault());     * getDisplayVariant(Locale.getDefault());
592     * </pre>     * </pre>
593       *
594       * @return the variant code of this locale localized to the given locale,
595       *         with the ISO code as backup
596     */     */
597    public String getDisplayVariant()    public String getDisplayVariant()
598    {    {
599      return getDisplayVariant(getDefault());      return getDisplayVariant(defaultLocale);
600    }    }
601    
602    /**    /**
603     * Returns the variant name of this locale localized to the     * Returns the variant name of this locale localized to the
604     * given locale.  If the localized is not found, the variant code     * given locale. If the localized is not found, the variant code
605     * itself is returned.     * itself is returned.
606       *
607       * @param locale locale to use for formatting
608       * @return the variant code of this locale localized to the given locale,
609       *         with the ISO code as backup
610     */     */
611    public String getDisplayVariant(Locale locale)    public String getDisplayVariant(Locale locale)
612    {    {
613      /*XXX - load a bundle? */      // XXX - load a bundle?
614      return variant;      return variant;
615    }    }
616    
617    /**    /**
618     * Gets all local components suitable for display to the user, formatted     * Gets all local components suitable for display to the user, formatted
619     * for the default locale.  For the language component, getDisplayLanguage     * for the default locale. For the language component, getDisplayLanguage
620     * is called.  For the country component, getDisplayCountry is called.     * is called. For the country component, getDisplayCountry is called.
621     * For the variant set component, getDisplayVariant is called.     * For the variant set component, getDisplayVariant is called.
622     * <br><br>     *
623     * The returned String will be one of the following forms:<br>     * <p>The returned String will be one of the following forms:<br>
624     * <pre>     * <pre>
625     * language (country, variant)     * language (country, variant)
626     * language (country)     * language (country)
# Line 597  public final class Locale implements jav Line 630  public final class Locale implements jav
630     * country     * country
631     * variant     * variant
632     * </pre>     * </pre>
633     * @return String version of this locale, suitable for display to the     *
634     * user.     * @return String version of this locale, suitable for display to the user
635     */     */
636    public String getDisplayName()    public String getDisplayName()
637    {    {
638      return getDisplayName(getDefault());      return getDisplayName(defaultLocale);
639    }    }
640    
641    /**    /**
642     * Gets all local components suitable for display to the user, formatted     * Gets all local components suitable for display to the user, formatted
643     * for a specified locale.  For the language component,     * for a specified locale. For the language component,
644     * getDisplayLanguage(Locale) is called.  For the country component,     * getDisplayLanguage(Locale) is called. For the country component,
645     * getDisplayCountry(Locale) is called.  For the variant set component,     * getDisplayCountry(Locale) is called. For the variant set component,
646     * getDisplayVariant(Locale) is called.     * getDisplayVariant(Locale) is called.
647     * <br><br>     *
648     * The returned String will be one of the following forms:<br>     * <p>The returned String will be one of the following forms:<br>
649     * <pre>     * <pre>
650     * language (country, variant)     * language (country, variant)
651     * language (country)     * language (country)
# Line 624  public final class Locale implements jav Line 657  public final class Locale implements jav
657     * </pre>     * </pre>
658     *     *
659     * @param locale locale to use for formatting     * @param locale locale to use for formatting
660     *     * @return String version of this locale, suitable for display to the user
    * @return String version of this locale, suitable for display to the  
    * user.  
661     */     */
662    public String getDisplayName(Locale locale)    public String getDisplayName(Locale locale)
663    {    {
664      StringBuffer result = new StringBuffer();      StringBuffer result = new StringBuffer();
665      int count = 0;      int count = 0;
666      String[] delimiters = {"", " (", ","};      String[] delimiters = {"", " (", ","};
       
667      if (language.length() != 0)      if (language.length() != 0)
668        {        {
669          result.append(delimiters[count++]);          result.append(delimiters[count++]);
670          result.append(getDisplayLanguage(locale));          result.append(getDisplayLanguage(locale));
671        }        }
   
672      if (country.length() != 0)      if (country.length() != 0)
673        {        {
674          result.append(delimiters[count++]);          result.append(delimiters[count++]);
675          result.append(getDisplayCountry(locale));          result.append(getDisplayCountry(locale));
676        }        }
   
677      if (variant.length() != 0)      if (variant.length() != 0)
678        {        {
679          result.append(delimiters[count++]);          result.append(delimiters[count++]);
680          result.append(getDisplayVariant(locale));          result.append(getDisplayVariant(locale));
681        }        }
   
682      if (count > 1)      if (count > 1)
683        result.append(")");        result.append(")");
         
684      return result.toString();      return result.toString();
685    }    }
686    
687    /**    /**
688     * Does the same as <code>Object.clone()</code> but does not throw     * Does the same as <code>Object.clone()</code> but does not throw
689     * an <code>CloneNotSupportedException</code>.  Why anyone would     * a <code>CloneNotSupportedException</code>. Why anyone would
690     * use this method is a secret to me, since this class is     * use this method is a secret to me, since this class is immutable.
691     * immutable.       *
692       * @return the clone
693     */     */
694    public Object clone()    public Object clone()
695    {    {
696      try      // This class is final, so no need to use native super.clone().
697        {      return new Locale(language, country, variant);
         return super.clone();  
       }  
     catch (CloneNotSupportedException ex)  
       {  
         return null;  
       }  
698    }    }
699    
700    /**    /**
701     * Return the hash code for this locale.  The hashcode is the logical     * Return the hash code for this locale. The hashcode is the logical
702     * xor of the hash codes of the language, the country and the variant.     * xor of the hash codes of the language, the country and the variant.
703     * The hash code is precomputed, since <code>Locale</code>s are often     * The hash code is precomputed, since <code>Locale</code>s are often
704     * used in hash tables.     * used in hash tables.
705       *
706       * @return the hashcode
707     */     */
708    public synchronized int hashCode()    public synchronized int hashCode()
709    {    {
# Line 690  public final class Locale implements jav Line 713  public final class Locale implements jav
713    }    }
714    
715    /**    /**
716     * Compares two locales.     * Compares two locales. To be equal, obj must be a Locale with the same
717     * @param obj the other locale.     * language, country, and variant code.
718     * @return true, if obj is a Locale with the same language, country, and     *
719     * variant code as this locale, otherwise false.     * @param obj the other locale
720       * @return true if obj is equal to this
721     */     */
722    public boolean equals(Object obj)    public boolean equals(Object obj)
723    {    {
724      if (this == obj)      if (! (obj instanceof Locale))
       return true;  
     if (!(obj instanceof Locale))  
725        return false;        return false;
726      Locale l = (Locale) obj;      Locale l = (Locale) obj;
727      return (language.equals(l.language)      return (language.equals(l.language)
728              && country.equals(l.country)              && country.equals(l.country)
729              && variant.equals(l.variant));              && variant.equals(l.variant));
730    }    }
731    
732    /**    /**
733     * @serialdata According to jdk1.2 the hashcode should always be     * Write the locale to an object stream.
734     * written as -1;     *
735       * @param output the stream to write to
736       * @throws IOException if the write fails
737       * @serialData the hashcode should always be written as -1, and recomputed
738       *      when reading it back
739     */     */
740    private synchronized void writeObject(java.io.ObjectOutputStream output)    private synchronized void writeObject(ObjectOutputStream output)
741      throws java.io.IOException      throws IOException
742    {    {
743        // Synchronized so that hashCode() doesn't get wrong value.
744      int tmpHashcode = hashcode;      int tmpHashcode = hashcode;
745      hashcode = -1;      hashcode = -1;
746      output.defaultWriteObject();      output.defaultWriteObject();
# Line 721  public final class Locale implements jav Line 748  public final class Locale implements jav
748    }    }
749    
750    /**    /**
751     * @serialdata  According to jdk1.2 the hashCode is always invalid     * Reads a locale from the input stream.
752     * and must be recomputed.     *
753       * @param input the stream to read from
754       * @throws IOException if reading fails
755       * @throws ClassNotFoundException if reading fails
756       * @serialData the hashCode is always invalid and must be recomputed
757     */     */
758    private void readObject(java.io.ObjectInputStream input)    private void readObject(ObjectInputStream input)
759      throws java.io.IOException, ClassNotFoundException      throws IOException, ClassNotFoundException
760    {    {
761      input.defaultReadObject();      input.defaultReadObject();
762      hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();      hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
763    }    }
764  }  } // class Locale

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26