1   /*
2    * %W% %E%
3    *
4    * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
5    * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6    */
7   
8   /*
9    * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
10   * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
11   *
12   * The original version of this source code and documentation
13   * is copyrighted and owned by Taligent, Inc., a wholly-owned
14   * subsidiary of IBM. These materials are provided under terms
15   * of a License Agreement between Taligent and Sun. This technology
16   * is protected by multiple US and International patents.
17   *
18   * This notice and attribution to Taligent may not be removed.
19   * Taligent is a registered trademark of Taligent, Inc.
20   *
21   */
22  
23  package java.util;
24  
25  import java.io.*;
26  import java.security.AccessController;
27  import java.text.MessageFormat;
28  import java.util.List;
29  import java.util.concurrent.ConcurrentHashMap;
30  import java.util.spi.LocaleNameProvider;
31  import java.util.spi.LocaleServiceProvider;
32  import sun.security.action.GetPropertyAction;
33  import sun.util.LocaleServiceProviderPool;
34  import sun.util.resources.LocaleData;
35  import sun.util.resources.OpenListResourceBundle;
36  
37  /**
38   *
39   * A <code>Locale</code> object represents a specific geographical, political,
40   * or cultural region. An operation that requires a <code>Locale</code> to perform
41   * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
42   * to tailor information for the user. For example, displaying a number
43   * is a locale-sensitive operation--the number should be formatted
44   * according to the customs/conventions of the user's native country,
45   * region, or culture.
46   *
47   * <P>
48   * Create a <code>Locale</code> object using the constructors in this class:
49   * <blockquote>
50   * <pre>
51   * Locale(String language)
52   * Locale(String language, String country)
53   * Locale(String language, String country, String variant)
54   * </pre>
55   * </blockquote>
56   * The language argument is a valid <STRONG>ISO Language Code.</STRONG>
57   * These codes are the lower-case, two-letter codes as defined by ISO-639.
58   * You can find a full list of these codes at a number of sites, such as:
59   * <BR><a href ="http://www.loc.gov/standards/iso639-2/englangn.html">
60   * <code>http://www.loc.gov/standards/iso639-2/englangn.html</code></a>
61   *
62   * <P>
63   * The country argument is a valid <STRONG>ISO Country Code.</STRONG> These
64   * codes are the upper-case, two-letter codes as defined by ISO-3166.
65   * You can find a full list of these codes at a number of sites, such as:
66   * <BR><a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">
67   * <code>http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html</code></a>
68   *
69   * <P>
70   * The variant argument is a vendor or browser-specific code.
71   * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX.
72   * Where there are two variants, separate them with an underscore, and
73   * put the most important one first. For example, a Traditional Spanish collation
74   * might construct a locale with parameters for language, country and variant as:
75   * "es", "ES", "Traditional_WIN".
76   *
77   * <P>
78   * Because a <code>Locale</code> object is just an identifier for a region,
79   * no validity check is performed when you construct a <code>Locale</code>.
80   * If you want to see whether particular resources are available for the
81   * <code>Locale</code> you construct, you must query those resources. For
82   * example, ask the <code>NumberFormat</code> for the locales it supports
83   * using its <code>getAvailableLocales</code> method.
84   * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular
85   * locale, you get back the best available match, not necessarily
86   * precisely what you asked for. For more information, look at
87   * {@link ResourceBundle}.
88   *
89   * <P>
90   * The <code>Locale</code> class provides a number of convenient constants
91   * that you can use to create <code>Locale</code> objects for commonly used
92   * locales. For example, the following creates a <code>Locale</code> object
93   * for the United States:
94   * <blockquote>
95   * <pre>
96   * Locale.US
97   * </pre>
98   * </blockquote>
99   *
100  * <P>
101  * Once you've created a <code>Locale</code> you can query it for information about
102  * itself. Use <code>getCountry</code> to get the ISO Country Code and
103  * <code>getLanguage</code> to get the ISO Language Code. You can
104  * use <code>getDisplayCountry</code> to get the
105  * name of the country suitable for displaying to the user. Similarly,
106  * you can use <code>getDisplayLanguage</code> to get the name of
107  * the language suitable for displaying to the user. Interestingly,
108  * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
109  * and have two versions: one that uses the default locale and one
110  * that uses the locale specified as an argument.
111  *
112  * <P>
113  * The Java Platform provides a number of classes that perform locale-sensitive
114  * operations. For example, the <code>NumberFormat</code> class formats
115  * numbers, currency, or percentages in a locale-sensitive manner. Classes
116  * such as <code>NumberFormat</code> have a number of convenience methods
117  * for creating a default object of that type. For example, the
118  * <code>NumberFormat</code> class provides these three convenience methods
119  * for creating a default <code>NumberFormat</code> object:
120  * <blockquote>
121  * <pre>
122  * NumberFormat.getInstance()
123  * NumberFormat.getCurrencyInstance()
124  * NumberFormat.getPercentInstance()
125  * </pre>
126  * </blockquote>
127  * These methods have two variants; one with an explicit locale
128  * and one without; the latter using the default locale.
129  * <blockquote>
130  * <pre>
131  * NumberFormat.getInstance(myLocale)
132  * NumberFormat.getCurrencyInstance(myLocale)
133  * NumberFormat.getPercentInstance(myLocale)
134  * </pre>
135  * </blockquote>
136  * A <code>Locale</code> is the mechanism for identifying the kind of object
137  * (<code>NumberFormat</code>) that you would like to get. The locale is
138  * <STRONG>just</STRONG> a mechanism for identifying objects,
139  * <STRONG>not</STRONG> a container for the objects themselves.
140  *
141  * @see         ResourceBundle
142  * @see         java.text.Format
143  * @see         java.text.NumberFormat
144  * @see         java.text.Collator
145  * @author      Mark Davis
146  * @since       1.1
147  */
148 
149 public final class Locale implements Cloneable, Serializable {
150 
151     // cache to store singleton Locales
152     private final static ConcurrentHashMap<String, Locale> cache =
153     new ConcurrentHashMap<String, Locale>(32);
154 
155     /** Useful constant for language.
156      */
157     static public final Locale ENGLISH = createSingleton("en__", "en", "");
158 
159     /** Useful constant for language.
160      */
161     static public final Locale FRENCH = createSingleton("fr__", "fr", "");
162 
163     /** Useful constant for language.
164      */
165     static public final Locale GERMAN = createSingleton("de__", "de", "");
166 
167     /** Useful constant for language.
168      */
169     static public final Locale ITALIAN = createSingleton("it__", "it", "");
170 
171     /** Useful constant for language.
172      */
173     static public final Locale JAPANESE = createSingleton("ja__", "ja", "");
174 
175     /** Useful constant for language.
176      */
177     static public final Locale KOREAN = createSingleton("ko__", "ko", "");
178 
179     /** Useful constant for language.
180      */
181     static public final Locale CHINESE = createSingleton("zh__", "zh", "");
182 
183     /** Useful constant for language.
184      */
185     static public final Locale SIMPLIFIED_CHINESE = createSingleton("zh_CN_", "zh", "CN");
186 
187     /** Useful constant for language.
188      */
189     static public final Locale TRADITIONAL_CHINESE = createSingleton("zh_TW_", "zh", "TW");
190 
191     /** Useful constant for country.
192      */
193     static public final Locale FRANCE = createSingleton("fr_FR_", "fr", "FR");
194 
195     /** Useful constant for country.
196      */
197     static public final Locale GERMANY = createSingleton("de_DE_", "de", "DE");
198 
199     /** Useful constant for country.
200      */
201     static public final Locale ITALY = createSingleton("it_IT_", "it", "IT");
202 
203     /** Useful constant for country.
204      */
205     static public final Locale JAPAN = createSingleton("ja_JP_", "ja", "JP");
206 
207     /** Useful constant for country.
208      */
209     static public final Locale KOREA = createSingleton("ko_KR_", "ko", "KR");
210 
211     /** Useful constant for country.
212      */
213     static public final Locale CHINA = SIMPLIFIED_CHINESE;
214 
215     /** Useful constant for country.
216      */
217     static public final Locale PRC = SIMPLIFIED_CHINESE;
218 
219     /** Useful constant for country.
220      */
221     static public final Locale TAIWAN = TRADITIONAL_CHINESE;
222 
223     /** Useful constant for country.
224      */
225     static public final Locale UK = createSingleton("en_GB_", "en", "GB");
226 
227     /** Useful constant for country.
228      */
229     static public final Locale US = createSingleton("en_US_", "en", "US");
230 
231     /** Useful constant for country.
232      */
233     static public final Locale CANADA = createSingleton("en_CA_", "en", "CA");
234 
235     /** Useful constant for country.
236      */
237     static public final Locale CANADA_FRENCH = createSingleton("fr_CA_", "fr", "CA");
238 
239     /**
240      * Useful constant for the root locale.  The root locale is the locale whose
241      * language, country, and variant are empty ("") strings.  This is regarded
242      * as the base locale of all locales, and is used as the language/country 
243      * neutral locale for the locale sensitive operations.
244      *
245      * @since 1.6
246      */
247     static public final Locale ROOT = createSingleton("__", "", "");
248 
249     /** serialization ID
250      */
251     static final long serialVersionUID = 9149081749638150636L;
252 
253     /**
254      * Display types for retrieving localized names from the name providers.
255      */
256     private static final int DISPLAY_LANGUAGE = 0;
257     private static final int DISPLAY_COUNTRY  = 1;
258     private static final int DISPLAY_VARIANT  = 2;
259 
260     /**
261      * Construct a locale from language, country, variant.
262      * NOTE:  ISO 639 is not a stable standard; some of the language codes it defines
263      * (specifically iw, ji, and in) have changed.  This constructor accepts both the
264      * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other 
265      * API on Locale will return only the OLD codes. 
266      * @param language lowercase two-letter ISO-639 code.
267      * @param country uppercase two-letter ISO-3166 code.
268      * @param variant vendor and browser specific code. See class description.
269      * @exception NullPointerException thrown if any argument is null.
270      */
271     public Locale(String language, String country, String variant) {
272         this.language = convertOldISOCodes(language);
273         this.country = toUpperCase(country).intern();
274         this.variant = variant.intern();
275     }
276 
277     /**
278      * Construct a locale from language, country.
279      * NOTE:  ISO 639 is not a stable standard; some of the language codes it defines
280      * (specifically iw, ji, and in) have changed.  This constructor accepts both the
281      * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other 
282      * API on Locale will return only the OLD codes. 
283      * @param language lowercase two-letter ISO-639 code.
284      * @param country uppercase two-letter ISO-3166 code.
285      * @exception NullPointerException thrown if either argument is null.
286      */
287     public Locale(String language, String country) {
288         this(language, country, "");
289     }
290 
291     /**
292      * Construct a locale from a language code.
293      * NOTE:  ISO 639 is not a stable standard; some of the language codes it defines
294      * (specifically iw, ji, and in) have changed.  This constructor accepts both the
295      * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other 
296      * API on Locale will return only the OLD codes. 
297      * @param language lowercase two-letter ISO-639 code.
298      * @exception NullPointerException thrown if argument is null.
299      * @since 1.4
300      */
301     public Locale(String language) {
302         this(language, "", "");
303     }
304 
305     /**
306      * Constructs a <code>Locale</code> using <code>language</code>
307      * and <code>country</code>.  This constructor assumes that
308      * <code>language</code> and <code>contry</code> are interned and
309      * it is invoked by createSingleton only. (flag is just for
310      * avoiding the conflict with the public constructors.
311      */
312     private Locale(String language, String country, boolean flag) {
313     this.language = language;
314     this.country = country;
315     this.variant = "";
316     }
317 
318     /**
319      * Creates a <code>Locale</code> instance with the given
320      * <code>language</code> and <code>counry</code> and puts the
321      * instance under the given <code>key</code> in the cache. This
322      * method must be called only when initializing the Locale
323      * constants.
324      */
325     private static Locale createSingleton(String key, String language, String country) {
326     Locale locale = new Locale(language, country, false);
327     cache.put(key, locale);
328     return locale;
329     }
330 
331     /**
332      * Returns a <code>Locale</code> constructed from the given
333      * <code>language</code>, <code>country</code> and
334      * <code>variant</code>. If the same <code>Locale</code> instance
335      * is available in the cache, then that instance is
336      * returned. Otherwise, a new <code>Locale</code> instance is
337      * created and cached.
338      *
339      * @param language lowercase two-letter ISO-639 code.
340      * @param country uppercase two-letter ISO-3166 code.
341      * @param variant vendor and browser specific code. See class description.
342      * @return the <code>Locale</code> instance requested
343      * @exception NullPointerException if any argument is null.
344      */
345     static Locale getInstance(String language, String country, String variant) {
346         if (language== null || country == null || variant == null) {
347             throw new NullPointerException();
348         }
349 
350     StringBuilder sb = new StringBuilder();
351     sb.append(language).append('_').append(country).append('_').append(variant);
352     String key = sb.toString();
353     Locale locale = cache.get(key);
354     if (locale == null) {
355         locale = new Locale(language, country, variant);
356         Locale l = cache.putIfAbsent(key, locale);
357         if (l != null) {
358         locale = l;
359         }
360     }
361     return locale;
362     }
363 
364     /**
365      * Gets the current value of the default locale for this instance
366      * of the Java Virtual Machine.
367      * <p>
368      * The Java Virtual Machine sets the default locale during startup
369      * based on the host environment. It is used by many locale-sensitive
370      * methods if no locale is explicitly specified.
371      * It can be changed using the
372      * {@link #setDefault(java.util.Locale) setDefault} method.
373      *
374      * @return the default locale for this instance of the Java Virtual Machine
375      */
376     public static Locale getDefault() {
377         // do not synchronize this method - see 4071298
378         // it's OK if more than one default locale happens to be created
379         if (defaultLocale == null) {
380             String language, region, country, variant;
381             language = (String) AccessController.doPrivileged(
382                             new GetPropertyAction("user.language", "en"));
383             // for compatibility, check for old user.region property
384             region = (String) AccessController.doPrivileged(
385                             new GetPropertyAction("user.region"));
386             if (region != null) {
387                 // region can be of form country, country_variant, or _variant
388                 int i = region.indexOf('_');
389                 if (i >= 0) {
390                     country = region.substring(0, i);
391                     variant = region.substring(i + 1);
392                 } else {
393                     country = region;
394                     variant = "";
395                 }
396             } else {
397                 country = (String) AccessController.doPrivileged(
398                                 new GetPropertyAction("user.country", ""));
399                 variant = (String) AccessController.doPrivileged(
400                                 new GetPropertyAction("user.variant", ""));
401             }
402             defaultLocale = getInstance(language, country, variant);
403         }
404         return defaultLocale;
405     }
406 
407     /**
408      * Sets the default locale for this instance of the Java Virtual Machine.
409      * This does not affect the host locale.
410      * <p>
411      * If there is a security manager, its <code>checkPermission</code>
412      * method is called with a <code>PropertyPermission("user.language", "write")</code>
413      * permission before the default locale is changed.
414      * <p>
415      * The Java Virtual Machine sets the default locale during startup
416      * based on the host environment. It is used by many locale-sensitive
417      * methods if no locale is explicitly specified.
418      * <p>
419      * Since changing the default locale may affect many different areas
420      * of functionality, this method should only be used if the caller
421      * is prepared to reinitialize locale-sensitive code running
422      * within the same Java Virtual Machine.
423      *
424      * @throws SecurityException
425      *        if a security manager exists and its
426      *        <code>checkPermission</code> method doesn't allow the operation.
427      * @throws NullPointerException if <code>newLocale</code> is null
428      * @param newLocale the new default locale
429      * @see SecurityManager#checkPermission
430      * @see java.util.PropertyPermission
431      */
432     public static synchronized void setDefault(Locale newLocale) {
433         if (newLocale == null)
434             throw new NullPointerException("Can't set default locale to NULL");
435 
436         SecurityManager sm = System.getSecurityManager();
437         if (sm != null) sm.checkPermission(new PropertyPermission
438                         ("user.language", "write"));
439             defaultLocale = newLocale;
440     }
441 
442     /**
443      * Returns an array of all installed locales.
444      * The returned array represents the union of locales supported 
445      * by the Java runtime environment and by installed 
446      * {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider}
447      * implementations.  It must contain at least a <code>Locale</code>
448      * instance equal to {@link java.util.Locale#US Locale.US}.
449      *
450      * @return An array of installed locales.
451      */
452     public static Locale[] getAvailableLocales() {
453         return LocaleServiceProviderPool.getAllAvailableLocales();
454     }
455 
456     /**
457      * Returns a list of all 2-letter country codes defined in ISO 3166.
458      * Can be used to create Locales.
459      */
460     public static String[] getISOCountries() {
461         if (isoCountries == null) {
462             isoCountries = getISO2Table(LocaleISOData.isoCountryTable);
463         }
464         String[] result = new String[isoCountries.length];
465         System.arraycopy(isoCountries, 0, result, 0, isoCountries.length);
466         return result;
467     }
468 
469     /**
470      * Returns a list of all 2-letter language codes defined in ISO 639.
471      * Can be used to create Locales.
472      * [NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
473      * The list this function returns includes both the new and the old codes for the
474      * languages whose codes have changed.]
475      */
476     public static String[] getISOLanguages() {
477         if (isoLanguages == null) {
478             isoLanguages = getISO2Table(LocaleISOData.isoLanguageTable);
479         }
480         String[] result = new String[isoLanguages.length];
481         System.arraycopy(isoLanguages, 0, result, 0, isoLanguages.length);
482         return result;
483     }
484 
485     private static final String[] getISO2Table(String table) {
486     int len = table.length() / 5;
487     String[] isoTable = new String[len];
488     for (int i = 0, j = 0; i < len; i++, j += 5) {
489         isoTable[i] = table.substring(j, j + 2);
490     }
491     return isoTable;
492     }
493 
494     /**
495      * Returns the language code for this locale, which will either be the empty string
496      * or a lowercase ISO 639 code.
497      * <p>NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
498      * Locale's constructor recognizes both the new and the old codes for the languages
499      * whose codes have changed, but this function always returns the old code.  If you 
500      * want to check for a specific language whose code has changed, don't do <pre> 
501      * if (locale.getLanguage().equals("he")) 
502      *    ... 
503      * </pre>Instead, do<pre> 
504      * if (locale.getLanguage().equals(new Locale("he", "", "").getLanguage())) 
505      *    ...</pre>
506      * @see #getDisplayLanguage
507      */
508     public String getLanguage() {
509         return language;
510     }
511 
512     /**
513      * Returns the country/region code for this locale, which will
514      * either be the empty string or an uppercase ISO 3166 2-letter code.
515      * @see #getDisplayCountry
516      */
517     public String getCountry() {
518         return country;
519     }
520 
521     /**
522      * Returns the variant code for this locale.
523      * @see #getDisplayVariant
524      */
525     public String getVariant() {
526         return variant;
527     }
528 
529     /**
530      * Getter for the programmatic name of the entire locale,
531      * with the language, country and variant separated by underbars.
532      * Language is always lower case, and country is always upper case.
533      * If the language is missing, the string will begin with an underbar.
534      * If both the language and country fields are missing, this function
535      * will return the empty string, even if the variant field is filled in
536      * (you can't have a locale with just a variant-- the variant must accompany
537      * a valid language or country code).
538      * Examples: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr__MAC"
539      * @see #getDisplayName
540      */
541     public final String toString() {
542         boolean l = language.length() != 0;
543         boolean c = country.length() != 0;
544         boolean v = variant.length() != 0;
545         StringBuilder result = new StringBuilder(language);
546         if (c||(l&&v)) {
547             result.append('_').append(country); // This may just append '_'
548         }
549         if (v&&(l||c)) {
550             result.append('_').append(variant);
551         }
552         return result.toString();
553     }
554 
555     /**
556      * Returns a three-letter abbreviation for this locale's language.  If the locale
557      * doesn't specify a language, this will be the empty string.  Otherwise, this will
558      * be a lowercase ISO 639-2/T language code.
559      * The ISO 639-2 language codes can be found on-line at
560      * <a href="http://www.loc.gov/standards/iso639-2/englangn.html">
561      * <code>http://www.loc.gov/standards/iso639-2/englangn.html</code>.</a>
562      * @exception MissingResourceException Throws MissingResourceException if the
563      * three-letter language abbreviation is not available for this locale.
564      */
565     public String getISO3Language() throws MissingResourceException {
566     String language3 = getISO3Code(language, LocaleISOData.isoLanguageTable);
567         if (language3 == null) {
568             throw new MissingResourceException("Couldn't find 3-letter language code for "
569                     + language, "FormatData_" + toString(), "ShortLanguage");
570         }
571         return language3;
572     }
573 
574     /**
575      * Returns a three-letter abbreviation for this locale's country.  If the locale
576      * doesn't specify a country, this will be the empty string.  Otherwise, this will
577      * be an uppercase ISO 3166 3-letter country code.
578      * The ISO 3166-2 country codes can be found on-line at
579      * <a href="http://www.davros.org/misc/iso3166.txt">
580      * <code>http://www.davros.org/misc/iso3166.txt</code>.</a>
581      * @exception MissingResourceException Throws MissingResourceException if the
582      * three-letter country abbreviation is not available for this locale.
583      */
584     public String getISO3Country() throws MissingResourceException {
585     String country3 = getISO3Code(country, LocaleISOData.isoCountryTable);
586         if (country3 == null) {
587             throw new MissingResourceException("Couldn't find 3-letter country code for "
588                     + country, "FormatData_" + toString(), "ShortCountry");
589         }
590     return country3;
591     }
592 
593     private static final String getISO3Code(String iso2Code, String table) {
594     int codeLength = iso2Code.length();
595         if (codeLength == 0) {
596             return "";
597         }
598 
599     int tableLength = table.length();
600         int index = tableLength;
601     if (codeLength == 2) {
602         char c1 = iso2Code.charAt(0);
603         char c2 = iso2Code.charAt(1);
604         for (index = 0; index < tableLength; index += 5) {
605         if (table.charAt(index) == c1
606             && table.charAt(index + 1) == c2) {
607             break;
608         }
609         }
610     }
611         return index < tableLength ? table.substring(index + 2, index + 5) : null;
612     }
613 
614     /**
615      * Returns a name for the locale's language that is appropriate for display to the
616      * user.
617      * If possible, the name returned will be localized for the default locale.
618      * For example, if the locale is fr_FR and the default locale
619      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
620      * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
621      * If the name returned cannot be localized for the default locale,
622      * (say, we don't have a Japanese name for Croatian),
623      * this function falls back on the English name, and uses the ISO code as a last-resort
624      * value.  If the locale doesn't specify a language, this function returns the empty string.
625      */
626     public final String getDisplayLanguage() {
627         return getDisplayLanguage(getDefault());
628     }
629 
630     /**
631      * Returns a name for the locale's language that is appropriate for display to the
632      * user.
633      * If possible, the name returned will be localized according to inLocale.
634      * For example, if the locale is fr_FR and inLocale
635      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
636      * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
637      * If the name returned cannot be localized according to inLocale,
638      * (say, we don't have a Japanese name for Croatian),
639      * this function falls back on the English name, and finally
640      * on the ISO code as a last-resort value.  If the locale doesn't specify a language,
641      * this function returns the empty string.
642      *
643      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
644      */
645     public String getDisplayLanguage(Locale inLocale) {
646         return getDisplayString(language, inLocale, DISPLAY_LANGUAGE);
647     }
648 
649     /**
650      * Returns a name for the locale's country that is appropriate for display to the
651      * user.
652      * If possible, the name returned will be localized for the default locale.
653      * For example, if the locale is fr_FR and the default locale
654      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
655      * the default locale is fr_FR, getDisplayCountry() will return "Etats-Unis".
656      * If the name returned cannot be localized for the default locale,
657      * (say, we don't have a Japanese name for Croatia),
658      * this function falls back on the English name, and uses the ISO code as a last-resort
659      * value.  If the locale doesn't specify a country, this function returns the empty string.
660      */
661     public final String getDisplayCountry() {
662         return getDisplayCountry(getDefault());
663     }
664 
665     /**
666      * Returns a name for the locale's country that is appropriate for display to the
667      * user.
668      * If possible, the name returned will be localized according to inLocale.
669      * For example, if the locale is fr_FR and inLocale
670      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
671      * inLocale is fr_FR, getDisplayCountry() will return "Etats-Unis".
672      * If the name returned cannot be localized according to inLocale.
673      * (say, we don't have a Japanese name for Croatia),
674      * this function falls back on the English name, and finally
675      * on the ISO code as a last-resort value.  If the locale doesn't specify a country,
676      * this function returns the empty string.
677      *
678      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
679      */
680     public String getDisplayCountry(Locale inLocale) {
681         return getDisplayString(country, inLocale, DISPLAY_COUNTRY);
682     }
683     
684     private String getDisplayString(String code, Locale inLocale, int type) {
685         if (code.length() == 0) {
686             return "";
687         }
688 
689         if (inLocale == null) {
690             throw new NullPointerException();
691         }
692 
693         try {
694             OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
695             String key = (type == DISPLAY_VARIANT ? "%%"+code : code);
696             String result = null;
697 
698             // Check whether a provider can provide an implementation that's closer 
699             // to the requested locale than what the Java runtime itself can provide.
700             LocaleServiceProviderPool pool =
701                 LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
702             if (pool.hasProviders()) {
703                 result = pool.getLocalizedObject(
704                                     LocaleNameGetter.INSTANCE,
705                                     inLocale, bundle, key,
706                                     type, code);
707             }
708 
709             if (result == null) {
710                 result = bundle.getString(key);
711             }
712 
713             if (result != null) {
714                 return result;
715             }
716         }
717         catch (Exception e) {
718             // just fall through
719         }
720         return code;
721     }
722 
723     /**
724      * Returns a name for the locale's variant code that is appropriate for display to the
725      * user.  If possible, the name will be localized for the default locale.  If the locale
726      * doesn't specify a variant code, this function returns the empty string.
727      */
728     public final String getDisplayVariant() {
729         return getDisplayVariant(getDefault());
730     }
731 
732     /**
733      * Returns a name for the locale's variant code that is appropriate for display to the
734      * user.  If possible, the name will be localized for inLocale.  If the locale
735      * doesn't specify a variant code, this function returns the empty string.
736      *
737      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
738      */
739     public String getDisplayVariant(Locale inLocale) {
740         if (variant.length() == 0)
741             return "";
742 
743         OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
744 
745         String names[] = getDisplayVariantArray(bundle, inLocale);
746 
747         // Get the localized patterns for formatting a list, and use
748         // them to format the list.
749         String listPattern = null;
750         String listCompositionPattern = null;
751         try {
752             listPattern = bundle.getString("ListPattern");
753             listCompositionPattern = bundle.getString("ListCompositionPattern");
754         } catch (MissingResourceException e) {
755         }
756         return formatList(names, listPattern, listCompositionPattern);
757     }
758 
759     /**
760      * Returns a name for the locale that is appropriate for display to the
761      * user.  This will be the values returned by getDisplayLanguage(), getDisplayCountry(),
762      * and getDisplayVariant() assembled into a single string.  The display name will have
763      * one of the following forms:<p><blockquote>
764      * language (country, variant)<p>
765      * language (country)<p>
766      * language (variant)<p>
767      * country (variant)<p>
768      * language<p>
769      * country<p>
770      * variant<p></blockquote>
771      * depending on which fields are specified in the locale.  If the language, country,
772      * and variant fields are all empty, this function returns the empty string.
773      */
774     public final String getDisplayName() {
775         return getDisplayName(getDefault());
776     }
777 
778     /**
779      * Returns a name for the locale that is appropriate for display to the
780      * user.  This will be the values returned by getDisplayLanguage(), getDisplayCountry(),
781      * and getDisplayVariant() assembled into a single string.  The display name will have
782      * one of the following forms:<p><blockquote>
783      * language (country, variant)<p>
784      * language (country)<p>
785      * language (variant)<p>
786      * country (variant)<p>
787      * language<p>
788      * country<p>
789      * variant<p></blockquote>
790      * depending on which fields are specified in the locale.  If the language, country,
791      * and variant fields are all empty, this function returns the empty string.
792      *
793      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
794      */
795     public String getDisplayName(Locale inLocale) {
796         OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
797 
798         String languageName = getDisplayLanguage(inLocale);
799         String countryName = getDisplayCountry(inLocale);
800         String[] variantNames = getDisplayVariantArray(bundle, inLocale);
801 
802         // Get the localized patterns for formatting a display name.
803         String displayNamePattern = null;
804         String listPattern = null;
805         String listCompositionPattern = null;
806         try {
807             displayNamePattern = bundle.getString("DisplayNamePattern");
808             listPattern = bundle.getString("ListPattern");
809             listCompositionPattern = bundle.getString("ListCompositionPattern");
810         } catch (MissingResourceException e) {
811         }
812 
813         // The display name consists of a main name, followed by qualifiers.
814         // Typically, the format is "MainName (Qualifier, Qualifier)" but this
815         // depends on what pattern is stored in the display locale.
816         String   mainName       = null;
817         String[] qualifierNames = null;
818 
819         // The main name is the language, or if there is no language, the country.
820         // If there is neither language nor country (an anomalous situation) then
821         // the display name is simply the variant's display name.
822         if (languageName.length() != 0) {
823             mainName = languageName;
824             if (countryName.length() != 0) {
825                 qualifierNames = new String[variantNames.length + 1];
826                 System.arraycopy(variantNames, 0, qualifierNames, 1, variantNames.length);
827                 qualifierNames[0] = countryName;
828             }
829             else qualifierNames = variantNames;
830         }
831         else if (countryName.length() != 0) {
832             mainName = countryName;
833             qualifierNames = variantNames;
834         }
835         else {
836             return formatList(variantNames, listPattern, listCompositionPattern);
837         }
838 
839         // Create an array whose first element is the number of remaining
840         // elements.  This serves as a selector into a ChoiceFormat pattern from
841         // the resource.  The second and third elements are the main name and
842         // the qualifier; if there are no qualifiers, the third element is
843         // unused by the format pattern.
844         Object[] displayNames = {
845             new Integer(qualifierNames.length != 0 ? 2 : 1),
846             mainName,
847             // We could also just call formatList() and have it handle the empty
848             // list case, but this is more efficient, and we want it to be
849             // efficient since all the language-only locales will not have any
850             // qualifiers.
851             qualifierNames.length != 0 ? formatList(qualifierNames, listPattern, listCompositionPattern) : null
852         };
853 
854         if (displayNamePattern != null) {
855             return new MessageFormat(displayNamePattern).format(displayNames);
856         }
857         else {
858             // If we cannot get the message format pattern, then we use a simple
859             // hard-coded pattern.  This should not occur in practice unless the
860             // installation is missing some core files (FormatData etc.).
861             StringBuilder result = new StringBuilder();
862             result.append((String)displayNames[1]);
863             if (displayNames.length > 2) {
864                 result.append(" (");
865                 result.append((String)displayNames[2]);
866                 result.append(')');
867             }
868             return result.toString();
869         }
870     }
871 
872     /**
873      * Overrides Cloneable
874      */
875     public Object clone()
876     {
877         try {
878             Locale that = (Locale)super.clone();
879             return that;
880         } catch (CloneNotSupportedException e) {
881             throw new InternalError();
882         }
883     }
884 
885     /**
886      * Override hashCode.
887      * Since Locales are often used in hashtables, caches the value
888      * for speed.
889      */
890     public int hashCode() {
891         int hc = hashCodeValue;
892         if (hc == 0) {
893         hc = (language.hashCode() << 8) ^ country.hashCode() ^ (variant.hashCode() << 4);
894             hashCodeValue = hc;
895         }
896         return hc;
897     }
898 
899     // Overrides
900 
901     /**
902      * Returns true if this Locale is equal to another object.  A Locale is
903      * deemed equal to another Locale with identical language, country,
904      * and variant, and unequal to all other objects.
905      *
906      * @return true if this Locale is equal to the specified object.
907      */
908 
909     public boolean equals(Object obj) {
910         if (this == obj)                      // quick check
911             return true;
912         if (!(obj instanceof Locale))
913             return false;
914         Locale other = (Locale) obj;
915     return language == other.language
916             && country == other.country
917             && variant == other.variant;
918     }
919 
920     // ================= privates =====================================
921 
922     // XXX instance and class variables. For now keep these separate, since it is
923     // faster to match. Later, make into single string.
924 
925     /**
926      * @serial
927      * @see #getLanguage
928      */
929     private final String language;
930 
931     /**
932      * @serial
933      * @see #getCountry
934      */
935     private final String country;
936 
937     /**
938      * @serial
939      * @see #getVariant
940      */
941     private final String variant;
942 
943     /**
944      * Placeholder for the object's hash code.  Always -1.
945      * @serial
946      */
947     private volatile int hashcode = -1;        // lazy evaluate
948 
949     /**
950      * Calculated hashcode to fix 4518797.
951      */
952     private transient volatile int hashCodeValue = 0;
953 
954     private static Locale defaultLocale = null;
955 
956     /**
957      * Return an array of the display names of the variant.
958      * @param bundle the ResourceBundle to use to get the display names
959      * @return an array of display names, possible of zero length.
960      */
961     private String[] getDisplayVariantArray(OpenListResourceBundle bundle, Locale inLocale) {
962         // Split the variant name into tokens separated by '_'.
963         StringTokenizer tokenizer = new StringTokenizer(variant, "_");
964         String[] names = new String[tokenizer.countTokens()];
965 
966         // For each variant token, lookup the display name.  If
967         // not found, use the variant name itself.
968         for (int i=0; i<names.length; ++i) {
969             names[i] = getDisplayString(tokenizer.nextToken(), 
970                                 inLocale, DISPLAY_VARIANT); 
971         }
972 
973         return names;
974     }
975 
976     /**
977      * Format a list using given pattern strings.
978      * If either of the patterns is null, then a the list is
979      * formatted by concatenation with the delimiter ','.
980      * @param stringList the list of strings to be formatted.
981      * @param listPattern should create a MessageFormat taking 0-3 arguments
982      * and formatting them into a list.
983      * @param listCompositionPattern should take 2 arguments
984      * and is used by composeList.
985      * @return a string representing the list.
986      */
987     private static String formatList(String[] stringList, String listPattern, String listCompositionPattern) {
988         // If we have no list patterns, compose the list in a simple,
989         // non-localized way.
990         if (listPattern == null || listCompositionPattern == null) {
991             StringBuffer result = new StringBuffer();
992             for (int i=0; i<stringList.length; ++i) {
993                 if (i>0) result.append(',');
994                 result.append(stringList[i]);
995             }
996             return result.toString();
997         }
998 
999         // Compose the list down to three elements if necessary
1000        if (stringList.length > 3) {
1001            MessageFormat format = new MessageFormat(listCompositionPattern);
1002            stringList = composeList(format, stringList);
1003        }
1004
1005        // Rebuild the argument list with the list length as the first element
1006        Object[] args = new Object[stringList.length + 1];
1007        System.arraycopy(stringList, 0, args, 1, stringList.length);
1008        args[0] = new Integer(stringList.length);
1009
1010        // Format it using the pattern in the resource
1011        MessageFormat format = new MessageFormat(listPattern);
1012        return format.format(args);
1013    }
1014
1015    /**
1016     * Given a list of strings, return a list shortened to three elements.
1017     * Shorten it by applying the given format to the first two elements
1018     * recursively.
1019     * @param format a format which takes two arguments
1020     * @param list a list of strings
1021     * @return if the list is three elements or shorter, the same list;
1022     * otherwise, a new list of three elements.
1023     */
1024    private static String[] composeList(MessageFormat format, String[] list) {
1025        if (list.length <= 3) return list;
1026
1027        // Use the given format to compose the first two elements into one
1028        String[] listItems = { list[0], list[1] };
1029        String newItem = format.format(listItems);
1030
1031        // Form a new list one element shorter
1032        String[] newList = new String[list.length-1];
1033        System.arraycopy(list, 2, newList, 1, newList.length-1);
1034        newList[0] = newItem;
1035
1036        // Recurse
1037        return composeList(format, newList);
1038    }
1039
1040    /**
1041     * Replace the deserialized Locale object with a newly
1042     * created object. Newer language codes are replaced with older ISO 
1043     * codes. The country and variant codes are replaced with internalized 
1044     * String copies. 
1045     */
1046    private Object readResolve() throws java.io.ObjectStreamException {
1047        return getInstance(language, country, variant);
1048    }
1049
1050    private static volatile String[] isoLanguages = null;
1051
1052    private static volatile String[] isoCountries = null;
1053
1054    /*
1055     * Locale needs its own, locale insensitive version of toLowerCase to
1056     * avoid circularity problems between Locale and String.
1057     * The most straightforward algorithm is used. Look at optimizations later.
1058     */
1059    private String toLowerCase(String str) {
1060    char[] buf = new char[str.length()];
1061        for (int i = 0; i < buf.length; i++) {
1062        buf[i] = Character.toLowerCase(str.charAt(i));
1063        }
1064        return new String( buf );
1065    }
1066
1067    /*
1068     * Locale needs its own, locale insensitive version of toUpperCase to
1069     * avoid circularity problems between Locale and String.
1070     * The most straightforward algorithm is used. Look at optimizations later.
1071     */
1072    private String toUpperCase(String str) {
1073    char[] buf = new char[str.length()];
1074        for (int i = 0; i < buf.length; i++) {
1075        buf[i] = Character.toUpperCase(str.charAt(i));
1076        }
1077        return new String( buf );
1078    }
1079
1080    private String convertOldISOCodes(String language) { 
1081        // we accept both the old and the new ISO codes for the languages whose ISO 
1082        // codes have changed, but we always store the OLD code, for backward compatibility 
1083        language = toLowerCase(language).intern(); 
1084        if (language == "he") { 
1085            return "iw"; 
1086        } else if (language == "yi") { 
1087            return "ji"; 
1088        } else if (language == "id") { 
1089            return "in"; 
1090        } else { 
1091            return language; 
1092        }
1093    }
1094
1095    /**
1096     * Obtains a localized locale names from a LocaleNameProvider
1097     * implementation.
1098     */
1099    private static class LocaleNameGetter 
1100        implements LocaleServiceProviderPool.LocalizedObjectGetter<LocaleNameProvider, String> {
1101        private static final LocaleNameGetter INSTANCE = new LocaleNameGetter();
1102
1103        public String getObject(LocaleNameProvider localeNameProvider,
1104                                Locale locale, 
1105                                String key,
1106                                Object... params) {
1107            assert params.length == 2;
1108            int type = (Integer)params[0];
1109            String code = (String)params[1];
1110
1111            switch(type) {
1112            case DISPLAY_LANGUAGE:
1113        return localeNameProvider.getDisplayLanguage(code, locale);
1114            case DISPLAY_COUNTRY:
1115        return localeNameProvider.getDisplayCountry(code, locale);
1116            case DISPLAY_VARIANT:
1117        return localeNameProvider.getDisplayVariant(code, locale);
1118            default:
1119                assert false; // shouldn't happen
1120            }
1121
1122            return null;
1123        }
1124    }
1125}
1126