Locale.java revision 51b1b6997fd3f980076b8081f7f1165ccc2a4008
1/*
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29 *
30 * The original version of this source code and documentation
31 * is copyrighted and owned by Taligent, Inc., a wholly-owned
32 * subsidiary of IBM. These materials are provided under terms
33 * of a License Agreement between Taligent and Sun. This technology
34 * is protected by multiple US and International patents.
35 *
36 * This notice and attribution to Taligent may not be removed.
37 * Taligent is a registered trademark of Taligent, Inc.
38 *
39 */
40
41package java.util;
42
43import java.io.IOException;
44import java.io.ObjectInputStream;
45import java.io.ObjectOutputStream;
46import java.io.ObjectStreamField;
47import java.io.Serializable;
48import java.security.AccessController;
49import java.text.MessageFormat;
50import java.util.spi.LocaleNameProvider;
51
52import sun.security.action.GetPropertyAction;
53import sun.util.LocaleServiceProviderPool;
54import sun.util.locale.BaseLocale;
55import sun.util.locale.InternalLocaleBuilder;
56import sun.util.locale.LanguageTag;
57import sun.util.locale.LocaleExtensions;
58import sun.util.locale.LocaleObjectCache;
59import sun.util.locale.LocaleSyntaxException;
60import sun.util.locale.LocaleUtils;
61import sun.util.locale.ParseStatus;
62import sun.util.locale.UnicodeLocaleExtension;
63import sun.util.resources.LocaleData;
64import sun.util.resources.OpenListResourceBundle;
65
66/**
67 * A <code>Locale</code> object represents a specific geographical, political,
68 * or cultural region. An operation that requires a <code>Locale</code> to perform
69 * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
70 * to tailor information for the user. For example, displaying a number
71 * is a locale-sensitive operation&mdash; the number should be formatted
72 * according to the customs and conventions of the user's native country,
73 * region, or culture.
74 *
75 * <p> The <code>Locale</code> class implements identifiers
76 * interchangeable with BCP 47 (IETF BCP 47, "Tags for Identifying
77 * Languages"), with support for the LDML (UTS#35, "Unicode Locale
78 * Data Markup Language") BCP 47-compatible extensions for locale data
79 * exchange.
80 *
81 * <p> A <code>Locale</code> object logically consists of the fields
82 * described below.
83 *
84 * <dl>
85 *   <dt><a name="def_language"/><b>language</b></dt>
86 *
87 *   <dd>ISO 639 alpha-2 or alpha-3 language code, or registered
88 *   language subtags up to 8 alpha letters (for future enhancements).
89 *   When a language has both an alpha-2 code and an alpha-3 code, the
90 *   alpha-2 code must be used.  You can find a full list of valid
91 *   language codes in the IANA Language Subtag Registry (search for
92 *   "Type: language").  The language field is case insensitive, but
93 *   <code>Locale</code> always canonicalizes to lower case.</dd><br>
94 *
95 *   <dd>Well-formed language values have the form
96 *   <code>[a-zA-Z]{2,8}</code>.  Note that this is not the the full
97 *   BCP47 language production, since it excludes extlang.  They are
98 *   not needed since modern three-letter language codes replace
99 *   them.</dd><br>
100 *
101 *   <dd>Example: "en" (English), "ja" (Japanese), "kok" (Konkani)</dd><br>
102 *
103 *   <dt><a name="def_script"/><b>script</b></dt>
104 *
105 *   <dd>ISO 15924 alpha-4 script code.  You can find a full list of
106 *   valid script codes in the IANA Language Subtag Registry (search
107 *   for "Type: script").  The script field is case insensitive, but
108 *   <code>Locale</code> always canonicalizes to title case (the first
109 *   letter is upper case and the rest of the letters are lower
110 *   case).</dd><br>
111 *
112 *   <dd>Well-formed script values have the form
113 *   <code>[a-zA-Z]{4}</code></dd><br>
114 *
115 *   <dd>Example: "Latn" (Latin), "Cyrl" (Cyrillic)</dd><br>
116 *
117 *   <dt><a name="def_region"/><b>country (region)</b></dt>
118 *
119 *   <dd>ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code.
120 *   You can find a full list of valid country and region codes in the
121 *   IANA Language Subtag Registry (search for "Type: region").  The
122 *   country (region) field is case insensitive, but
123 *   <code>Locale</code> always canonicalizes to upper case.</dd><br>
124 *
125 *   <dd>Well-formed country/region values have
126 *   the form <code>[a-zA-Z]{2} | [0-9]{3}</code></dd><br>
127 *
128 *   <dd>Example: "US" (United States), "FR" (France), "029"
129 *   (Caribbean)</dd><br>
130 *
131 *   <dt><a name="def_variant"/><b>variant</b></dt>
132 *
133 *   <dd>Any arbitrary value used to indicate a variation of a
134 *   <code>Locale</code>.  Where there are two or more variant values
135 *   each indicating its own semantics, these values should be ordered
136 *   by importance, with most important first, separated by
137 *   underscore('_').  The variant field is case sensitive.</dd><br>
138 *
139 *   <dd>Note: IETF BCP 47 places syntactic restrictions on variant
140 *   subtags.  Also BCP 47 subtags are strictly used to indicate
141 *   additional variations that define a language or its dialects that
142 *   are not covered by any combinations of language, script and
143 *   region subtags.  You can find a full list of valid variant codes
144 *   in the IANA Language Subtag Registry (search for "Type: variant").
145 *
146 *   <p>However, the variant field in <code>Locale</code> has
147 *   historically been used for any kind of variation, not just
148 *   language variations.  For example, some supported variants
149 *   available in Java SE Runtime Environments indicate alternative
150 *   cultural behaviors such as calendar type or number script.  In
151 *   BCP 47 this kind of information, which does not identify the
152 *   language, is supported by extension subtags or private use
153 *   subtags.</dd><br>
154 *
155 *   <dd>Well-formed variant values have the form <code>SUBTAG
156 *   (('_'|'-') SUBTAG)*</code> where <code>SUBTAG =
157 *   [0-9][0-9a-zA-Z]{3} | [0-9a-zA-Z]{5,8}</code>. (Note: BCP 47 only
158 *   uses hyphen ('-') as a delimiter, this is more lenient).</dd><br>
159 *
160 *   <dd>Example: "polyton" (Polytonic Greek), "POSIX"</dd><br>
161 *
162 *   <dt><a name="def_extensions"/><b>extensions</b></dt>
163 *
164 *   <dd>A map from single character keys to string values, indicating
165 *   extensions apart from language identification.  The extensions in
166 *   <code>Locale</code> implement the semantics and syntax of BCP 47
167 *   extension subtags and private use subtags. The extensions are
168 *   case insensitive, but <code>Locale</code> canonicalizes all
169 *   extension keys and values to lower case. Note that extensions
170 *   cannot have empty values.</dd><br>
171 *
172 *   <dd>Well-formed keys are single characters from the set
173 *   <code>[0-9a-zA-Z]</code>.  Well-formed values have the form
174 *   <code>SUBTAG ('-' SUBTAG)*</code> where for the key 'x'
175 *   <code>SUBTAG = [0-9a-zA-Z]{1,8}</code> and for other keys
176 *   <code>SUBTAG = [0-9a-zA-Z]{2,8}</code> (that is, 'x' allows
177 *   single-character subtags).</dd><br>
178 *
179 *   <dd>Example: key="u"/value="ca-japanese" (Japanese Calendar),
180 *   key="x"/value="java-1-7"</dd>
181 * </dl>
182 *
183 * <b>Note:</b> Although BCP 47 requires field values to be registered
184 * in the IANA Language Subtag Registry, the <code>Locale</code> class
185 * does not provide any validation features.  The <code>Builder</code>
186 * only checks if an individual field satisfies the syntactic
187 * requirement (is well-formed), but does not validate the value
188 * itself.  See {@link Builder} for details.
189 *
190 * <h4><a name="def_locale_extension">Unicode locale/language extension</h4>
191 *
192 * <p>UTS#35, "Unicode Locale Data Markup Language" defines optional
193 * attributes and keywords to override or refine the default behavior
194 * associated with a locale.  A keyword is represented by a pair of
195 * key and type.  For example, "nu-thai" indicates that Thai local
196 * digits (value:"thai") should be used for formatting numbers
197 * (key:"nu").
198 *
199 * <p>The keywords are mapped to a BCP 47 extension value using the
200 * extension key 'u' ({@link #UNICODE_LOCALE_EXTENSION}).  The above
201 * example, "nu-thai", becomes the extension "u-nu-thai".code
202 *
203 * <p>Thus, when a <code>Locale</code> object contains Unicode locale
204 * attributes and keywords,
205 * <code>getExtension(UNICODE_LOCALE_EXTENSION)</code> will return a
206 * String representing this information, for example, "nu-thai".  The
207 * <code>Locale</code> class also provides {@link
208 * #getUnicodeLocaleAttributes}, {@link #getUnicodeLocaleKeys}, and
209 * {@link #getUnicodeLocaleType} which allow you to access Unicode
210 * locale attributes and key/type pairs directly.  When represented as
211 * a string, the Unicode Locale Extension lists attributes
212 * alphabetically, followed by key/type sequences with keys listed
213 * alphabetically (the order of subtags comprising a key's type is
214 * fixed when the type is defined)
215 *
216 * <p>A well-formed locale key has the form
217 * <code>[0-9a-zA-Z]{2}</code>.  A well-formed locale type has the
218 * form <code>"" | [0-9a-zA-Z]{3,8} ('-' [0-9a-zA-Z]{3,8})*</code> (it
219 * can be empty, or a series of subtags 3-8 alphanums in length).  A
220 * well-formed locale attribute has the form
221 * <code>[0-9a-zA-Z]{3,8}</code> (it is a single subtag with the same
222 * form as a locale type subtag).
223 *
224 * <p>The Unicode locale extension specifies optional behavior in
225 * locale-sensitive services.  Although the LDML specification defines
226 * various keys and values, actual locale-sensitive service
227 * implementations in a Java Runtime Environment might not support any
228 * particular Unicode locale attributes or key/type pairs.
229 *
230 * <h4>Creating a Locale</h4>
231 *
232 * <p>There are several different ways to create a <code>Locale</code>
233 * object.
234 *
235 * <h5>Builder</h5>
236 *
237 * <p>Using {@link Builder} you can construct a <code>Locale</code> object
238 * that conforms to BCP 47 syntax.
239 *
240 * <h5>Constructors</h5>
241 *
242 * <p>The <code>Locale</code> class provides three constructors:
243 * <blockquote>
244 * <pre>
245 *     {@link #Locale(String language)}
246 *     {@link #Locale(String language, String country)}
247 *     {@link #Locale(String language, String country, String variant)}
248 * </pre>
249 * </blockquote>
250 * These constructors allow you to create a <code>Locale</code> object
251 * with language, country and variant, but you cannot specify
252 * script or extensions.
253 *
254 * <h5>Factory Methods</h5>
255 *
256 * <p>The method {@link #forLanguageTag} creates a <code>Locale</code>
257 * object for a well-formed BCP 47 language tag.
258 *
259 * <h5>Locale Constants</h5>
260 *
261 * <p>The <code>Locale</code> class provides a number of convenient constants
262 * that you can use to create <code>Locale</code> objects for commonly used
263 * locales. For example, the following creates a <code>Locale</code> object
264 * for the United States:
265 * <blockquote>
266 * <pre>
267 *     Locale.US
268 * </pre>
269 * </blockquote>
270 *
271 * <h4>Use of Locale</h4>
272 *
273 * <p>Once you've created a <code>Locale</code> you can query it for information
274 * about itself. Use <code>getCountry</code> to get the country (or region)
275 * code and <code>getLanguage</code> to get the language code.
276 * You can use <code>getDisplayCountry</code> to get the
277 * name of the country suitable for displaying to the user. Similarly,
278 * you can use <code>getDisplayLanguage</code> to get the name of
279 * the language suitable for displaying to the user. Interestingly,
280 * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
281 * and have two versions: one that uses the default locale and one
282 * that uses the locale specified as an argument.
283 *
284 * <p>The Java Platform provides a number of classes that perform locale-sensitive
285 * operations. For example, the <code>NumberFormat</code> class formats
286 * numbers, currency, and percentages in a locale-sensitive manner. Classes
287 * such as <code>NumberFormat</code> have several convenience methods
288 * for creating a default object of that type. For example, the
289 * <code>NumberFormat</code> class provides these three convenience methods
290 * for creating a default <code>NumberFormat</code> object:
291 * <blockquote>
292 * <pre>
293 *     NumberFormat.getInstance()
294 *     NumberFormat.getCurrencyInstance()
295 *     NumberFormat.getPercentInstance()
296 * </pre>
297 * </blockquote>
298 * Each of these methods has two variants; one with an explicit locale
299 * and one without; the latter uses the default locale:
300 * <blockquote>
301 * <pre>
302 *     NumberFormat.getInstance(myLocale)
303 *     NumberFormat.getCurrencyInstance(myLocale)
304 *     NumberFormat.getPercentInstance(myLocale)
305 * </pre>
306 * </blockquote>
307 * A <code>Locale</code> is the mechanism for identifying the kind of object
308 * (<code>NumberFormat</code>) that you would like to get. The locale is
309 * <STRONG>just</STRONG> a mechanism for identifying objects,
310 * <STRONG>not</STRONG> a container for the objects themselves.
311 *
312 * <h4>Compatibility</h4>
313 *
314 * <p>In order to maintain compatibility with existing usage, Locale's
315 * constructors retain their behavior prior to the Java Runtime
316 * Environment version 1.7.  The same is largely true for the
317 * <code>toString</code> method. Thus Locale objects can continue to
318 * be used as they were. In particular, clients who parse the output
319 * of toString into language, country, and variant fields can continue
320 * to do so (although this is strongly discouraged), although the
321 * variant field will have additional information in it if script or
322 * extensions are present.
323 *
324 * <p>In addition, BCP 47 imposes syntax restrictions that are not
325 * imposed by Locale's constructors. This means that conversions
326 * between some Locales and BCP 47 language tags cannot be made without
327 * losing information. Thus <code>toLanguageTag</code> cannot
328 * represent the state of locales whose language, country, or variant
329 * do not conform to BCP 47.
330 *
331 * <p>Because of these issues, it is recommended that clients migrate
332 * away from constructing non-conforming locales and use the
333 * <code>forLanguageTag</code> and <code>Locale.Builder</code> APIs instead.
334 * Clients desiring a string representation of the complete locale can
335 * then always rely on <code>toLanguageTag</code> for this purpose.
336 *
337 * <h5><a name="special_cases_constructor"/>Special cases</h5>
338 *
339 * <p>For compatibility reasons, two
340 * non-conforming locales are treated as special cases.  These are
341 * <b><tt>ja_JP_JP</tt></b> and <b><tt>th_TH_TH</tt></b>. These are ill-formed
342 * in BCP 47 since the variants are too short. To ease migration to BCP 47,
343 * these are treated specially during construction.  These two cases (and only
344 * these) cause a constructor to generate an extension, all other values behave
345 * exactly as they did prior to Java 7.
346 *
347 * <p>Java has used <tt>ja_JP_JP</tt> to represent Japanese as used in
348 * Japan together with the Japanese Imperial calendar. This is now
349 * representable using a Unicode locale extension, by specifying the
350 * Unicode locale key <tt>ca</tt> (for "calendar") and type
351 * <tt>japanese</tt>. When the Locale constructor is called with the
352 * arguments "ja", "JP", "JP", the extension "u-ca-japanese" is
353 * automatically added.
354 *
355 * <p>Java has used <tt>th_TH_TH</tt> to represent Thai as used in
356 * Thailand together with Thai digits. This is also now representable using
357 * a Unicode locale extension, by specifying the Unicode locale key
358 * <tt>nu</tt> (for "number") and value <tt>thai</tt>. When the Locale
359 * constructor is called with the arguments "th", "TH", "TH", the
360 * extension "u-nu-thai" is automatically added.
361 *
362 * <h5>Serialization</h5>
363 *
364 * <p>During serialization, writeObject writes all fields to the output
365 * stream, including extensions.
366 *
367 * <p>During deserialization, readResolve adds extensions as described
368 * in <a href="#special_cases_constructor">Special Cases</a>, only
369 * for the two cases th_TH_TH and ja_JP_JP.
370 *
371 * <h5>Legacy language codes</h5>
372 *
373 * <p>Locale's constructor has always converted three language codes to
374 * their earlier, obsoleted forms: <tt>he</tt> maps to <tt>iw</tt>,
375 * <tt>yi</tt> maps to <tt>ji</tt>, and <tt>id</tt> maps to
376 * <tt>in</tt>.  This continues to be the case, in order to not break
377 * backwards compatibility.
378 *
379 * <p>The APIs added in 1.7 map between the old and new language codes,
380 * maintaining the old codes internal to Locale (so that
381 * <code>getLanguage</code> and <code>toString</code> reflect the old
382 * code), but using the new codes in the BCP 47 language tag APIs (so
383 * that <code>toLanguageTag</code> reflects the new one). This
384 * preserves the equivalence between Locales no matter which code or
385 * API is used to construct them. Java's default resource bundle
386 * lookup mechanism also implements this mapping, so that resources
387 * can be named using either convention, see {@link ResourceBundle.Control}.
388 *
389 * <h5>Three-letter language/country(region) codes</h5>
390 *
391 * <p>The Locale constructors have always specified that the language
392 * and the country param be two characters in length, although in
393 * practice they have accepted any length.  The specification has now
394 * been relaxed to allow language codes of two to eight characters and
395 * country (region) codes of two to three characters, and in
396 * particular, three-letter language codes and three-digit region
397 * codes as specified in the IANA Language Subtag Registry.  For
398 * compatibility, the implementation still does not impose a length
399 * constraint.
400 *
401 * @see Builder
402 * @see ResourceBundle
403 * @see java.text.Format
404 * @see java.text.NumberFormat
405 * @see java.text.Collator
406 * @author Mark Davis
407 * @since 1.1
408 */
409public final class Locale implements Cloneable, Serializable {
410
411    static private final  Cache LOCALECACHE = new Cache();
412
413    /** Useful constant for language.
414     */
415    static public final Locale ENGLISH = createConstant("en", "");
416
417    /** Useful constant for language.
418     */
419    static public final Locale FRENCH = createConstant("fr", "");
420
421    /** Useful constant for language.
422     */
423    static public final Locale GERMAN = createConstant("de", "");
424
425    /** Useful constant for language.
426     */
427    static public final Locale ITALIAN = createConstant("it", "");
428
429    /** Useful constant for language.
430     */
431    static public final Locale JAPANESE = createConstant("ja", "");
432
433    /** Useful constant for language.
434     */
435    static public final Locale KOREAN = createConstant("ko", "");
436
437    /** Useful constant for language.
438     */
439    static public final Locale CHINESE = createConstant("zh", "");
440
441    /** Useful constant for language.
442     */
443    static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
444
445    /** Useful constant for language.
446     */
447    static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
448
449    /** Useful constant for country.
450     */
451    static public final Locale FRANCE = createConstant("fr", "FR");
452
453    /** Useful constant for country.
454     */
455    static public final Locale GERMANY = createConstant("de", "DE");
456
457    /** Useful constant for country.
458     */
459    static public final Locale ITALY = createConstant("it", "IT");
460
461    /** Useful constant for country.
462     */
463    static public final Locale JAPAN = createConstant("ja", "JP");
464
465    /** Useful constant for country.
466     */
467    static public final Locale KOREA = createConstant("ko", "KR");
468
469    /** Useful constant for country.
470     */
471    static public final Locale CHINA = SIMPLIFIED_CHINESE;
472
473    /** Useful constant for country.
474     */
475    static public final Locale PRC = SIMPLIFIED_CHINESE;
476
477    /** Useful constant for country.
478     */
479    static public final Locale TAIWAN = TRADITIONAL_CHINESE;
480
481    /** Useful constant for country.
482     */
483    static public final Locale UK = createConstant("en", "GB");
484
485    /** Useful constant for country.
486     */
487    static public final Locale US = createConstant("en", "US");
488
489    /** Useful constant for country.
490     */
491    static public final Locale CANADA = createConstant("en", "CA");
492
493    /** Useful constant for country.
494     */
495    static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
496
497    /**
498     * Useful constant for the root locale.  The root locale is the locale whose
499     * language, country, and variant are empty ("") strings.  This is regarded
500     * as the base locale of all locales, and is used as the language/country
501     * neutral locale for the locale sensitive operations.
502     *
503     * @since 1.6
504     */
505    static public final Locale ROOT = createConstant("", "");
506
507    /**
508     * The key for the private use extension ('x').
509     *
510     * @see #getExtension(char)
511     * @see Builder#setExtension(char, String)
512     * @since 1.7
513     */
514    static public final char PRIVATE_USE_EXTENSION = 'x';
515
516    /**
517     * The key for Unicode locale extension ('u').
518     *
519     * @see #getExtension(char)
520     * @see Builder#setExtension(char, String)
521     * @since 1.7
522     */
523    static public final char UNICODE_LOCALE_EXTENSION = 'u';
524
525    /** serialization ID
526     */
527    static final long serialVersionUID = 9149081749638150636L;
528
529    /**
530     * Display types for retrieving localized names from the name providers.
531     */
532    private static final int DISPLAY_LANGUAGE = 0;
533    private static final int DISPLAY_COUNTRY  = 1;
534    private static final int DISPLAY_VARIANT  = 2;
535    private static final int DISPLAY_SCRIPT   = 3;
536
537    /**
538     * Private constructor used by getInstance method
539     */
540    private Locale(BaseLocale baseLocale, LocaleExtensions extensions) {
541        this.baseLocale = baseLocale;
542        this.localeExtensions = extensions;
543    }
544
545    /**
546     * Construct a locale from language, country and variant.
547     * This constructor normalizes the language value to lowercase and
548     * the country value to uppercase.
549     * <p>
550     * <b>Note:</b>
551     * <ul>
552     * <li>ISO 639 is not a stable standard; some of the language codes it defines
553     * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
554     * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
555     * API on Locale will return only the OLD codes.
556     * <li>For backward compatibility reasons, this constructor does not make
557     * any syntactic checks on the input.
558     * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
559     * see <a href="#special_cases_constructor">Special Cases</a> for more information.
560     * </ul>
561     *
562     * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
563     * up to 8 characters in length.  See the <code>Locale</code> class description about
564     * valid language values.
565     * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
566     * See the <code>Locale</code> class description about valid country values.
567     * @param variant Any arbitrary value used to indicate a variation of a <code>Locale</code>.
568     * See the <code>Locale</code> class description for the details.
569     * @exception NullPointerException thrown if any argument is null.
570     */
571    public Locale(String language, String country, String variant) {
572        if (language== null || country == null || variant == null) {
573            throw new NullPointerException();
574        }
575        baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
576        localeExtensions = getCompatibilityExtensions(language, "", country, variant);
577    }
578
579    /**
580     * Construct a locale from language and country.
581     * This constructor normalizes the language value to lowercase and
582     * the country value to uppercase.
583     * <p>
584     * <b>Note:</b>
585     * <ul>
586     * <li>ISO 639 is not a stable standard; some of the language codes it defines
587     * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
588     * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
589     * API on Locale will return only the OLD codes.
590     * <li>For backward compatibility reasons, this constructor does not make
591     * any syntactic checks on the input.
592     * </ul>
593     *
594     * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
595     * up to 8 characters in length.  See the <code>Locale</code> class description about
596     * valid language values.
597     * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
598     * See the <code>Locale</code> class description about valid country values.
599     * @exception NullPointerException thrown if either argument is null.
600     */
601    public Locale(String language, String country) {
602        this(language, country, "");
603    }
604
605    /**
606     * Construct a locale from a language code.
607     * This constructor normalizes the language value to lowercase.
608     * <p>
609     * <b>Note:</b>
610     * <ul>
611     * <li>ISO 639 is not a stable standard; some of the language codes it defines
612     * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
613     * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
614     * API on Locale will return only the OLD codes.
615     * <li>For backward compatibility reasons, this constructor does not make
616     * any syntactic checks on the input.
617     * </ul>
618     *
619     * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
620     * up to 8 characters in length.  See the <code>Locale</code> class description about
621     * valid language values.
622     * @exception NullPointerException thrown if argument is null.
623     * @since 1.4
624     */
625    public Locale(String language) {
626        this(language, "", "");
627    }
628
629    /**
630     * This method must be called only for creating the Locale.*
631     * constants due to making shortcuts.
632     */
633    private static Locale createConstant(String lang, String country) {
634        BaseLocale base = BaseLocale.createInstance(lang, country);
635        return getInstance(base, null);
636    }
637
638    /**
639     * Returns a <code>Locale</code> constructed from the given
640     * <code>language</code>, <code>country</code> and
641     * <code>variant</code>. If the same <code>Locale</code> instance
642     * is available in the cache, then that instance is
643     * returned. Otherwise, a new <code>Locale</code> instance is
644     * created and cached.
645     *
646     * @param language lowercase 2 to 8 language code.
647     * @param country uppercase two-letter ISO-3166 code and numric-3 UN M.49 area code.
648     * @param variant vendor and browser specific code. See class description.
649     * @return the <code>Locale</code> instance requested
650     * @exception NullPointerException if any argument is null.
651     */
652    static Locale getInstance(String language, String country, String variant) {
653        return getInstance(language, "", country, variant, null);
654    }
655
656    static Locale getInstance(String language, String script, String country,
657                                      String variant, LocaleExtensions extensions) {
658        if (language== null || script == null || country == null || variant == null) {
659            throw new NullPointerException();
660        }
661
662        if (extensions == null) {
663            extensions = getCompatibilityExtensions(language, script, country, variant);
664        }
665
666        BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
667        return getInstance(baseloc, extensions);
668    }
669
670    static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
671        LocaleKey key = new LocaleKey(baseloc, extensions);
672        return LOCALECACHE.get(key);
673    }
674
675    private static class Cache extends LocaleObjectCache<LocaleKey, Locale> {
676        private Cache() {
677        }
678
679        @Override
680        protected Locale createObject(LocaleKey key) {
681            return new Locale(key.base, key.exts);
682        }
683    }
684
685    private static final class LocaleKey {
686        private final BaseLocale base;
687        private final LocaleExtensions exts;
688        private final int hash;
689
690        private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {
691            base = baseLocale;
692            exts = extensions;
693
694            // Calculate the hash value here because it's always used.
695            int h = base.hashCode();
696            if (exts != null) {
697                h ^= exts.hashCode();
698            }
699            hash = h;
700        }
701
702        @Override
703        public boolean equals(Object obj) {
704            if (this == obj) {
705                return true;
706            }
707            if (!(obj instanceof LocaleKey)) {
708                return false;
709            }
710            LocaleKey other = (LocaleKey)obj;
711            if (hash != other.hash || !base.equals(other.base)) {
712                return false;
713            }
714            if (exts == null) {
715                return other.exts == null;
716            }
717            return exts.equals(other.exts);
718        }
719
720        @Override
721        public int hashCode() {
722            return hash;
723        }
724    }
725
726    /**
727     * Gets the current value of the default locale for this instance
728     * of the Java Virtual Machine.
729     * <p>
730     * The Java Virtual Machine sets the default locale during startup
731     * based on the host environment. It is used by many locale-sensitive
732     * methods if no locale is explicitly specified.
733     * It can be changed using the
734     * {@link #setDefault(java.util.Locale) setDefault} method.
735     *
736     * @return the default locale for this instance of the Java Virtual Machine
737     */
738    public static Locale getDefault() {
739        // do not synchronize this method - see 4071298
740        // it's OK if more than one default locale happens to be created
741        if (defaultLocale == null) {
742            initDefault();
743        }
744        return defaultLocale;
745    }
746
747    /**
748     * Gets the current value of the default locale for the specified Category
749     * for this instance of the Java Virtual Machine.
750     * <p>
751     * The Java Virtual Machine sets the default locale during startup based
752     * on the host environment. It is used by many locale-sensitive methods
753     * if no locale is explicitly specified. It can be changed using the
754     * setDefault(Locale.Category, Locale) method.
755     *
756     * @param category - the specified category to get the default locale
757     * @throws NullPointerException - if category is null
758     * @return the default locale for the specified Category for this instance
759     *     of the Java Virtual Machine
760     * @see #setDefault(Locale.Category, Locale)
761     * @since 1.7
762     */
763    public static Locale getDefault(Locale.Category category) {
764        // do not synchronize this method - see 4071298
765        // it's OK if more than one default locale happens to be created
766        switch (category) {
767        case DISPLAY:
768            if (defaultDisplayLocale == null) {
769                initDefault(category);
770            }
771            return defaultDisplayLocale;
772        case FORMAT:
773            if (defaultFormatLocale == null) {
774                initDefault(category);
775            }
776            return defaultFormatLocale;
777        default:
778            assert false: "Unknown Category";
779        }
780        return getDefault();
781    }
782
783    private static void initDefault() {
784        String language, region, script, country, variant;
785        language = AccessController.doPrivileged(
786            new GetPropertyAction("user.language", "en"));
787        // for compatibility, check for old user.region property
788        region = AccessController.doPrivileged(
789            new GetPropertyAction("user.region"));
790        if (region != null) {
791            // region can be of form country, country_variant, or _variant
792            int i = region.indexOf('_');
793            if (i >= 0) {
794                country = region.substring(0, i);
795                variant = region.substring(i + 1);
796            } else {
797                country = region;
798                variant = "";
799            }
800            script = "";
801        } else {
802            script = AccessController.doPrivileged(
803                new GetPropertyAction("user.script", ""));
804            country = AccessController.doPrivileged(
805                new GetPropertyAction("user.country", ""));
806            variant = AccessController.doPrivileged(
807                new GetPropertyAction("user.variant", ""));
808        }
809        defaultLocale = getInstance(language, script, country, variant, null);
810    }
811
812    private static void initDefault(Locale.Category category) {
813        // make sure defaultLocale is initialized
814        if (defaultLocale == null) {
815            initDefault();
816        }
817
818        Locale defaultCategoryLocale = getInstance(
819            AccessController.doPrivileged(
820                new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
821            AccessController.doPrivileged(
822                new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
823            AccessController.doPrivileged(
824                new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
825            AccessController.doPrivileged(
826                new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
827            null);
828
829        switch (category) {
830        case DISPLAY:
831            defaultDisplayLocale = defaultCategoryLocale;
832            break;
833        case FORMAT:
834            defaultFormatLocale = defaultCategoryLocale;
835            break;
836        }
837    }
838
839    /**
840     * Sets the default locale for this instance of the Java Virtual Machine.
841     * This does not affect the host locale.
842     * <p>
843     * If there is a security manager, its <code>checkPermission</code>
844     * method is called with a <code>PropertyPermission("user.language", "write")</code>
845     * permission before the default locale is changed.
846     * <p>
847     * The Java Virtual Machine sets the default locale during startup
848     * based on the host environment. It is used by many locale-sensitive
849     * methods if no locale is explicitly specified.
850     * <p>
851     * Since changing the default locale may affect many different areas
852     * of functionality, this method should only be used if the caller
853     * is prepared to reinitialize locale-sensitive code running
854     * within the same Java Virtual Machine.
855     * <p>
856     * By setting the default locale with this method, all of the default
857     * locales for each Category are also set to the specified default locale.
858     *
859     * @throws SecurityException
860     *        if a security manager exists and its
861     *        <code>checkPermission</code> method doesn't allow the operation.
862     * @throws NullPointerException if <code>newLocale</code> is null
863     * @param newLocale the new default locale
864     * @see SecurityManager#checkPermission
865     * @see java.util.PropertyPermission
866     */
867    public static synchronized void setDefault(Locale newLocale) {
868        setDefault(Category.DISPLAY, newLocale);
869        setDefault(Category.FORMAT, newLocale);
870        defaultLocale = newLocale;
871    }
872
873    /**
874     * Sets the default locale for the specified Category for this instance
875     * of the Java Virtual Machine. This does not affect the host locale.
876     * <p>
877     * If there is a security manager, its checkPermission method is called
878     * with a PropertyPermission("user.language", "write") permission before
879     * the default locale is changed.
880     * <p>
881     * The Java Virtual Machine sets the default locale during startup based
882     * on the host environment. It is used by many locale-sensitive methods
883     * if no locale is explicitly specified.
884     * <p>
885     * Since changing the default locale may affect many different areas of
886     * functionality, this method should only be used if the caller is
887     * prepared to reinitialize locale-sensitive code running within the
888     * same Java Virtual Machine.
889     * <p>
890     *
891     * @param category - the specified category to set the default locale
892     * @param newLocale - the new default locale
893     * @throws SecurityException - if a security manager exists and its
894     *     checkPermission method doesn't allow the operation.
895     * @throws NullPointerException - if category and/or newLocale is null
896     * @see SecurityManager#checkPermission(java.security.Permission)
897     * @see PropertyPermission
898     * @see #getDefault(Locale.Category)
899     * @since 1.7
900     */
901    public static synchronized void setDefault(Locale.Category category,
902        Locale newLocale) {
903        if (category == null)
904            throw new NullPointerException("Category cannot be NULL");
905        if (newLocale == null)
906            throw new NullPointerException("Can't set default locale to NULL");
907
908        SecurityManager sm = System.getSecurityManager();
909        if (sm != null) sm.checkPermission(new PropertyPermission
910                        ("user.language", "write"));
911        switch (category) {
912        case DISPLAY:
913            defaultDisplayLocale = newLocale;
914            break;
915        case FORMAT:
916            defaultFormatLocale = newLocale;
917            break;
918        default:
919            assert false: "Unknown Category";
920        }
921    }
922
923    /**
924     * Returns an array of all installed locales.
925     * The returned array represents the union of locales supported
926     * by the Java runtime environment and by installed
927     * {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider}
928     * implementations.  It must contain at least a <code>Locale</code>
929     * instance equal to {@link java.util.Locale#US Locale.US}.
930     *
931     * @return An array of installed locales.
932     */
933    public static Locale[] getAvailableLocales() {
934        return LocaleServiceProviderPool.getAllAvailableLocales();
935    }
936
937    /**
938     * Returns a list of all 2-letter country codes defined in ISO 3166.
939     * Can be used to create Locales.
940     * <p>
941     * <b>Note:</b> The <code>Locale</code> class also supports other codes for
942     * country (region), such as 3-letter numeric UN M.49 area codes.
943     * Therefore, the list returned by this method does not contain ALL valid
944     * codes that can be used to create Locales.
945     */
946    public static String[] getISOCountries() {
947        if (isoCountries == null) {
948            isoCountries = getISO2Table(LocaleISOData.isoCountryTable);
949        }
950        String[] result = new String[isoCountries.length];
951        System.arraycopy(isoCountries, 0, result, 0, isoCountries.length);
952        return result;
953    }
954
955    /**
956     * Returns a list of all 2-letter language codes defined in ISO 639.
957     * Can be used to create Locales.
958     * <p>
959     * <b>Note:</b>
960     * <ul>
961     * <li>ISO 639 is not a stable standard&mdash; some languages' codes have changed.
962     * The list this function returns includes both the new and the old codes for the
963     * languages whose codes have changed.
964     * <li>The <code>Locale</code> class also supports language codes up to
965     * 8 characters in length.  Therefore, the list returned by this method does
966     * not contain ALL valid codes that can be used to create Locales.
967     * </ul>
968     */
969    public static String[] getISOLanguages() {
970        if (isoLanguages == null) {
971            isoLanguages = getISO2Table(LocaleISOData.isoLanguageTable);
972        }
973        String[] result = new String[isoLanguages.length];
974        System.arraycopy(isoLanguages, 0, result, 0, isoLanguages.length);
975        return result;
976    }
977
978    private static final String[] getISO2Table(String table) {
979        int len = table.length() / 5;
980        String[] isoTable = new String[len];
981        for (int i = 0, j = 0; i < len; i++, j += 5) {
982            isoTable[i] = table.substring(j, j + 2);
983        }
984        return isoTable;
985    }
986
987    /**
988     * Returns the language code of this Locale.
989     *
990     * <p><b>Note:</b> ISO 639 is not a stable standard&mdash; some languages' codes have changed.
991     * Locale's constructor recognizes both the new and the old codes for the languages
992     * whose codes have changed, but this function always returns the old code.  If you
993     * want to check for a specific language whose code has changed, don't do
994     * <pre>
995     * if (locale.getLanguage().equals("he")) // BAD!
996     *    ...
997     * </pre>
998     * Instead, do
999     * <pre>
1000     * if (locale.getLanguage().equals(new Locale("he").getLanguage()))
1001     *    ...
1002     * </pre>
1003     * @return The language code, or the empty string if none is defined.
1004     * @see #getDisplayLanguage
1005     */
1006    public String getLanguage() {
1007        return baseLocale.getLanguage();
1008    }
1009
1010    /**
1011     * Returns the script for this locale, which should
1012     * either be the empty string or an ISO 15924 4-letter script
1013     * code. The first letter is uppercase and the rest are
1014     * lowercase, for example, 'Latn', 'Cyrl'.
1015     *
1016     * @return The script code, or the empty string if none is defined.
1017     * @see #getDisplayScript
1018     * @since 1.7
1019     */
1020    public String getScript() {
1021        return baseLocale.getScript();
1022    }
1023
1024    /**
1025     * Returns the country/region code for this locale, which should
1026     * either be the empty string, an uppercase ISO 3166 2-letter code,
1027     * or a UN M.49 3-digit code.
1028     *
1029     * @return The country/region code, or the empty string if none is defined.
1030     * @see #getDisplayCountry
1031     */
1032    public String getCountry() {
1033        return baseLocale.getRegion();
1034    }
1035
1036    /**
1037     * Returns the variant code for this locale.
1038     *
1039     * @return The variant code, or the empty string if none is defined.
1040     * @see #getDisplayVariant
1041     */
1042    public String getVariant() {
1043        return baseLocale.getVariant();
1044    }
1045
1046    /**
1047     * Returns the extension (or private use) value associated with
1048     * the specified key, or null if there is no extension
1049     * associated with the key. To be well-formed, the key must be one
1050     * of <code>[0-9A-Za-z]</code>. Keys are case-insensitive, so
1051     * for example 'z' and 'Z' represent the same extension.
1052     *
1053     * @param key the extension key
1054     * @return The extension, or null if this locale defines no
1055     * extension for the specified key.
1056     * @throws IllegalArgumentException if key is not well-formed
1057     * @see #PRIVATE_USE_EXTENSION
1058     * @see #UNICODE_LOCALE_EXTENSION
1059     * @since 1.7
1060     */
1061    public String getExtension(char key) {
1062        if (!LocaleExtensions.isValidKey(key)) {
1063            throw new IllegalArgumentException("Ill-formed extension key: " + key);
1064        }
1065        return (localeExtensions == null) ? null : localeExtensions.getExtensionValue(key);
1066    }
1067
1068    /**
1069     * Returns the set of extension keys associated with this locale, or the
1070     * empty set if it has no extensions. The returned set is unmodifiable.
1071     * The keys will all be lower-case.
1072     *
1073     * @return The set of extension keys, or the empty set if this locale has
1074     * no extensions.
1075     * @since 1.7
1076     */
1077    public Set<Character> getExtensionKeys() {
1078        if (localeExtensions == null) {
1079            return Collections.emptySet();
1080        }
1081        return localeExtensions.getKeys();
1082    }
1083
1084    /**
1085     * Returns the set of unicode locale attributes associated with
1086     * this locale, or the empty set if it has no attributes. The
1087     * returned set is unmodifiable.
1088     *
1089     * @return The set of attributes.
1090     * @since 1.7
1091     */
1092    public Set<String> getUnicodeLocaleAttributes() {
1093        if (localeExtensions == null) {
1094            return Collections.emptySet();
1095        }
1096        return localeExtensions.getUnicodeLocaleAttributes();
1097    }
1098
1099    /**
1100     * Returns the Unicode locale type associated with the specified Unicode locale key
1101     * for this locale. Returns the empty string for keys that are defined with no type.
1102     * Returns null if the key is not defined. Keys are case-insensitive. The key must
1103     * be two alphanumeric characters ([0-9a-zA-Z]), or an IllegalArgumentException is
1104     * thrown.
1105     *
1106     * @param key the Unicode locale key
1107     * @return The Unicode locale type associated with the key, or null if the
1108     * locale does not define the key.
1109     * @throws IllegalArgumentException if the key is not well-formed
1110     * @throws NullPointerException if <code>key</code> is null
1111     * @since 1.7
1112     */
1113    public String getUnicodeLocaleType(String key) {
1114        if (!UnicodeLocaleExtension.isKey(key)) {
1115            throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key);
1116        }
1117        return (localeExtensions == null) ? null : localeExtensions.getUnicodeLocaleType(key);
1118    }
1119
1120    /**
1121     * Returns the set of Unicode locale keys defined by this locale, or the empty set if
1122     * this locale has none.  The returned set is immutable.  Keys are all lower case.
1123     *
1124     * @return The set of Unicode locale keys, or the empty set if this locale has
1125     * no Unicode locale keywords.
1126     * @since 1.7
1127     */
1128    public Set<String> getUnicodeLocaleKeys() {
1129        if (localeExtensions == null) {
1130            return Collections.emptySet();
1131        }
1132        return localeExtensions.getUnicodeLocaleKeys();
1133    }
1134
1135    /**
1136     * Package locale method returning the Locale's BaseLocale,
1137     * used by ResourceBundle
1138     * @return base locale of this Locale
1139     */
1140    BaseLocale getBaseLocale() {
1141        return baseLocale;
1142    }
1143
1144    /**
1145     * Package private method returning the Locale's LocaleExtensions,
1146     * used by ResourceBundle.
1147     * @return locale exnteions of this Locale,
1148     *         or {@code null} if no extensions are defined
1149     */
1150     LocaleExtensions getLocaleExtensions() {
1151         return localeExtensions;
1152     }
1153
1154    /**
1155     * Returns a string representation of this <code>Locale</code>
1156     * object, consisting of language, country, variant, script,
1157     * and extensions as below:
1158     * <p><blockquote>
1159     * language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
1160     * </blockquote>
1161     *
1162     * Language is always lower case, country is always upper case, script is always title
1163     * case, and extensions are always lower case.  Extensions and private use subtags
1164     * will be in canonical order as explained in {@link #toLanguageTag}.
1165     *
1166     * <p>When the locale has neither script nor extensions, the result is the same as in
1167     * Java 6 and prior.
1168     *
1169     * <p>If both the language and country fields are missing, this function will return
1170     * the empty string, even if the variant, script, or extensions field is present (you
1171     * can't have a locale with just a variant, the variant must accompany a well-formed
1172     * language or country code).
1173     *
1174     * <p>If script or extensions are present and variant is missing, no underscore is
1175     * added before the "#".
1176     *
1177     * <p>This behavior is designed to support debugging and to be compatible with
1178     * previous uses of <code>toString</code> that expected language, country, and variant
1179     * fields only.  To represent a Locale as a String for interchange purposes, use
1180     * {@link #toLanguageTag}.
1181     *
1182     * <p>Examples: <ul><tt>
1183     * <li>en
1184     * <li>de_DE
1185     * <li>_GB
1186     * <li>en_US_WIN
1187     * <li>de__POSIX
1188     * <li>zh_CN_#Hans
1189     * <li>zh_TW_#Hant-x-java
1190     * <li>th_TH_TH_#u-nu-thai</tt></ul>
1191     *
1192     * @return A string representation of the Locale, for debugging.
1193     * @see #getDisplayName
1194     * @see #toLanguageTag
1195     */
1196    @Override
1197    public final String toString() {
1198        boolean l = (baseLocale.getLanguage().length() != 0);
1199        boolean s = (baseLocale.getScript().length() != 0);
1200        boolean r = (baseLocale.getRegion().length() != 0);
1201        boolean v = (baseLocale.getVariant().length() != 0);
1202        boolean e = (localeExtensions != null && localeExtensions.getID().length() != 0);
1203
1204        StringBuilder result = new StringBuilder(baseLocale.getLanguage());
1205        if (r || (l && (v || s || e))) {
1206            result.append('_')
1207                .append(baseLocale.getRegion()); // This may just append '_'
1208        }
1209        if (v && (l || r)) {
1210            result.append('_')
1211                .append(baseLocale.getVariant());
1212        }
1213
1214        if (s && (l || r)) {
1215            result.append("_#")
1216                .append(baseLocale.getScript());
1217        }
1218
1219        if (e && (l || r)) {
1220            result.append('_');
1221            if (!s) {
1222                result.append('#');
1223            }
1224            result.append(localeExtensions.getID());
1225        }
1226
1227        return result.toString();
1228    }
1229
1230    /**
1231     * Returns a well-formed IETF BCP 47 language tag representing
1232     * this locale.
1233     *
1234     * <p>If this <code>Locale</code> has a language, country, or
1235     * variant that does not satisfy the IETF BCP 47 language tag
1236     * syntax requirements, this method handles these fields as
1237     * described below:
1238     *
1239     * <p><b>Language:</b> If language is empty, or not <a
1240     * href="#def_language" >well-formed</a> (for example "a" or
1241     * "e2"), it will be emitted as "und" (Undetermined).
1242     *
1243     * <p><b>Country:</b> If country is not <a
1244     * href="#def_region">well-formed</a> (for example "12" or "USA"),
1245     * it will be omitted.
1246     *
1247     * <p><b>Variant:</b> If variant <b>is</b> <a
1248     * href="#def_variant">well-formed</a>, each sub-segment
1249     * (delimited by '-' or '_') is emitted as a subtag.  Otherwise:
1250     * <ul>
1251     *
1252     * <li>if all sub-segments match <code>[0-9a-zA-Z]{1,8}</code>
1253     * (for example "WIN" or "Oracle_JDK_Standard_Edition"), the first
1254     * ill-formed sub-segment and all following will be appended to
1255     * the private use subtag.  The first appended subtag will be
1256     * "lvariant", followed by the sub-segments in order, separated by
1257     * hyphen. For example, "x-lvariant-WIN",
1258     * "Oracle-x-lvariant-JDK-Standard-Edition".
1259     *
1260     * <li>if any sub-segment does not match
1261     * <code>[0-9a-zA-Z]{1,8}</code>, the variant will be truncated
1262     * and the problematic sub-segment and all following sub-segments
1263     * will be omitted.  If the remainder is non-empty, it will be
1264     * emitted as a private use subtag as above (even if the remainder
1265     * turns out to be well-formed).  For example,
1266     * "Solaris_isjustthecoolestthing" is emitted as
1267     * "x-lvariant-Solaris", not as "solaris".</li></ul>
1268     *
1269     * <p><b>Special Conversions:</b> Java supports some old locale
1270     * representations, including deprecated ISO language codes,
1271     * for compatibility. This method performs the following
1272     * conversions:
1273     * <ul>
1274     *
1275     * <li>Deprecated ISO language codes "iw", "ji", and "in" are
1276     * converted to "he", "yi", and "id", respectively.
1277     *
1278     * <li>A locale with language "no", country "NO", and variant
1279     * "NY", representing Norwegian Nynorsk (Norway), is converted
1280     * to a language tag "nn-NO".</li></ul>
1281     *
1282     * <p><b>Note:</b> Although the language tag created by this
1283     * method is well-formed (satisfies the syntax requirements
1284     * defined by the IETF BCP 47 specification), it is not
1285     * necessarily a valid BCP 47 language tag.  For example,
1286     * <pre>
1287     *   new Locale("xx", "YY").toLanguageTag();</pre>
1288     *
1289     * will return "xx-YY", but the language subtag "xx" and the
1290     * region subtag "YY" are invalid because they are not registered
1291     * in the IANA Language Subtag Registry.
1292     *
1293     * @return a BCP47 language tag representing the locale
1294     * @see #forLanguageTag(String)
1295     * @since 1.7
1296     */
1297    public String toLanguageTag() {
1298        LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
1299        StringBuilder buf = new StringBuilder();
1300
1301        String subtag = tag.getLanguage();
1302        if (subtag.length() > 0) {
1303            buf.append(LanguageTag.canonicalizeLanguage(subtag));
1304        }
1305
1306        subtag = tag.getScript();
1307        if (subtag.length() > 0) {
1308            buf.append(LanguageTag.SEP);
1309            buf.append(LanguageTag.canonicalizeScript(subtag));
1310        }
1311
1312        subtag = tag.getRegion();
1313        if (subtag.length() > 0) {
1314            buf.append(LanguageTag.SEP);
1315            buf.append(LanguageTag.canonicalizeRegion(subtag));
1316        }
1317
1318        List<String>subtags = tag.getVariants();
1319        for (String s : subtags) {
1320            buf.append(LanguageTag.SEP);
1321            // preserve casing
1322            buf.append(s);
1323        }
1324
1325        subtags = tag.getExtensions();
1326        for (String s : subtags) {
1327            buf.append(LanguageTag.SEP);
1328            buf.append(LanguageTag.canonicalizeExtension(s));
1329        }
1330
1331        subtag = tag.getPrivateuse();
1332        if (subtag.length() > 0) {
1333            if (buf.length() > 0) {
1334                buf.append(LanguageTag.SEP);
1335            }
1336            buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
1337            // preserve casing
1338            buf.append(subtag);
1339        }
1340
1341        return buf.toString();
1342    }
1343
1344    /**
1345     * Returns a locale for the specified IETF BCP 47 language tag string.
1346     *
1347     * <p>If the specified language tag contains any ill-formed subtags,
1348     * the first such subtag and all following subtags are ignored.  Compare
1349     * to {@link Locale.Builder#setLanguageTag} which throws an exception
1350     * in this case.
1351     *
1352     * <p>The following <b>conversions</b> are performed:<ul>
1353     *
1354     * <li>The language code "und" is mapped to language "".
1355     *
1356     * <li>The language codes "he", "yi", and "id" are mapped to "iw",
1357     * "ji", and "in" respectively. (This is the same canonicalization
1358     * that's done in Locale's constructors.)
1359     *
1360     * <li>The portion of a private use subtag prefixed by "lvariant",
1361     * if any, is removed and appended to the variant field in the
1362     * result locale (without case normalization).  If it is then
1363     * empty, the private use subtag is discarded:
1364     *
1365     * <pre>
1366     *     Locale loc;
1367     *     loc = Locale.forLanguageTag("en-US-x-lvariant-POSIX");
1368     *     loc.getVariant(); // returns "POSIX"
1369     *     loc.getExtension('x'); // returns null
1370     *
1371     *     loc = Locale.forLanguageTag("de-POSIX-x-URP-lvariant-Abc-Def");
1372     *     loc.getVariant(); // returns "POSIX_Abc_Def"
1373     *     loc.getExtension('x'); // returns "urp"
1374     * </pre>
1375     *
1376     * <li>When the languageTag argument contains an extlang subtag,
1377     * the first such subtag is used as the language, and the primary
1378     * language subtag and other extlang subtags are ignored:
1379     *
1380     * <pre>
1381     *     Locale.forLanguageTag("ar-aao").getLanguage(); // returns "aao"
1382     *     Locale.forLanguageTag("en-abc-def-us").toString(); // returns "abc_US"
1383     * </pre>
1384     *
1385     * <li>Case is normalized except for variant tags, which are left
1386     * unchanged.  Language is normalized to lower case, script to
1387     * title case, country to upper case, and extensions to lower
1388     * case.
1389     *
1390     * <li>If, after processing, the locale would exactly match either
1391     * ja_JP_JP or th_TH_TH with no extensions, the appropriate
1392     * extensions are added as though the constructor had been called:
1393     *
1394     * <pre>
1395     *    Locale.forLanguageTag("ja-JP-x-lvariant-JP").toLanguageTag();
1396     *    // returns "ja-JP-u-ca-japanese-x-lvariant-JP"
1397     *    Locale.forLanguageTag("th-TH-x-lvariant-TH").toLanguageTag();
1398     *    // returns "th-TH-u-nu-thai-x-lvariant-TH"
1399     * <pre></ul>
1400     *
1401     * <p>This implements the 'Language-Tag' production of BCP47, and
1402     * so supports grandfathered (regular and irregular) as well as
1403     * private use language tags.  Stand alone private use tags are
1404     * represented as empty language and extension 'x-whatever',
1405     * and grandfathered tags are converted to their canonical replacements
1406     * where they exist.
1407     *
1408     * <p>Grandfathered tags with canonical replacements are as follows:
1409     *
1410     * <table>
1411     * <tbody align="center">
1412     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
1413     * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
1414     * <tr><td>i-ami</td><td>&nbsp;</td><td>ami</td></tr>
1415     * <tr><td>i-bnn</td><td>&nbsp;</td><td>bnn</td></tr>
1416     * <tr><td>i-hak</td><td>&nbsp;</td><td>hak</td></tr>
1417     * <tr><td>i-klingon</td><td>&nbsp;</td><td>tlh</td></tr>
1418     * <tr><td>i-lux</td><td>&nbsp;</td><td>lb</td></tr>
1419     * <tr><td>i-navajo</td><td>&nbsp;</td><td>nv</td></tr>
1420     * <tr><td>i-pwn</td><td>&nbsp;</td><td>pwn</td></tr>
1421     * <tr><td>i-tao</td><td>&nbsp;</td><td>tao</td></tr>
1422     * <tr><td>i-tay</td><td>&nbsp;</td><td>tay</td></tr>
1423     * <tr><td>i-tsu</td><td>&nbsp;</td><td>tsu</td></tr>
1424     * <tr><td>no-bok</td><td>&nbsp;</td><td>nb</td></tr>
1425     * <tr><td>no-nyn</td><td>&nbsp;</td><td>nn</td></tr>
1426     * <tr><td>sgn-BE-FR</td><td>&nbsp;</td><td>sfb</td></tr>
1427     * <tr><td>sgn-BE-NL</td><td>&nbsp;</td><td>vgt</td></tr>
1428     * <tr><td>sgn-CH-DE</td><td>&nbsp;</td><td>sgg</td></tr>
1429     * <tr><td>zh-guoyu</td><td>&nbsp;</td><td>cmn</td></tr>
1430     * <tr><td>zh-hakka</td><td>&nbsp;</td><td>hak</td></tr>
1431     * <tr><td>zh-min-nan</td><td>&nbsp;</td><td>nan</td></tr>
1432     * <tr><td>zh-xiang</td><td>&nbsp;</td><td>hsn</td></tr>
1433     * </tbody>
1434     * </table>
1435     *
1436     * <p>Grandfathered tags with no modern replacement will be
1437     * converted as follows:
1438     *
1439     * <table>
1440     * <tbody align="center">
1441     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
1442     * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
1443     * <tr><td>en-GB-oed</td><td>&nbsp;</td><td>en-GB-x-oed</td></tr>
1444     * <tr><td>i-default</td><td>&nbsp;</td><td>en-x-i-default</td></tr>
1445     * <tr><td>i-enochian</td><td>&nbsp;</td><td>und-x-i-enochian</td></tr>
1446     * <tr><td>i-mingo</td><td>&nbsp;</td><td>see-x-i-mingo</td></tr>
1447     * <tr><td>zh-min</td><td>&nbsp;</td><td>nan-x-zh-min</td></tr>
1448     * </tbody>
1449     * </table>
1450     *
1451     * <p>For a list of all grandfathered tags, see the
1452     * IANA Language Subtag Registry (search for "Type: grandfathered").
1453     *
1454     * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code>
1455     * and <code>forLanguageTag</code> will round-trip.
1456     *
1457     * @param languageTag the language tag
1458     * @return The locale that best represents the language tag.
1459     * @throws NullPointerException if <code>languageTag</code> is <code>null</code>
1460     * @see #toLanguageTag()
1461     * @see java.util.Locale.Builder#setLanguageTag(String)
1462     * @since 1.7
1463     */
1464    public static Locale forLanguageTag(String languageTag) {
1465        LanguageTag tag = LanguageTag.parse(languageTag, null);
1466        InternalLocaleBuilder bldr = new InternalLocaleBuilder();
1467        bldr.setLanguageTag(tag);
1468        BaseLocale base = bldr.getBaseLocale();
1469        LocaleExtensions exts = bldr.getLocaleExtensions();
1470        if (exts == null && base.getVariant().length() > 0) {
1471            exts = getCompatibilityExtensions(base.getLanguage(), base.getScript(),
1472                                              base.getRegion(), base.getVariant());
1473        }
1474        return getInstance(base, exts);
1475    }
1476
1477    /**
1478     * Returns a three-letter abbreviation of this locale's language.
1479     * If the language matches an ISO 639-1 two-letter code, the
1480     * corresponding ISO 639-2/T three-letter lowercase code is
1481     * returned.  The ISO 639-2 language codes can be found on-line,
1482     * see "Codes for the Representation of Names of Languages Part 2:
1483     * Alpha-3 Code".  If the locale specifies a three-letter
1484     * language, the language is returned as is.  If the locale does
1485     * not specify a language the empty string is returned.
1486     *
1487     * @return A three-letter abbreviation of this locale's language.
1488     * @exception MissingResourceException Throws MissingResourceException if
1489     * three-letter language abbreviation is not available for this locale.
1490     */
1491    public String getISO3Language() throws MissingResourceException {
1492        String lang = baseLocale.getLanguage();
1493        if (lang.length() == 3) {
1494            return lang;
1495        }
1496
1497        String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
1498        if (language3 == null) {
1499            throw new MissingResourceException("Couldn't find 3-letter language code for "
1500                    + lang, "FormatData_" + toString(), "ShortLanguage");
1501        }
1502        return language3;
1503    }
1504
1505    /**
1506     * Returns a three-letter abbreviation for this locale's country.
1507     * If the country matches an ISO 3166-1 alpha-2 code, the
1508     * corresponding ISO 3166-1 alpha-3 uppercase code is returned.
1509     * If the locale doesn't specify a country, this will be the empty
1510     * string.
1511     *
1512     * <p>The ISO 3166-1 codes can be found on-line.
1513     *
1514     * @return A three-letter abbreviation of this locale's country.
1515     * @exception MissingResourceException Throws MissingResourceException if the
1516     * three-letter country abbreviation is not available for this locale.
1517     */
1518    public String getISO3Country() throws MissingResourceException {
1519        String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable);
1520        if (country3 == null) {
1521            throw new MissingResourceException("Couldn't find 3-letter country code for "
1522                    + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
1523        }
1524        return country3;
1525    }
1526
1527    private static final String getISO3Code(String iso2Code, String table) {
1528        int codeLength = iso2Code.length();
1529        if (codeLength == 0) {
1530            return "";
1531        }
1532
1533        int tableLength = table.length();
1534        int index = tableLength;
1535        if (codeLength == 2) {
1536            char c1 = iso2Code.charAt(0);
1537            char c2 = iso2Code.charAt(1);
1538            for (index = 0; index < tableLength; index += 5) {
1539                if (table.charAt(index) == c1
1540                    && table.charAt(index + 1) == c2) {
1541                    break;
1542                }
1543            }
1544        }
1545        return index < tableLength ? table.substring(index + 2, index + 5) : null;
1546    }
1547
1548    /**
1549     * Returns a name for the locale's language that is appropriate for display to the
1550     * user.
1551     * If possible, the name returned will be localized for the default locale.
1552     * For example, if the locale is fr_FR and the default locale
1553     * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
1554     * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
1555     * If the name returned cannot be localized for the default locale,
1556     * (say, we don't have a Japanese name for Croatian),
1557     * this function falls back on the English name, and uses the ISO code as a last-resort
1558     * value.  If the locale doesn't specify a language, this function returns the empty string.
1559     */
1560    public final String getDisplayLanguage() {
1561        return getDisplayLanguage(getDefault(Category.DISPLAY));
1562    }
1563
1564    /**
1565     * Returns a name for the locale's language that is appropriate for display to the
1566     * user.
1567     * If possible, the name returned will be localized according to inLocale.
1568     * For example, if the locale is fr_FR and inLocale
1569     * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
1570     * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
1571     * If the name returned cannot be localized according to inLocale,
1572     * (say, we don't have a Japanese name for Croatian),
1573     * this function falls back on the English name, and finally
1574     * on the ISO code as a last-resort value.  If the locale doesn't specify a language,
1575     * this function returns the empty string.
1576     *
1577     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
1578     */
1579    public String getDisplayLanguage(Locale inLocale) {
1580        return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE);
1581    }
1582
1583    /**
1584     * Returns a name for the the locale's script that is appropriate for display to
1585     * the user. If possible, the name will be localized for the default locale.  Returns
1586     * the empty string if this locale doesn't specify a script code.
1587     *
1588     * @return the display name of the script code for the current default locale
1589     * @since 1.7
1590     */
1591    public String getDisplayScript() {
1592        return getDisplayScript(getDefault());
1593    }
1594
1595    /**
1596     * Returns a name for the locale's script that is appropriate
1597     * for display to the user. If possible, the name will be
1598     * localized for the given locale. Returns the empty string if
1599     * this locale doesn't specify a script code.
1600     *
1601     * @return the display name of the script code for the current default locale
1602     * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
1603     * @since 1.7
1604     */
1605    public String getDisplayScript(Locale inLocale) {
1606        return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT);
1607    }
1608
1609    /**
1610     * Returns a name for the locale's country that is appropriate for display to the
1611     * user.
1612     * If possible, the name returned will be localized for the default locale.
1613     * For example, if the locale is fr_FR and the default locale
1614     * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
1615     * the default locale is fr_FR, getDisplayCountry() will return "Etats-Unis".
1616     * If the name returned cannot be localized for the default locale,
1617     * (say, we don't have a Japanese name for Croatia),
1618     * this function falls back on the English name, and uses the ISO code as a last-resort
1619     * value.  If the locale doesn't specify a country, this function returns the empty string.
1620     */
1621    public final String getDisplayCountry() {
1622        return getDisplayCountry(getDefault(Category.DISPLAY));
1623    }
1624
1625    /**
1626     * Returns a name for the locale's country that is appropriate for display to the
1627     * user.
1628     * If possible, the name returned will be localized according to inLocale.
1629     * For example, if the locale is fr_FR and inLocale
1630     * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
1631     * inLocale is fr_FR, getDisplayCountry() will return "Etats-Unis".
1632     * If the name returned cannot be localized according to inLocale.
1633     * (say, we don't have a Japanese name for Croatia),
1634     * this function falls back on the English name, and finally
1635     * on the ISO code as a last-resort value.  If the locale doesn't specify a country,
1636     * this function returns the empty string.
1637     *
1638     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
1639     */
1640    public String getDisplayCountry(Locale inLocale) {
1641        return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY);
1642    }
1643
1644    private String getDisplayString(String code, Locale inLocale, int type) {
1645        if (code.length() == 0) {
1646            return "";
1647        }
1648
1649        if (inLocale == null) {
1650            throw new NullPointerException();
1651        }
1652
1653        try {
1654            OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
1655            String key = (type == DISPLAY_VARIANT ? "%%"+code : code);
1656            String result = null;
1657
1658            // Check whether a provider can provide an implementation that's closer
1659            // to the requested locale than what the Java runtime itself can provide.
1660            LocaleServiceProviderPool pool =
1661                LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
1662            if (pool.hasProviders()) {
1663                result = pool.getLocalizedObject(
1664                                    LocaleNameGetter.INSTANCE,
1665                                    inLocale, bundle, key,
1666                                    type, code);
1667            }
1668
1669            if (result == null) {
1670                result = bundle.getString(key);
1671            }
1672
1673            if (result != null) {
1674                return result;
1675            }
1676        }
1677        catch (Exception e) {
1678            // just fall through
1679        }
1680        return code;
1681    }
1682
1683    /**
1684     * Returns a name for the locale's variant code that is appropriate for display to the
1685     * user.  If possible, the name will be localized for the default locale.  If the locale
1686     * doesn't specify a variant code, this function returns the empty string.
1687     */
1688    public final String getDisplayVariant() {
1689        return getDisplayVariant(getDefault(Category.DISPLAY));
1690    }
1691
1692    /**
1693     * Returns a name for the locale's variant code that is appropriate for display to the
1694     * user.  If possible, the name will be localized for inLocale.  If the locale
1695     * doesn't specify a variant code, this function returns the empty string.
1696     *
1697     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
1698     */
1699    public String getDisplayVariant(Locale inLocale) {
1700        if (baseLocale.getVariant().length() == 0)
1701            return "";
1702
1703        OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
1704
1705        String names[] = getDisplayVariantArray(bundle, inLocale);
1706
1707        // Get the localized patterns for formatting a list, and use
1708        // them to format the list.
1709        String listPattern = null;
1710        String listCompositionPattern = null;
1711        try {
1712            listPattern = bundle.getString("ListPattern");
1713            listCompositionPattern = bundle.getString("ListCompositionPattern");
1714        } catch (MissingResourceException e) {
1715        }
1716        return formatList(names, listPattern, listCompositionPattern);
1717    }
1718
1719    /**
1720     * Returns a name for the locale that is appropriate for display to the
1721     * user. This will be the values returned by getDisplayLanguage(),
1722     * getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled
1723     * into a single string. The the non-empty values are used in order,
1724     * with the second and subsequent names in parentheses.  For example:
1725     * <blockquote>
1726     * language (script, country, variant)<br>
1727     * language (country)<br>
1728     * language (variant)<br>
1729     * script (country)<br>
1730     * country<br>
1731     * </blockquote>
1732     * depending on which fields are specified in the locale.  If the
1733     * language, sacript, country, and variant fields are all empty,
1734     * this function returns the empty string.
1735     */
1736    public final String getDisplayName() {
1737        return getDisplayName(getDefault(Category.DISPLAY));
1738    }
1739
1740    /**
1741     * Returns a name for the locale that is appropriate for display
1742     * to the user.  This will be the values returned by
1743     * getDisplayLanguage(), getDisplayScript(),getDisplayCountry(),
1744     * and getDisplayVariant() assembled into a single string.
1745     * The non-empty values are used in order,
1746     * with the second and subsequent names in parentheses.  For example:
1747     * <blockquote>
1748     * language (script, country, variant)<br>
1749     * language (country)<br>
1750     * language (variant)<br>
1751     * script (country)<br>
1752     * country<br>
1753     * </blockquote>
1754     * depending on which fields are specified in the locale.  If the
1755     * language, script, country, and variant fields are all empty,
1756     * this function returns the empty string.
1757     *
1758     * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
1759     */
1760    public String getDisplayName(Locale inLocale) {
1761        OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
1762
1763        String languageName = getDisplayLanguage(inLocale);
1764        String scriptName = getDisplayScript(inLocale);
1765        String countryName = getDisplayCountry(inLocale);
1766        String[] variantNames = getDisplayVariantArray(bundle, inLocale);
1767
1768        // Get the localized patterns for formatting a display name.
1769        String displayNamePattern = null;
1770        String listPattern = null;
1771        String listCompositionPattern = null;
1772        try {
1773            displayNamePattern = bundle.getString("DisplayNamePattern");
1774            listPattern = bundle.getString("ListPattern");
1775            listCompositionPattern = bundle.getString("ListCompositionPattern");
1776        } catch (MissingResourceException e) {
1777        }
1778
1779        // The display name consists of a main name, followed by qualifiers.
1780        // Typically, the format is "MainName (Qualifier, Qualifier)" but this
1781        // depends on what pattern is stored in the display locale.
1782        String   mainName       = null;
1783        String[] qualifierNames = null;
1784
1785        // The main name is the language, or if there is no language, the script,
1786        // then if no script, the country. If there is no language/script/country
1787        // (an anomalous situation) then the display name is simply the variant's
1788        // display name.
1789        if (languageName.length() == 0 && scriptName.length() == 0 && countryName.length() == 0) {
1790            if (variantNames.length == 0) {
1791                return "";
1792            } else {
1793                return formatList(variantNames, listPattern, listCompositionPattern);
1794            }
1795        }
1796        ArrayList<String> names = new ArrayList<>(4);
1797        if (languageName.length() != 0) {
1798            names.add(languageName);
1799        }
1800        if (scriptName.length() != 0) {
1801            names.add(scriptName);
1802        }
1803        if (countryName.length() != 0) {
1804            names.add(countryName);
1805        }
1806        if (variantNames.length != 0) {
1807            for (String var : variantNames) {
1808                names.add(var);
1809            }
1810        }
1811
1812        // The first one in the main name
1813        mainName = names.get(0);
1814
1815        // Others are qualifiers
1816        int numNames = names.size();
1817        qualifierNames = (numNames > 1) ?
1818                names.subList(1, numNames).toArray(new String[numNames - 1]) : new String[0];
1819
1820        // Create an array whose first element is the number of remaining
1821        // elements.  This serves as a selector into a ChoiceFormat pattern from
1822        // the resource.  The second and third elements are the main name and
1823        // the qualifier; if there are no qualifiers, the third element is
1824        // unused by the format pattern.
1825        Object[] displayNames = {
1826            new Integer(qualifierNames.length != 0 ? 2 : 1),
1827            mainName,
1828            // We could also just call formatList() and have it handle the empty
1829            // list case, but this is more efficient, and we want it to be
1830            // efficient since all the language-only locales will not have any
1831            // qualifiers.
1832            qualifierNames.length != 0 ? formatList(qualifierNames, listPattern, listCompositionPattern) : null
1833        };
1834
1835        if (displayNamePattern != null) {
1836            return new MessageFormat(displayNamePattern).format(displayNames);
1837        }
1838        else {
1839            // If we cannot get the message format pattern, then we use a simple
1840            // hard-coded pattern.  This should not occur in practice unless the
1841            // installation is missing some core files (FormatData etc.).
1842            StringBuilder result = new StringBuilder();
1843            result.append((String)displayNames[1]);
1844            if (displayNames.length > 2) {
1845                result.append(" (");
1846                result.append((String)displayNames[2]);
1847                result.append(')');
1848            }
1849            return result.toString();
1850        }
1851    }
1852
1853    /**
1854     * Overrides Cloneable.
1855     */
1856    public Object clone()
1857    {
1858        try {
1859            Locale that = (Locale)super.clone();
1860            return that;
1861        } catch (CloneNotSupportedException e) {
1862            throw new InternalError();
1863        }
1864    }
1865
1866    /**
1867     * Override hashCode.
1868     * Since Locales are often used in hashtables, caches the value
1869     * for speed.
1870     */
1871    @Override
1872    public int hashCode() {
1873        int hc = hashCodeValue;
1874        if (hc == 0) {
1875            hc = baseLocale.hashCode();
1876            if (localeExtensions != null) {
1877                hc ^= localeExtensions.hashCode();
1878            }
1879            hashCodeValue = hc;
1880        }
1881        return hc;
1882    }
1883
1884    // Overrides
1885
1886    /**
1887     * Returns true if this Locale is equal to another object.  A Locale is
1888     * deemed equal to another Locale with identical language, script, country,
1889     * variant and extensions, and unequal to all other objects.
1890     *
1891     * @return true if this Locale is equal to the specified object.
1892     */
1893    @Override
1894    public boolean equals(Object obj) {
1895        if (this == obj)                      // quick check
1896            return true;
1897        if (!(obj instanceof Locale))
1898            return false;
1899        BaseLocale otherBase = ((Locale)obj).baseLocale;
1900        if (!baseLocale.equals(otherBase)) {
1901            return false;
1902        }
1903        if (localeExtensions == null) {
1904            return ((Locale)obj).localeExtensions == null;
1905        }
1906        return localeExtensions.equals(((Locale)obj).localeExtensions);
1907    }
1908
1909    // ================= privates =====================================
1910
1911    private transient BaseLocale baseLocale;
1912    private transient LocaleExtensions localeExtensions;
1913
1914    /**
1915     * Calculated hashcode
1916     */
1917    private transient volatile int hashCodeValue = 0;
1918
1919    private static Locale defaultLocale = null;
1920    private static Locale defaultDisplayLocale = null;
1921    private static Locale defaultFormatLocale = null;
1922
1923    /**
1924     * Return an array of the display names of the variant.
1925     * @param bundle the ResourceBundle to use to get the display names
1926     * @return an array of display names, possible of zero length.
1927     */
1928    private String[] getDisplayVariantArray(OpenListResourceBundle bundle, Locale inLocale) {
1929        // Split the variant name into tokens separated by '_'.
1930        StringTokenizer tokenizer = new StringTokenizer(baseLocale.getVariant(), "_");
1931        String[] names = new String[tokenizer.countTokens()];
1932
1933        // For each variant token, lookup the display name.  If
1934        // not found, use the variant name itself.
1935        for (int i=0; i<names.length; ++i) {
1936            names[i] = getDisplayString(tokenizer.nextToken(),
1937                                inLocale, DISPLAY_VARIANT);
1938        }
1939
1940        return names;
1941    }
1942
1943    /**
1944     * Format a list using given pattern strings.
1945     * If either of the patterns is null, then a the list is
1946     * formatted by concatenation with the delimiter ','.
1947     * @param stringList the list of strings to be formatted.
1948     * @param listPattern should create a MessageFormat taking 0-3 arguments
1949     * and formatting them into a list.
1950     * @param listCompositionPattern should take 2 arguments
1951     * and is used by composeList.
1952     * @return a string representing the list.
1953     */
1954    private static String formatList(String[] stringList, String listPattern, String listCompositionPattern) {
1955        // If we have no list patterns, compose the list in a simple,
1956        // non-localized way.
1957        if (listPattern == null || listCompositionPattern == null) {
1958            StringBuffer result = new StringBuffer();
1959            for (int i=0; i<stringList.length; ++i) {
1960                if (i>0) result.append(',');
1961                result.append(stringList[i]);
1962            }
1963            return result.toString();
1964        }
1965
1966        // Compose the list down to three elements if necessary
1967        if (stringList.length > 3) {
1968            MessageFormat format = new MessageFormat(listCompositionPattern);
1969            stringList = composeList(format, stringList);
1970        }
1971
1972        // Rebuild the argument list with the list length as the first element
1973        Object[] args = new Object[stringList.length + 1];
1974        System.arraycopy(stringList, 0, args, 1, stringList.length);
1975        args[0] = new Integer(stringList.length);
1976
1977        // Format it using the pattern in the resource
1978        MessageFormat format = new MessageFormat(listPattern);
1979        return format.format(args);
1980    }
1981
1982    /**
1983     * Given a list of strings, return a list shortened to three elements.
1984     * Shorten it by applying the given format to the first two elements
1985     * recursively.
1986     * @param format a format which takes two arguments
1987     * @param list a list of strings
1988     * @return if the list is three elements or shorter, the same list;
1989     * otherwise, a new list of three elements.
1990     */
1991    private static String[] composeList(MessageFormat format, String[] list) {
1992        if (list.length <= 3) return list;
1993
1994        // Use the given format to compose the first two elements into one
1995        String[] listItems = { list[0], list[1] };
1996        String newItem = format.format(listItems);
1997
1998        // Form a new list one element shorter
1999        String[] newList = new String[list.length-1];
2000        System.arraycopy(list, 2, newList, 1, newList.length-1);
2001        newList[0] = newItem;
2002
2003        // Recurse
2004        return composeList(format, newList);
2005    }
2006
2007    /**
2008     * @serialField language    String
2009     *      language subtag in lower case. (See <a href="java/util/Locale.html#getLanguage()">getLanguage()</a>)
2010     * @serialField country     String
2011     *      country subtag in upper case. (See <a href="java/util/Locale.html#getCountry()">getCountry()</a>)
2012     * @serialField variant     String
2013     *      variant subtags separated by LOWLINE characters. (See <a href="java/util/Locale.html#getVariant()">getVariant()</a>)
2014     * @serialField hashcode    int
2015     *      deprecated, for forward compatibility only
2016     * @serialField script      String
2017     *      script subtag in title case (See <a href="java/util/Locale.html#getScript()">getScript()</a>)
2018     * @serialField extensions  String
2019     *      canonical representation of extensions, that is,
2020     *      BCP47 extensions in alphabetical order followed by
2021     *      BCP47 private use subtags, all in lower case letters
2022     *      separated by HYPHEN-MINUS characters.
2023     *      (See <a href="java/util/Locale.html#getExtensionKeys()">getExtensionKeys()</a>,
2024     *      <a href="java/util/Locale.html#getExtension(char)">getExtension(char)</a>)
2025     */
2026    private static final ObjectStreamField[] serialPersistentFields = {
2027        new ObjectStreamField("language", String.class),
2028        new ObjectStreamField("country", String.class),
2029        new ObjectStreamField("variant", String.class),
2030        new ObjectStreamField("hashcode", int.class),
2031        new ObjectStreamField("script", String.class),
2032        new ObjectStreamField("extensions", String.class),
2033    };
2034
2035    /**
2036     * Serializes this <code>Locale</code> to the specified <code>ObjectOutputStream</code>.
2037     * @param out the <code>ObjectOutputStream</code> to write
2038     * @throws IOException
2039     * @since 1.7
2040     */
2041    private void writeObject(ObjectOutputStream out) throws IOException {
2042        ObjectOutputStream.PutField fields = out.putFields();
2043        fields.put("language", baseLocale.getLanguage());
2044        fields.put("script", baseLocale.getScript());
2045        fields.put("country", baseLocale.getRegion());
2046        fields.put("variant", baseLocale.getVariant());
2047        fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
2048        fields.put("hashcode", -1); // place holder just for backward support
2049        out.writeFields();
2050    }
2051
2052    /**
2053     * Deserializes this <code>Locale</code>.
2054     * @param in the <code>ObjectInputStream</code> to read
2055     * @throws IOException
2056     * @throws ClassNotFoundException
2057     * @throws IllformdLocaleException
2058     * @since 1.7
2059     */
2060    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
2061        ObjectInputStream.GetField fields = in.readFields();
2062        String language = (String)fields.get("language", "");
2063        String script = (String)fields.get("script", "");
2064        String country = (String)fields.get("country", "");
2065        String variant = (String)fields.get("variant", "");
2066        String extStr = (String)fields.get("extensions", "");
2067        baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
2068        if (extStr.length() > 0) {
2069            try {
2070                InternalLocaleBuilder bldr = new InternalLocaleBuilder();
2071                bldr.setExtensions(extStr);
2072                localeExtensions = bldr.getLocaleExtensions();
2073            } catch (LocaleSyntaxException e) {
2074                throw new IllformedLocaleException(e.getMessage());
2075            }
2076        } else {
2077            localeExtensions = null;
2078        }
2079    }
2080
2081    /**
2082     * Returns a cached <code>Locale</code> instance equivalent to
2083     * the deserialized <code>Locale</code>. When serialized
2084     * language, country and variant fields read from the object data stream
2085     * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
2086     * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>
2087     * "ca"/"japanese" (calendar type is "japanese") or "nu"/"thai" (number script
2088     * type is "thai"). See <a href="Locale.html#special_cases_constructor"/>Special Cases</a>
2089     * for more information.
2090     *
2091     * @return an instance of <code>Locale</code> equivalent to
2092     * the deserialized <code>Locale</code>.
2093     * @throws java.io.ObjectStreamException
2094     */
2095    private Object readResolve() throws java.io.ObjectStreamException {
2096        return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
2097                baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
2098    }
2099
2100    private static volatile String[] isoLanguages = null;
2101
2102    private static volatile String[] isoCountries = null;
2103
2104    private static String convertOldISOCodes(String language) {
2105        // we accept both the old and the new ISO codes for the languages whose ISO
2106        // codes have changed, but we always store the OLD code, for backward compatibility
2107        language = LocaleUtils.toLowerString(language).intern();
2108        if (language == "he") {
2109            return "iw";
2110        } else if (language == "yi") {
2111            return "ji";
2112        } else if (language == "id") {
2113            return "in";
2114        } else {
2115            return language;
2116        }
2117    }
2118
2119    private static LocaleExtensions getCompatibilityExtensions(String language,
2120                                                               String script,
2121                                                               String country,
2122                                                               String variant) {
2123        LocaleExtensions extensions = null;
2124        // Special cases for backward compatibility support
2125        if (LocaleUtils.caseIgnoreMatch(language, "ja")
2126                && script.length() == 0
2127                && LocaleUtils.caseIgnoreMatch(country, "jp")
2128                && "JP".equals(variant)) {
2129            // ja_JP_JP -> u-ca-japanese (calendar = japanese)
2130            extensions = LocaleExtensions.CALENDAR_JAPANESE;
2131        } else if (LocaleUtils.caseIgnoreMatch(language, "th")
2132                && script.length() == 0
2133                && LocaleUtils.caseIgnoreMatch(country, "th")
2134                && "TH".equals(variant)) {
2135            // th_TH_TH -> u-nu-thai (numbersystem = thai)
2136            extensions = LocaleExtensions.NUMBER_THAI;
2137        }
2138        return extensions;
2139    }
2140
2141    /**
2142     * Obtains a localized locale names from a LocaleNameProvider
2143     * implementation.
2144     */
2145    private static class LocaleNameGetter
2146        implements LocaleServiceProviderPool.LocalizedObjectGetter<LocaleNameProvider, String> {
2147        private static final LocaleNameGetter INSTANCE = new LocaleNameGetter();
2148
2149        public String getObject(LocaleNameProvider localeNameProvider,
2150                                Locale locale,
2151                                String key,
2152                                Object... params) {
2153            assert params.length == 2;
2154            int type = (Integer)params[0];
2155            String code = (String)params[1];
2156
2157            switch(type) {
2158            case DISPLAY_LANGUAGE:
2159                return localeNameProvider.getDisplayLanguage(code, locale);
2160            case DISPLAY_COUNTRY:
2161                return localeNameProvider.getDisplayCountry(code, locale);
2162            case DISPLAY_VARIANT:
2163                return localeNameProvider.getDisplayVariant(code, locale);
2164            case DISPLAY_SCRIPT:
2165                return localeNameProvider.getDisplayScript(code, locale);
2166            default:
2167                assert false; // shouldn't happen
2168            }
2169
2170            return null;
2171        }
2172    }
2173
2174    /**
2175     * Enum for locale categories.  These locale categories are used to get/set
2176     * the default locale for the specific functionality represented by the
2177     * category.
2178     *
2179     * @see #getDefault(Locale.Category)
2180     * @see #setDefault(Locale.Category, Locale)
2181     * @since 1.7
2182     */
2183    public enum Category {
2184
2185        /**
2186         * Category used to represent the default locale for
2187         * displaying user interfaces.
2188         */
2189        DISPLAY("user.language.display",
2190                "user.script.display",
2191                "user.country.display",
2192                "user.variant.display"),
2193
2194        /**
2195         * Category used to represent the default locale for
2196         * formatting dates, numbers, and/or currencies.
2197         */
2198        FORMAT("user.language.format",
2199               "user.script.format",
2200               "user.country.format",
2201               "user.variant.format");
2202
2203        Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
2204            this.languageKey = languageKey;
2205            this.scriptKey = scriptKey;
2206            this.countryKey = countryKey;
2207            this.variantKey = variantKey;
2208        }
2209
2210        final String languageKey;
2211        final String scriptKey;
2212        final String countryKey;
2213        final String variantKey;
2214    }
2215
2216    /**
2217     * <code>Builder</code> is used to build instances of <code>Locale</code>
2218     * from values configured by the setters.  Unlike the <code>Locale</code>
2219     * constructors, the <code>Builder</code> checks if a value configured by a
2220     * setter satisfies the syntax requirements defined by the <code>Locale</code>
2221     * class.  A <code>Locale</code> object created by a <code>Builder</code> is
2222     * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
2223     * without losing information.
2224     *
2225     * <p><b>Note:</b> The <code>Locale</code> class does not provide any
2226     * syntactic restrictions on variant, while BCP 47 requires each variant
2227     * subtag to be 5 to 8 alphanumerics or a single numeric followed by 3
2228     * alphanumerics.  The method <code>setVariant</code> throws
2229     * <code>IllformedLocaleException</code> for a variant that does not satisfy
2230     * this restriction. If it is necessary to support such a variant, use a
2231     * Locale constructor.  However, keep in mind that a <code>Locale</code>
2232     * object created this way might lose the variant information when
2233     * transformed to a BCP 47 language tag.
2234     *
2235     * <p>The following example shows how to create a <code>Locale</code> object
2236     * with the <code>Builder</code>.
2237     * <blockquote>
2238     * <pre>
2239     *     Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
2240     * </pre>
2241     * </blockquote>
2242     *
2243     * <p>Builders can be reused; <code>clear()</code> resets all
2244     * fields to their default values.
2245     *
2246     * @see Locale#forLanguageTag
2247     * @since 1.7
2248     */
2249    public static final class Builder {
2250        private final InternalLocaleBuilder localeBuilder;
2251
2252        /**
2253         * Constructs an empty Builder. The default value of all
2254         * fields, extensions, and private use information is the
2255         * empty string.
2256         */
2257        public Builder() {
2258            localeBuilder = new InternalLocaleBuilder();
2259        }
2260
2261        /**
2262         * Resets the <code>Builder</code> to match the provided
2263         * <code>locale</code>.  Existing state is discarded.
2264         *
2265         * <p>All fields of the locale must be well-formed, see {@link Locale}.
2266         *
2267         * <p>Locales with any ill-formed fields cause
2268         * <code>IllformedLocaleException</code> to be thrown, except for the
2269         * following three cases which are accepted for compatibility
2270         * reasons:<ul>
2271         * <li>Locale("ja", "JP", "JP") is treated as "ja-JP-u-ca-japanese"
2272         * <li>Locale("th", "TH", "TH") is treated as "th-TH-u-nu-thai"
2273         * <li>Locale("no", "NO", "NY") is treated as "nn-NO"</ul>
2274         *
2275         * @param locale the locale
2276         * @return This builder.
2277         * @throws IllformedLocaleException if <code>locale</code> has
2278         * any ill-formed fields.
2279         * @throws NullPointerException if <code>locale</code> is null.
2280         */
2281        public Builder setLocale(Locale locale) {
2282            try {
2283                localeBuilder.setLocale(locale.baseLocale, locale.localeExtensions);
2284            } catch (LocaleSyntaxException e) {
2285                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2286            }
2287            return this;
2288        }
2289
2290        /**
2291         * Resets the Builder to match the provided IETF BCP 47
2292         * language tag.  Discards the existing state.  Null and the
2293         * empty string cause the builder to be reset, like {@link
2294         * #clear}.  Grandfathered tags (see {@link
2295         * Locale#forLanguageTag}) are converted to their canonical
2296         * form before being processed.  Otherwise, the language tag
2297         * must be well-formed (see {@link Locale}) or an exception is
2298         * thrown (unlike <code>Locale.forLanguageTag</code>, which
2299         * just discards ill-formed and following portions of the
2300         * tag).
2301         *
2302         * @param languageTag the language tag
2303         * @return This builder.
2304         * @throws IllformedLocaleException if <code>languageTag</code> is ill-formed
2305         * @see Locale#forLanguageTag(String)
2306         */
2307        public Builder setLanguageTag(String languageTag) {
2308            ParseStatus sts = new ParseStatus();
2309            LanguageTag tag = LanguageTag.parse(languageTag, sts);
2310            if (sts.isError()) {
2311                throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
2312            }
2313            localeBuilder.setLanguageTag(tag);
2314            return this;
2315        }
2316
2317        /**
2318         * Sets the language.  If <code>language</code> is the empty string or
2319         * null, the language in this <code>Builder</code> is removed.  Otherwise,
2320         * the language must be <a href="./Locale.html#def_language">well-formed</a>
2321         * or an exception is thrown.
2322         *
2323         * <p>The typical language value is a two or three-letter language
2324         * code as defined in ISO639.
2325         *
2326         * @param language the language
2327         * @return This builder.
2328         * @throws IllformedLocaleException if <code>language</code> is ill-formed
2329         */
2330        public Builder setLanguage(String language) {
2331            try {
2332                localeBuilder.setLanguage(language);
2333            } catch (LocaleSyntaxException e) {
2334                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2335            }
2336            return this;
2337        }
2338
2339        /**
2340         * Sets the script. If <code>script</code> is null or the empty string,
2341         * the script in this <code>Builder</code> is removed.
2342         * Otherwise, the script must be <a href="./Locale.html#def_script">well-formed</a> or an
2343         * exception is thrown.
2344         *
2345         * <p>The typical script value is a four-letter script code as defined by ISO 15924.
2346         *
2347         * @param script the script
2348         * @return This builder.
2349         * @throws IllformedLocaleException if <code>script</code> is ill-formed
2350         */
2351        public Builder setScript(String script) {
2352            try {
2353                localeBuilder.setScript(script);
2354            } catch (LocaleSyntaxException e) {
2355                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2356            }
2357            return this;
2358        }
2359
2360        /**
2361         * Sets the region.  If region is null or the empty string, the region
2362         * in this <code>Builder</code> is removed.  Otherwise,
2363         * the region must be <a href="./Locale.html#def_region">well-formed</a> or an
2364         * exception is thrown.
2365         *
2366         * <p>The typical region value is a two-letter ISO 3166 code or a
2367         * three-digit UN M.49 area code.
2368         *
2369         * <p>The country value in the <code>Locale</code> created by the
2370         * <code>Builder</code> is always normalized to upper case.
2371         *
2372         * @param region the region
2373         * @return This builder.
2374         * @throws IllformedLocaleException if <code>region</code> is ill-formed
2375         */
2376        public Builder setRegion(String region) {
2377            try {
2378                localeBuilder.setRegion(region);
2379            } catch (LocaleSyntaxException e) {
2380                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2381            }
2382            return this;
2383        }
2384
2385        /**
2386         * Sets the variant.  If variant is null or the empty string, the
2387         * variant in this <code>Builder</code> is removed.  Otherwise, it
2388         * must consist of one or more <a href="./Locale.html#def_variant">well-formed</a>
2389         * subtags, or an exception is thrown.
2390         *
2391         * <p><b>Note:</b> This method checks if <code>variant</code>
2392         * satisfies the IETF BCP 47 variant subtag's syntax requirements,
2393         * and normalizes the value to lowercase letters.  However,
2394         * the <code>Locale</code> class does not impose any syntactic
2395         * restriction on variant, and the variant value in
2396         * <code>Locale</code> is case sensitive.  To set such a variant,
2397         * use a Locale constructor.
2398         *
2399         * @param variant the variant
2400         * @return This builder.
2401         * @throws IllformedLocaleException if <code>variant</code> is ill-formed
2402         */
2403        public Builder setVariant(String variant) {
2404            try {
2405                localeBuilder.setVariant(variant);
2406            } catch (LocaleSyntaxException e) {
2407                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2408            }
2409            return this;
2410        }
2411
2412        /**
2413         * Sets the extension for the given key. If the value is null or the
2414         * empty string, the extension is removed.  Otherwise, the extension
2415         * must be <a href="./Locale.html#def_extensions">well-formed</a> or an exception
2416         * is thrown.
2417         *
2418         * <p><b>Note:</b> The key {@link Locale#UNICODE_LOCALE_EXTENSION
2419         * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension.
2420         * Setting a value for this key replaces any existing Unicode locale key/type
2421         * pairs with those defined in the extension.
2422         *
2423         * <p><b>Note:</b> The key {@link Locale#PRIVATE_USE_EXTENSION
2424         * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be
2425         * well-formed, the value for this key needs only to have subtags of one to
2426         * eight alphanumeric characters, not two to eight as in the general case.
2427         *
2428         * @param key the extension key
2429         * @param value the extension value
2430         * @return This builder.
2431         * @throws IllformedLocaleException if <code>key</code> is illegal
2432         * or <code>value</code> is ill-formed
2433         * @see #setUnicodeLocaleKeyword(String, String)
2434         */
2435        public Builder setExtension(char key, String value) {
2436            try {
2437                localeBuilder.setExtension(key, value);
2438            } catch (LocaleSyntaxException e) {
2439                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2440            }
2441            return this;
2442        }
2443
2444        /**
2445         * Sets the Unicode locale keyword type for the given key.  If the type
2446         * is null, the Unicode keyword is removed.  Otherwise, the key must be
2447         * non-null and both key and type must be <a
2448         * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
2449         * is thrown.
2450         *
2451         * <p>Keys and types are converted to lower case.
2452         *
2453         * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension}
2454         * replaces all Unicode locale keywords with those defined in the
2455         * extension.
2456         *
2457         * @param key the Unicode locale key
2458         * @param type the Unicode locale type
2459         * @return This builder.
2460         * @throws IllformedLocaleException if <code>key</code> or <code>type</code>
2461         * is ill-formed
2462         * @throws NullPointerException if <code>key</code> is null
2463         * @see #setExtension(char, String)
2464         */
2465        public Builder setUnicodeLocaleKeyword(String key, String type) {
2466            try {
2467                localeBuilder.setUnicodeLocaleKeyword(key, type);
2468            } catch (LocaleSyntaxException e) {
2469                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2470            }
2471            return this;
2472        }
2473
2474        /**
2475         * Adds a unicode locale attribute, if not already present, otherwise
2476         * has no effect.  The attribute must not be null and must be <a
2477         * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
2478         * is thrown.
2479         *
2480         * @param attribute the attribute
2481         * @return This builder.
2482         * @throws NullPointerException if <code>attribute</code> is null
2483         * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
2484         * @see #setExtension(char, String)
2485         */
2486        public Builder addUnicodeLocaleAttribute(String attribute) {
2487            try {
2488                localeBuilder.addUnicodeLocaleAttribute(attribute);
2489            } catch (LocaleSyntaxException e) {
2490                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2491            }
2492            return this;
2493        }
2494
2495        /**
2496         * Removes a unicode locale attribute, if present, otherwise has no
2497         * effect.  The attribute must not be null and must be <a
2498         * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
2499         * is thrown.
2500         *
2501         * <p>Attribute comparision for removal is case-insensitive.
2502         *
2503         * @param attribute the attribute
2504         * @return This builder.
2505         * @throws NullPointerException if <code>attribute</code> is null
2506         * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
2507         * @see #setExtension(char, String)
2508         */
2509        public Builder removeUnicodeLocaleAttribute(String attribute) {
2510            try {
2511                localeBuilder.removeUnicodeLocaleAttribute(attribute);
2512            } catch (LocaleSyntaxException e) {
2513                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
2514            }
2515            return this;
2516        }
2517
2518        /**
2519         * Resets the builder to its initial, empty state.
2520         *
2521         * @return This builder.
2522         */
2523        public Builder clear() {
2524            localeBuilder.clear();
2525            return this;
2526        }
2527
2528        /**
2529         * Resets the extensions to their initial, empty state.
2530         * Language, script, region and variant are unchanged.
2531         *
2532         * @return This builder.
2533         * @see #setExtension(char, String)
2534         */
2535        public Builder clearExtensions() {
2536            localeBuilder.clearExtensions();
2537            return this;
2538        }
2539
2540        /**
2541         * Returns an instance of <code>Locale</code> created from the fields set
2542         * on this builder.
2543         *
2544         * <p>This applies the conversions listed in {@link Locale#forLanguageTag}
2545         * when constructing a Locale. (Grandfathered tags are handled in
2546         * {@link #setLanguageTag}.)
2547         *
2548         * @return A Locale.
2549         */
2550        public Locale build() {
2551            BaseLocale baseloc = localeBuilder.getBaseLocale();
2552            LocaleExtensions extensions = localeBuilder.getLocaleExtensions();
2553            if (extensions == null && baseloc.getVariant().length() > 0) {
2554                extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(),
2555                        baseloc.getRegion(), baseloc.getVariant());
2556            }
2557            return Locale.getInstance(baseloc, extensions);
2558        }
2559    }
2560}
2561