Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 /*
     28  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
     29  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
     30  *
     31  * The original version of this source code and documentation
     32  * is copyrighted and owned by Taligent, Inc., a wholly-owned
     33  * subsidiary of IBM. These materials are provided under terms
     34  * of a License Agreement between Taligent and Sun. This technology
     35  * is protected by multiple US and International patents.
     36  *
     37  * This notice and attribution to Taligent may not be removed.
     38  * Taligent is a registered trademark of Taligent, Inc.
     39  *
     40  */
     41 
     42 package java.util;
     43 
     44 import java.io.IOException;
     45 import java.io.ObjectInputStream;
     46 import java.io.ObjectOutputStream;
     47 import java.io.ObjectStreamField;
     48 import java.io.Serializable;
     49 import java.security.AccessController;
     50 import java.text.MessageFormat;
     51 import java.util.spi.LocaleNameProvider;
     52 import libcore.icu.ICU;
     53 
     54 import sun.security.action.GetPropertyAction;
     55 import sun.util.LocaleServiceProviderPool;
     56 import sun.util.locale.BaseLocale;
     57 import sun.util.locale.InternalLocaleBuilder;
     58 import sun.util.locale.LanguageTag;
     59 import sun.util.locale.LocaleExtensions;
     60 import sun.util.locale.LocaleObjectCache;
     61 import sun.util.locale.LocaleSyntaxException;
     62 import sun.util.locale.LocaleUtils;
     63 import sun.util.locale.ParseStatus;
     64 import sun.util.locale.UnicodeLocaleExtension;
     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"></a><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"/></a><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"></a><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"></a><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"></a><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"></a>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"></a>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  * <a name="locale_data"></a><h4>Locale data</h4>
    402  * <p>Note that locale data comes solely from ICU. User-supplied locale service providers (using
    403  * the {@code java.text.spi} or {@code java.util.spi} mechanisms) are not supported.
    404  *
    405  * <p>Here are the versions of ICU (and the corresponding CLDR and Unicode versions) used in
    406  * various Android releases:
    407  * <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
    408  * <tr><td>Android 1.5 (Cupcake)/Android 1.6 (Donut)/Android 2.0 (Eclair)</td>
    409  *     <td>ICU 3.8</td>
    410  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-5">CLDR 1.5</a></td>
    411  *     <td><a href="http://www.unicode.org/versions/Unicode5.0.0/">Unicode 5.0</a></td></tr>
    412  * <tr><td>Android 2.2 (Froyo)</td>
    413  *     <td>ICU 4.2</td>
    414  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-7">CLDR 1.7</a></td>
    415  *     <td><a href="http://www.unicode.org/versions/Unicode5.1.0/">Unicode 5.1</a></td></tr>
    416  * <tr><td>Android 2.3 (Gingerbread)/Android 3.0 (Honeycomb)</td>
    417  *     <td>ICU 4.4</td>
    418  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-8">CLDR 1.8</a></td>
    419  *     <td><a href="http://www.unicode.org/versions/Unicode5.2.0/">Unicode 5.2</a></td></tr>
    420  * <tr><td>Android 4.0 (Ice Cream Sandwich)</td>
    421  *     <td><a href="http://site.icu-project.org/download/46">ICU 4.6</a></td>
    422  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-9">CLDR 1.9</a></td>
    423  *     <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
    424  * <tr><td>Android 4.1 (Jelly Bean)</td>
    425  *     <td><a href="http://site.icu-project.org/download/48">ICU 4.8</a></td>
    426  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-2-0">CLDR 2.0</a></td>
    427  *     <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
    428  * <tr><td>Android 4.3 (Jelly Bean MR2)</td>
    429  *     <td><a href="http://site.icu-project.org/download/50">ICU 50</a></td>
    430  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-22-1">CLDR 22.1</a></td>
    431  *     <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
    432  * <tr><td>Android 4.4 (KitKat)</td>
    433  *     <td><a href="http://site.icu-project.org/download/51">ICU 51</a></td>
    434  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-23">CLDR 23</a></td>
    435  *     <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
    436  * <tr><td>Android 5.0 (Lollipop)</td>
    437  *     <td><a href="http://site.icu-project.org/download/53">ICU 53</a></td>
    438  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-25">CLDR 25</a></td>
    439  *     <td><a href="http://www.unicode.org/versions/Unicode6.3.0/">Unicode 6.3</a></td></tr>
    440  * <tr><td>Android 6.0 (Marshmallow)</td>
    441  *     <td><a href="http://site.icu-project.org/download/55">ICU 55.1</a></td>
    442  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-27">CLDR 27.0.1</a></td>
    443  *     <td><a href="http://www.unicode.org/versions/Unicode7.0.0/">Unicode 7.0</a></td></tr>
    444  * </table>
    445  *
    446  * <a name="default_locale"></a><h4>Be wary of the default locale</h3>
    447  * <p>Note that there are many convenience methods that automatically use the default locale, but
    448  * using them may lead to subtle bugs.
    449  *
    450  * <p>The default locale is appropriate for tasks that involve presenting data to the user. In
    451  * this case, you want to use the user's date/time formats, number
    452  * formats, rules for conversion to lowercase, and so on. In this case, it's safe to use the
    453  * convenience methods.
    454  *
    455  * <p>The default locale is <i>not</i> appropriate for machine-readable output. The best choice
    456  * there is usually {@code Locale.US}&nbsp;&ndash; this locale is guaranteed to be available on all
    457  * devices, and the fact that it has no surprising special cases and is frequently used (especially
    458  * for computer-computer communication) means that it tends to be the most efficient choice too.
    459  *
    460  * <p>A common mistake is to implicitly use the default locale when producing output meant to be
    461  * machine-readable. This tends to work on the developer's test devices (especially because so many
    462  * developers use en_US), but fails when run on a device whose user is in a more complex locale.
    463  *
    464  * <p>For example, if you're formatting integers some locales will use non-ASCII decimal
    465  * digits. As another example, if you're formatting floating-point numbers some locales will use
    466  * {@code ','} as the decimal point and {@code '.'} for digit grouping. That's correct for
    467  * human-readable output, but likely to cause problems if presented to another
    468  * computer ({@link Double#parseDouble} can't parse such a number, for example).
    469  * You should also be wary of the {@link String#toLowerCase} and
    470  * {@link String#toUpperCase} overloads that don't take a {@code Locale}: in Turkey, for example,
    471  * the characters {@code 'i'} and {@code 'I'} won't be converted to {@code 'I'} and {@code 'i'}.
    472  * This is the correct behavior for Turkish text (such as user input), but inappropriate for, say,
    473  * HTTP headers.
    474  *
    475  * @see Builder
    476  * @see ResourceBundle
    477  * @see java.text.Format
    478  * @see java.text.NumberFormat
    479  * @see java.text.Collator
    480  * @author Mark Davis
    481  * @since 1.1
    482  */
    483 public final class Locale implements Cloneable, Serializable {
    484 
    485     static private final  Cache LOCALECACHE = new Cache();
    486 
    487     /** Useful constant for language.
    488      */
    489     static public final Locale ENGLISH = createConstant("en", "");
    490 
    491     /** Useful constant for language.
    492      */
    493     static public final Locale FRENCH = createConstant("fr", "");
    494 
    495     /** Useful constant for language.
    496      */
    497     static public final Locale GERMAN = createConstant("de", "");
    498 
    499     /** Useful constant for language.
    500      */
    501     static public final Locale ITALIAN = createConstant("it", "");
    502 
    503     /** Useful constant for language.
    504      */
    505     static public final Locale JAPANESE = createConstant("ja", "");
    506 
    507     /** Useful constant for language.
    508      */
    509     static public final Locale KOREAN = createConstant("ko", "");
    510 
    511     /** Useful constant for language.
    512      */
    513     static public final Locale CHINESE = createConstant("zh", "");
    514 
    515     /** Useful constant for language.
    516      */
    517     static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
    518 
    519     /** Useful constant for language.
    520      */
    521     static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
    522 
    523     /** Useful constant for country.
    524      */
    525     static public final Locale FRANCE = createConstant("fr", "FR");
    526 
    527     /** Useful constant for country.
    528      */
    529     static public final Locale GERMANY = createConstant("de", "DE");
    530 
    531     /** Useful constant for country.
    532      */
    533     static public final Locale ITALY = createConstant("it", "IT");
    534 
    535     /** Useful constant for country.
    536      */
    537     static public final Locale JAPAN = createConstant("ja", "JP");
    538 
    539     /** Useful constant for country.
    540      */
    541     static public final Locale KOREA = createConstant("ko", "KR");
    542 
    543     /** Useful constant for country.
    544      */
    545     static public final Locale CHINA = SIMPLIFIED_CHINESE;
    546 
    547     /** Useful constant for country.
    548      */
    549     static public final Locale PRC = SIMPLIFIED_CHINESE;
    550 
    551     /** Useful constant for country.
    552      */
    553     static public final Locale TAIWAN = TRADITIONAL_CHINESE;
    554 
    555     /** Useful constant for country.
    556      */
    557     static public final Locale UK = createConstant("en", "GB");
    558 
    559     /** Useful constant for country.
    560      */
    561     static public final Locale US = createConstant("en", "US");
    562 
    563     /** Useful constant for country.
    564      */
    565     static public final Locale CANADA = createConstant("en", "CA");
    566 
    567     /** Useful constant for country.
    568      */
    569     static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
    570 
    571     /**
    572      * ISO 639-3 generic code for undetermined languages.
    573      */
    574     private static final String UNDETERMINED_LANGUAGE = "und";
    575 
    576     /**
    577      * Useful constant for the root locale.  The root locale is the locale whose
    578      * language, country, and variant are empty ("") strings.  This is regarded
    579      * as the base locale of all locales, and is used as the language/country
    580      * neutral locale for the locale sensitive operations.
    581      *
    582      * @since 1.6
    583      */
    584     static public final Locale ROOT = createConstant("", "");
    585 
    586     /**
    587      * The key for the private use extension ('x').
    588      *
    589      * @see #getExtension(char)
    590      * @see Builder#setExtension(char, String)
    591      * @since 1.7
    592      */
    593     static public final char PRIVATE_USE_EXTENSION = 'x';
    594 
    595     /**
    596      * The key for Unicode locale extension ('u').
    597      *
    598      * @see #getExtension(char)
    599      * @see Builder#setExtension(char, String)
    600      * @since 1.7
    601      */
    602     static public final char UNICODE_LOCALE_EXTENSION = 'u';
    603 
    604     /** serialization ID
    605      */
    606     static final long serialVersionUID = 9149081749638150636L;
    607 
    608     /**
    609      * Display types for retrieving localized names from the name providers.
    610      */
    611     private static final int DISPLAY_LANGUAGE = 0;
    612     private static final int DISPLAY_COUNTRY  = 1;
    613     private static final int DISPLAY_VARIANT  = 2;
    614     private static final int DISPLAY_SCRIPT   = 3;
    615 
    616     /**
    617      * Private constructor used by getInstance method
    618      */
    619     private Locale(BaseLocale baseLocale, LocaleExtensions extensions) {
    620         this.baseLocale = baseLocale;
    621         this.localeExtensions = extensions;
    622     }
    623 
    624     /**
    625      * Construct a locale from language, country and variant.
    626      * This constructor normalizes the language value to lowercase and
    627      * the country value to uppercase.
    628      * <p>
    629      * <b>Note:</b>
    630      * <ul>
    631      * <li>ISO 639 is not a stable standard; some of the language codes it defines
    632      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
    633      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
    634      * API on Locale will return only the OLD codes.
    635      * <li>For backward compatibility reasons, this constructor does not make
    636      * any syntactic checks on the input.
    637      * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
    638      * see <a href="#special_cases_constructor">Special Cases</a> for more information.
    639      * </ul>
    640      *
    641      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
    642      * up to 8 characters in length.  See the <code>Locale</code> class description about
    643      * valid language values.
    644      * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
    645      * See the <code>Locale</code> class description about valid country values.
    646      * @param variant Any arbitrary value used to indicate a variation of a <code>Locale</code>.
    647      * See the <code>Locale</code> class description for the details.
    648      * @exception NullPointerException thrown if any argument is null.
    649      */
    650     public Locale(String language, String country, String variant) {
    651         if (language== null || country == null || variant == null) {
    652             throw new NullPointerException();
    653         }
    654         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
    655         localeExtensions = getCompatibilityExtensions(language, "", country, variant);
    656     }
    657 
    658     /**
    659      * Construct a locale from language and country.
    660      * This constructor normalizes the language value to lowercase and
    661      * the country value to uppercase.
    662      * <p>
    663      * <b>Note:</b>
    664      * <ul>
    665      * <li>ISO 639 is not a stable standard; some of the language codes it defines
    666      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
    667      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
    668      * API on Locale will return only the OLD codes.
    669      * <li>For backward compatibility reasons, this constructor does not make
    670      * any syntactic checks on the input.
    671      * </ul>
    672      *
    673      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
    674      * up to 8 characters in length.  See the <code>Locale</code> class description about
    675      * valid language values.
    676      * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
    677      * See the <code>Locale</code> class description about valid country values.
    678      * @exception NullPointerException thrown if either argument is null.
    679      */
    680     public Locale(String language, String country) {
    681         this(language, country, "");
    682     }
    683 
    684     /**
    685      * Construct a locale from a language code.
    686      * This constructor normalizes the language value to lowercase.
    687      * <p>
    688      * <b>Note:</b>
    689      * <ul>
    690      * <li>ISO 639 is not a stable standard; some of the language codes it defines
    691      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
    692      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
    693      * API on Locale will return only the OLD codes.
    694      * <li>For backward compatibility reasons, this constructor does not make
    695      * any syntactic checks on the input.
    696      * </ul>
    697      *
    698      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
    699      * up to 8 characters in length.  See the <code>Locale</code> class description about
    700      * valid language values.
    701      * @exception NullPointerException thrown if argument is null.
    702      * @since 1.4
    703      */
    704     public Locale(String language) {
    705         this(language, "", "");
    706     }
    707 
    708     /**
    709      * This method must be called only for creating the Locale.*
    710      * constants due to making shortcuts.
    711      */
    712     private static Locale createConstant(String lang, String country) {
    713         BaseLocale base = BaseLocale.createInstance(lang, country);
    714         return getInstance(base, null);
    715     }
    716 
    717     /**
    718      * Returns a <code>Locale</code> constructed from the given
    719      * <code>language</code>, <code>country</code> and
    720      * <code>variant</code>. If the same <code>Locale</code> instance
    721      * is available in the cache, then that instance is
    722      * returned. Otherwise, a new <code>Locale</code> instance is
    723      * created and cached.
    724      *
    725      * @param language lowercase 2 to 8 language code.
    726      * @param country uppercase two-letter ISO-3166 code and numric-3 UN M.49 area code.
    727      * @param variant vendor and browser specific code. See class description.
    728      * @return the <code>Locale</code> instance requested
    729      * @exception NullPointerException if any argument is null.
    730      */
    731     static Locale getInstance(String language, String country, String variant) {
    732         return getInstance(language, "", country, variant, null);
    733     }
    734 
    735     static Locale getInstance(String language, String script, String country,
    736                                       String variant, LocaleExtensions extensions) {
    737         if (language== null || script == null || country == null || variant == null) {
    738             throw new NullPointerException();
    739         }
    740 
    741         if (extensions == null) {
    742             extensions = getCompatibilityExtensions(language, script, country, variant);
    743         }
    744 
    745         BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
    746         return getInstance(baseloc, extensions);
    747     }
    748 
    749     static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
    750         LocaleKey key = new LocaleKey(baseloc, extensions);
    751         return LOCALECACHE.get(key);
    752     }
    753 
    754     private static class Cache extends LocaleObjectCache<LocaleKey, Locale> {
    755         private Cache() {
    756         }
    757 
    758         @Override
    759         protected Locale createObject(LocaleKey key) {
    760             return new Locale(key.base, key.exts);
    761         }
    762     }
    763 
    764     private static final class LocaleKey {
    765         private final BaseLocale base;
    766         private final LocaleExtensions exts;
    767         private final int hash;
    768 
    769         private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {
    770             base = baseLocale;
    771             exts = extensions;
    772 
    773             // Calculate the hash value here because it's always used.
    774             int h = base.hashCode();
    775             if (exts != null) {
    776                 h ^= exts.hashCode();
    777             }
    778             hash = h;
    779         }
    780 
    781         @Override
    782         public boolean equals(Object obj) {
    783             if (this == obj) {
    784                 return true;
    785             }
    786             if (!(obj instanceof LocaleKey)) {
    787                 return false;
    788             }
    789             LocaleKey other = (LocaleKey)obj;
    790             if (hash != other.hash || !base.equals(other.base)) {
    791                 return false;
    792             }
    793             if (exts == null) {
    794                 return other.exts == null;
    795             }
    796             return exts.equals(other.exts);
    797         }
    798 
    799         @Override
    800         public int hashCode() {
    801             return hash;
    802         }
    803     }
    804 
    805     /**
    806      * Gets the current value of the default locale for this instance
    807      * of the Java Virtual Machine.
    808      * <p>
    809      * The Java Virtual Machine sets the default locale during startup
    810      * based on the host environment. It is used by many locale-sensitive
    811      * methods if no locale is explicitly specified.
    812      * It can be changed using the
    813      * {@link #setDefault(java.util.Locale) setDefault} method.
    814      *
    815      * @return the default locale for this instance of the Java Virtual Machine
    816      */
    817     public static Locale getDefault() {
    818         // do not synchronize this method - see 4071298
    819         // it's OK if more than one default locale happens to be created
    820         if (defaultLocale == null) {
    821             defaultLocale = initDefault();
    822         }
    823         return defaultLocale;
    824     }
    825 
    826     /**
    827      * Gets the current value of the default locale for the specified Category
    828      * for this instance of the Java Virtual Machine.
    829      * <p>
    830      * The Java Virtual Machine sets the default locale during startup based
    831      * on the host environment. It is used by many locale-sensitive methods
    832      * if no locale is explicitly specified. It can be changed using the
    833      * setDefault(Locale.Category, Locale) method.
    834      *
    835      * @param category - the specified category to get the default locale
    836      * @throws NullPointerException - if category is null
    837      * @return the default locale for the specified Category for this instance
    838      *     of the Java Virtual Machine
    839      * @see #setDefault(Locale.Category, Locale)
    840      * @since 1.7
    841      */
    842     public static Locale getDefault(Locale.Category category) {
    843         // do not synchronize this method - see 4071298
    844         // it's OK if more than one default locale happens to be created
    845         switch (category) {
    846         case DISPLAY:
    847             if (defaultDisplayLocale == null) {
    848                 defaultDisplayLocale = initDefault(category);
    849             }
    850             return defaultDisplayLocale;
    851         case FORMAT:
    852             if (defaultFormatLocale == null) {
    853                 defaultFormatLocale = initDefault(category);
    854             }
    855             return defaultFormatLocale;
    856         default:
    857             assert false: "Unknown Category";
    858         }
    859         return getDefault();
    860     }
    861 
    862     /**
    863      * @hide visible for testing.
    864      */
    865     public static Locale initDefault() {
    866         // user.locale gets priority
    867         final String languageTag = System.getProperty("user.locale", "");
    868         if (!languageTag.isEmpty()) {
    869             return Locale.forLanguageTag(languageTag);
    870         }
    871 
    872         // user.locale is empty
    873         String language, region, script, country, variant;
    874         language = System.getProperty("user.language", "en");
    875         // for compatibility, check for old user.region property
    876         region = System.getProperty("user.region");
    877         if (region != null) {
    878             // region can be of form country, country_variant, or _variant
    879             int i = region.indexOf('_');
    880             if (i >= 0) {
    881                 country = region.substring(0, i);
    882                 variant = region.substring(i + 1);
    883             } else {
    884                 country = region;
    885                 variant = "";
    886             }
    887             script = "";
    888         } else {
    889             script = System.getProperty("user.script", "");
    890             country = System.getProperty("user.country", "");
    891             variant = System.getProperty("user.variant", "");
    892         }
    893         return getInstance(language, script, country, variant, null);
    894     }
    895 
    896     private static Locale initDefault(Locale.Category category) {
    897         // make sure defaultLocale is initialized
    898         final Locale defaultLocale = getDefault();
    899 
    900         return getInstance(
    901             System.getProperty(category.languageKey, defaultLocale.getLanguage()),
    902             System.getProperty(category.scriptKey, defaultLocale.getScript()),
    903             System.getProperty(category.countryKey, defaultLocale.getCountry()),
    904             System.getProperty(category.variantKey, defaultLocale.getVariant()),
    905             null);
    906     }
    907 
    908     /**
    909      * Sets the default locale for this instance of the Java Virtual Machine.
    910      * This does not affect the host locale.
    911      * <p>
    912      * If there is a security manager, its <code>checkPermission</code>
    913      * method is called with a <code>PropertyPermission("user.language", "write")</code>
    914      * permission before the default locale is changed.
    915      * <p>
    916      * The Java Virtual Machine sets the default locale during startup
    917      * based on the host environment. It is used by many locale-sensitive
    918      * methods if no locale is explicitly specified.
    919      * <p>
    920      * Since changing the default locale may affect many different areas
    921      * of functionality, this method should only be used if the caller
    922      * is prepared to reinitialize locale-sensitive code running
    923      * within the same Java Virtual Machine.
    924      * <p>
    925      * By setting the default locale with this method, all of the default
    926      * locales for each Category are also set to the specified default locale.
    927      *
    928      * @throws SecurityException
    929      *        if a security manager exists and its
    930      *        <code>checkPermission</code> method doesn't allow the operation.
    931      * @throws NullPointerException if <code>newLocale</code> is null
    932      * @param newLocale the new default locale
    933      * @see SecurityManager#checkPermission
    934      * @see java.util.PropertyPermission
    935      */
    936     public static synchronized void setDefault(Locale newLocale) {
    937         setDefault(Category.DISPLAY, newLocale);
    938         setDefault(Category.FORMAT, newLocale);
    939         defaultLocale = newLocale;
    940         ICU.setDefaultLocale(newLocale.toLanguageTag());
    941     }
    942 
    943     /**
    944      * Sets the default locale for the specified Category for this instance
    945      * of the Java Virtual Machine. This does not affect the host locale.
    946      * <p>
    947      * If there is a security manager, its checkPermission method is called
    948      * with a PropertyPermission("user.language", "write") permission before
    949      * the default locale is changed.
    950      * <p>
    951      * The Java Virtual Machine sets the default locale during startup based
    952      * on the host environment. It is used by many locale-sensitive methods
    953      * if no locale is explicitly specified.
    954      * <p>
    955      * Since changing the default locale may affect many different areas of
    956      * functionality, this method should only be used if the caller is
    957      * prepared to reinitialize locale-sensitive code running within the
    958      * same Java Virtual Machine.
    959      * <p>
    960      *
    961      * @param category - the specified category to set the default locale
    962      * @param newLocale - the new default locale
    963      * @throws SecurityException - if a security manager exists and its
    964      *     checkPermission method doesn't allow the operation.
    965      * @throws NullPointerException - if category and/or newLocale is null
    966      * @see SecurityManager#checkPermission(java.security.Permission)
    967      * @see PropertyPermission
    968      * @see #getDefault(Locale.Category)
    969      * @since 1.7
    970      */
    971     public static synchronized void setDefault(Locale.Category category,
    972         Locale newLocale) {
    973         if (category == null)
    974             throw new NullPointerException("Category cannot be NULL");
    975         if (newLocale == null)
    976             throw new NullPointerException("Can't set default locale to NULL");
    977 
    978         SecurityManager sm = System.getSecurityManager();
    979         if (sm != null) sm.checkPermission(new PropertyPermission
    980                         ("user.language", "write"));
    981         switch (category) {
    982         case DISPLAY:
    983             defaultDisplayLocale = newLocale;
    984             break;
    985         case FORMAT:
    986             defaultFormatLocale = newLocale;
    987             break;
    988         default:
    989             assert false: "Unknown Category";
    990         }
    991     }
    992 
    993     /**
    994      * Returns an array of all installed locales.
    995      * The returned array represents the union of locales supported
    996      * by the Java runtime environment and by installed
    997      * {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider}
    998      * implementations.  It must contain at least a <code>Locale</code>
    999      * instance equal to {@link java.util.Locale#US Locale.US}.
   1000      *
   1001      * @return An array of installed locales.
   1002      */
   1003     public static Locale[] getAvailableLocales() {
   1004         return LocaleServiceProviderPool.getAllAvailableLocales();
   1005     }
   1006 
   1007     /**
   1008      * Returns a list of all 2-letter country codes defined in ISO 3166.
   1009      * Can be used to create Locales.
   1010      * <p>
   1011      * <b>Note:</b> The <code>Locale</code> class also supports other codes for
   1012      * country (region), such as 3-letter numeric UN M.49 area codes.
   1013      * Therefore, the list returned by this method does not contain ALL valid
   1014      * codes that can be used to create Locales.
   1015      */
   1016     public static String[] getISOCountries() {
   1017         // Android-changed: Use ICU.
   1018         return ICU.getISOCountries();
   1019     }
   1020 
   1021     /**
   1022      * Returns a list of all 2-letter language codes defined in ISO 639.
   1023      * Can be used to create Locales.
   1024      * <p>
   1025      * <b>Note:</b>
   1026      * <ul>
   1027      * <li>ISO 639 is not a stable standard&mdash; some languages' codes have changed.
   1028      * The list this function returns includes both the new and the old codes for the
   1029      * languages whose codes have changed.
   1030      * <li>The <code>Locale</code> class also supports language codes up to
   1031      * 8 characters in length.  Therefore, the list returned by this method does
   1032      * not contain ALL valid codes that can be used to create Locales.
   1033      * </ul>
   1034      */
   1035     public static String[] getISOLanguages() {
   1036         // Android-changed: Use ICU.
   1037         return ICU.getISOLanguages();
   1038     }
   1039 
   1040     /**
   1041      * Returns the language code of this Locale.
   1042      *
   1043      * <p><b>Note:</b> ISO 639 is not a stable standard&mdash; some languages' codes have changed.
   1044      * Locale's constructor recognizes both the new and the old codes for the languages
   1045      * whose codes have changed, but this function always returns the old code.  If you
   1046      * want to check for a specific language whose code has changed, don't do
   1047      * <pre>
   1048      * if (locale.getLanguage().equals("he")) // BAD!
   1049      *    ...
   1050      * </pre>
   1051      * Instead, do
   1052      * <pre>
   1053      * if (locale.getLanguage().equals(new Locale("he").getLanguage()))
   1054      *    ...
   1055      * </pre>
   1056      * @return The language code, or the empty string if none is defined.
   1057      * @see #getDisplayLanguage
   1058      */
   1059     public String getLanguage() {
   1060         return baseLocale.getLanguage();
   1061     }
   1062 
   1063     /**
   1064      * Returns the script for this locale, which should
   1065      * either be the empty string or an ISO 15924 4-letter script
   1066      * code. The first letter is uppercase and the rest are
   1067      * lowercase, for example, 'Latn', 'Cyrl'.
   1068      *
   1069      * @return The script code, or the empty string if none is defined.
   1070      * @see #getDisplayScript
   1071      * @since 1.7
   1072      */
   1073     public String getScript() {
   1074         return baseLocale.getScript();
   1075     }
   1076 
   1077     /**
   1078      * Returns the country/region code for this locale, which should
   1079      * either be the empty string, an uppercase ISO 3166 2-letter code,
   1080      * or a UN M.49 3-digit code.
   1081      *
   1082      * @return The country/region code, or the empty string if none is defined.
   1083      * @see #getDisplayCountry
   1084      */
   1085     public String getCountry() {
   1086         return baseLocale.getRegion();
   1087     }
   1088 
   1089     /**
   1090      * Returns the variant code for this locale.
   1091      *
   1092      * @return The variant code, or the empty string if none is defined.
   1093      * @see #getDisplayVariant
   1094      */
   1095     public String getVariant() {
   1096         return baseLocale.getVariant();
   1097     }
   1098 
   1099     /**
   1100      * Returns the extension (or private use) value associated with
   1101      * the specified key, or null if there is no extension
   1102      * associated with the key. To be well-formed, the key must be one
   1103      * of <code>[0-9A-Za-z]</code>. Keys are case-insensitive, so
   1104      * for example 'z' and 'Z' represent the same extension.
   1105      *
   1106      * @param key the extension key
   1107      * @return The extension, or null if this locale defines no
   1108      * extension for the specified key.
   1109      * @throws IllegalArgumentException if key is not well-formed
   1110      * @see #PRIVATE_USE_EXTENSION
   1111      * @see #UNICODE_LOCALE_EXTENSION
   1112      * @since 1.7
   1113      */
   1114     public String getExtension(char key) {
   1115         if (!LocaleExtensions.isValidKey(key)) {
   1116             throw new IllegalArgumentException("Ill-formed extension key: " + key);
   1117         }
   1118         return (localeExtensions == null) ? null : localeExtensions.getExtensionValue(key);
   1119     }
   1120 
   1121     /**
   1122      * Returns the set of extension keys associated with this locale, or the
   1123      * empty set if it has no extensions. The returned set is unmodifiable.
   1124      * The keys will all be lower-case.
   1125      *
   1126      * @return The set of extension keys, or the empty set if this locale has
   1127      * no extensions.
   1128      * @since 1.7
   1129      */
   1130     public Set<Character> getExtensionKeys() {
   1131         if (localeExtensions == null) {
   1132             return Collections.emptySet();
   1133         }
   1134         return localeExtensions.getKeys();
   1135     }
   1136 
   1137     /**
   1138      * Returns the set of unicode locale attributes associated with
   1139      * this locale, or the empty set if it has no attributes. The
   1140      * returned set is unmodifiable.
   1141      *
   1142      * @return The set of attributes.
   1143      * @since 1.7
   1144      */
   1145     public Set<String> getUnicodeLocaleAttributes() {
   1146         if (localeExtensions == null) {
   1147             return Collections.emptySet();
   1148         }
   1149         return localeExtensions.getUnicodeLocaleAttributes();
   1150     }
   1151 
   1152     /**
   1153      * Returns the Unicode locale type associated with the specified Unicode locale key
   1154      * for this locale. Returns the empty string for keys that are defined with no type.
   1155      * Returns null if the key is not defined. Keys are case-insensitive. The key must
   1156      * be two alphanumeric characters ([0-9a-zA-Z]), or an IllegalArgumentException is
   1157      * thrown.
   1158      *
   1159      * @param key the Unicode locale key
   1160      * @return The Unicode locale type associated with the key, or null if the
   1161      * locale does not define the key.
   1162      * @throws IllegalArgumentException if the key is not well-formed
   1163      * @throws NullPointerException if <code>key</code> is null
   1164      * @since 1.7
   1165      */
   1166     public String getUnicodeLocaleType(String key) {
   1167         if (!UnicodeLocaleExtension.isKey(key)) {
   1168             throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key);
   1169         }
   1170         return (localeExtensions == null) ? null : localeExtensions.getUnicodeLocaleType(key);
   1171     }
   1172 
   1173     /**
   1174      * Returns the set of Unicode locale keys defined by this locale, or the empty set if
   1175      * this locale has none.  The returned set is immutable.  Keys are all lower case.
   1176      *
   1177      * @return The set of Unicode locale keys, or the empty set if this locale has
   1178      * no Unicode locale keywords.
   1179      * @since 1.7
   1180      */
   1181     public Set<String> getUnicodeLocaleKeys() {
   1182         if (localeExtensions == null) {
   1183             return Collections.emptySet();
   1184         }
   1185         return localeExtensions.getUnicodeLocaleKeys();
   1186     }
   1187 
   1188     /**
   1189      * Package locale method returning the Locale's BaseLocale,
   1190      * used by ResourceBundle
   1191      * @return base locale of this Locale
   1192      */
   1193     BaseLocale getBaseLocale() {
   1194         return baseLocale;
   1195     }
   1196 
   1197     /**
   1198      * Package private method returning the Locale's LocaleExtensions,
   1199      * used by ResourceBundle.
   1200      * @return locale exnteions of this Locale,
   1201      *         or {@code null} if no extensions are defined
   1202      */
   1203      LocaleExtensions getLocaleExtensions() {
   1204          return localeExtensions;
   1205      }
   1206 
   1207     /**
   1208      * Returns a string representation of this <code>Locale</code>
   1209      * object, consisting of language, country, variant, script,
   1210      * and extensions as below:
   1211      * <p><blockquote>
   1212      * language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
   1213      * </blockquote>
   1214      *
   1215      * Language is always lower case, country is always upper case, script is always title
   1216      * case, and extensions are always lower case.  Extensions and private use subtags
   1217      * will be in canonical order as explained in {@link #toLanguageTag}.
   1218      *
   1219      * <p>When the locale has neither script nor extensions, the result is the same as in
   1220      * Java 6 and prior.
   1221      *
   1222      * <p>If both the language and country fields are missing, this function will return
   1223      * the empty string, even if the variant, script, or extensions field is present (you
   1224      * can't have a locale with just a variant, the variant must accompany a well-formed
   1225      * language or country code).
   1226      *
   1227      * <p>If script or extensions are present and variant is missing, no underscore is
   1228      * added before the "#".
   1229      *
   1230      * <p>This behavior is designed to support debugging and to be compatible with
   1231      * previous uses of <code>toString</code> that expected language, country, and variant
   1232      * fields only.  To represent a Locale as a String for interchange purposes, use
   1233      * {@link #toLanguageTag}.
   1234      *
   1235      * <p>Examples: <ul><tt>
   1236      * <li>en
   1237      * <li>de_DE
   1238      * <li>_GB
   1239      * <li>en_US_WIN
   1240      * <li>de__POSIX
   1241      * <li>zh_CN_#Hans
   1242      * <li>zh_TW_#Hant-x-java
   1243      * <li>th_TH_TH_#u-nu-thai</tt></ul>
   1244      *
   1245      * @return A string representation of the Locale, for debugging.
   1246      * @see #getDisplayName
   1247      * @see #toLanguageTag
   1248      */
   1249     @Override
   1250     public final String toString() {
   1251         boolean l = (baseLocale.getLanguage().length() != 0);
   1252         boolean s = (baseLocale.getScript().length() != 0);
   1253         boolean r = (baseLocale.getRegion().length() != 0);
   1254         boolean v = (baseLocale.getVariant().length() != 0);
   1255         boolean e = (localeExtensions != null && localeExtensions.getID().length() != 0);
   1256 
   1257         StringBuilder result = new StringBuilder(baseLocale.getLanguage());
   1258         if (r || (l && (v || s || e))) {
   1259             result.append('_')
   1260                 .append(baseLocale.getRegion()); // This may just append '_'
   1261         }
   1262         if (v && (l || r)) {
   1263             result.append('_')
   1264                 .append(baseLocale.getVariant());
   1265         }
   1266 
   1267         if (s && (l || r)) {
   1268             result.append("_#")
   1269                 .append(baseLocale.getScript());
   1270         }
   1271 
   1272         if (e && (l || r)) {
   1273             result.append('_');
   1274             if (!s) {
   1275                 result.append('#');
   1276             }
   1277             result.append(localeExtensions.getID());
   1278         }
   1279 
   1280         return result.toString();
   1281     }
   1282 
   1283     /**
   1284      * Returns a well-formed IETF BCP 47 language tag representing
   1285      * this locale.
   1286      *
   1287      * <p>If this <code>Locale</code> has a language, country, or
   1288      * variant that does not satisfy the IETF BCP 47 language tag
   1289      * syntax requirements, this method handles these fields as
   1290      * described below:
   1291      *
   1292      * <p><b>Language:</b> If language is empty, or not <a
   1293      * href="#def_language" >well-formed</a> (for example "a" or
   1294      * "e2"), it will be emitted as "und" (Undetermined).
   1295      *
   1296      * <p><b>Country:</b> If country is not <a
   1297      * href="#def_region">well-formed</a> (for example "12" or "USA"),
   1298      * it will be omitted.
   1299      *
   1300      * <p><b>Variant:</b> If variant <b>is</b> <a
   1301      * href="#def_variant">well-formed</a>, each sub-segment
   1302      * (delimited by '-' or '_') is emitted as a subtag.  Otherwise:
   1303      * <ul>
   1304      *
   1305      * <li>if all sub-segments match <code>[0-9a-zA-Z]{1,8}</code>
   1306      * (for example "WIN" or "Oracle_JDK_Standard_Edition"), the first
   1307      * ill-formed sub-segment and all following will be appended to
   1308      * the private use subtag.  The first appended subtag will be
   1309      * "lvariant", followed by the sub-segments in order, separated by
   1310      * hyphen. For example, "x-lvariant-WIN",
   1311      * "Oracle-x-lvariant-JDK-Standard-Edition".
   1312      *
   1313      * <li>if any sub-segment does not match
   1314      * <code>[0-9a-zA-Z]{1,8}</code>, the variant will be truncated
   1315      * and the problematic sub-segment and all following sub-segments
   1316      * will be omitted.  If the remainder is non-empty, it will be
   1317      * emitted as a private use subtag as above (even if the remainder
   1318      * turns out to be well-formed).  For example,
   1319      * "Solaris_isjustthecoolestthing" is emitted as
   1320      * "x-lvariant-Solaris", not as "solaris".</li></ul>
   1321      *
   1322      * <p><b>Special Conversions:</b> Java supports some old locale
   1323      * representations, including deprecated ISO language codes,
   1324      * for compatibility. This method performs the following
   1325      * conversions:
   1326      * <ul>
   1327      *
   1328      * <li>Deprecated ISO language codes "iw", "ji", and "in" are
   1329      * converted to "he", "yi", and "id", respectively.
   1330      *
   1331      * <li>A locale with language "no", country "NO", and variant
   1332      * "NY", representing Norwegian Nynorsk (Norway), is converted
   1333      * to a language tag "nn-NO".</li></ul>
   1334      *
   1335      * <p><b>Note:</b> Although the language tag created by this
   1336      * method is well-formed (satisfies the syntax requirements
   1337      * defined by the IETF BCP 47 specification), it is not
   1338      * necessarily a valid BCP 47 language tag.  For example,
   1339      * <pre>
   1340      *   new Locale("xx", "YY").toLanguageTag();</pre>
   1341      *
   1342      * will return "xx-YY", but the language subtag "xx" and the
   1343      * region subtag "YY" are invalid because they are not registered
   1344      * in the IANA Language Subtag Registry.
   1345      *
   1346      * @return a BCP47 language tag representing the locale
   1347      * @see #forLanguageTag(String)
   1348      * @since 1.7
   1349      */
   1350     public String toLanguageTag() {
   1351         LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
   1352         StringBuilder buf = new StringBuilder();
   1353 
   1354         String subtag = tag.getLanguage();
   1355         if (subtag.length() > 0) {
   1356             buf.append(LanguageTag.canonicalizeLanguage(subtag));
   1357         }
   1358 
   1359         subtag = tag.getScript();
   1360         if (subtag.length() > 0) {
   1361             buf.append(LanguageTag.SEP);
   1362             buf.append(LanguageTag.canonicalizeScript(subtag));
   1363         }
   1364 
   1365         subtag = tag.getRegion();
   1366         if (subtag.length() > 0) {
   1367             buf.append(LanguageTag.SEP);
   1368             buf.append(LanguageTag.canonicalizeRegion(subtag));
   1369         }
   1370 
   1371         List<String>subtags = tag.getVariants();
   1372         for (String s : subtags) {
   1373             buf.append(LanguageTag.SEP);
   1374             // preserve casing
   1375             buf.append(s);
   1376         }
   1377 
   1378         subtags = tag.getExtensions();
   1379         for (String s : subtags) {
   1380             buf.append(LanguageTag.SEP);
   1381             buf.append(LanguageTag.canonicalizeExtension(s));
   1382         }
   1383 
   1384         subtag = tag.getPrivateuse();
   1385         if (subtag.length() > 0) {
   1386             if (buf.length() > 0) {
   1387                 buf.append(LanguageTag.SEP);
   1388             }
   1389             buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
   1390             // preserve casing
   1391             buf.append(subtag);
   1392         }
   1393 
   1394         return buf.toString();
   1395     }
   1396 
   1397     /**
   1398      * Returns a locale for the specified IETF BCP 47 language tag string.
   1399      *
   1400      * <p>If the specified language tag contains any ill-formed subtags,
   1401      * the first such subtag and all following subtags are ignored.  Compare
   1402      * to {@link Locale.Builder#setLanguageTag} which throws an exception
   1403      * in this case.
   1404      *
   1405      * <p>The following <b>conversions</b> are performed:<ul>
   1406      *
   1407      * <li>The language code "und" is mapped to language "".
   1408      *
   1409      * <li>The language codes "he", "yi", and "id" are mapped to "iw",
   1410      * "ji", and "in" respectively. (This is the same canonicalization
   1411      * that's done in Locale's constructors.)
   1412      *
   1413      * <li>The portion of a private use subtag prefixed by "lvariant",
   1414      * if any, is removed and appended to the variant field in the
   1415      * result locale (without case normalization).  If it is then
   1416      * empty, the private use subtag is discarded:
   1417      *
   1418      * <pre>
   1419      *     Locale loc;
   1420      *     loc = Locale.forLanguageTag("en-US-x-lvariant-POSIX");
   1421      *     loc.getVariant(); // returns "POSIX"
   1422      *     loc.getExtension('x'); // returns null
   1423      *
   1424      *     loc = Locale.forLanguageTag("de-POSIX-x-URP-lvariant-Abc-Def");
   1425      *     loc.getVariant(); // returns "POSIX_Abc_Def"
   1426      *     loc.getExtension('x'); // returns "urp"
   1427      * </pre>
   1428      *
   1429      * <li>When the languageTag argument contains an extlang subtag,
   1430      * the first such subtag is used as the language, and the primary
   1431      * language subtag and other extlang subtags are ignored:
   1432      *
   1433      * <pre>
   1434      *     Locale.forLanguageTag("ar-aao").getLanguage(); // returns "aao"
   1435      *     Locale.forLanguageTag("en-abc-def-us").toString(); // returns "abc_US"
   1436      * </pre>
   1437      *
   1438      * <li>Case is normalized except for variant tags, which are left
   1439      * unchanged.  Language is normalized to lower case, script to
   1440      * title case, country to upper case, and extensions to lower
   1441      * case.
   1442      *
   1443      * <li>If, after processing, the locale would exactly match either
   1444      * ja_JP_JP or th_TH_TH with no extensions, the appropriate
   1445      * extensions are added as though the constructor had been called:
   1446      *
   1447      * <pre>
   1448      *    Locale.forLanguageTag("ja-JP-x-lvariant-JP").toLanguageTag();
   1449      *    // returns "ja-JP-u-ca-japanese-x-lvariant-JP"
   1450      *    Locale.forLanguageTag("th-TH-x-lvariant-TH").toLanguageTag();
   1451      *    // returns "th-TH-u-nu-thai-x-lvariant-TH"
   1452      * <pre></ul>
   1453      *
   1454      * <p>This implements the 'Language-Tag' production of BCP47, and
   1455      * so supports grandfathered (regular and irregular) as well as
   1456      * private use language tags.  Stand alone private use tags are
   1457      * represented as empty language and extension 'x-whatever',
   1458      * and grandfathered tags are converted to their canonical replacements
   1459      * where they exist.
   1460      *
   1461      * <p>Grandfathered tags with canonical replacements are as follows:
   1462      *
   1463      * <table>
   1464      * <tbody align="center">
   1465      * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
   1466      * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
   1467      * <tr><td>i-ami</td><td>&nbsp;</td><td>ami</td></tr>
   1468      * <tr><td>i-bnn</td><td>&nbsp;</td><td>bnn</td></tr>
   1469      * <tr><td>i-hak</td><td>&nbsp;</td><td>hak</td></tr>
   1470      * <tr><td>i-klingon</td><td>&nbsp;</td><td>tlh</td></tr>
   1471      * <tr><td>i-lux</td><td>&nbsp;</td><td>lb</td></tr>
   1472      * <tr><td>i-navajo</td><td>&nbsp;</td><td>nv</td></tr>
   1473      * <tr><td>i-pwn</td><td>&nbsp;</td><td>pwn</td></tr>
   1474      * <tr><td>i-tao</td><td>&nbsp;</td><td>tao</td></tr>
   1475      * <tr><td>i-tay</td><td>&nbsp;</td><td>tay</td></tr>
   1476      * <tr><td>i-tsu</td><td>&nbsp;</td><td>tsu</td></tr>
   1477      * <tr><td>no-bok</td><td>&nbsp;</td><td>nb</td></tr>
   1478      * <tr><td>no-nyn</td><td>&nbsp;</td><td>nn</td></tr>
   1479      * <tr><td>sgn-BE-FR</td><td>&nbsp;</td><td>sfb</td></tr>
   1480      * <tr><td>sgn-BE-NL</td><td>&nbsp;</td><td>vgt</td></tr>
   1481      * <tr><td>sgn-CH-DE</td><td>&nbsp;</td><td>sgg</td></tr>
   1482      * <tr><td>zh-guoyu</td><td>&nbsp;</td><td>cmn</td></tr>
   1483      * <tr><td>zh-hakka</td><td>&nbsp;</td><td>hak</td></tr>
   1484      * <tr><td>zh-min-nan</td><td>&nbsp;</td><td>nan</td></tr>
   1485      * <tr><td>zh-xiang</td><td>&nbsp;</td><td>hsn</td></tr>
   1486      * </tbody>
   1487      * </table>
   1488      *
   1489      * <p>Grandfathered tags with no modern replacement will be
   1490      * converted as follows:
   1491      *
   1492      * <table>
   1493      * <tbody align="center">
   1494      * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
   1495      * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
   1496      * <tr><td>en-GB-oed</td><td>&nbsp;</td><td>en-GB-x-oed</td></tr>
   1497      * <tr><td>i-default</td><td>&nbsp;</td><td>en-x-i-default</td></tr>
   1498      * <tr><td>i-enochian</td><td>&nbsp;</td><td>und-x-i-enochian</td></tr>
   1499      * <tr><td>i-mingo</td><td>&nbsp;</td><td>see-x-i-mingo</td></tr>
   1500      * <tr><td>zh-min</td><td>&nbsp;</td><td>nan-x-zh-min</td></tr>
   1501      * </tbody>
   1502      * </table>
   1503      *
   1504      * <p>For a list of all grandfathered tags, see the
   1505      * IANA Language Subtag Registry (search for "Type: grandfathered").
   1506      *
   1507      * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code>
   1508      * and <code>forLanguageTag</code> will round-trip.
   1509      *
   1510      * @param languageTag the language tag
   1511      * @return The locale that best represents the language tag.
   1512      * @throws NullPointerException if <code>languageTag</code> is <code>null</code>
   1513      * @see #toLanguageTag()
   1514      * @see java.util.Locale.Builder#setLanguageTag(String)
   1515      * @since 1.7
   1516      */
   1517     public static Locale forLanguageTag(String languageTag) {
   1518         LanguageTag tag = LanguageTag.parse(languageTag, null);
   1519         InternalLocaleBuilder bldr = new InternalLocaleBuilder();
   1520         bldr.setLanguageTag(tag);
   1521         BaseLocale base = bldr.getBaseLocale();
   1522         LocaleExtensions exts = bldr.getLocaleExtensions();
   1523         if (exts == null && base.getVariant().length() > 0) {
   1524             exts = getCompatibilityExtensions(base.getLanguage(), base.getScript(),
   1525                                               base.getRegion(), base.getVariant());
   1526         }
   1527         return getInstance(base, exts);
   1528     }
   1529 
   1530     /**
   1531      * Returns a three-letter abbreviation of this locale's language.
   1532      * If the language matches an ISO 639-1 two-letter code, the
   1533      * corresponding ISO 639-2/T three-letter lowercase code is
   1534      * returned.  The ISO 639-2 language codes can be found on-line,
   1535      * see "Codes for the Representation of Names of Languages Part 2:
   1536      * Alpha-3 Code".  If the locale specifies a three-letter
   1537      * language, the language is returned as is.  If the locale does
   1538      * not specify a language the empty string is returned.
   1539      *
   1540      * @return A three-letter abbreviation of this locale's language.
   1541      * @exception MissingResourceException Throws MissingResourceException if
   1542      * three-letter language abbreviation is not available for this locale.
   1543      */
   1544     public String getISO3Language() throws MissingResourceException {
   1545         // Android-changed: Use ICU.getIso3Language. Also return "" for empty languages
   1546         // for the sake of backwards compatibility.
   1547         String lang = baseLocale.getLanguage();
   1548         if (lang.length() == 3) {
   1549             return lang;
   1550         } else if (lang.isEmpty()) {
   1551             return "";
   1552         }
   1553 
   1554         String language3 = ICU.getISO3Language(lang);
   1555         if (!lang.isEmpty() && language3.isEmpty()) {
   1556             throw new MissingResourceException("Couldn't find 3-letter language code for "
   1557                     + lang, "FormatData_" + toString(), "ShortLanguage");
   1558         }
   1559 
   1560         return language3;
   1561     }
   1562 
   1563     /**
   1564      * Returns a three-letter abbreviation for this locale's country.
   1565      * If the country matches an ISO 3166-1 alpha-2 code, the
   1566      * corresponding ISO 3166-1 alpha-3 uppercase code is returned.
   1567      * If the locale doesn't specify a country, this will be the empty
   1568      * string.
   1569      *
   1570      * <p>The ISO 3166-1 codes can be found on-line.
   1571      *
   1572      * @return A three-letter abbreviation of this locale's country.
   1573      * @exception MissingResourceException Throws MissingResourceException if the
   1574      * three-letter country abbreviation is not available for this locale.
   1575      */
   1576     public String getISO3Country() throws MissingResourceException {
   1577         // Android changed: Use.getIso3Country. Also return "" for missing regions.
   1578         final String region = baseLocale.getRegion();
   1579         // Note that this will return an UN.M49 region code
   1580         if (region.length() == 3) {
   1581             return baseLocale.getRegion();
   1582         } else if (region.isEmpty()) {
   1583             return "";
   1584         }
   1585 
   1586         // Prefix "en-" because ICU doesn't really care about what the language is.
   1587         String country3 = ICU.getISO3Country("en-" + region);
   1588         if (!region.isEmpty() && country3.isEmpty()) {
   1589             throw new MissingResourceException("Couldn't find 3-letter country code for "
   1590                     + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
   1591         }
   1592         return country3;
   1593     }
   1594 
   1595     /**
   1596      * Returns a name for the locale's language that is appropriate for display to the
   1597      * user.
   1598      * If possible, the name returned will be localized for the default locale.
   1599      * For example, if the locale is fr_FR and the default locale
   1600      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
   1601      * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
   1602      * If the name returned cannot be localized for the default locale,
   1603      * (say, we don't have a Japanese name for Croatian),
   1604      * this function falls back on the English name, and uses the ISO code as a last-resort
   1605      * value.  If the locale doesn't specify a language, this function returns the empty string.
   1606      */
   1607     public final String getDisplayLanguage() {
   1608         return getDisplayLanguage(getDefault(Category.DISPLAY));
   1609     }
   1610 
   1611     /**
   1612      * Returns the name of this locale's language, localized to {@code locale}.
   1613      * If the language name is unknown, the language code is returned.
   1614      */
   1615     public String getDisplayLanguage(Locale locale) {
   1616         String languageCode = baseLocale.getLanguage();
   1617         if (languageCode.isEmpty()) {
   1618             return "";
   1619         }
   1620 
   1621         // Hacks for backward compatibility.
   1622         //
   1623         // Our language tag will contain "und" if the languageCode is invalid
   1624         // or missing. ICU will then return "langue indtermine" or the equivalent
   1625         // display language for the indeterminate language code.
   1626         //
   1627         // Sigh... ugh... and what not.
   1628         final String normalizedLanguage = normalizeAndValidateLanguage(
   1629                 languageCode, false /* strict */);
   1630         if (UNDETERMINED_LANGUAGE.equals(normalizedLanguage)) {
   1631             return languageCode;
   1632         }
   1633 
   1634         // TODO: We need a new hack or a complete fix for http://b/8049507 --- We would
   1635         // cover the frameworks' tracks when they were using "tl" instead of "fil".
   1636         String result = ICU.getDisplayLanguage(this, locale);
   1637         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1638             result = ICU.getDisplayLanguage(this, Locale.getDefault());
   1639         }
   1640         return result;
   1641     }
   1642 
   1643     private static String normalizeAndValidateLanguage(String language, boolean strict) {
   1644         if (language == null || language.isEmpty()) {
   1645             return "";
   1646         }
   1647 
   1648         final String lowercaseLanguage = language.toLowerCase(Locale.ROOT);
   1649         if (!isValidBcp47Alpha(lowercaseLanguage, 2, 3)) {
   1650             if (strict) {
   1651                 throw new IllformedLocaleException("Invalid language: " + language);
   1652             } else {
   1653                 return UNDETERMINED_LANGUAGE;
   1654             }
   1655         }
   1656 
   1657         return lowercaseLanguage;
   1658     }
   1659 
   1660     /*
   1661      * Checks whether a given string is an ASCII alphanumeric string.
   1662      */
   1663     private static boolean isAsciiAlphaNum(String string) {
   1664         for (int i = 0; i < string.length(); i++) {
   1665             final char character = string.charAt(i);
   1666             if (!(character >= 'a' && character <= 'z' ||
   1667                     character >= 'A' && character <= 'Z' ||
   1668                     character >= '0' && character <= '9')) {
   1669                 return false;
   1670             }
   1671         }
   1672 
   1673         return true;
   1674     }
   1675 
   1676     /**
   1677      * Returns a name for the the locale's script that is appropriate for display to
   1678      * the user. If possible, the name will be localized for the default locale.  Returns
   1679      * the empty string if this locale doesn't specify a script code.
   1680      *
   1681      * @return the display name of the script code for the current default locale
   1682      * @since 1.7
   1683      */
   1684     public String getDisplayScript() {
   1685         return getDisplayScript(getDefault());
   1686     }
   1687 
   1688     /**
   1689      * Returns the name of this locale's script code, localized to {@link Locale}. If the
   1690      * script code is unknown, the return value of this method is the same as that of
   1691      * {@link #getScript()}.
   1692      *
   1693      * @since 1.7
   1694      */
   1695     public String getDisplayScript(Locale locale) {
   1696         String scriptCode = baseLocale.getScript();
   1697         if (scriptCode.isEmpty()) {
   1698             return "";
   1699         }
   1700 
   1701         String result = ICU.getDisplayScript(this, locale);
   1702         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1703             result = ICU.getDisplayScript(this, Locale.getDefault());
   1704         }
   1705 
   1706         return result;
   1707 
   1708     }
   1709 
   1710     /**
   1711      * Returns a name for the locale's country that is appropriate for display to the
   1712      * user.
   1713      * If possible, the name returned will be localized for the default locale.
   1714      * For example, if the locale is fr_FR and the default locale
   1715      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
   1716      * the default locale is fr_FR, getDisplayCountry() will return "Etats-Unis".
   1717      * If the name returned cannot be localized for the default locale,
   1718      * (say, we don't have a Japanese name for Croatia),
   1719      * this function falls back on the English name, and uses the ISO code as a last-resort
   1720      * value.  If the locale doesn't specify a country, this function returns the empty string.
   1721      */
   1722     public final String getDisplayCountry() {
   1723         return getDisplayCountry(getDefault(Category.DISPLAY));
   1724     }
   1725     /**
   1726      * Returns the name of this locale's country, localized to {@code locale}.
   1727      * Returns the empty string if this locale does not correspond to a specific
   1728      * country.
   1729      */
   1730     public String getDisplayCountry(Locale locale) {
   1731         String countryCode = baseLocale.getRegion();
   1732         if (countryCode.isEmpty()) {
   1733             return "";
   1734         }
   1735 
   1736         final String normalizedRegion = normalizeAndValidateRegion(
   1737                 countryCode, false /* strict */);
   1738         if (normalizedRegion.isEmpty()) {
   1739             return countryCode;
   1740         }
   1741 
   1742         String result = ICU.getDisplayCountry(this, locale);
   1743         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1744             result = ICU.getDisplayCountry(this, Locale.getDefault());
   1745         }
   1746         return result;
   1747     }
   1748 
   1749     private static String normalizeAndValidateRegion(String region, boolean strict) {
   1750         if (region == null || region.isEmpty()) {
   1751             return "";
   1752         }
   1753 
   1754         final String uppercaseRegion = region.toUpperCase(Locale.ROOT);
   1755         if (!isValidBcp47Alpha(uppercaseRegion, 2, 2) &&
   1756                 !isUnM49AreaCode(uppercaseRegion)) {
   1757             if (strict) {
   1758                 throw new IllformedLocaleException("Invalid region: " + region);
   1759             } else {
   1760                 return "";
   1761             }
   1762         }
   1763 
   1764         return uppercaseRegion;
   1765     }
   1766 
   1767     private static boolean isValidBcp47Alpha(String string, int lowerBound, int upperBound) {
   1768         final int length = string.length();
   1769         if (length < lowerBound || length > upperBound) {
   1770             return false;
   1771         }
   1772 
   1773         for (int i = 0; i < length; ++i) {
   1774             final char character = string.charAt(i);
   1775             if (!(character >= 'a' && character <= 'z' ||
   1776                     character >= 'A' && character <= 'Z')) {
   1777                 return false;
   1778             }
   1779         }
   1780 
   1781         return true;
   1782     }
   1783 
   1784     /**
   1785      * A UN M.49 is a 3 digit numeric code.
   1786      */
   1787     private static boolean isUnM49AreaCode(String code) {
   1788         if (code.length() != 3) {
   1789             return false;
   1790         }
   1791 
   1792         for (int i = 0; i < 3; ++i) {
   1793             final char character = code.charAt(i);
   1794             if (!(character >= '0' && character <= '9')) {
   1795                 return false;
   1796             }
   1797         }
   1798 
   1799         return true;
   1800     }
   1801 
   1802     /**
   1803      * Returns a name for the locale's variant code that is appropriate for display to the
   1804      * user.  If possible, the name will be localized for the default locale.  If the locale
   1805      * doesn't specify a variant code, this function returns the empty string.
   1806      */
   1807     public final String getDisplayVariant() {
   1808         return getDisplayVariant(getDefault(Category.DISPLAY));
   1809     }
   1810 
   1811     /**
   1812      * Returns the full variant name in the specified {@code Locale} for the variant code
   1813      * of this {@code Locale}. If there is no matching variant name, the variant code is
   1814      * returned.
   1815      *
   1816      * @since 1.7
   1817      */
   1818     public String getDisplayVariant(Locale locale) {
   1819         String variantCode = baseLocale.getVariant();
   1820         if (variantCode.isEmpty()) {
   1821             return "";
   1822         }
   1823 
   1824         try {
   1825             normalizeAndValidateVariant(variantCode);
   1826         } catch (IllformedLocaleException ilfe) {
   1827             return variantCode;
   1828         }
   1829 
   1830         String result = ICU.getDisplayVariant(this, locale);
   1831         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1832             result = ICU.getDisplayVariant(this, Locale.getDefault());
   1833         }
   1834 
   1835         // The "old style" locale constructors allow us to pass in variants that aren't
   1836         // valid BCP-47 variant subtags. When that happens, toLanguageTag will not emit
   1837         // them. Note that we know variantCode.length() > 0 due to the isEmpty check at
   1838         // the beginning of this function.
   1839         if (result.isEmpty()) {
   1840             return variantCode;
   1841         }
   1842         return result;
   1843     }
   1844 
   1845     private static String normalizeAndValidateVariant(String variant) {
   1846         if (variant == null || variant.isEmpty()) {
   1847             return "";
   1848         }
   1849 
   1850         // Note that unlike extensions, we canonicalize to lower case alphabets
   1851         // and underscores instead of hyphens.
   1852         final String normalizedVariant = variant.replace('-', '_');
   1853         String[] subTags = normalizedVariant.split("_");
   1854 
   1855         for (String subTag : subTags) {
   1856             if (!isValidVariantSubtag(subTag)) {
   1857                 throw new IllformedLocaleException("Invalid variant: " + variant);
   1858             }
   1859         }
   1860 
   1861         return normalizedVariant;
   1862     }
   1863 
   1864     private static boolean isValidVariantSubtag(String subTag) {
   1865         // The BCP-47 spec states that :
   1866         // - Subtags can be between [5, 8] alphanumeric chars in length.
   1867         // - Subtags that start with a number are allowed to be 4 chars in length.
   1868         if (subTag.length() >= 5 && subTag.length() <= 8) {
   1869             if (isAsciiAlphaNum(subTag)) {
   1870                 return true;
   1871             }
   1872         } else if (subTag.length() == 4) {
   1873             final char firstChar = subTag.charAt(0);
   1874             if ((firstChar >= '0' && firstChar <= '9') && isAsciiAlphaNum(subTag)) {
   1875                 return true;
   1876             }
   1877         }
   1878 
   1879         return false;
   1880     }
   1881 
   1882     /**
   1883      * Returns a name for the locale that is appropriate for display to the
   1884      * user. This will be the values returned by getDisplayLanguage(),
   1885      * getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled
   1886      * into a single string. The the non-empty values are used in order,
   1887      * with the second and subsequent names in parentheses.  For example:
   1888      * <blockquote>
   1889      * language (script, country, variant)<br>
   1890      * language (country)<br>
   1891      * language (variant)<br>
   1892      * script (country)<br>
   1893      * country<br>
   1894      * </blockquote>
   1895      * depending on which fields are specified in the locale.  If the
   1896      * language, sacript, country, and variant fields are all empty,
   1897      * this function returns the empty string.
   1898      */
   1899     public final String getDisplayName() {
   1900         return getDisplayName(getDefault(Category.DISPLAY));
   1901     }
   1902 
   1903     /**
   1904      * Returns this locale's language name, country name, and variant, localized
   1905      * to {@code locale}. The exact output form depends on whether this locale
   1906      * corresponds to a specific language, script, country and variant.
   1907      *
   1908      * <p>For example:
   1909      * <ul>
   1910      * <li>{@code new Locale("en").getDisplayName(Locale.US)} -> {@code English}
   1911      * <li>{@code new Locale("en", "US").getDisplayName(Locale.US)} -> {@code English (United States)}
   1912      * <li>{@code new Locale("en", "US", "POSIX").getDisplayName(Locale.US)} -> {@code English (United States,Computer)}
   1913      * <li>{@code Locale.fromLanguageTag("zh-Hant-CN").getDisplayName(Locale.US)} -> {@code Chinese (Traditional Han,China)}
   1914      * <li>{@code new Locale("en").getDisplayName(Locale.FRANCE)} -> {@code anglais}
   1915      * <li>{@code new Locale("en", "US").getDisplayName(Locale.FRANCE)} -> {@code anglais (tats-Unis)}
   1916      * <li>{@code new Locale("en", "US", "POSIX").getDisplayName(Locale.FRANCE)} -> {@code anglais (tats-Unis,informatique)}.
   1917      * </ul>
   1918      */
   1919     public String getDisplayName(Locale locale) {
   1920         int count = 0;
   1921         StringBuilder buffer = new StringBuilder();
   1922         String languageCode = baseLocale.getLanguage();
   1923         if (!languageCode.isEmpty()) {
   1924             String displayLanguage = getDisplayLanguage(locale);
   1925             buffer.append(displayLanguage.isEmpty() ? languageCode : displayLanguage);
   1926             ++count;
   1927         }
   1928         String scriptCode = baseLocale.getScript();
   1929         if (!scriptCode.isEmpty()) {
   1930             if (count == 1) {
   1931                 buffer.append(" (");
   1932             }
   1933             String displayScript = getDisplayScript(locale);
   1934             buffer.append(displayScript.isEmpty() ? scriptCode : displayScript);
   1935             ++count;
   1936         }
   1937         String countryCode = baseLocale.getRegion();
   1938         if (!countryCode.isEmpty()) {
   1939             if (count == 1) {
   1940                 buffer.append(" (");
   1941             } else if (count == 2) {
   1942                 buffer.append(",");
   1943             }
   1944             String displayCountry = getDisplayCountry(locale);
   1945             buffer.append(displayCountry.isEmpty() ? countryCode : displayCountry);
   1946             ++count;
   1947         }
   1948         String variantCode = baseLocale.getVariant();
   1949         if (!variantCode.isEmpty()) {
   1950             if (count == 1) {
   1951                 buffer.append(" (");
   1952             } else if (count == 2 || count == 3) {
   1953                 buffer.append(",");
   1954             }
   1955             String displayVariant = getDisplayVariant(locale);
   1956             buffer.append(displayVariant.isEmpty() ? variantCode : displayVariant);
   1957             ++count;
   1958         }
   1959         if (count > 1) {
   1960             buffer.append(")");
   1961         }
   1962         return buffer.toString();
   1963     }
   1964 
   1965     /**
   1966      * Overrides Cloneable.
   1967      */
   1968     public Object clone()
   1969     {
   1970         try {
   1971             Locale that = (Locale)super.clone();
   1972             return that;
   1973         } catch (CloneNotSupportedException e) {
   1974             throw new InternalError();
   1975         }
   1976     }
   1977 
   1978     /**
   1979      * Override hashCode.
   1980      * Since Locales are often used in hashtables, caches the value
   1981      * for speed.
   1982      */
   1983     @Override
   1984     public int hashCode() {
   1985         int hc = hashCodeValue;
   1986         if (hc == 0) {
   1987             hc = baseLocale.hashCode();
   1988             if (localeExtensions != null) {
   1989                 hc ^= localeExtensions.hashCode();
   1990             }
   1991             hashCodeValue = hc;
   1992         }
   1993         return hc;
   1994     }
   1995 
   1996     // Overrides
   1997 
   1998     /**
   1999      * Returns true if this Locale is equal to another object.  A Locale is
   2000      * deemed equal to another Locale with identical language, script, country,
   2001      * variant and extensions, and unequal to all other objects.
   2002      *
   2003      * @return true if this Locale is equal to the specified object.
   2004      */
   2005     @Override
   2006     public boolean equals(Object obj) {
   2007         if (this == obj)                      // quick check
   2008             return true;
   2009         if (!(obj instanceof Locale))
   2010             return false;
   2011         BaseLocale otherBase = ((Locale)obj).baseLocale;
   2012         if (!baseLocale.equals(otherBase)) {
   2013             return false;
   2014         }
   2015         if (localeExtensions == null) {
   2016             return ((Locale)obj).localeExtensions == null;
   2017         }
   2018         return localeExtensions.equals(((Locale)obj).localeExtensions);
   2019     }
   2020 
   2021     // ================= privates =====================================
   2022 
   2023     private transient BaseLocale baseLocale;
   2024     private transient LocaleExtensions localeExtensions;
   2025 
   2026     /**
   2027      * Calculated hashcode
   2028      */
   2029     private transient volatile int hashCodeValue = 0;
   2030 
   2031     private static Locale defaultLocale = null;
   2032     private static Locale defaultDisplayLocale = null;
   2033     private static Locale defaultFormatLocale = null;
   2034 
   2035     /**
   2036      * Format a list using given pattern strings.
   2037      * If either of the patterns is null, then a the list is
   2038      * formatted by concatenation with the delimiter ','.
   2039      * @param stringList the list of strings to be formatted.
   2040      * @param listPattern should create a MessageFormat taking 0-3 arguments
   2041      * and formatting them into a list.
   2042      * @param listCompositionPattern should take 2 arguments
   2043      * and is used by composeList.
   2044      * @return a string representing the list.
   2045      */
   2046     private static String formatList(String[] stringList, String listPattern, String listCompositionPattern) {
   2047         // If we have no list patterns, compose the list in a simple,
   2048         // non-localized way.
   2049         if (listPattern == null || listCompositionPattern == null) {
   2050             StringBuffer result = new StringBuffer();
   2051             for (int i=0; i<stringList.length; ++i) {
   2052                 if (i>0) result.append(',');
   2053                 result.append(stringList[i]);
   2054             }
   2055             return result.toString();
   2056         }
   2057 
   2058         // Compose the list down to three elements if necessary
   2059         if (stringList.length > 3) {
   2060             MessageFormat format = new MessageFormat(listCompositionPattern);
   2061             stringList = composeList(format, stringList);
   2062         }
   2063 
   2064         // Rebuild the argument list with the list length as the first element
   2065         Object[] args = new Object[stringList.length + 1];
   2066         System.arraycopy(stringList, 0, args, 1, stringList.length);
   2067         args[0] = new Integer(stringList.length);
   2068 
   2069         // Format it using the pattern in the resource
   2070         MessageFormat format = new MessageFormat(listPattern);
   2071         return format.format(args);
   2072     }
   2073 
   2074     /**
   2075      * Given a list of strings, return a list shortened to three elements.
   2076      * Shorten it by applying the given format to the first two elements
   2077      * recursively.
   2078      * @param format a format which takes two arguments
   2079      * @param list a list of strings
   2080      * @return if the list is three elements or shorter, the same list;
   2081      * otherwise, a new list of three elements.
   2082      */
   2083     private static String[] composeList(MessageFormat format, String[] list) {
   2084         if (list.length <= 3) return list;
   2085 
   2086         // Use the given format to compose the first two elements into one
   2087         String[] listItems = { list[0], list[1] };
   2088         String newItem = format.format(listItems);
   2089 
   2090         // Form a new list one element shorter
   2091         String[] newList = new String[list.length-1];
   2092         System.arraycopy(list, 2, newList, 1, newList.length-1);
   2093         newList[0] = newItem;
   2094 
   2095         // Recurse
   2096         return composeList(format, newList);
   2097     }
   2098 
   2099     /**
   2100      * @serialField language    String
   2101      *      language subtag in lower case. (See <a href="java/util/Locale.html#getLanguage()">getLanguage()</a>)
   2102      * @serialField country     String
   2103      *      country subtag in upper case. (See <a href="java/util/Locale.html#getCountry()">getCountry()</a>)
   2104      * @serialField variant     String
   2105      *      variant subtags separated by LOWLINE characters. (See <a href="java/util/Locale.html#getVariant()">getVariant()</a>)
   2106      * @serialField hashcode    int
   2107      *      deprecated, for forward compatibility only
   2108      * @serialField script      String
   2109      *      script subtag in title case (See <a href="java/util/Locale.html#getScript()">getScript()</a>)
   2110      * @serialField extensions  String
   2111      *      canonical representation of extensions, that is,
   2112      *      BCP47 extensions in alphabetical order followed by
   2113      *      BCP47 private use subtags, all in lower case letters
   2114      *      separated by HYPHEN-MINUS characters.
   2115      *      (See <a href="java/util/Locale.html#getExtensionKeys()">getExtensionKeys()</a>,
   2116      *      <a href="java/util/Locale.html#getExtension(char)">getExtension(char)</a>)
   2117      */
   2118     private static final ObjectStreamField[] serialPersistentFields = {
   2119         new ObjectStreamField("language", String.class),
   2120         new ObjectStreamField("country", String.class),
   2121         new ObjectStreamField("variant", String.class),
   2122         new ObjectStreamField("hashcode", int.class),
   2123         new ObjectStreamField("script", String.class),
   2124         new ObjectStreamField("extensions", String.class),
   2125     };
   2126 
   2127     /**
   2128      * Serializes this <code>Locale</code> to the specified <code>ObjectOutputStream</code>.
   2129      * @param out the <code>ObjectOutputStream</code> to write
   2130      * @throws IOException
   2131      * @since 1.7
   2132      */
   2133     private void writeObject(ObjectOutputStream out) throws IOException {
   2134         ObjectOutputStream.PutField fields = out.putFields();
   2135         fields.put("language", baseLocale.getLanguage());
   2136         fields.put("script", baseLocale.getScript());
   2137         fields.put("country", baseLocale.getRegion());
   2138         fields.put("variant", baseLocale.getVariant());
   2139         fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
   2140         fields.put("hashcode", -1); // place holder just for backward support
   2141         out.writeFields();
   2142     }
   2143 
   2144     /**
   2145      * Deserializes this <code>Locale</code>.
   2146      * @param in the <code>ObjectInputStream</code> to read
   2147      * @throws IOException
   2148      * @throws ClassNotFoundException
   2149      * @throws IllformedLocaleException
   2150      * @since 1.7
   2151      */
   2152     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
   2153         ObjectInputStream.GetField fields = in.readFields();
   2154         String language = (String)fields.get("language", "");
   2155         String script = (String)fields.get("script", "");
   2156         String country = (String)fields.get("country", "");
   2157         String variant = (String)fields.get("variant", "");
   2158         String extStr = (String)fields.get("extensions", "");
   2159         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
   2160         if (extStr != null && extStr.length() > 0) {
   2161             try {
   2162                 InternalLocaleBuilder bldr = new InternalLocaleBuilder();
   2163                 bldr.setExtensions(extStr);
   2164                 localeExtensions = bldr.getLocaleExtensions();
   2165             } catch (LocaleSyntaxException e) {
   2166                 throw new IllformedLocaleException(e.getMessage());
   2167             }
   2168         } else {
   2169             localeExtensions = null;
   2170         }
   2171     }
   2172 
   2173     /**
   2174      * Returns a cached <code>Locale</code> instance equivalent to
   2175      * the deserialized <code>Locale</code>. When serialized
   2176      * language, country and variant fields read from the object data stream
   2177      * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
   2178      * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>
   2179      * "ca"/"japanese" (calendar type is "japanese") or "nu"/"thai" (number script
   2180      * type is "thai"). See <a href="Locale.html#special_cases_constructor"/>Special Cases</a>
   2181      * for more information.
   2182      *
   2183      * @return an instance of <code>Locale</code> equivalent to
   2184      * the deserialized <code>Locale</code>.
   2185      * @throws java.io.ObjectStreamException
   2186      */
   2187     private Object readResolve() throws java.io.ObjectStreamException {
   2188         return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
   2189                 baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
   2190     }
   2191 
   2192     private static volatile String[] isoLanguages = null;
   2193 
   2194     private static volatile String[] isoCountries = null;
   2195 
   2196     private static String convertOldISOCodes(String language) {
   2197         // we accept both the old and the new ISO codes for the languages whose ISO
   2198         // codes have changed, but we always store the OLD code, for backward compatibility
   2199         language = LocaleUtils.toLowerString(language).intern();
   2200         if (language == "he") {
   2201             return "iw";
   2202         } else if (language == "yi") {
   2203             return "ji";
   2204         } else if (language == "id") {
   2205             return "in";
   2206         } else {
   2207             return language;
   2208         }
   2209     }
   2210 
   2211     private static LocaleExtensions getCompatibilityExtensions(String language,
   2212                                                                String script,
   2213                                                                String country,
   2214                                                                String variant) {
   2215         LocaleExtensions extensions = null;
   2216         // Special cases for backward compatibility support
   2217         if (LocaleUtils.caseIgnoreMatch(language, "ja")
   2218                 && script.length() == 0
   2219                 && LocaleUtils.caseIgnoreMatch(country, "jp")
   2220                 && "JP".equals(variant)) {
   2221             // ja_JP_JP -> u-ca-japanese (calendar = japanese)
   2222             extensions = LocaleExtensions.CALENDAR_JAPANESE;
   2223         } else if (LocaleUtils.caseIgnoreMatch(language, "th")
   2224                 && script.length() == 0
   2225                 && LocaleUtils.caseIgnoreMatch(country, "th")
   2226                 && "TH".equals(variant)) {
   2227             // th_TH_TH -> u-nu-thai (numbersystem = thai)
   2228             extensions = LocaleExtensions.NUMBER_THAI;
   2229         }
   2230         return extensions;
   2231     }
   2232 
   2233     /**
   2234      * @hide for internal use only.
   2235      */
   2236     public static String adjustLanguageCode(String languageCode) {
   2237         String adjusted = languageCode.toLowerCase(Locale.US);
   2238         // Map new language codes to the obsolete language
   2239         // codes so the correct resource bundles will be used.
   2240         if (languageCode.equals("he")) {
   2241             adjusted = "iw";
   2242         } else if (languageCode.equals("id")) {
   2243             adjusted = "in";
   2244         } else if (languageCode.equals("yi")) {
   2245             adjusted = "ji";
   2246         }
   2247 
   2248         return adjusted;
   2249     }
   2250 
   2251     /**
   2252      * Enum for locale categories.  These locale categories are used to get/set
   2253      * the default locale for the specific functionality represented by the
   2254      * category.
   2255      *
   2256      * @see #getDefault(Locale.Category)
   2257      * @see #setDefault(Locale.Category, Locale)
   2258      * @since 1.7
   2259      */
   2260     public enum Category {
   2261 
   2262         /**
   2263          * Category used to represent the default locale for
   2264          * displaying user interfaces.
   2265          */
   2266         DISPLAY("user.language.display",
   2267                 "user.script.display",
   2268                 "user.country.display",
   2269                 "user.variant.display"),
   2270 
   2271         /**
   2272          * Category used to represent the default locale for
   2273          * formatting dates, numbers, and/or currencies.
   2274          */
   2275         FORMAT("user.language.format",
   2276                "user.script.format",
   2277                "user.country.format",
   2278                "user.variant.format");
   2279 
   2280         Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
   2281             this.languageKey = languageKey;
   2282             this.scriptKey = scriptKey;
   2283             this.countryKey = countryKey;
   2284             this.variantKey = variantKey;
   2285         }
   2286 
   2287         final String languageKey;
   2288         final String scriptKey;
   2289         final String countryKey;
   2290         final String variantKey;
   2291     }
   2292 
   2293     /**
   2294      * <code>Builder</code> is used to build instances of <code>Locale</code>
   2295      * from values configured by the setters.  Unlike the <code>Locale</code>
   2296      * constructors, the <code>Builder</code> checks if a value configured by a
   2297      * setter satisfies the syntax requirements defined by the <code>Locale</code>
   2298      * class.  A <code>Locale</code> object created by a <code>Builder</code> is
   2299      * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
   2300      * without losing information.
   2301      *
   2302      * <p><b>Note:</b> The <code>Locale</code> class does not provide any
   2303      * syntactic restrictions on variant, while BCP 47 requires each variant
   2304      * subtag to be 5 to 8 alphanumerics or a single numeric followed by 3
   2305      * alphanumerics.  The method <code>setVariant</code> throws
   2306      * <code>IllformedLocaleException</code> for a variant that does not satisfy
   2307      * this restriction. If it is necessary to support such a variant, use a
   2308      * Locale constructor.  However, keep in mind that a <code>Locale</code>
   2309      * object created this way might lose the variant information when
   2310      * transformed to a BCP 47 language tag.
   2311      *
   2312      * <p>The following example shows how to create a <code>Locale</code> object
   2313      * with the <code>Builder</code>.
   2314      * <blockquote>
   2315      * <pre>
   2316      *     Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
   2317      * </pre>
   2318      * </blockquote>
   2319      *
   2320      * <p>Builders can be reused; <code>clear()</code> resets all
   2321      * fields to their default values.
   2322      *
   2323      * @see Locale#forLanguageTag
   2324      * @since 1.7
   2325      */
   2326     public static final class Builder {
   2327         private final InternalLocaleBuilder localeBuilder;
   2328 
   2329         /**
   2330          * Constructs an empty Builder. The default value of all
   2331          * fields, extensions, and private use information is the
   2332          * empty string.
   2333          */
   2334         public Builder() {
   2335             localeBuilder = new InternalLocaleBuilder();
   2336         }
   2337 
   2338         /**
   2339          * Resets the <code>Builder</code> to match the provided
   2340          * <code>locale</code>.  Existing state is discarded.
   2341          *
   2342          * <p>All fields of the locale must be well-formed, see {@link Locale}.
   2343          *
   2344          * <p>Locales with any ill-formed fields cause
   2345          * <code>IllformedLocaleException</code> to be thrown, except for the
   2346          * following three cases which are accepted for compatibility
   2347          * reasons:<ul>
   2348          * <li>Locale("ja", "JP", "JP") is treated as "ja-JP-u-ca-japanese"
   2349          * <li>Locale("th", "TH", "TH") is treated as "th-TH-u-nu-thai"
   2350          * <li>Locale("no", "NO", "NY") is treated as "nn-NO"</ul>
   2351          *
   2352          * @param locale the locale
   2353          * @return This builder.
   2354          * @throws IllformedLocaleException if <code>locale</code> has
   2355          * any ill-formed fields.
   2356          * @throws NullPointerException if <code>locale</code> is null.
   2357          */
   2358         public Builder setLocale(Locale locale) {
   2359             try {
   2360                 localeBuilder.setLocale(locale.baseLocale, locale.localeExtensions);
   2361             } catch (LocaleSyntaxException e) {
   2362                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2363             }
   2364             return this;
   2365         }
   2366 
   2367         /**
   2368          * Resets the Builder to match the provided IETF BCP 47
   2369          * language tag.  Discards the existing state.  Null and the
   2370          * empty string cause the builder to be reset, like {@link
   2371          * #clear}.  Grandfathered tags (see {@link
   2372          * Locale#forLanguageTag}) are converted to their canonical
   2373          * form before being processed.  Otherwise, the language tag
   2374          * must be well-formed (see {@link Locale}) or an exception is
   2375          * thrown (unlike <code>Locale.forLanguageTag</code>, which
   2376          * just discards ill-formed and following portions of the
   2377          * tag).
   2378          *
   2379          * @param languageTag the language tag
   2380          * @return This builder.
   2381          * @throws IllformedLocaleException if <code>languageTag</code> is ill-formed
   2382          * @see Locale#forLanguageTag(String)
   2383          */
   2384         public Builder setLanguageTag(String languageTag) {
   2385             ParseStatus sts = new ParseStatus();
   2386             LanguageTag tag = LanguageTag.parse(languageTag, sts);
   2387             if (sts.isError()) {
   2388                 throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
   2389             }
   2390             localeBuilder.setLanguageTag(tag);
   2391             return this;
   2392         }
   2393 
   2394         /**
   2395          * Sets the language.  If <code>language</code> is the empty string or
   2396          * null, the language in this <code>Builder</code> is removed.  Otherwise,
   2397          * the language must be <a href="./Locale.html#def_language">well-formed</a>
   2398          * or an exception is thrown.
   2399          *
   2400          * <p>The typical language value is a two or three-letter language
   2401          * code as defined in ISO639.
   2402          *
   2403          * @param language the language
   2404          * @return This builder.
   2405          * @throws IllformedLocaleException if <code>language</code> is ill-formed
   2406          */
   2407         public Builder setLanguage(String language) {
   2408             try {
   2409                 localeBuilder.setLanguage(language);
   2410             } catch (LocaleSyntaxException e) {
   2411                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2412             }
   2413             return this;
   2414         }
   2415 
   2416         /**
   2417          * Sets the script. If <code>script</code> is null or the empty string,
   2418          * the script in this <code>Builder</code> is removed.
   2419          * Otherwise, the script must be <a href="./Locale.html#def_script">well-formed</a> or an
   2420          * exception is thrown.
   2421          *
   2422          * <p>The typical script value is a four-letter script code as defined by ISO 15924.
   2423          *
   2424          * @param script the script
   2425          * @return This builder.
   2426          * @throws IllformedLocaleException if <code>script</code> is ill-formed
   2427          */
   2428         public Builder setScript(String script) {
   2429             try {
   2430                 localeBuilder.setScript(script);
   2431             } catch (LocaleSyntaxException e) {
   2432                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2433             }
   2434             return this;
   2435         }
   2436 
   2437         /**
   2438          * Sets the region.  If region is null or the empty string, the region
   2439          * in this <code>Builder</code> is removed.  Otherwise,
   2440          * the region must be <a href="./Locale.html#def_region">well-formed</a> or an
   2441          * exception is thrown.
   2442          *
   2443          * <p>The typical region value is a two-letter ISO 3166 code or a
   2444          * three-digit UN M.49 area code.
   2445          *
   2446          * <p>The country value in the <code>Locale</code> created by the
   2447          * <code>Builder</code> is always normalized to upper case.
   2448          *
   2449          * @param region the region
   2450          * @return This builder.
   2451          * @throws IllformedLocaleException if <code>region</code> is ill-formed
   2452          */
   2453         public Builder setRegion(String region) {
   2454             try {
   2455                 localeBuilder.setRegion(region);
   2456             } catch (LocaleSyntaxException e) {
   2457                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2458             }
   2459             return this;
   2460         }
   2461 
   2462         /**
   2463          * Sets the variant.  If variant is null or the empty string, the
   2464          * variant in this <code>Builder</code> is removed.  Otherwise, it
   2465          * must consist of one or more <a href="./Locale.html#def_variant">well-formed</a>
   2466          * subtags, or an exception is thrown.
   2467          *
   2468          * <p><b>Note:</b> This method checks if <code>variant</code>
   2469          * satisfies the IETF BCP 47 variant subtag's syntax requirements,
   2470          * and normalizes the value to lowercase letters.  However,
   2471          * the <code>Locale</code> class does not impose any syntactic
   2472          * restriction on variant, and the variant value in
   2473          * <code>Locale</code> is case sensitive.  To set such a variant,
   2474          * use a Locale constructor.
   2475          *
   2476          * @param variant the variant
   2477          * @return This builder.
   2478          * @throws IllformedLocaleException if <code>variant</code> is ill-formed
   2479          */
   2480         public Builder setVariant(String variant) {
   2481             try {
   2482                 localeBuilder.setVariant(variant);
   2483             } catch (LocaleSyntaxException e) {
   2484                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2485             }
   2486             return this;
   2487         }
   2488 
   2489         /**
   2490          * Sets the extension for the given key. If the value is null or the
   2491          * empty string, the extension is removed.  Otherwise, the extension
   2492          * must be <a href="./Locale.html#def_extensions">well-formed</a> or an exception
   2493          * is thrown.
   2494          *
   2495          * <p><b>Note:</b> The key {@link Locale#UNICODE_LOCALE_EXTENSION
   2496          * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension.
   2497          * Setting a value for this key replaces any existing Unicode locale key/type
   2498          * pairs with those defined in the extension.
   2499          *
   2500          * <p><b>Note:</b> The key {@link Locale#PRIVATE_USE_EXTENSION
   2501          * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be
   2502          * well-formed, the value for this key needs only to have subtags of one to
   2503          * eight alphanumeric characters, not two to eight as in the general case.
   2504          *
   2505          * @param key the extension key
   2506          * @param value the extension value
   2507          * @return This builder.
   2508          * @throws IllformedLocaleException if <code>key</code> is illegal
   2509          * or <code>value</code> is ill-formed
   2510          * @see #setUnicodeLocaleKeyword(String, String)
   2511          */
   2512         public Builder setExtension(char key, String value) {
   2513             try {
   2514                 localeBuilder.setExtension(key, value);
   2515             } catch (LocaleSyntaxException e) {
   2516                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2517             }
   2518             return this;
   2519         }
   2520 
   2521         /**
   2522          * Sets the Unicode locale keyword type for the given key.  If the type
   2523          * is null, the Unicode keyword is removed.  Otherwise, the key must be
   2524          * non-null and both key and type must be <a
   2525          * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
   2526          * is thrown.
   2527          *
   2528          * <p>Keys and types are converted to lower case.
   2529          *
   2530          * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension}
   2531          * replaces all Unicode locale keywords with those defined in the
   2532          * extension.
   2533          *
   2534          * @param key the Unicode locale key
   2535          * @param type the Unicode locale type
   2536          * @return This builder.
   2537          * @throws IllformedLocaleException if <code>key</code> or <code>type</code>
   2538          * is ill-formed
   2539          * @throws NullPointerException if <code>key</code> is null
   2540          * @see #setExtension(char, String)
   2541          */
   2542         public Builder setUnicodeLocaleKeyword(String key, String type) {
   2543             try {
   2544                 localeBuilder.setUnicodeLocaleKeyword(key, type);
   2545             } catch (LocaleSyntaxException e) {
   2546                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2547             }
   2548             return this;
   2549         }
   2550 
   2551         /**
   2552          * Adds a unicode locale attribute, if not already present, otherwise
   2553          * has no effect.  The attribute must not be null and must be <a
   2554          * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
   2555          * is thrown.
   2556          *
   2557          * @param attribute the attribute
   2558          * @return This builder.
   2559          * @throws NullPointerException if <code>attribute</code> is null
   2560          * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
   2561          * @see #setExtension(char, String)
   2562          */
   2563         public Builder addUnicodeLocaleAttribute(String attribute) {
   2564             try {
   2565                 localeBuilder.addUnicodeLocaleAttribute(attribute);
   2566             } catch (LocaleSyntaxException e) {
   2567                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2568             }
   2569             return this;
   2570         }
   2571 
   2572         /**
   2573          * Removes a unicode locale attribute, if present, otherwise has no
   2574          * effect.  The attribute must not be null and must be <a
   2575          * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
   2576          * is thrown.
   2577          *
   2578          * <p>Attribute comparision for removal is case-insensitive.
   2579          *
   2580          * @param attribute the attribute
   2581          * @return This builder.
   2582          * @throws NullPointerException if <code>attribute</code> is null
   2583          * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
   2584          * @see #setExtension(char, String)
   2585          */
   2586         public Builder removeUnicodeLocaleAttribute(String attribute) {
   2587             if (attribute == null) {
   2588                 throw new NullPointerException("attribute == null");
   2589             }
   2590 
   2591             try {
   2592                 localeBuilder.removeUnicodeLocaleAttribute(attribute);
   2593             } catch (LocaleSyntaxException e) {
   2594                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2595             }
   2596             return this;
   2597         }
   2598 
   2599         /**
   2600          * Resets the builder to its initial, empty state.
   2601          *
   2602          * @return This builder.
   2603          */
   2604         public Builder clear() {
   2605             localeBuilder.clear();
   2606             return this;
   2607         }
   2608 
   2609         /**
   2610          * Resets the extensions to their initial, empty state.
   2611          * Language, script, region and variant are unchanged.
   2612          *
   2613          * @return This builder.
   2614          * @see #setExtension(char, String)
   2615          */
   2616         public Builder clearExtensions() {
   2617             localeBuilder.clearExtensions();
   2618             return this;
   2619         }
   2620 
   2621         /**
   2622          * Returns an instance of <code>Locale</code> created from the fields set
   2623          * on this builder.
   2624          *
   2625          * <p>This applies the conversions listed in {@link Locale#forLanguageTag}
   2626          * when constructing a Locale. (Grandfathered tags are handled in
   2627          * {@link #setLanguageTag}.)
   2628          *
   2629          * @return A Locale.
   2630          */
   2631         public Locale build() {
   2632             BaseLocale baseloc = localeBuilder.getBaseLocale();
   2633             LocaleExtensions extensions = localeBuilder.getLocaleExtensions();
   2634             if (extensions == null && baseloc.getVariant().length() > 0) {
   2635                 extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(),
   2636                         baseloc.getRegion(), baseloc.getVariant());
   2637             }
   2638             return Locale.getInstance(baseloc, extensions);
   2639         }
   2640     }
   2641 }
   2642