KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > Locale


1 /*
2  * @(#)Locale.java 1.79 04/05/10
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN 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 JavaDoc;
27 import java.text.MessageFormat JavaDoc;
28 import sun.security.action.GetPropertyAction;
29 import sun.text.resources.LocaleData;
30
31 /**
32  *
33  * A <code>Locale</code> object represents a specific geographical, political,
34  * or cultural region. An operation that requires a <code>Locale</code> to perform
35  * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
36  * to tailor information for the user. For example, displaying a number
37  * is a locale-sensitive operation--the number should be formatted
38  * according to the customs/conventions of the user's native country,
39  * region, or culture.
40  *
41  * <P>
42  * Create a <code>Locale</code> object using the constructors in this class:
43  * <blockquote>
44  * <pre>
45  * Locale(String language)
46  * Locale(String language, String country)
47  * Locale(String language, String country, String variant)
48  * </pre>
49  * </blockquote>
50  * The language argument is a valid <STRONG>ISO Language Code.</STRONG>
51  * These codes are the lower-case, two-letter codes as defined by ISO-639.
52  * You can find a full list of these codes at a number of sites, such as:
53  * <BR><a href ="http://www.loc.gov/standards/iso639-2/englangn.html">
54  * <code>http://www.loc.gov/standards/iso639-2/englangn.html</code></a>
55  *
56  * <P>
57  * The country argument is a valid <STRONG>ISO Country Code.</STRONG> These
58  * codes are the upper-case, two-letter codes as defined by ISO-3166.
59  * You can find a full list of these codes at a number of sites, such as:
60  * <BR><a HREF="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">
61  * <code>http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html</code></a>
62  *
63  * <P>
64  * The variant argument is a vendor or browser-specific code.
65  * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX.
66  * Where there are two variants, separate them with an underscore, and
67  * put the most important one first. For example, a Traditional Spanish collation
68  * might construct a locale with parameters for language, country and variant as:
69  * "es", "ES", "Traditional_WIN".
70  *
71  * <P>
72  * Because a <code>Locale</code> object is just an identifier for a region,
73  * no validity check is performed when you construct a <code>Locale</code>.
74  * If you want to see whether particular resources are available for the
75  * <code>Locale</code> you construct, you must query those resources. For
76  * example, ask the <code>NumberFormat</code> for the locales it supports
77  * using its <code>getAvailableLocales</code> method.
78  * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular
79  * locale, you get back the best available match, not necessarily
80  * precisely what you asked for. For more information, look at
81  * {@link ResourceBundle}.
82  *
83  * <P>
84  * The <code>Locale</code> class provides a number of convenient constants
85  * that you can use to create <code>Locale</code> objects for commonly used
86  * locales. For example, the following creates a <code>Locale</code> object
87  * for the United States:
88  * <blockquote>
89  * <pre>
90  * Locale.US
91  * </pre>
92  * </blockquote>
93  *
94  * <P>
95  * Once you've created a <code>Locale</code> you can query it for information about
96  * itself. Use <code>getCountry</code> to get the ISO Country Code and
97  * <code>getLanguage</code> to get the ISO Language Code. You can
98  * use <code>getDisplayCountry</code> to get the
99  * name of the country suitable for displaying to the user. Similarly,
100  * you can use <code>getDisplayLanguage</code> to get the name of
101  * the language suitable for displaying to the user. Interestingly,
102  * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
103  * and have two versions: one that uses the default locale and one
104  * that uses the locale specified as an argument.
105  *
106  * <P>
107  * The Java 2 platform provides a number of classes that perform locale-sensitive
108  * operations. For example, the <code>NumberFormat</code> class formats
109  * numbers, currency, or percentages in a locale-sensitive manner. Classes
110  * such as <code>NumberFormat</code> have a number of convenience methods
111  * for creating a default object of that type. For example, the
112  * <code>NumberFormat</code> class provides these three convenience methods
113  * for creating a default <code>NumberFormat</code> object:
114  * <blockquote>
115  * <pre>
116  * NumberFormat.getInstance()
117  * NumberFormat.getCurrencyInstance()
118  * NumberFormat.getPercentInstance()
119  * </pre>
120  * </blockquote>
121  * These methods have two variants; one with an explicit locale
122  * and one without; the latter using the default locale.
123  * <blockquote>
124  * <pre>
125  * NumberFormat.getInstance(myLocale)
126  * NumberFormat.getCurrencyInstance(myLocale)
127  * NumberFormat.getPercentInstance(myLocale)
128  * </pre>
129  * </blockquote>
130  * A <code>Locale</code> is the mechanism for identifying the kind of object
131  * (<code>NumberFormat</code>) that you would like to get. The locale is
132  * <STRONG>just</STRONG> a mechanism for identifying objects,
133  * <STRONG>not</STRONG> a container for the objects themselves.
134  *
135  * @see ResourceBundle
136  * @see java.text.Format
137  * @see java.text.NumberFormat
138  * @see java.text.Collator
139  * @author Mark Davis
140  * @since 1.1
141  */

142
143 public final class Locale implements Cloneable JavaDoc, Serializable {
144
145     /** Useful constant for language.
146      */

147     static public final Locale JavaDoc ENGLISH = new Locale JavaDoc("en","","");
148
149     /** Useful constant for language.
150      */

151     static public final Locale JavaDoc FRENCH = new Locale JavaDoc("fr","","");
152
153     /** Useful constant for language.
154      */

155     static public final Locale JavaDoc GERMAN = new Locale JavaDoc("de","","");
156
157     /** Useful constant for language.
158      */

159     static public final Locale JavaDoc ITALIAN = new Locale JavaDoc("it","","");
160
161     /** Useful constant for language.
162      */

163     static public final Locale JavaDoc JAPANESE = new Locale JavaDoc("ja","","");
164
165     /** Useful constant for language.
166      */

167     static public final Locale JavaDoc KOREAN = new Locale JavaDoc("ko","","");
168
169     /** Useful constant for language.
170      */

171     static public final Locale JavaDoc CHINESE = new Locale JavaDoc("zh","","");
172
173     /** Useful constant for language.
174      */

175     static public final Locale JavaDoc SIMPLIFIED_CHINESE = new Locale JavaDoc("zh","CN","");
176
177     /** Useful constant for language.
178      */

179     static public final Locale JavaDoc TRADITIONAL_CHINESE = new Locale JavaDoc("zh","TW","");
180
181     /** Useful constant for country.
182      */

183     static public final Locale JavaDoc FRANCE = new Locale JavaDoc("fr","FR","");
184
185     /** Useful constant for country.
186      */

187     static public final Locale JavaDoc GERMANY = new Locale JavaDoc("de","DE","");
188
189     /** Useful constant for country.
190      */

191     static public final Locale JavaDoc ITALY = new Locale JavaDoc("it","IT","");
192
193     /** Useful constant for country.
194      */

195     static public final Locale JavaDoc JAPAN = new Locale JavaDoc("ja","JP","");
196
197     /** Useful constant for country.
198      */

199     static public final Locale JavaDoc KOREA = new Locale JavaDoc("ko","KR","");
200
201     /** Useful constant for country.
202      */

203     static public final Locale JavaDoc CHINA = new Locale JavaDoc("zh","CN","");
204
205     /** Useful constant for country.
206      */

207     static public final Locale JavaDoc PRC = new Locale JavaDoc("zh","CN","");
208
209     /** Useful constant for country.
210      */

211     static public final Locale JavaDoc TAIWAN = new Locale JavaDoc("zh","TW","");
212
213     /** Useful constant for country.
214      */

215     static public final Locale JavaDoc UK = new Locale JavaDoc("en","GB","");
216
217     /** Useful constant for country.
218      */

219     static public final Locale JavaDoc US = new Locale JavaDoc("en","US","");
220
221     /** Useful constant for country.
222      */

223     static public final Locale JavaDoc CANADA = new Locale JavaDoc("en","CA","");
224
225     /** Useful constant for country.
226      */

227     static public final Locale JavaDoc CANADA_FRENCH = new Locale JavaDoc("fr","CA","");
228
229     /** serialization ID
230      */

231     static final long serialVersionUID = 9149081749638150636L;
232
233     /**
234      * Construct a locale from language, country, variant.
235      * NOTE: ISO 639 is not a stable standard; some of the language codes it defines
236      * (specifically iw, ji, and in) have changed. This constructor accepts both the
237      * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other
238      * API on Locale will return only the OLD codes.
239      * @param language lowercase two-letter ISO-639 code.
240      * @param country uppercase two-letter ISO-3166 code.
241      * @param variant vendor and browser specific code. See class description.
242      * @exception NullPointerException thrown if any argument is null.
243      */

244     public Locale(String JavaDoc language, String JavaDoc country, String JavaDoc variant) {
245         this.language = convertOldISOCodes(language);
246         this.country = toUpperCase(country).intern();
247         this.variant = variant.intern();
248     }
249
250     /**
251      * Construct a locale from language, country.
252      * NOTE: ISO 639 is not a stable standard; some of the language codes it defines
253      * (specifically iw, ji, and in) have changed. This constructor accepts both the
254      * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other
255      * API on Locale will return only the OLD codes.
256      * @param language lowercase two-letter ISO-639 code.
257      * @param country uppercase two-letter ISO-3166 code.
258      * @exception NullPointerException thrown if either argument is null.
259      */

260     public Locale(String JavaDoc language, String JavaDoc country) {
261         this(language, country, "");
262     }
263
264     /**
265      * Construct a locale from a language code.
266      * NOTE: ISO 639 is not a stable standard; some of the language codes it defines
267      * (specifically iw, ji, and in) have changed. This constructor accepts both the
268      * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other
269      * API on Locale will return only the OLD codes.
270      * @param language lowercase two-letter ISO-639 code.
271      * @exception NullPointerException thrown if argument is null.
272      * @since 1.4
273      */

274     public Locale(String JavaDoc language) {
275         this(language, "", "");
276     }
277
278
279     /**
280      * Gets the current value of the default locale for this instance
281      * of the Java Virtual Machine.
282      * <p>
283      * The Java Virtual Machine sets the default locale during startup
284      * based on the host environment. It is used by many locale-sensitive
285      * methods if no locale is explicitly specified.
286      * It can be changed using the
287      * {@link #setDefault(java.util.Locale) setDefault} method.
288      *
289      * @return the default locale for this instance of the Java Virtual Machine
290      */

291     public static Locale JavaDoc getDefault() {
292         // do not synchronize this method - see 4071298
293
// it's OK if more than one default locale happens to be created
294
if (defaultLocale == null) {
295             String JavaDoc language, region, country, variant;
296             language = (String JavaDoc) AccessController.doPrivileged(
297                             new GetPropertyAction("user.language", "en"));
298             // for compatibility, check for old user.region property
299
region = (String JavaDoc) AccessController.doPrivileged(
300                             new GetPropertyAction("user.region"));
301             if (region != null) {
302                 // region can be of form country, country_variant, or _variant
303
int i = region.indexOf('_');
304                 if (i >= 0) {
305                     country = region.substring(0, i);
306                     variant = region.substring(i + 1);
307                 } else {
308                     country = region;
309                     variant = "";
310                 }
311             } else {
312                 country = (String JavaDoc) AccessController.doPrivileged(
313                                 new GetPropertyAction("user.country", ""));
314                 variant = (String JavaDoc) AccessController.doPrivileged(
315                                 new GetPropertyAction("user.variant", ""));
316             }
317             defaultLocale = new Locale JavaDoc(language, country, variant);
318         }
319         return defaultLocale;
320     }
321
322     /**
323      * Sets the default locale for this instance of the Java Virtual Machine.
324      * This does not affect the host locale.
325      * <p>
326      * If there is a security manager, its <code>checkPermission</code>
327      * method is called with a <code>PropertyPermission("user.language", "write")</code>
328      * permission before the default locale is changed.
329      * <p>
330      * The Java Virtual Machine sets the default locale during startup
331      * based on the host environment. It is used by many locale-sensitive
332      * methods if no locale is explicitly specified.
333      * <p>
334      * Since changing the default locale may affect many different areas
335      * of functionality, this method should only be used if the caller
336      * is prepared to reinitialize locale-sensitive code running
337      * within the same Java Virtual Machine, such as the user interface.
338      *
339      * @throws SecurityException
340      * if a security manager exists and its
341      * <code>checkPermission</code> method doesn't allow the operation.
342      * @throws NullPointerException if <code>newLocale</code> is null
343      * @param newLocale the new default locale
344      * @see SecurityManager#checkPermission
345      * @see java.util.PropertyPermission
346      */

347     public static synchronized void setDefault(Locale JavaDoc newLocale) {
348         if (newLocale == null)
349             throw new NullPointerException JavaDoc("Can't set default locale to NULL");
350
351         SecurityManager JavaDoc sm = System.getSecurityManager();
352         if (sm != null) sm.checkPermission(new PropertyPermission JavaDoc
353                         ("user.language", "write"));
354             defaultLocale = newLocale;
355     }
356
357     /**
358      * Returns an array of all installed locales.
359      * The array returned must contain at least a <code>Locale</code>
360      * instance equal to {@link java.util.Locale#US Locale.US}.
361      *
362      * @return An array of installed locales.
363      */

364     public static Locale JavaDoc[] getAvailableLocales() {
365         return LocaleData.getAvailableLocales("LocaleString");
366     }
367
368     /**
369      * Returns a list of all 2-letter country codes defined in ISO 3166.
370      * Can be used to create Locales.
371      */

372     public static String JavaDoc[] getISOCountries() {
373         if (isoCountries == null) {
374             isoCountries = new String JavaDoc[compressedIsoCountries.length() / 6];
375             for (int i = 0; i < isoCountries.length; i++)
376                 isoCountries[i] = compressedIsoCountries.substring((i * 6) + 1, (i * 6) + 3);
377         }
378         String JavaDoc[] result = new String JavaDoc[isoCountries.length];
379         System.arraycopy(isoCountries, 0, result, 0, isoCountries.length);
380         return result;
381     }
382
383     /**
384      * Returns a list of all 2-letter language codes defined in ISO 639.
385      * Can be used to create Locales.
386      * [NOTE: ISO 639 is not a stable standard-- some languages' codes have changed.
387      * The list this function returns includes both the new and the old codes for the
388      * languages whose codes have changed.]
389      */

390     public static String JavaDoc[] getISOLanguages() {
391         if (isoLanguages == null) {
392             isoLanguages = new String JavaDoc[compressedIsoLanguages.length() / 6];
393             for (int i = 0; i < isoLanguages.length; i++)
394                 isoLanguages[i] = compressedIsoLanguages.substring((i * 6) + 1, (i * 6) + 3);
395         }
396         String JavaDoc[] result = new String JavaDoc[isoLanguages.length];
397         System.arraycopy(isoLanguages, 0, result, 0, isoLanguages.length);
398         return result;
399     }
400
401     /**
402      * Returns the language code for this locale, which will either be the empty string
403      * or a lowercase ISO 639 code.
404      * <p>NOTE: ISO 639 is not a stable standard-- some languages' codes have changed.
405      * Locale's constructor recognizes both the new and the old codes for the languages
406      * whose codes have changed, but this function always returns the old code. If you
407      * want to check for a specific language whose code has changed, don't do <pre>
408      * if (locale.getLanguage().equals("he")
409      * ...
410      * </pre>Instead, do<pre>
411      * if (locale.getLanguage().equals(new Locale("he", "", "").getLanguage())
412      * ...</pre>
413      * @see #getDisplayLanguage
414      */

415     public String JavaDoc getLanguage() {
416         return language;
417     }
418
419     /**
420      * Returns the country/region code for this locale, which will
421      * either be the empty string or an uppercase ISO 3166 2-letter code.
422      * @see #getDisplayCountry
423      */

424     public String JavaDoc getCountry() {
425         return country;
426     }
427
428     /**
429      * Returns the variant code for this locale.
430      * @see #getDisplayVariant
431      */

432     public String JavaDoc getVariant() {
433         return variant;
434     }
435
436     /**
437      * Getter for the programmatic name of the entire locale,
438      * with the language, country and variant separated by underbars.
439      * Language is always lower case, and country is always upper case.
440      * If the language is missing, the string will begin with an underbar.
441      * If both the language and country fields are missing, this function
442      * will return the empty string, even if the variant field is filled in
443      * (you can't have a locale with just a variant-- the variant must accompany
444      * a valid language or country code).
445      * Examples: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr__MAC"
446      * @see #getDisplayName
447      */

448     public final String JavaDoc toString() {
449         boolean l = language.length() != 0;
450         boolean c = country.length() != 0;
451         boolean v = variant.length() != 0;
452         StringBuffer JavaDoc result = new StringBuffer JavaDoc(language);
453         if (c||(l&&v)) {
454             result.append('_').append(country); // This may just append '_'
455
}
456         if (v&&(l||c)) {
457             result.append('_').append(variant);
458         }
459         return result.toString();
460     }
461
462     /**
463      * Returns a three-letter abbreviation for this locale's language. If the locale
464      * doesn't specify a language, this will be the empty string. Otherwise, this will
465      * be a lowercase ISO 639-2/T language code.
466      * The ISO 639-2 language codes can be found on-line at
467      * <a HREF="http://www.loc.gov/standards/iso639-2/englangn.html"><code>http://www.loc.gov/standards/iso639-2/englangn.html</code></a>
468      * @exception MissingResourceException Throws MissingResourceException if the
469      * three-letter language abbreviation is not available for this locale.
470      */

471     public String JavaDoc getISO3Language() throws MissingResourceException JavaDoc {
472         int length = language.length();
473
474         if (length == 0) {
475             return "";
476         }
477
478         int index = compressedIsoLanguages.indexOf("," + language);
479         if (index == -1 || length != 2) {
480             throw new MissingResourceException JavaDoc("Couldn't find 3-letter language code for "
481                     + language, "LocaleElements_" + toString(), "ShortLanguage");
482         }
483         return compressedIsoLanguages.substring(index + 3, index + 6);
484     }
485
486     /**
487      * Returns a three-letter abbreviation for this locale's country. If the locale
488      * doesn't specify a country, this will be the empty string. Otherwise, this will
489      * be an uppercase ISO 3166 3-letter country code.
490      * The ISO 3166-2 country codes can be found on-line at
491      * <a HREF="http://www.davros.org/misc/iso3166.txt"><code>http://www.davros.org/misc/iso3166.txt</code></a>
492      * @exception MissingResourceException Throws MissingResourceException if the
493      * three-letter country abbreviation is not available for this locale.
494      */

495     public String JavaDoc getISO3Country() throws MissingResourceException JavaDoc {
496         int length = country.length();
497
498         if (length == 0) {
499             return "";
500         }
501
502         int index = compressedIsoCountries.indexOf("," + country);
503         if (index == -1 || length != 2) {
504             throw new MissingResourceException JavaDoc("Couldn't find 3-letter country code for "
505                     + country, "LocaleElements_" + toString(), "ShortCountry");
506         }
507         return compressedIsoCountries.substring(index + 3, index + 6);
508     }
509
510     /**
511      * Returns a name for the locale's language that is appropriate for display to the
512      * user.
513      * If possible, the name returned will be localized for the default locale.
514      * For example, if the locale is fr_FR and the default locale
515      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
516      * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
517      * If the name returned cannot be localized for the default locale,
518      * (say, we don't have a Japanese name for Croatian),
519      * this function falls back on the English name, and uses the ISO code as a last-resort
520      * value. If the locale doesn't specify a language, this function returns the empty string.
521      */

522     public final String JavaDoc getDisplayLanguage() {
523         return getDisplayLanguage(getDefault());
524     }
525
526     /**
527      * Returns a name for the locale's language that is appropriate for display to the
528      * user.
529      * If possible, the name returned will be localized according to inLocale.
530      * For example, if the locale is fr_FR and inLocale
531      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
532      * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
533      * If the name returned cannot be localized according to inLocale,
534      * (say, we don't have a Japanese name for Croatian),
535      * this function falls back on the default locale, on the English name, and finally
536      * on the ISO code as a last-resort value. If the locale doesn't specify a language,
537      * this function returns the empty string.
538      */

539     public String JavaDoc getDisplayLanguage(Locale JavaDoc inLocale) {
540         String JavaDoc langCode = language;
541         if (langCode.length() == 0)
542             return "";
543
544         Locale JavaDoc workingLocale = (Locale JavaDoc)inLocale.clone();
545         String JavaDoc result = null;
546         int phase = 0;
547         boolean done = false;
548
549         if (workingLocale.variant.length() == 0)
550             phase = 1;
551         if (workingLocale.country.length() == 0)
552             phase = 2;
553
554         while (!done) {
555             try {
556                 ResourceBundle JavaDoc bundle = LocaleData.getLocaleElements(workingLocale);
557                 result = findStringMatch((String JavaDoc[][])bundle.getObject("Languages"),
558                                     langCode, langCode);
559                 if (result.length() != 0)
560                     done = true;
561             }
562             catch (Exception JavaDoc e) {
563                 // just fall through
564
}
565
566             if (!done) {
567                 switch (phase) {
568                     case 0:
569                         workingLocale = new Locale JavaDoc(workingLocale.language,
570                                                    workingLocale.country,
571                                                    "");
572                         break;
573
574                     case 1:
575                         workingLocale = new Locale JavaDoc(workingLocale.language,
576                                                    "",
577                                                    workingLocale.variant);
578                         break;
579
580                     case 2:
581                         workingLocale = getDefault();
582                         break;
583
584                     case 3:
585                         workingLocale = new Locale JavaDoc("", "", "");
586                         break;
587
588                     default:
589                         return langCode;
590                 }
591                 phase++;
592             }
593         }
594         return result;
595     }
596
597     /**
598      * Returns a name for the locale's country that is appropriate for display to the
599      * user.
600      * If possible, the name returned will be localized for the default locale.
601      * For example, if the locale is fr_FR and the default locale
602      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
603      * the default locale is fr_FR, getDisplayLanguage() will return "Etats-Unis".
604      * If the name returned cannot be localized for the default locale,
605      * (say, we don't have a Japanese name for Croatia),
606      * this function falls back on the English name, and uses the ISO code as a last-resort
607      * value. If the locale doesn't specify a country, this function returns the empty string.
608      */

609     public final String JavaDoc getDisplayCountry() {
610         return getDisplayCountry(getDefault());
611     }
612
613     /**
614      * Returns a name for the locale's country that is appropriate for display to the
615      * user.
616      * If possible, the name returned will be localized according to inLocale.
617      * For example, if the locale is fr_FR and inLocale
618      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
619      * inLocale is fr_FR, getDisplayLanguage() will return "Etats-Unis".
620      * If the name returned cannot be localized according to inLocale.
621      * (say, we don't have a Japanese name for Croatia),
622      * this function falls back on the default locale, on the English name, and finally
623      * on the ISO code as a last-resort value. If the locale doesn't specify a country,
624      * this function returns the empty string.
625      */

626     public String JavaDoc getDisplayCountry(Locale JavaDoc inLocale) {
627         String JavaDoc ctryCode = country;
628         if (ctryCode.length() == 0)
629             return "";
630
631         Locale JavaDoc workingLocale = (Locale JavaDoc)inLocale.clone();
632         String JavaDoc result = null;
633         int phase = 0;
634         boolean done = false;
635
636         if (workingLocale.variant.length() == 0)
637             phase = 1;
638         if (workingLocale.country.length() == 0)
639             phase = 2;
640
641         while (!done) {
642             try {
643                 ResourceBundle JavaDoc bundle = LocaleData.getLocaleElements(workingLocale);
644                 result = findStringMatch((String JavaDoc[][])bundle.getObject("Countries"),
645                                     ctryCode, ctryCode);
646                 if (result.length() != 0)
647                     done = true;
648             }
649             catch (Exception JavaDoc e) {
650                 // just fall through
651
}
652
653             if (!done) {
654                 switch (phase) {
655                     case 0:
656                         workingLocale = new Locale JavaDoc(workingLocale.language,
657                                                    workingLocale.country,
658                                                    "");
659                         break;
660
661                     case 1:
662                         workingLocale = new Locale JavaDoc(workingLocale.language,
663                                                    "",
664                                                    workingLocale.variant);
665                         break;
666
667                     case 2:
668                         workingLocale = getDefault();
669                         break;
670
671                     case 3:
672                         workingLocale = new Locale JavaDoc("", "", "");
673                         break;
674
675                     default:
676                         return ctryCode;
677                 }
678                 phase++;
679             }
680         }
681         return result;
682     }
683
684     /**
685      * Returns a name for the locale's variant code that is appropriate for display to the
686      * user. If possible, the name will be localized for the default locale. If the locale
687      * doesn't specify a variant code, this function returns the empty string.
688      */

689     public final String JavaDoc getDisplayVariant() {
690         return getDisplayVariant(getDefault());
691     }
692
693     /**
694      * Returns a name for the locale's variant code that is appropriate for display to the
695      * user. If possible, the name will be localized for inLocale. If the locale
696      * doesn't specify a variant code, this function returns the empty string.
697      */

698     public String JavaDoc getDisplayVariant(Locale JavaDoc inLocale) {
699         if (variant.length() == 0)
700             return "";
701
702         ResourceBundle JavaDoc bundle = LocaleData.getLocaleElements(inLocale);
703
704         String JavaDoc names[] = getDisplayVariantArray(bundle);
705
706         // Get the localized patterns for formatting a list, and use
707
// them to format the list.
708
String JavaDoc[] patterns;
709         try {
710             patterns = (String JavaDoc[])bundle.getObject("LocaleNamePatterns");
711         }
712         catch (MissingResourceException JavaDoc e) {
713             patterns = null;
714         }
715         return formatList(patterns, names);
716     }
717
718     /**
719      * Returns a name for the locale that is appropriate for display to the
720      * user. This will be the values returned by getDisplayLanguage(), getDisplayCountry(),
721      * and getDisplayVariant() assembled into a single string. The display name will have
722      * one of the following forms:<p><blockquote>
723      * language (country, variant)<p>
724      * language (country)<p>
725      * language (variant)<p>
726      * country (variant)<p>
727      * language<p>
728      * country<p>
729      * variant<p></blockquote>
730      * depending on which fields are specified in the locale. If the language, country,
731      * and variant fields are all empty, this function returns the empty string.
732      */

733     public final String JavaDoc getDisplayName() {
734         return getDisplayName(getDefault());
735     }
736
737     /**
738      * Returns a name for the locale that is appropriate for display to the
739      * user. This will be the values returned by getDisplayLanguage(), getDisplayCountry(),
740      * and getDisplayVariant() assembled into a single string. The display name will have
741      * one of the following forms:<p><blockquote>
742      * language (country, variant)<p>
743      * language (country)<p>
744      * language (variant)<p>
745      * country (variant)<p>
746      * language<p>
747      * country<p>
748      * variant<p></blockquote>
749      * depending on which fields are specified in the locale. If the language, country,
750      * and variant fields are all empty, this function returns the empty string.
751      */

752     public String JavaDoc getDisplayName(Locale JavaDoc inLocale) {
753         ResourceBundle JavaDoc bundle = LocaleData.getLocaleElements(inLocale);
754
755         String JavaDoc languageName = getDisplayLanguage(inLocale);
756         String JavaDoc countryName = getDisplayCountry(inLocale);
757         String JavaDoc[] variantNames = getDisplayVariantArray(bundle);
758
759         // Get the localized patterns for formatting a display name.
760
String JavaDoc[] patterns;
761         try {
762             patterns = (String JavaDoc[])bundle.getObject("LocaleNamePatterns");
763         }
764         catch (MissingResourceException JavaDoc e) {
765             patterns = null;
766         }
767
768         // The display name consists of a main name, followed by qualifiers.
769
// Typically, the format is "MainName (Qualifier, Qualifier)" but this
770
// depends on what pattern is stored in the display locale.
771
String JavaDoc mainName = null;
772         String JavaDoc[] qualifierNames = null;
773
774         // The main name is the language, or if there is no language, the country.
775
// If there is neither language nor country (an anomalous situation) then
776
// the display name is simply the variant's display name.
777
if (languageName.length() != 0) {
778             mainName = languageName;
779             if (countryName.length() != 0) {
780                 qualifierNames = new String JavaDoc[variantNames.length + 1];
781                 System.arraycopy(variantNames, 0, qualifierNames, 1, variantNames.length);
782                 qualifierNames[0] = countryName;
783             }
784             else qualifierNames = variantNames;
785         }
786         else if (countryName.length() != 0) {
787             mainName = countryName;
788             qualifierNames = variantNames;
789         }
790         else {
791             return formatList(patterns, variantNames);
792         }
793
794         // Create an array whose first element is the number of remaining
795
// elements. This serves as a selector into a ChoiceFormat pattern from
796
// the resource. The second and third elements are the main name and
797
// the qualifier; if there are no qualifiers, the third element is
798
// unused by the format pattern.
799
Object JavaDoc<