Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2014, 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.text.MessageFormat;
     50 import libcore.icu.ICU;
     51 
     52 import sun.util.locale.BaseLocale;
     53 import sun.util.locale.InternalLocaleBuilder;
     54 import sun.util.locale.LanguageTag;
     55 import sun.util.locale.LocaleExtensions;
     56 import sun.util.locale.LocaleMatcher;
     57 import sun.util.locale.LocaleObjectCache;
     58 import sun.util.locale.LocaleSyntaxException;
     59 import sun.util.locale.LocaleUtils;
     60 import sun.util.locale.ParseStatus;
     61 
     62 // Android-added: documentation about ICU data & warning of default locale.
     63 /**
     64  * A <code>Locale</code> object represents a specific geographical, political,
     65  * or cultural region. An operation that requires a <code>Locale</code> to perform
     66  * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
     67  * to tailor information for the user. For example, displaying a number
     68  * is a locale-sensitive operation&mdash; the number should be formatted
     69  * according to the customs and conventions of the user's native country,
     70  * region, or culture.
     71  *
     72  * <p> The {@code Locale} class implements IETF BCP 47 which is composed of
     73  * <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 "Matching of Language
     74  * Tags"</a> and <a href="http://tools.ietf.org/html/rfc5646">RFC 5646 "Tags
     75  * for Identifying Languages"</a> with support for the LDML (UTS#35, "Unicode
     76  * Locale Data Markup Language") BCP 47-compatible extensions for locale data
     77  * exchange.
     78  *
     79  * <p> A <code>Locale</code> object logically consists of the fields
     80  * described below.
     81  *
     82  * <dl>
     83  *   <dt><a name="def_language"><b>language</b></a></dt>
     84  *
     85  *   <dd>ISO 639 alpha-2 or alpha-3 language code, or registered
     86  *   language subtags up to 8 alpha letters (for future enhancements).
     87  *   When a language has both an alpha-2 code and an alpha-3 code, the
     88  *   alpha-2 code must be used.  You can find a full list of valid
     89  *   language codes in the IANA Language Subtag Registry (search for
     90  *   "Type: language").  The language field is case insensitive, but
     91  *   <code>Locale</code> always canonicalizes to lower case.</dd>
     92  *
     93  *   <dd>Well-formed language values have the form
     94  *   <code>[a-zA-Z]{2,8}</code>.  Note that this is not the the full
     95  *   BCP47 language production, since it excludes extlang.  They are
     96  *   not needed since modern three-letter language codes replace
     97  *   them.</dd>
     98  *
     99  *   <dd>Example: "en" (English), "ja" (Japanese), "kok" (Konkani)</dd>
    100  *
    101  *   <dt><a name="def_script"><b>script</b></a></dt>
    102  *
    103  *   <dd>ISO 15924 alpha-4 script code.  You can find a full list of
    104  *   valid script codes in the IANA Language Subtag Registry (search
    105  *   for "Type: script").  The script field is case insensitive, but
    106  *   <code>Locale</code> always canonicalizes to title case (the first
    107  *   letter is upper case and the rest of the letters are lower
    108  *   case).</dd>
    109  *
    110  *   <dd>Well-formed script values have the form
    111  *   <code>[a-zA-Z]{4}</code></dd>
    112  *
    113  *   <dd>Example: "Latn" (Latin), "Cyrl" (Cyrillic)</dd>
    114  *
    115  *   <dt><a name="def_region"><b>country (region)</b></a></dt>
    116  *
    117  *   <dd>ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code.
    118  *   You can find a full list of valid country and region codes in the
    119  *   IANA Language Subtag Registry (search for "Type: region").  The
    120  *   country (region) field is case insensitive, but
    121  *   <code>Locale</code> always canonicalizes to upper case.</dd>
    122  *
    123  *   <dd>Well-formed country/region values have
    124  *   the form <code>[a-zA-Z]{2} | [0-9]{3}</code></dd>
    125  *
    126  *   <dd>Example: "US" (United States), "FR" (France), "029"
    127  *   (Caribbean)</dd>
    128  *
    129  *   <dt><a name="def_variant"><b>variant</b></a></dt>
    130  *
    131  *   <dd>Any arbitrary value used to indicate a variation of a
    132  *   <code>Locale</code>.  Where there are two or more variant values
    133  *   each indicating its own semantics, these values should be ordered
    134  *   by importance, with most important first, separated by
    135  *   underscore('_').  The variant field is case sensitive.</dd>
    136  *
    137  *   <dd>Note: IETF BCP 47 places syntactic restrictions on variant
    138  *   subtags.  Also BCP 47 subtags are strictly used to indicate
    139  *   additional variations that define a language or its dialects that
    140  *   are not covered by any combinations of language, script and
    141  *   region subtags.  You can find a full list of valid variant codes
    142  *   in the IANA Language Subtag Registry (search for "Type: variant").
    143  *
    144  *   <p>However, the variant field in <code>Locale</code> has
    145  *   historically been used for any kind of variation, not just
    146  *   language variations.  For example, some supported variants
    147  *   available in Java SE Runtime Environments indicate alternative
    148  *   cultural behaviors such as calendar type or number script.  In
    149  *   BCP 47 this kind of information, which does not identify the
    150  *   language, is supported by extension subtags or private use
    151  *   subtags.</dd>
    152  *
    153  *   <dd>Well-formed variant values have the form <code>SUBTAG
    154  *   (('_'|'-') SUBTAG)*</code> where <code>SUBTAG =
    155  *   [0-9][0-9a-zA-Z]{3} | [0-9a-zA-Z]{5,8}</code>. (Note: BCP 47 only
    156  *   uses hyphen ('-') as a delimiter, this is more lenient).</dd>
    157  *
    158  *   <dd>Example: "polyton" (Polytonic Greek), "POSIX"</dd>
    159  *
    160  *   <dt><a name="def_extensions"><b>extensions</b></a></dt>
    161  *
    162  *   <dd>A map from single character keys to string values, indicating
    163  *   extensions apart from language identification.  The extensions in
    164  *   <code>Locale</code> implement the semantics and syntax of BCP 47
    165  *   extension subtags and private use subtags. The extensions are
    166  *   case insensitive, but <code>Locale</code> canonicalizes all
    167  *   extension keys and values to lower case. Note that extensions
    168  *   cannot have empty values.</dd>
    169  *
    170  *   <dd>Well-formed keys are single characters from the set
    171  *   <code>[0-9a-zA-Z]</code>.  Well-formed values have the form
    172  *   <code>SUBTAG ('-' SUBTAG)*</code> where for the key 'x'
    173  *   <code>SUBTAG = [0-9a-zA-Z]{1,8}</code> and for other keys
    174  *   <code>SUBTAG = [0-9a-zA-Z]{2,8}</code> (that is, 'x' allows
    175  *   single-character subtags).</dd>
    176  *
    177  *   <dd>Example: key="u"/value="ca-japanese" (Japanese Calendar),
    178  *   key="x"/value="java-1-7"</dd>
    179  * </dl>
    180  *
    181  * <b>Note:</b> Although BCP 47 requires field values to be registered
    182  * in the IANA Language Subtag Registry, the <code>Locale</code> class
    183  * does not provide any validation features.  The <code>Builder</code>
    184  * only checks if an individual field satisfies the syntactic
    185  * requirement (is well-formed), but does not validate the value
    186  * itself.  See {@link Builder} for details.
    187  *
    188  * <h3><a name="def_locale_extension">Unicode locale/language extension</a></h3>
    189  *
    190  * <p>UTS#35, "Unicode Locale Data Markup Language" defines optional
    191  * attributes and keywords to override or refine the default behavior
    192  * associated with a locale.  A keyword is represented by a pair of
    193  * key and type.  For example, "nu-thai" indicates that Thai local
    194  * digits (value:"thai") should be used for formatting numbers
    195  * (key:"nu").
    196  *
    197  * <p>The keywords are mapped to a BCP 47 extension value using the
    198  * extension key 'u' ({@link #UNICODE_LOCALE_EXTENSION}).  The above
    199  * example, "nu-thai", becomes the extension "u-nu-thai".code
    200  *
    201  * <p>Thus, when a <code>Locale</code> object contains Unicode locale
    202  * attributes and keywords,
    203  * <code>getExtension(UNICODE_LOCALE_EXTENSION)</code> will return a
    204  * String representing this information, for example, "nu-thai".  The
    205  * <code>Locale</code> class also provides {@link
    206  * #getUnicodeLocaleAttributes}, {@link #getUnicodeLocaleKeys}, and
    207  * {@link #getUnicodeLocaleType} which allow you to access Unicode
    208  * locale attributes and key/type pairs directly.  When represented as
    209  * a string, the Unicode Locale Extension lists attributes
    210  * alphabetically, followed by key/type sequences with keys listed
    211  * alphabetically (the order of subtags comprising a key's type is
    212  * fixed when the type is defined)
    213  *
    214  * <p>A well-formed locale key has the form
    215  * <code>[0-9a-zA-Z]{2}</code>.  A well-formed locale type has the
    216  * form <code>"" | [0-9a-zA-Z]{3,8} ('-' [0-9a-zA-Z]{3,8})*</code> (it
    217  * can be empty, or a series of subtags 3-8 alphanums in length).  A
    218  * well-formed locale attribute has the form
    219  * <code>[0-9a-zA-Z]{3,8}</code> (it is a single subtag with the same
    220  * form as a locale type subtag).
    221  *
    222  * <p>The Unicode locale extension specifies optional behavior in
    223  * locale-sensitive services.  Although the LDML specification defines
    224  * various keys and values, actual locale-sensitive service
    225  * implementations in a Java Runtime Environment might not support any
    226  * particular Unicode locale attributes or key/type pairs.
    227  *
    228  * <h4>Creating a Locale</h4>
    229  *
    230  * <p>There are several different ways to create a <code>Locale</code>
    231  * object.
    232  *
    233  * <h5>Builder</h5>
    234  *
    235  * <p>Using {@link Builder} you can construct a <code>Locale</code> object
    236  * that conforms to BCP 47 syntax.
    237  *
    238  * <h5>Constructors</h5>
    239  *
    240  * <p>The <code>Locale</code> class provides three constructors:
    241  * <blockquote>
    242  * <pre>
    243  *     {@link #Locale(String language)}
    244  *     {@link #Locale(String language, String country)}
    245  *     {@link #Locale(String language, String country, String variant)}
    246  * </pre>
    247  * </blockquote>
    248  * These constructors allow you to create a <code>Locale</code> object
    249  * with language, country and variant, but you cannot specify
    250  * script or extensions.
    251  *
    252  * <h5>Factory Methods</h5>
    253  *
    254  * <p>The method {@link #forLanguageTag} creates a <code>Locale</code>
    255  * object for a well-formed BCP 47 language tag.
    256  *
    257  * <h5>Locale Constants</h5>
    258  *
    259  * <p>The <code>Locale</code> class provides a number of convenient constants
    260  * that you can use to create <code>Locale</code> objects for commonly used
    261  * locales. For example, the following creates a <code>Locale</code> object
    262  * for the United States:
    263  * <blockquote>
    264  * <pre>
    265  *     Locale.US
    266  * </pre>
    267  * </blockquote>
    268  *
    269  * <h4><a name="LocaleMatching">Locale Matching</a></h4>
    270  *
    271  * <p>If an application or a system is internationalized and provides localized
    272  * resources for multiple locales, it sometimes needs to find one or more
    273  * locales (or language tags) which meet each user's specific preferences. Note
    274  * that a term "language tag" is used interchangeably with "locale" in this
    275  * locale matching documentation.
    276  *
    277  * <p>In order to do matching a user's preferred locales to a set of language
    278  * tags, <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 Matching of
    279  * Language Tags</a> defines two mechanisms: filtering and lookup.
    280  * <em>Filtering</em> is used to get all matching locales, whereas
    281  * <em>lookup</em> is to choose the best matching locale.
    282  * Matching is done case-insensitively. These matching mechanisms are described
    283  * in the following sections.
    284  *
    285  * <p>A user's preference is called a <em>Language Priority List</em> and is
    286  * expressed as a list of language ranges. There are syntactically two types of
    287  * language ranges: basic and extended. See
    288  * {@link Locale.LanguageRange Locale.LanguageRange} for details.
    289  *
    290  * <h5>Filtering</h5>
    291  *
    292  * <p>The filtering operation returns all matching language tags. It is defined
    293  * in RFC 4647 as follows:
    294  * "In filtering, each language range represents the least specific language
    295  * tag (that is, the language tag with fewest number of subtags) that is an
    296  * acceptable match. All of the language tags in the matching set of tags will
    297  * have an equal or greater number of subtags than the language range. Every
    298  * non-wildcard subtag in the language range will appear in every one of the
    299  * matching language tags."
    300  *
    301  * <p>There are two types of filtering: filtering for basic language ranges
    302  * (called "basic filtering") and filtering for extended language ranges
    303  * (called "extended filtering"). They may return different results by what
    304  * kind of language ranges are included in the given Language Priority List.
    305  * {@link Locale.FilteringMode} is a parameter to specify how filtering should
    306  * be done.
    307  *
    308  * <h5>Lookup</h5>
    309  *
    310  * <p>The lookup operation returns the best matching language tags. It is
    311  * defined in RFC 4647 as follows:
    312  * "By contrast with filtering, each language range represents the most
    313  * specific tag that is an acceptable match.  The first matching tag found,
    314  * according to the user's priority, is considered the closest match and is the
    315  * item returned."
    316  *
    317  * <p>For example, if a Language Priority List consists of two language ranges,
    318  * {@code "zh-Hant-TW"} and {@code "en-US"}, in prioritized order, lookup
    319  * method progressively searches the language tags below in order to find the
    320  * best matching language tag.
    321  * <blockquote>
    322  * <pre>
    323  *    1. zh-Hant-TW
    324  *    2. zh-Hant
    325  *    3. zh
    326  *    4. en-US
    327  *    5. en
    328  * </pre>
    329  * </blockquote>
    330  * If there is a language tag which matches completely to a language range
    331  * above, the language tag is returned.
    332  *
    333  * <p>{@code "*"} is the special language range, and it is ignored in lookup.
    334  *
    335  * <p>If multiple language tags match as a result of the subtag {@code '*'}
    336  * included in a language range, the first matching language tag returned by
    337  * an {@link Iterator} over a {@link Collection} of language tags is treated as
    338  * the best matching one.
    339  *
    340  * <h4>Use of Locale</h4>
    341  *
    342  * <p>Once you've created a <code>Locale</code> you can query it for information
    343  * about itself. Use <code>getCountry</code> to get the country (or region)
    344  * code and <code>getLanguage</code> to get the language code.
    345  * You can use <code>getDisplayCountry</code> to get the
    346  * name of the country suitable for displaying to the user. Similarly,
    347  * you can use <code>getDisplayLanguage</code> to get the name of
    348  * the language suitable for displaying to the user. Interestingly,
    349  * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
    350  * and have two versions: one that uses the default
    351  * {@link Locale.Category#DISPLAY DISPLAY} locale and one
    352  * that uses the locale specified as an argument.
    353  *
    354  * <p>The Java Platform provides a number of classes that perform locale-sensitive
    355  * operations. For example, the <code>NumberFormat</code> class formats
    356  * numbers, currency, and percentages in a locale-sensitive manner. Classes
    357  * such as <code>NumberFormat</code> have several convenience methods
    358  * for creating a default object of that type. For example, the
    359  * <code>NumberFormat</code> class provides these three convenience methods
    360  * for creating a default <code>NumberFormat</code> object:
    361  * <blockquote>
    362  * <pre>
    363  *     NumberFormat.getInstance()
    364  *     NumberFormat.getCurrencyInstance()
    365  *     NumberFormat.getPercentInstance()
    366  * </pre>
    367  * </blockquote>
    368  * Each of these methods has two variants; one with an explicit locale
    369  * and one without; the latter uses the default
    370  * {@link Locale.Category#FORMAT FORMAT} locale:
    371  * <blockquote>
    372  * <pre>
    373  *     NumberFormat.getInstance(myLocale)
    374  *     NumberFormat.getCurrencyInstance(myLocale)
    375  *     NumberFormat.getPercentInstance(myLocale)
    376  * </pre>
    377  * </blockquote>
    378  * A <code>Locale</code> is the mechanism for identifying the kind of object
    379  * (<code>NumberFormat</code>) that you would like to get. The locale is
    380  * <STRONG>just</STRONG> a mechanism for identifying objects,
    381  * <STRONG>not</STRONG> a container for the objects themselves.
    382  *
    383  * <h4>Compatibility</h4>
    384  *
    385  * <p>In order to maintain compatibility with existing usage, Locale's
    386  * constructors retain their behavior prior to the Java Runtime
    387  * Environment version 1.7.  The same is largely true for the
    388  * <code>toString</code> method. Thus Locale objects can continue to
    389  * be used as they were. In particular, clients who parse the output
    390  * of toString into language, country, and variant fields can continue
    391  * to do so (although this is strongly discouraged), although the
    392  * variant field will have additional information in it if script or
    393  * extensions are present.
    394  *
    395  * <p>In addition, BCP 47 imposes syntax restrictions that are not
    396  * imposed by Locale's constructors. This means that conversions
    397  * between some Locales and BCP 47 language tags cannot be made without
    398  * losing information. Thus <code>toLanguageTag</code> cannot
    399  * represent the state of locales whose language, country, or variant
    400  * do not conform to BCP 47.
    401  *
    402  * <p>Because of these issues, it is recommended that clients migrate
    403  * away from constructing non-conforming locales and use the
    404  * <code>forLanguageTag</code> and <code>Locale.Builder</code> APIs instead.
    405  * Clients desiring a string representation of the complete locale can
    406  * then always rely on <code>toLanguageTag</code> for this purpose.
    407  *
    408  * <h5><a name="special_cases_constructor">Special cases</a></h5>
    409  *
    410  * <p>For compatibility reasons, two
    411  * non-conforming locales are treated as special cases.  These are
    412  * <b><tt>ja_JP_JP</tt></b> and <b><tt>th_TH_TH</tt></b>. These are ill-formed
    413  * in BCP 47 since the variants are too short. To ease migration to BCP 47,
    414  * these are treated specially during construction.  These two cases (and only
    415  * these) cause a constructor to generate an extension, all other values behave
    416  * exactly as they did prior to Java 7.
    417  *
    418  * <p>Java has used <tt>ja_JP_JP</tt> to represent Japanese as used in
    419  * Japan together with the Japanese Imperial calendar. This is now
    420  * representable using a Unicode locale extension, by specifying the
    421  * Unicode locale key <tt>ca</tt> (for "calendar") and type
    422  * <tt>japanese</tt>. When the Locale constructor is called with the
    423  * arguments "ja", "JP", "JP", the extension "u-ca-japanese" is
    424  * automatically added.
    425  *
    426  * <p>Java has used <tt>th_TH_TH</tt> to represent Thai as used in
    427  * Thailand together with Thai digits. This is also now representable using
    428  * a Unicode locale extension, by specifying the Unicode locale key
    429  * <tt>nu</tt> (for "number") and value <tt>thai</tt>. When the Locale
    430  * constructor is called with the arguments "th", "TH", "TH", the
    431  * extension "u-nu-thai" is automatically added.
    432  *
    433  * <h5>Serialization</h5>
    434  *
    435  * <p>During serialization, writeObject writes all fields to the output
    436  * stream, including extensions.
    437  *
    438  * <p>During deserialization, readResolve adds extensions as described
    439  * in <a href="#special_cases_constructor">Special Cases</a>, only
    440  * for the two cases th_TH_TH and ja_JP_JP.
    441  *
    442  * <h5>Legacy language codes</h5>
    443  *
    444  * <p>Locale's constructor has always converted three language codes to
    445  * their earlier, obsoleted forms: <tt>he</tt> maps to <tt>iw</tt>,
    446  * <tt>yi</tt> maps to <tt>ji</tt>, and <tt>id</tt> maps to
    447  * <tt>in</tt>.  This continues to be the case, in order to not break
    448  * backwards compatibility.
    449  *
    450  * <p>The APIs added in 1.7 map between the old and new language codes,
    451  * maintaining the old codes internal to Locale (so that
    452  * <code>getLanguage</code> and <code>toString</code> reflect the old
    453  * code), but using the new codes in the BCP 47 language tag APIs (so
    454  * that <code>toLanguageTag</code> reflects the new one). This
    455  * preserves the equivalence between Locales no matter which code or
    456  * API is used to construct them. Java's default resource bundle
    457  * lookup mechanism also implements this mapping, so that resources
    458  * can be named using either convention, see {@link ResourceBundle.Control}.
    459  *
    460  * <h5>Three-letter language/country(region) codes</h5>
    461  *
    462  * <p>The Locale constructors have always specified that the language
    463  * and the country param be two characters in length, although in
    464  * practice they have accepted any length.  The specification has now
    465  * been relaxed to allow language codes of two to eight characters and
    466  * country (region) codes of two to three characters, and in
    467  * particular, three-letter language codes and three-digit region
    468  * codes as specified in the IANA Language Subtag Registry.  For
    469  * compatibility, the implementation still does not impose a length
    470  * constraint.
    471  *
    472  * <a name="locale_data"></a><h4>Locale data</h4>
    473  * <p>Note that locale data comes solely from ICU. User-supplied locale service providers (using
    474  * the {@code java.text.spi} or {@code java.util.spi} mechanisms) are not supported.
    475  *
    476  * <p>Here are the versions of ICU (and the corresponding CLDR and Unicode versions) used in
    477  * various Android releases:
    478  * <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
    479  * <tr><td>Android 1.5 (Cupcake)/Android 1.6 (Donut)/Android 2.0 (Eclair)</td>
    480  *     <td>ICU 3.8</td>
    481  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-5">CLDR 1.5</a></td>
    482  *     <td><a href="http://www.unicode.org/versions/Unicode5.0.0/">Unicode 5.0</a></td></tr>
    483  * <tr><td>Android 2.2 (Froyo)</td>
    484  *     <td>ICU 4.2</td>
    485  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-7">CLDR 1.7</a></td>
    486  *     <td><a href="http://www.unicode.org/versions/Unicode5.1.0/">Unicode 5.1</a></td></tr>
    487  * <tr><td>Android 2.3 (Gingerbread)/Android 3.0 (Honeycomb)</td>
    488  *     <td>ICU 4.4</td>
    489  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-8">CLDR 1.8</a></td>
    490  *     <td><a href="http://www.unicode.org/versions/Unicode5.2.0/">Unicode 5.2</a></td></tr>
    491  * <tr><td>Android 4.0 (Ice Cream Sandwich)</td>
    492  *     <td><a href="http://site.icu-project.org/download/46">ICU 4.6</a></td>
    493  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-9">CLDR 1.9</a></td>
    494  *     <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
    495  * <tr><td>Android 4.1 (Jelly Bean)</td>
    496  *     <td><a href="http://site.icu-project.org/download/48">ICU 4.8</a></td>
    497  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-2-0">CLDR 2.0</a></td>
    498  *     <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
    499  * <tr><td>Android 4.3 (Jelly Bean MR2)</td>
    500  *     <td><a href="http://site.icu-project.org/download/50">ICU 50</a></td>
    501  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-22-1">CLDR 22.1</a></td>
    502  *     <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
    503  * <tr><td>Android 4.4 (KitKat)</td>
    504  *     <td><a href="http://site.icu-project.org/download/51">ICU 51</a></td>
    505  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-23">CLDR 23</a></td>
    506  *     <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
    507  * <tr><td>Android 5.0 (Lollipop)</td>
    508  *     <td><a href="http://site.icu-project.org/download/53">ICU 53</a></td>
    509  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-25">CLDR 25</a></td>
    510  *     <td><a href="http://www.unicode.org/versions/Unicode6.3.0/">Unicode 6.3</a></td></tr>
    511  * <tr><td>Android 6.0 (Marshmallow)</td>
    512  *     <td><a href="http://site.icu-project.org/download/55">ICU 55.1</a></td>
    513  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-27">CLDR 27.0.1</a></td>
    514  *     <td><a href="http://www.unicode.org/versions/Unicode7.0.0/">Unicode 7.0</a></td></tr>
    515  * <tr><td>Android 7.0 (Nougat)</td>
    516  *     <td><a href="http://site.icu-project.org/download/56">ICU 56.1</a></td>
    517  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-28">CLDR 28</a></td>
    518  *     <td><a href="http://www.unicode.org/versions/Unicode8.0.0/">Unicode 8.0</a></td></tr>
    519  * <tr><td>Android 8.0 (Oreo)</td>
    520  *     <td><a href="http://site.icu-project.org/download/58">ICU 58.2</a></td>
    521  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-30">CLDR 30.0.3</a></td>
    522  *     <td><a href="http://www.unicode.org/versions/Unicode9.0.0/">Unicode 9.0</a></td></tr>
    523  * <tr><td>Android 9.0 (TBD)</td>
    524  *     <td><a href="http://site.icu-project.org/download/60">ICU 60.2</a></td>
    525  *     <td><a href="http://cldr.unicode.org/index/downloads/cldr-32">CLDR 32.0.1</a></td>
    526  *     <td><a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a></td></tr>
    527  * </table>
    528  *
    529  * <a name="default_locale"></a><h4>Be wary of the default locale</h3>
    530  * <p>Note that there are many convenience methods that automatically use the default locale, but
    531  * using them may lead to subtle bugs.
    532  *
    533  * <p>The default locale is appropriate for tasks that involve presenting data to the user. In
    534  * this case, you want to use the user's date/time formats, number
    535  * formats, rules for conversion to lowercase, and so on. In this case, it's safe to use the
    536  * convenience methods.
    537  *
    538  * <p>The default locale is <i>not</i> appropriate for machine-readable output. The best choice
    539  * there is usually {@code Locale.US}&nbsp;&ndash; this locale is guaranteed to be available on all
    540  * devices, and the fact that it has no surprising special cases and is frequently used (especially
    541  * for computer-computer communication) means that it tends to be the most efficient choice too.
    542  *
    543  * <p>A common mistake is to implicitly use the default locale when producing output meant to be
    544  * machine-readable. This tends to work on the developer's test devices (especially because so many
    545  * developers use en_US), but fails when run on a device whose user is in a more complex locale.
    546  *
    547  * <p>For example, if you're formatting integers some locales will use non-ASCII decimal
    548  * digits. As another example, if you're formatting floating-point numbers some locales will use
    549  * {@code ','} as the decimal point and {@code '.'} for digit grouping. That's correct for
    550  * human-readable output, but likely to cause problems if presented to another
    551  * computer ({@link Double#parseDouble} can't parse such a number, for example).
    552  * You should also be wary of the {@link String#toLowerCase} and
    553  * {@link String#toUpperCase} overloads that don't take a {@code Locale}: in Turkey, for example,
    554  * the characters {@code 'i'} and {@code 'I'} won't be converted to {@code 'I'} and {@code 'i'}.
    555  * This is the correct behavior for Turkish text (such as user input), but inappropriate for, say,
    556  * HTTP headers.
    557  *
    558  * @see Builder
    559  * @see ResourceBundle
    560  * @see java.text.Format
    561  * @see java.text.NumberFormat
    562  * @see java.text.Collator
    563  * @author Mark Davis
    564  * @since 1.1
    565  */
    566 public final class Locale implements Cloneable, Serializable {
    567 
    568     static private final  Cache LOCALECACHE = new Cache();
    569 
    570     /** Useful constant for language.
    571      */
    572     static public final Locale ENGLISH = createConstant("en", "");
    573 
    574     /** Useful constant for language.
    575      */
    576     static public final Locale FRENCH = createConstant("fr", "");
    577 
    578     /** Useful constant for language.
    579      */
    580     static public final Locale GERMAN = createConstant("de", "");
    581 
    582     /** Useful constant for language.
    583      */
    584     static public final Locale ITALIAN = createConstant("it", "");
    585 
    586     /** Useful constant for language.
    587      */
    588     static public final Locale JAPANESE = createConstant("ja", "");
    589 
    590     /** Useful constant for language.
    591      */
    592     static public final Locale KOREAN = createConstant("ko", "");
    593 
    594     /** Useful constant for language.
    595      */
    596     static public final Locale CHINESE = createConstant("zh", "");
    597 
    598     /** Useful constant for language.
    599      */
    600     static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
    601 
    602     /** Useful constant for language.
    603      */
    604     static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
    605 
    606     /** Useful constant for country.
    607      */
    608     static public final Locale FRANCE = createConstant("fr", "FR");
    609 
    610     /** Useful constant for country.
    611      */
    612     static public final Locale GERMANY = createConstant("de", "DE");
    613 
    614     /** Useful constant for country.
    615      */
    616     static public final Locale ITALY = createConstant("it", "IT");
    617 
    618     /** Useful constant for country.
    619      */
    620     static public final Locale JAPAN = createConstant("ja", "JP");
    621 
    622     /** Useful constant for country.
    623      */
    624     static public final Locale KOREA = createConstant("ko", "KR");
    625 
    626     /** Useful constant for country.
    627      */
    628     static public final Locale CHINA = SIMPLIFIED_CHINESE;
    629 
    630     /** Useful constant for country.
    631      */
    632     static public final Locale PRC = SIMPLIFIED_CHINESE;
    633 
    634     /** Useful constant for country.
    635      */
    636     static public final Locale TAIWAN = TRADITIONAL_CHINESE;
    637 
    638     /** Useful constant for country.
    639      */
    640     static public final Locale UK = createConstant("en", "GB");
    641 
    642     /** Useful constant for country.
    643      */
    644     static public final Locale US = createConstant("en", "US");
    645 
    646     /** Useful constant for country.
    647      */
    648     static public final Locale CANADA = createConstant("en", "CA");
    649 
    650     /** Useful constant for country.
    651      */
    652     static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
    653 
    654     // Android-added: (internal only): ISO 639-3 generic code for undetermined languages.
    655     private static final String UNDETERMINED_LANGUAGE = "und";
    656 
    657     /**
    658      * Useful constant for the root locale.  The root locale is the locale whose
    659      * language, country, and variant are empty ("") strings.  This is regarded
    660      * as the base locale of all locales, and is used as the language/country
    661      * neutral locale for the locale sensitive operations.
    662      *
    663      * @since 1.6
    664      */
    665     static public final Locale ROOT = createConstant("", "");
    666 
    667     /**
    668      * The key for the private use extension ('x').
    669      *
    670      * @see #getExtension(char)
    671      * @see Builder#setExtension(char, String)
    672      * @since 1.7
    673      */
    674     static public final char PRIVATE_USE_EXTENSION = 'x';
    675 
    676     /**
    677      * The key for Unicode locale extension ('u').
    678      *
    679      * @see #getExtension(char)
    680      * @see Builder#setExtension(char, String)
    681      * @since 1.7
    682      */
    683     static public final char UNICODE_LOCALE_EXTENSION = 'u';
    684 
    685     /** serialization ID
    686      */
    687     static final long serialVersionUID = 9149081749638150636L;
    688 
    689     /**
    690      * Display types for retrieving localized names from the name providers.
    691      */
    692     private static final int DISPLAY_LANGUAGE = 0;
    693     private static final int DISPLAY_COUNTRY  = 1;
    694     private static final int DISPLAY_VARIANT  = 2;
    695     private static final int DISPLAY_SCRIPT   = 3;
    696 
    697     /**
    698      * Private constructor used by getInstance method
    699      */
    700     private Locale(BaseLocale baseLocale, LocaleExtensions extensions) {
    701         this.baseLocale = baseLocale;
    702         this.localeExtensions = extensions;
    703     }
    704 
    705     /**
    706      * Construct a locale from language, country and variant.
    707      * This constructor normalizes the language value to lowercase and
    708      * the country value to uppercase.
    709      * <p>
    710      * <b>Note:</b>
    711      * <ul>
    712      * <li>ISO 639 is not a stable standard; some of the language codes it defines
    713      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
    714      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
    715      * API on Locale will return only the OLD codes.
    716      * <li>For backward compatibility reasons, this constructor does not make
    717      * any syntactic checks on the input.
    718      * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
    719      * see <a href="#special_cases_constructor">Special Cases</a> for more information.
    720      * </ul>
    721      *
    722      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
    723      * up to 8 characters in length.  See the <code>Locale</code> class description about
    724      * valid language values.
    725      * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
    726      * See the <code>Locale</code> class description about valid country values.
    727      * @param variant Any arbitrary value used to indicate a variation of a <code>Locale</code>.
    728      * See the <code>Locale</code> class description for the details.
    729      * @exception NullPointerException thrown if any argument is null.
    730      */
    731     public Locale(String language, String country, String variant) {
    732         if (language== null || country == null || variant == null) {
    733             throw new NullPointerException();
    734         }
    735         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
    736         localeExtensions = getCompatibilityExtensions(language, "", country, variant);
    737     }
    738 
    739     /**
    740      * Construct a locale from language and country.
    741      * This constructor normalizes the language value to lowercase and
    742      * the country value to uppercase.
    743      * <p>
    744      * <b>Note:</b>
    745      * <ul>
    746      * <li>ISO 639 is not a stable standard; some of the language codes it defines
    747      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
    748      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
    749      * API on Locale will return only the OLD codes.
    750      * <li>For backward compatibility reasons, this constructor does not make
    751      * any syntactic checks on the input.
    752      * </ul>
    753      *
    754      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
    755      * up to 8 characters in length.  See the <code>Locale</code> class description about
    756      * valid language values.
    757      * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
    758      * See the <code>Locale</code> class description about valid country values.
    759      * @exception NullPointerException thrown if either argument is null.
    760      */
    761     public Locale(String language, String country) {
    762         this(language, country, "");
    763     }
    764 
    765     /**
    766      * Construct a locale from a language code.
    767      * This constructor normalizes the language value to lowercase.
    768      * <p>
    769      * <b>Note:</b>
    770      * <ul>
    771      * <li>ISO 639 is not a stable standard; some of the language codes it defines
    772      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
    773      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
    774      * API on Locale will return only the OLD codes.
    775      * <li>For backward compatibility reasons, this constructor does not make
    776      * any syntactic checks on the input.
    777      * </ul>
    778      *
    779      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
    780      * up to 8 characters in length.  See the <code>Locale</code> class description about
    781      * valid language values.
    782      * @exception NullPointerException thrown if argument is null.
    783      * @since 1.4
    784      */
    785     public Locale(String language) {
    786         this(language, "", "");
    787     }
    788 
    789     /**
    790      * This method must be called only for creating the Locale.*
    791      * constants due to making shortcuts.
    792      */
    793     private static Locale createConstant(String lang, String country) {
    794         BaseLocale base = BaseLocale.createInstance(lang, country);
    795         return getInstance(base, null);
    796     }
    797 
    798     /**
    799      * Returns a <code>Locale</code> constructed from the given
    800      * <code>language</code>, <code>country</code> and
    801      * <code>variant</code>. If the same <code>Locale</code> instance
    802      * is available in the cache, then that instance is
    803      * returned. Otherwise, a new <code>Locale</code> instance is
    804      * created and cached.
    805      *
    806      * @param language lowercase 2 to 8 language code.
    807      * @param country uppercase two-letter ISO-3166 code and numric-3 UN M.49 area code.
    808      * @param variant vendor and browser specific code. See class description.
    809      * @return the <code>Locale</code> instance requested
    810      * @exception NullPointerException if any argument is null.
    811      */
    812     static Locale getInstance(String language, String country, String variant) {
    813         return getInstance(language, "", country, variant, null);
    814     }
    815 
    816     static Locale getInstance(String language, String script, String country,
    817                                       String variant, LocaleExtensions extensions) {
    818         if (language== null || script == null || country == null || variant == null) {
    819             throw new NullPointerException();
    820         }
    821 
    822         if (extensions == null) {
    823             extensions = getCompatibilityExtensions(language, script, country, variant);
    824         }
    825 
    826         BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
    827         return getInstance(baseloc, extensions);
    828     }
    829 
    830     static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
    831         LocaleKey key = new LocaleKey(baseloc, extensions);
    832         return LOCALECACHE.get(key);
    833     }
    834 
    835     private static class Cache extends LocaleObjectCache<LocaleKey, Locale> {
    836         private Cache() {
    837         }
    838 
    839         @Override
    840         protected Locale createObject(LocaleKey key) {
    841             return new Locale(key.base, key.exts);
    842         }
    843     }
    844 
    845     private static final class LocaleKey {
    846         private final BaseLocale base;
    847         private final LocaleExtensions exts;
    848         private final int hash;
    849 
    850         private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {
    851             base = baseLocale;
    852             exts = extensions;
    853 
    854             // Calculate the hash value here because it's always used.
    855             int h = base.hashCode();
    856             if (exts != null) {
    857                 h ^= exts.hashCode();
    858             }
    859             hash = h;
    860         }
    861 
    862         @Override
    863         public boolean equals(Object obj) {
    864             if (this == obj) {
    865                 return true;
    866             }
    867             if (!(obj instanceof LocaleKey)) {
    868                 return false;
    869             }
    870             LocaleKey other = (LocaleKey)obj;
    871             if (hash != other.hash || !base.equals(other.base)) {
    872                 return false;
    873             }
    874             if (exts == null) {
    875                 return other.exts == null;
    876             }
    877             return exts.equals(other.exts);
    878         }
    879 
    880         @Override
    881         public int hashCode() {
    882             return hash;
    883         }
    884     }
    885 
    886     /**
    887      * Gets the current value of the default locale for this instance
    888      * of the Java Virtual Machine.
    889      * <p>
    890      * The Java Virtual Machine sets the default locale during startup
    891      * based on the host environment. It is used by many locale-sensitive
    892      * methods if no locale is explicitly specified.
    893      * It can be changed using the
    894      * {@link #setDefault(java.util.Locale) setDefault} method.
    895      *
    896      * @return the default locale for this instance of the Java Virtual Machine
    897      */
    898     public static Locale getDefault() {
    899         // do not synchronize this method - see 4071298
    900         // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
    901         // return defaultLocale;
    902         return NoImagePreloadHolder.defaultLocale;
    903     }
    904 
    905     /**
    906      * Gets the current value of the default locale for the specified Category
    907      * for this instance of the Java Virtual Machine.
    908      * <p>
    909      * The Java Virtual Machine sets the default locale during startup based
    910      * on the host environment. It is used by many locale-sensitive methods
    911      * if no locale is explicitly specified. It can be changed using the
    912      * setDefault(Locale.Category, Locale) method.
    913      *
    914      * @param category - the specified category to get the default locale
    915      * @throws NullPointerException - if category is null
    916      * @return the default locale for the specified Category for this instance
    917      *     of the Java Virtual Machine
    918      * @see #setDefault(Locale.Category, Locale)
    919      * @since 1.7
    920      */
    921     public static Locale getDefault(Locale.Category category) {
    922         // do not synchronize this method - see 4071298
    923         switch (category) {
    924         case DISPLAY:
    925             if (defaultDisplayLocale == null) {
    926                 synchronized(Locale.class) {
    927                     if (defaultDisplayLocale == null) {
    928                         defaultDisplayLocale = initDefault(category);
    929                     }
    930                 }
    931             }
    932             return defaultDisplayLocale;
    933         case FORMAT:
    934             if (defaultFormatLocale == null) {
    935                 synchronized(Locale.class) {
    936                     if (defaultFormatLocale == null) {
    937                         defaultFormatLocale = initDefault(category);
    938                     }
    939                 }
    940             }
    941             return defaultFormatLocale;
    942         default:
    943             assert false: "Unknown Category";
    944         }
    945         return getDefault();
    946     }
    947 
    948     // BEGIN Android-changed: initDefault changes
    949     //  1.) In initDefault(), user.locale gets priority
    950     //  2.) In both initDefault methods, use System.getProperty() instead
    951     //      of legacy AccessController / GetPropertyAction security code.
    952     /**
    953      * @hide visible for testing.
    954      */
    955     public static Locale initDefault() {
    956         // user.locale gets priority
    957         final String languageTag = System.getProperty("user.locale", "");
    958         if (!languageTag.isEmpty()) {
    959             return Locale.forLanguageTag(languageTag);
    960         }
    961 
    962         // user.locale is empty
    963         String language, region, script, country, variant;
    964         language = System.getProperty("user.language", "en");
    965         // for compatibility, check for old user.region property
    966         region = System.getProperty("user.region");
    967         if (region != null) {
    968             // region can be of form country, country_variant, or _variant
    969             int i = region.indexOf('_');
    970             if (i >= 0) {
    971                 country = region.substring(0, i);
    972                 variant = region.substring(i + 1);
    973             } else {
    974                 country = region;
    975                 variant = "";
    976             }
    977             script = "";
    978         } else {
    979             script = System.getProperty("user.script", "");
    980             country = System.getProperty("user.country", "");
    981             variant = System.getProperty("user.variant", "");
    982         }
    983 
    984         return getInstance(language, script, country, variant, null);
    985     }
    986 
    987     private static Locale initDefault(Locale.Category category) {
    988         // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
    989         final Locale defaultLocale = NoImagePreloadHolder.defaultLocale;
    990         return getInstance(
    991             System.getProperty(category.languageKey, defaultLocale.getLanguage()),
    992             System.getProperty(category.scriptKey, defaultLocale.getScript()),
    993             System.getProperty(category.countryKey, defaultLocale.getCountry()),
    994             System.getProperty(category.variantKey, defaultLocale.getVariant()),
    995             null);
    996     }
    997     // END Android-changed: initDefault changes
    998 
    999     /**
   1000      * Sets the default locale for this instance of the Java Virtual Machine.
   1001      * This does not affect the host locale.
   1002      * <p>
   1003      * If there is a security manager, its <code>checkPermission</code>
   1004      * method is called with a <code>PropertyPermission("user.language", "write")</code>
   1005      * permission before the default locale is changed.
   1006      * <p>
   1007      * The Java Virtual Machine sets the default locale during startup
   1008      * based on the host environment. It is used by many locale-sensitive
   1009      * methods if no locale is explicitly specified.
   1010      * <p>
   1011      * Since changing the default locale may affect many different areas
   1012      * of functionality, this method should only be used if the caller
   1013      * is prepared to reinitialize locale-sensitive code running
   1014      * within the same Java Virtual Machine.
   1015      * <p>
   1016      * By setting the default locale with this method, all of the default
   1017      * locales for each Category are also set to the specified default locale.
   1018      *
   1019      * @throws SecurityException
   1020      *        if a security manager exists and its
   1021      *        <code>checkPermission</code> method doesn't allow the operation.
   1022      * @throws NullPointerException if <code>newLocale</code> is null
   1023      * @param newLocale the new default locale
   1024      * @see SecurityManager#checkPermission
   1025      * @see java.util.PropertyPermission
   1026      */
   1027     public static synchronized void setDefault(Locale newLocale) {
   1028         setDefault(Category.DISPLAY, newLocale);
   1029         setDefault(Category.FORMAT, newLocale);
   1030         // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
   1031         // defaultLocale = newLocale;
   1032         NoImagePreloadHolder.defaultLocale = newLocale;
   1033         // Android-added: Keep ICU state in sync with java.util.
   1034         ICU.setDefaultLocale(newLocale.toLanguageTag());
   1035     }
   1036 
   1037     /**
   1038      * Sets the default locale for the specified Category for this instance
   1039      * of the Java Virtual Machine. This does not affect the host locale.
   1040      * <p>
   1041      * If there is a security manager, its checkPermission method is called
   1042      * with a PropertyPermission("user.language", "write") permission before
   1043      * the default locale is changed.
   1044      * <p>
   1045      * The Java Virtual Machine sets the default locale during startup based
   1046      * on the host environment. It is used by many locale-sensitive methods
   1047      * if no locale is explicitly specified.
   1048      * <p>
   1049      * Since changing the default locale may affect many different areas of
   1050      * functionality, this method should only be used if the caller is
   1051      * prepared to reinitialize locale-sensitive code running within the
   1052      * same Java Virtual Machine.
   1053      * <p>
   1054      *
   1055      * @param category - the specified category to set the default locale
   1056      * @param newLocale - the new default locale
   1057      * @throws SecurityException - if a security manager exists and its
   1058      *     checkPermission method doesn't allow the operation.
   1059      * @throws NullPointerException - if category and/or newLocale is null
   1060      * @see SecurityManager#checkPermission(java.security.Permission)
   1061      * @see PropertyPermission
   1062      * @see #getDefault(Locale.Category)
   1063      * @since 1.7
   1064      */
   1065     public static synchronized void setDefault(Locale.Category category,
   1066         Locale newLocale) {
   1067         if (category == null)
   1068             throw new NullPointerException("Category cannot be NULL");
   1069         if (newLocale == null)
   1070             throw new NullPointerException("Can't set default locale to NULL");
   1071 
   1072         SecurityManager sm = System.getSecurityManager();
   1073         if (sm != null) sm.checkPermission(new PropertyPermission
   1074                         ("user.language", "write"));
   1075         switch (category) {
   1076         case DISPLAY:
   1077             defaultDisplayLocale = newLocale;
   1078             break;
   1079         case FORMAT:
   1080             defaultFormatLocale = newLocale;
   1081             break;
   1082         default:
   1083             assert false: "Unknown Category";
   1084         }
   1085     }
   1086 
   1087     // Android-changed: Removed documentation references to LocaleServiceProvider.
   1088     /**
   1089      * Returns an array of all installed locales.
   1090      *
   1091      * @return An array of installed locales.
   1092      */
   1093     public static Locale[] getAvailableLocales() {
   1094         // Android-changed: Switched to use ICU.
   1095         // return LocaleServiceProviderPool.getAllAvailableLocales();
   1096         return ICU.getAvailableLocales();
   1097     }
   1098 
   1099     /**
   1100      * Returns a list of all 2-letter country codes defined in ISO 3166.
   1101      * Can be used to create Locales.
   1102      * <p>
   1103      * <b>Note:</b> The <code>Locale</code> class also supports other codes for
   1104      * country (region), such as 3-letter numeric UN M.49 area codes.
   1105      * Therefore, the list returned by this method does not contain ALL valid
   1106      * codes that can be used to create Locales.
   1107      *
   1108      * @return An array of ISO 3166 two-letter country codes.
   1109      */
   1110     public static String[] getISOCountries() {
   1111         // Android-changed: Switched to use ICU.
   1112         return ICU.getISOCountries();
   1113     }
   1114 
   1115     /**
   1116      * Returns a list of all 2-letter language codes defined in ISO 639.
   1117      * Can be used to create Locales.
   1118      * <p>
   1119      * <b>Note:</b>
   1120      * <ul>
   1121      * <li>ISO 639 is not a stable standard&mdash; some languages' codes have changed.
   1122      * The list this function returns includes both the new and the old codes for the
   1123      * languages whose codes have changed.
   1124      * <li>The <code>Locale</code> class also supports language codes up to
   1125      * 8 characters in length.  Therefore, the list returned by this method does
   1126      * not contain ALL valid codes that can be used to create Locales.
   1127      * </ul>
   1128      *
   1129      * @return Am array of ISO 639 two-letter language codes.
   1130      */
   1131     public static String[] getISOLanguages() {
   1132         // Android-changed: Switched to use ICU.
   1133         return ICU.getISOLanguages();
   1134     }
   1135 
   1136     /**
   1137      * Returns the language code of this Locale.
   1138      *
   1139      * <p><b>Note:</b> ISO 639 is not a stable standard&mdash; some languages' codes have changed.
   1140      * Locale's constructor recognizes both the new and the old codes for the languages
   1141      * whose codes have changed, but this function always returns the old code.  If you
   1142      * want to check for a specific language whose code has changed, don't do
   1143      * <pre>
   1144      * if (locale.getLanguage().equals("he")) // BAD!
   1145      *    ...
   1146      * </pre>
   1147      * Instead, do
   1148      * <pre>
   1149      * if (locale.getLanguage().equals(new Locale("he").getLanguage()))
   1150      *    ...
   1151      * </pre>
   1152      * @return The language code, or the empty string if none is defined.
   1153      * @see #getDisplayLanguage
   1154      */
   1155     public String getLanguage() {
   1156         return baseLocale.getLanguage();
   1157     }
   1158 
   1159     /**
   1160      * Returns the script for this locale, which should
   1161      * either be the empty string or an ISO 15924 4-letter script
   1162      * code. The first letter is uppercase and the rest are
   1163      * lowercase, for example, 'Latn', 'Cyrl'.
   1164      *
   1165      * @return The script code, or the empty string if none is defined.
   1166      * @see #getDisplayScript
   1167      * @since 1.7
   1168      */
   1169     public String getScript() {
   1170         return baseLocale.getScript();
   1171     }
   1172 
   1173     /**
   1174      * Returns the country/region code for this locale, which should
   1175      * either be the empty string, an uppercase ISO 3166 2-letter code,
   1176      * or a UN M.49 3-digit code.
   1177      *
   1178      * @return The country/region code, or the empty string if none is defined.
   1179      * @see #getDisplayCountry
   1180      */
   1181     public String getCountry() {
   1182         return baseLocale.getRegion();
   1183     }
   1184 
   1185     /**
   1186      * Returns the variant code for this locale.
   1187      *
   1188      * @return The variant code, or the empty string if none is defined.
   1189      * @see #getDisplayVariant
   1190      */
   1191     public String getVariant() {
   1192         return baseLocale.getVariant();
   1193     }
   1194 
   1195     /**
   1196      * Returns {@code true} if this {@code Locale} has any <a href="#def_extensions">
   1197      * extensions</a>.
   1198      *
   1199      * @return {@code true} if this {@code Locale} has any extensions
   1200      * @since 1.8
   1201      */
   1202     public boolean hasExtensions() {
   1203         return localeExtensions != null;
   1204     }
   1205 
   1206     /**
   1207      * Returns a copy of this {@code Locale} with no <a href="#def_extensions">
   1208      * extensions</a>. If this {@code Locale} has no extensions, this {@code Locale}
   1209      * is returned.
   1210      *
   1211      * @return a copy of this {@code Locale} with no extensions, or {@code this}
   1212      *         if {@code this} has no extensions
   1213      * @since 1.8
   1214      */
   1215     public Locale stripExtensions() {
   1216         return hasExtensions() ? Locale.getInstance(baseLocale, null) : this;
   1217     }
   1218 
   1219     /**
   1220      * Returns the extension (or private use) value associated with
   1221      * the specified key, or null if there is no extension
   1222      * associated with the key. To be well-formed, the key must be one
   1223      * of <code>[0-9A-Za-z]</code>. Keys are case-insensitive, so
   1224      * for example 'z' and 'Z' represent the same extension.
   1225      *
   1226      * @param key the extension key
   1227      * @return The extension, or null if this locale defines no
   1228      * extension for the specified key.
   1229      * @throws IllegalArgumentException if key is not well-formed
   1230      * @see #PRIVATE_USE_EXTENSION
   1231      * @see #UNICODE_LOCALE_EXTENSION
   1232      * @since 1.7
   1233      */
   1234     public String getExtension(char key) {
   1235         if (!LocaleExtensions.isValidKey(key)) {
   1236             throw new IllegalArgumentException("Ill-formed extension key: " + key);
   1237         }
   1238         return hasExtensions() ? localeExtensions.getExtensionValue(key) : null;
   1239     }
   1240 
   1241     /**
   1242      * Returns the set of extension keys associated with this locale, or the
   1243      * empty set if it has no extensions. The returned set is unmodifiable.
   1244      * The keys will all be lower-case.
   1245      *
   1246      * @return The set of extension keys, or the empty set if this locale has
   1247      * no extensions.
   1248      * @since 1.7
   1249      */
   1250     public Set<Character> getExtensionKeys() {
   1251         if (!hasExtensions()) {
   1252             return Collections.emptySet();
   1253         }
   1254         return localeExtensions.getKeys();
   1255     }
   1256 
   1257     /**
   1258      * Returns the set of unicode locale attributes associated with
   1259      * this locale, or the empty set if it has no attributes. The
   1260      * returned set is unmodifiable.
   1261      *
   1262      * @return The set of attributes.
   1263      * @since 1.7
   1264      */
   1265     public Set<String> getUnicodeLocaleAttributes() {
   1266         if (!hasExtensions()) {
   1267             return Collections.emptySet();
   1268         }
   1269         return localeExtensions.getUnicodeLocaleAttributes();
   1270     }
   1271 
   1272     /**
   1273      * Returns the Unicode locale type associated with the specified Unicode locale key
   1274      * for this locale. Returns the empty string for keys that are defined with no type.
   1275      * Returns null if the key is not defined. Keys are case-insensitive. The key must
   1276      * be two alphanumeric characters ([0-9a-zA-Z]), or an IllegalArgumentException is
   1277      * thrown.
   1278      *
   1279      * @param key the Unicode locale key
   1280      * @return The Unicode locale type associated with the key, or null if the
   1281      * locale does not define the key.
   1282      * @throws IllegalArgumentException if the key is not well-formed
   1283      * @throws NullPointerException if <code>key</code> is null
   1284      * @since 1.7
   1285      */
   1286     public String getUnicodeLocaleType(String key) {
   1287         if (!isUnicodeExtensionKey(key)) {
   1288             throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key);
   1289         }
   1290         return hasExtensions() ? localeExtensions.getUnicodeLocaleType(key) : null;
   1291     }
   1292 
   1293     /**
   1294      * Returns the set of Unicode locale keys defined by this locale, or the empty set if
   1295      * this locale has none.  The returned set is immutable.  Keys are all lower case.
   1296      *
   1297      * @return The set of Unicode locale keys, or the empty set if this locale has
   1298      * no Unicode locale keywords.
   1299      * @since 1.7
   1300      */
   1301     public Set<String> getUnicodeLocaleKeys() {
   1302         if (localeExtensions == null) {
   1303             return Collections.emptySet();
   1304         }
   1305         return localeExtensions.getUnicodeLocaleKeys();
   1306     }
   1307 
   1308     /**
   1309      * Package locale method returning the Locale's BaseLocale,
   1310      * used by ResourceBundle
   1311      * @return base locale of this Locale
   1312      */
   1313     BaseLocale getBaseLocale() {
   1314         return baseLocale;
   1315     }
   1316 
   1317     /**
   1318      * Package private method returning the Locale's LocaleExtensions,
   1319      * used by ResourceBundle.
   1320      * @return locale exnteions of this Locale,
   1321      *         or {@code null} if no extensions are defined
   1322      */
   1323      LocaleExtensions getLocaleExtensions() {
   1324          return localeExtensions;
   1325      }
   1326 
   1327     /**
   1328      * Returns a string representation of this <code>Locale</code>
   1329      * object, consisting of language, country, variant, script,
   1330      * and extensions as below:
   1331      * <blockquote>
   1332      * language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
   1333      * </blockquote>
   1334      *
   1335      * Language is always lower case, country is always upper case, script is always title
   1336      * case, and extensions are always lower case.  Extensions and private use subtags
   1337      * will be in canonical order as explained in {@link #toLanguageTag}.
   1338      *
   1339      * <p>When the locale has neither script nor extensions, the result is the same as in
   1340      * Java 6 and prior.
   1341      *
   1342      * <p>If both the language and country fields are missing, this function will return
   1343      * the empty string, even if the variant, script, or extensions field is present (you
   1344      * can't have a locale with just a variant, the variant must accompany a well-formed
   1345      * language or country code).
   1346      *
   1347      * <p>If script or extensions are present and variant is missing, no underscore is
   1348      * added before the "#".
   1349      *
   1350      * <p>This behavior is designed to support debugging and to be compatible with
   1351      * previous uses of <code>toString</code> that expected language, country, and variant
   1352      * fields only.  To represent a Locale as a String for interchange purposes, use
   1353      * {@link #toLanguageTag}.
   1354      *
   1355      * <p>Examples: <ul>
   1356      * <li><tt>en</tt></li>
   1357      * <li><tt>de_DE</tt></li>
   1358      * <li><tt>_GB</tt></li>
   1359      * <li><tt>en_US_WIN</tt></li>
   1360      * <li><tt>de__POSIX</tt></li>
   1361      * <li><tt>zh_CN_#Hans</tt></li>
   1362      * <li><tt>zh_TW_#Hant-x-java</tt></li>
   1363      * <li><tt>th_TH_TH_#u-nu-thai</tt></li></ul>
   1364      *
   1365      * @return A string representation of the Locale, for debugging.
   1366      * @see #getDisplayName
   1367      * @see #toLanguageTag
   1368      */
   1369     @Override
   1370     public final String toString() {
   1371         boolean l = (baseLocale.getLanguage().length() != 0);
   1372         boolean s = (baseLocale.getScript().length() != 0);
   1373         boolean r = (baseLocale.getRegion().length() != 0);
   1374         boolean v = (baseLocale.getVariant().length() != 0);
   1375         boolean e = (localeExtensions != null && localeExtensions.getID().length() != 0);
   1376 
   1377         StringBuilder result = new StringBuilder(baseLocale.getLanguage());
   1378         if (r || (l && (v || s || e))) {
   1379             result.append('_')
   1380                 .append(baseLocale.getRegion()); // This may just append '_'
   1381         }
   1382         if (v && (l || r)) {
   1383             result.append('_')
   1384                 .append(baseLocale.getVariant());
   1385         }
   1386 
   1387         if (s && (l || r)) {
   1388             result.append("_#")
   1389                 .append(baseLocale.getScript());
   1390         }
   1391 
   1392         if (e && (l || r)) {
   1393             result.append('_');
   1394             if (!s) {
   1395                 result.append('#');
   1396             }
   1397             result.append(localeExtensions.getID());
   1398         }
   1399 
   1400         return result.toString();
   1401     }
   1402 
   1403     /**
   1404      * Returns a well-formed IETF BCP 47 language tag representing
   1405      * this locale.
   1406      *
   1407      * <p>If this <code>Locale</code> has a language, country, or
   1408      * variant that does not satisfy the IETF BCP 47 language tag
   1409      * syntax requirements, this method handles these fields as
   1410      * described below:
   1411      *
   1412      * <p><b>Language:</b> If language is empty, or not <a
   1413      * href="#def_language" >well-formed</a> (for example "a" or
   1414      * "e2"), it will be emitted as "und" (Undetermined).
   1415      *
   1416      * <p><b>Country:</b> If country is not <a
   1417      * href="#def_region">well-formed</a> (for example "12" or "USA"),
   1418      * it will be omitted.
   1419      *
   1420      * <p><b>Variant:</b> If variant <b>is</b> <a
   1421      * href="#def_variant">well-formed</a>, each sub-segment
   1422      * (delimited by '-' or '_') is emitted as a subtag.  Otherwise:
   1423      * <ul>
   1424      *
   1425      * <li>if all sub-segments match <code>[0-9a-zA-Z]{1,8}</code>
   1426      * (for example "WIN" or "Oracle_JDK_Standard_Edition"), the first
   1427      * ill-formed sub-segment and all following will be appended to
   1428      * the private use subtag.  The first appended subtag will be
   1429      * "lvariant", followed by the sub-segments in order, separated by
   1430      * hyphen. For example, "x-lvariant-WIN",
   1431      * "Oracle-x-lvariant-JDK-Standard-Edition".
   1432      *
   1433      * <li>if any sub-segment does not match
   1434      * <code>[0-9a-zA-Z]{1,8}</code>, the variant will be truncated
   1435      * and the problematic sub-segment and all following sub-segments
   1436      * will be omitted.  If the remainder is non-empty, it will be
   1437      * emitted as a private use subtag as above (even if the remainder
   1438      * turns out to be well-formed).  For example,
   1439      * "Solaris_isjustthecoolestthing" is emitted as
   1440      * "x-lvariant-Solaris", not as "solaris".</li></ul>
   1441      *
   1442      * <p><b>Special Conversions:</b> Java supports some old locale
   1443      * representations, including deprecated ISO language codes,
   1444      * for compatibility. This method performs the following
   1445      * conversions:
   1446      * <ul>
   1447      *
   1448      * <li>Deprecated ISO language codes "iw", "ji", and "in" are
   1449      * converted to "he", "yi", and "id", respectively.
   1450      *
   1451      * <li>A locale with language "no", country "NO", and variant
   1452      * "NY", representing Norwegian Nynorsk (Norway), is converted
   1453      * to a language tag "nn-NO".</li></ul>
   1454      *
   1455      * <p><b>Note:</b> Although the language tag created by this
   1456      * method is well-formed (satisfies the syntax requirements
   1457      * defined by the IETF BCP 47 specification), it is not
   1458      * necessarily a valid BCP 47 language tag.  For example,
   1459      * <pre>
   1460      *   new Locale("xx", "YY").toLanguageTag();</pre>
   1461      *
   1462      * will return "xx-YY", but the language subtag "xx" and the
   1463      * region subtag "YY" are invalid because they are not registered
   1464      * in the IANA Language Subtag Registry.
   1465      *
   1466      * @return a BCP47 language tag representing the locale
   1467      * @see #forLanguageTag(String)
   1468      * @since 1.7
   1469      */
   1470     public String toLanguageTag() {
   1471         if (languageTag != null) {
   1472             return languageTag;
   1473         }
   1474 
   1475         LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
   1476         StringBuilder buf = new StringBuilder();
   1477 
   1478         String subtag = tag.getLanguage();
   1479         if (subtag.length() > 0) {
   1480             buf.append(LanguageTag.canonicalizeLanguage(subtag));
   1481         }
   1482 
   1483         subtag = tag.getScript();
   1484         if (subtag.length() > 0) {
   1485             buf.append(LanguageTag.SEP);
   1486             buf.append(LanguageTag.canonicalizeScript(subtag));
   1487         }
   1488 
   1489         subtag = tag.getRegion();
   1490         if (subtag.length() > 0) {
   1491             buf.append(LanguageTag.SEP);
   1492             buf.append(LanguageTag.canonicalizeRegion(subtag));
   1493         }
   1494 
   1495         List<String>subtags = tag.getVariants();
   1496         for (String s : subtags) {
   1497             buf.append(LanguageTag.SEP);
   1498             // preserve casing
   1499             buf.append(s);
   1500         }
   1501 
   1502         subtags = tag.getExtensions();
   1503         for (String s : subtags) {
   1504             buf.append(LanguageTag.SEP);
   1505             buf.append(LanguageTag.canonicalizeExtension(s));
   1506         }
   1507 
   1508         subtag = tag.getPrivateuse();
   1509         if (subtag.length() > 0) {
   1510             if (buf.length() > 0) {
   1511                 buf.append(LanguageTag.SEP);
   1512             }
   1513             buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
   1514             // preserve casing
   1515             buf.append(subtag);
   1516         }
   1517 
   1518         String langTag = buf.toString();
   1519         synchronized (this) {
   1520             if (languageTag == null) {
   1521                 languageTag = langTag;
   1522             }
   1523         }
   1524         return languageTag;
   1525     }
   1526 
   1527     /**
   1528      * Returns a locale for the specified IETF BCP 47 language tag string.
   1529      *
   1530      * <p>If the specified language tag contains any ill-formed subtags,
   1531      * the first such subtag and all following subtags are ignored.  Compare
   1532      * to {@link Locale.Builder#setLanguageTag} which throws an exception
   1533      * in this case.
   1534      *
   1535      * <p>The following <b>conversions</b> are performed:<ul>
   1536      *
   1537      * <li>The language code "und" is mapped to language "".
   1538      *
   1539      * <li>The language codes "he", "yi", and "id" are mapped to "iw",
   1540      * "ji", and "in" respectively. (This is the same canonicalization
   1541      * that's done in Locale's constructors.)
   1542      *
   1543      * <li>The portion of a private use subtag prefixed by "lvariant",
   1544      * if any, is removed and appended to the variant field in the
   1545      * result locale (without case normalization).  If it is then
   1546      * empty, the private use subtag is discarded:
   1547      *
   1548      * <pre>
   1549      *     Locale loc;
   1550      *     loc = Locale.forLanguageTag("en-US-x-lvariant-POSIX");
   1551      *     loc.getVariant(); // returns "POSIX"
   1552      *     loc.getExtension('x'); // returns null
   1553      *
   1554      *     loc = Locale.forLanguageTag("de-POSIX-x-URP-lvariant-Abc-Def");
   1555      *     loc.getVariant(); // returns "POSIX_Abc_Def"
   1556      *     loc.getExtension('x'); // returns "urp"
   1557      * </pre>
   1558      *
   1559      * <li>When the languageTag argument contains an extlang subtag,
   1560      * the first such subtag is used as the language, and the primary
   1561      * language subtag and other extlang subtags are ignored:
   1562      *
   1563      * <pre>
   1564      *     Locale.forLanguageTag("ar-aao").getLanguage(); // returns "aao"
   1565      *     Locale.forLanguageTag("en-abc-def-us").toString(); // returns "abc_US"
   1566      * </pre>
   1567      *
   1568      * <li>Case is normalized except for variant tags, which are left
   1569      * unchanged.  Language is normalized to lower case, script to
   1570      * title case, country to upper case, and extensions to lower
   1571      * case.
   1572      *
   1573      * <li>If, after processing, the locale would exactly match either
   1574      * ja_JP_JP or th_TH_TH with no extensions, the appropriate
   1575      * extensions are added as though the constructor had been called:
   1576      *
   1577      * <pre>
   1578      *    Locale.forLanguageTag("ja-JP-x-lvariant-JP").toLanguageTag();
   1579      *    // returns "ja-JP-u-ca-japanese-x-lvariant-JP"
   1580      *    Locale.forLanguageTag("th-TH-x-lvariant-TH").toLanguageTag();
   1581      *    // returns "th-TH-u-nu-thai-x-lvariant-TH"
   1582      * </pre></ul>
   1583      *
   1584      * <p>This implements the 'Language-Tag' production of BCP47, and
   1585      * so supports grandfathered (regular and irregular) as well as
   1586      * private use language tags.  Stand alone private use tags are
   1587      * represented as empty language and extension 'x-whatever',
   1588      * and grandfathered tags are converted to their canonical replacements
   1589      * where they exist.
   1590      *
   1591      * <p>Grandfathered tags with canonical replacements are as follows:
   1592      *
   1593      * <table summary="Grandfathered tags with canonical replacements">
   1594      * <tbody align="center">
   1595      * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
   1596      * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
   1597      * <tr><td>i-ami</td><td>&nbsp;</td><td>ami</td></tr>
   1598      * <tr><td>i-bnn</td><td>&nbsp;</td><td>bnn</td></tr>
   1599      * <tr><td>i-hak</td><td>&nbsp;</td><td>hak</td></tr>
   1600      * <tr><td>i-klingon</td><td>&nbsp;</td><td>tlh</td></tr>
   1601      * <tr><td>i-lux</td><td>&nbsp;</td><td>lb</td></tr>
   1602      * <tr><td>i-navajo</td><td>&nbsp;</td><td>nv</td></tr>
   1603      * <tr><td>i-pwn</td><td>&nbsp;</td><td>pwn</td></tr>
   1604      * <tr><td>i-tao</td><td>&nbsp;</td><td>tao</td></tr>
   1605      * <tr><td>i-tay</td><td>&nbsp;</td><td>tay</td></tr>
   1606      * <tr><td>i-tsu</td><td>&nbsp;</td><td>tsu</td></tr>
   1607      * <tr><td>no-bok</td><td>&nbsp;</td><td>nb</td></tr>
   1608      * <tr><td>no-nyn</td><td>&nbsp;</td><td>nn</td></tr>
   1609      * <tr><td>sgn-BE-FR</td><td>&nbsp;</td><td>sfb</td></tr>
   1610      * <tr><td>sgn-BE-NL</td><td>&nbsp;</td><td>vgt</td></tr>
   1611      * <tr><td>sgn-CH-DE</td><td>&nbsp;</td><td>sgg</td></tr>
   1612      * <tr><td>zh-guoyu</td><td>&nbsp;</td><td>cmn</td></tr>
   1613      * <tr><td>zh-hakka</td><td>&nbsp;</td><td>hak</td></tr>
   1614      * <tr><td>zh-min-nan</td><td>&nbsp;</td><td>nan</td></tr>
   1615      * <tr><td>zh-xiang</td><td>&nbsp;</td><td>hsn</td></tr>
   1616      * </tbody>
   1617      * </table>
   1618      *
   1619      * <p>Grandfathered tags with no modern replacement will be
   1620      * converted as follows:
   1621      *
   1622      * <table summary="Grandfathered tags with no modern replacement">
   1623      * <tbody align="center">
   1624      * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
   1625      * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
   1626      * <tr><td>en-GB-oed</td><td>&nbsp;</td><td>en-GB-x-oed</td></tr>
   1627      * <tr><td>i-default</td><td>&nbsp;</td><td>en-x-i-default</td></tr>
   1628      * <tr><td>i-enochian</td><td>&nbsp;</td><td>und-x-i-enochian</td></tr>
   1629      * <tr><td>i-mingo</td><td>&nbsp;</td><td>see-x-i-mingo</td></tr>
   1630      * <tr><td>zh-min</td><td>&nbsp;</td><td>nan-x-zh-min</td></tr>
   1631      * </tbody>
   1632      * </table>
   1633      *
   1634      * <p>For a list of all grandfathered tags, see the
   1635      * IANA Language Subtag Registry (search for "Type: grandfathered").
   1636      *
   1637      * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code>
   1638      * and <code>forLanguageTag</code> will round-trip.
   1639      *
   1640      * @param languageTag the language tag
   1641      * @return The locale that best represents the language tag.
   1642      * @throws NullPointerException if <code>languageTag</code> is <code>null</code>
   1643      * @see #toLanguageTag()
   1644      * @see java.util.Locale.Builder#setLanguageTag(String)
   1645      * @since 1.7
   1646      */
   1647     public static Locale forLanguageTag(String languageTag) {
   1648         LanguageTag tag = LanguageTag.parse(languageTag, null);
   1649         InternalLocaleBuilder bldr = new InternalLocaleBuilder();
   1650         bldr.setLanguageTag(tag);
   1651         BaseLocale base = bldr.getBaseLocale();
   1652         LocaleExtensions exts = bldr.getLocaleExtensions();
   1653         if (exts == null && base.getVariant().length() > 0) {
   1654             exts = getCompatibilityExtensions(base.getLanguage(), base.getScript(),
   1655                                               base.getRegion(), base.getVariant());
   1656         }
   1657         return getInstance(base, exts);
   1658     }
   1659 
   1660     /**
   1661      * Returns a three-letter abbreviation of this locale's language.
   1662      * If the language matches an ISO 639-1 two-letter code, the
   1663      * corresponding ISO 639-2/T three-letter lowercase code is
   1664      * returned.  The ISO 639-2 language codes can be found on-line,
   1665      * see "Codes for the Representation of Names of Languages Part 2:
   1666      * Alpha-3 Code".  If the locale specifies a three-letter
   1667      * language, the language is returned as is.  If the locale does
   1668      * not specify a language the empty string is returned.
   1669      *
   1670      * @return A three-letter abbreviation of this locale's language.
   1671      * @exception MissingResourceException Throws MissingResourceException if
   1672      * three-letter language abbreviation is not available for this locale.
   1673      */
   1674     public String getISO3Language() throws MissingResourceException {
   1675         String lang = baseLocale.getLanguage();
   1676         if (lang.length() == 3) {
   1677             return lang;
   1678         }
   1679         // BEGIN Android-added
   1680         // return "" for empty languages for the sake of backwards compatibility.
   1681         else if (lang.isEmpty()) {
   1682             return "";
   1683         }
   1684         // END Android-added
   1685 
   1686         // BEGIN Android-changed: Use ICU.
   1687         // String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
   1688         // if (language3 == null) {
   1689         String language3 = ICU.getISO3Language(lang);
   1690         if (!lang.isEmpty() && language3.isEmpty()) {
   1691         // END Android-changed
   1692             throw new MissingResourceException("Couldn't find 3-letter language code for "
   1693                     + lang, "FormatData_" + toString(), "ShortLanguage");
   1694         }
   1695         return language3;
   1696     }
   1697 
   1698     /**
   1699      * Returns a three-letter abbreviation for this locale's country.
   1700      * If the country matches an ISO 3166-1 alpha-2 code, the
   1701      * corresponding ISO 3166-1 alpha-3 uppercase code is returned.
   1702      * If the locale doesn't specify a country, this will be the empty
   1703      * string.
   1704      *
   1705      * <p>The ISO 3166-1 codes can be found on-line.
   1706      *
   1707      * @return A three-letter abbreviation of this locale's country.
   1708      * @exception MissingResourceException Throws MissingResourceException if the
   1709      * three-letter country abbreviation is not available for this locale.
   1710      */
   1711     public String getISO3Country() throws MissingResourceException {
   1712         // BEGIN Android-changed: Use ICU. Also return "" for missing regions.
   1713         final String region = baseLocale.getRegion();
   1714         // Note that this will return an UN.M49 region code
   1715         if (region.length() == 3) {
   1716             return baseLocale.getRegion();
   1717         } else if (region.isEmpty()) {
   1718             return "";
   1719         }
   1720 
   1721         // Prefix "en-" because ICU doesn't really care about what the language is.
   1722         String country3 = ICU.getISO3Country("en-" + region);
   1723         if (!region.isEmpty() && country3.isEmpty()) {
   1724             throw new MissingResourceException("Couldn't find 3-letter country code for "
   1725                     + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
   1726         }
   1727         // END Android-changed
   1728         return country3;
   1729     }
   1730 
   1731     /**
   1732      * Returns a name for the locale's language that is appropriate for display to the
   1733      * user.
   1734      * If possible, the name returned will be localized for the default
   1735      * {@link Locale.Category#DISPLAY DISPLAY} locale.
   1736      * For example, if the locale is fr_FR and the default
   1737      * {@link Locale.Category#DISPLAY DISPLAY} locale
   1738      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
   1739      * the default {@link Locale.Category#DISPLAY DISPLAY} locale is fr_FR,
   1740      * getDisplayLanguage() will return "anglais".
   1741      * If the name returned cannot be localized for the default
   1742      * {@link Locale.Category#DISPLAY DISPLAY} locale,
   1743      * (say, we don't have a Japanese name for Croatian),
   1744      * this function falls back on the English name, and uses the ISO code as a last-resort
   1745      * value.  If the locale doesn't specify a language, this function returns the empty string.
   1746      *
   1747      * @return The name of the display language.
   1748      */
   1749     public final String getDisplayLanguage() {
   1750         return getDisplayLanguage(getDefault(Category.DISPLAY));
   1751     }
   1752 
   1753     // BEGIN Android-changed: Use ICU; documentation; backwards compatibility hacks;
   1754     // added private helper methods.
   1755     /**
   1756      * Returns the name of this locale's language, localized to {@code locale}.
   1757      * If the language name is unknown, the language code is returned.
   1758      */
   1759     public String getDisplayLanguage(Locale locale) {
   1760         String languageCode = baseLocale.getLanguage();
   1761         if (languageCode.isEmpty()) {
   1762             return "";
   1763         }
   1764 
   1765         // Hacks for backward compatibility.
   1766         //
   1767         // Our language tag will contain "und" if the languageCode is invalid
   1768         // or missing. ICU will then return "langue indtermine" or the equivalent
   1769         // display language for the indeterminate language code.
   1770         //
   1771         // Sigh... ugh... and what not.
   1772         final String normalizedLanguage = normalizeAndValidateLanguage(
   1773                 languageCode, false /* strict */);
   1774         if (UNDETERMINED_LANGUAGE.equals(normalizedLanguage)) {
   1775             return languageCode;
   1776         }
   1777 
   1778         // TODO: We need a new hack or a complete fix for http://b/8049507 --- We would
   1779         // cover the frameworks' tracks when they were using "tl" instead of "fil".
   1780         String result = ICU.getDisplayLanguage(this, locale);
   1781         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1782             result = ICU.getDisplayLanguage(this, Locale.getDefault());
   1783         }
   1784         return result;
   1785     }
   1786 
   1787     private static String normalizeAndValidateLanguage(String language, boolean strict) {
   1788         if (language == null || language.isEmpty()) {
   1789             return "";
   1790         }
   1791 
   1792         final String lowercaseLanguage = language.toLowerCase(Locale.ROOT);
   1793         if (!isValidBcp47Alpha(lowercaseLanguage, 2, 3)) {
   1794             if (strict) {
   1795                 throw new IllformedLocaleException("Invalid language: " + language);
   1796             } else {
   1797                 return UNDETERMINED_LANGUAGE;
   1798             }
   1799         }
   1800 
   1801         return lowercaseLanguage;
   1802     }
   1803 
   1804     /*
   1805      * Checks whether a given string is an ASCII alphanumeric string.
   1806      */
   1807     private static boolean isAsciiAlphaNum(String string) {
   1808         for (int i = 0; i < string.length(); i++) {
   1809             final char character = string.charAt(i);
   1810             if (!(character >= 'a' && character <= 'z' ||
   1811                     character >= 'A' && character <= 'Z' ||
   1812                     character >= '0' && character <= '9')) {
   1813                 return false;
   1814             }
   1815         }
   1816 
   1817         return true;
   1818     }
   1819     // END Android-changed
   1820 
   1821     /**
   1822      * Returns a name for the the locale's script that is appropriate for display to
   1823      * the user. If possible, the name will be localized for the default
   1824      * {@link Locale.Category#DISPLAY DISPLAY} locale.  Returns
   1825      * the empty string if this locale doesn't specify a script code.
   1826      *
   1827      * @return the display name of the script code for the current default
   1828      *     {@link Locale.Category#DISPLAY DISPLAY} locale
   1829      * @since 1.7
   1830      */
   1831     public String getDisplayScript() {
   1832         return getDisplayScript(getDefault(Category.DISPLAY));
   1833     }
   1834 
   1835     /**
   1836      * Returns a name for the locale's script that is appropriate
   1837      * for display to the user. If possible, the name will be
   1838      * localized for the given locale. Returns the empty string if
   1839      * this locale doesn't specify a script code.
   1840      *
   1841      * @param inLocale The locale for which to retrieve the display script.
   1842      * @return the display name of the script code for the current default
   1843      * {@link Locale.Category#DISPLAY DISPLAY} locale
   1844      * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
   1845      * @since 1.7
   1846      */
   1847     public String getDisplayScript(Locale inLocale) {
   1848         // BEGIN Android-changed: Use ICU.
   1849         String scriptCode = baseLocale.getScript();
   1850         if (scriptCode.isEmpty()) {
   1851             return "";
   1852         }
   1853 
   1854         String result = ICU.getDisplayScript(this, inLocale);
   1855         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1856             result = ICU.getDisplayScript(this, Locale.getDefault(Category.DISPLAY));
   1857         }
   1858 
   1859         return result;
   1860         // END Android-changed
   1861     }
   1862 
   1863     /**
   1864      * Returns a name for the locale's country that is appropriate for display to the
   1865      * user.
   1866      * If possible, the name returned will be localized for the default
   1867      * {@link Locale.Category#DISPLAY DISPLAY} locale.
   1868      * For example, if the locale is fr_FR and the default
   1869      * {@link Locale.Category#DISPLAY DISPLAY} locale
   1870      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
   1871      * the default {@link Locale.Category#DISPLAY DISPLAY} locale is fr_FR,
   1872      * getDisplayCountry() will return "Etats-Unis".
   1873      * If the name returned cannot be localized for the default
   1874      * {@link Locale.Category#DISPLAY DISPLAY} locale,
   1875      * (say, we don't have a Japanese name for Croatia),
   1876      * this function falls back on the English name, and uses the ISO code as a last-resort
   1877      * value.  If the locale doesn't specify a country, this function returns the empty string.
   1878      *
   1879      * @return The name of the country appropriate to the locale.
   1880      */
   1881     public final String getDisplayCountry() {
   1882         return getDisplayCountry(getDefault(Category.DISPLAY));
   1883     }
   1884 
   1885     // BEGIN Android-changed: Use ICU; documentation; added private helper methods.
   1886     /**
   1887      * Returns the name of this locale's country, localized to {@code locale}.
   1888      * Returns the empty string if this locale does not correspond to a specific
   1889      * country.
   1890      */
   1891     public String getDisplayCountry(Locale locale) {
   1892         String countryCode = baseLocale.getRegion();
   1893         if (countryCode.isEmpty()) {
   1894             return "";
   1895         }
   1896 
   1897         final String normalizedRegion = normalizeAndValidateRegion(
   1898                 countryCode, false /* strict */);
   1899         if (normalizedRegion.isEmpty()) {
   1900             return countryCode;
   1901         }
   1902 
   1903         String result = ICU.getDisplayCountry(this, locale);
   1904         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   1905             result = ICU.getDisplayCountry(this, Locale.getDefault());
   1906         }
   1907         return result;
   1908     }
   1909 
   1910     private static String normalizeAndValidateRegion(String region, boolean strict) {
   1911         if (region == null || region.isEmpty()) {
   1912             return "";
   1913         }
   1914 
   1915         final String uppercaseRegion = region.toUpperCase(Locale.ROOT);
   1916         if (!isValidBcp47Alpha(uppercaseRegion, 2, 2) &&
   1917                 !isUnM49AreaCode(uppercaseRegion)) {
   1918             if (strict) {
   1919                 throw new IllformedLocaleException("Invalid region: " + region);
   1920             } else {
   1921                 return "";
   1922             }
   1923         }
   1924 
   1925         return uppercaseRegion;
   1926     }
   1927 
   1928     private static boolean isValidBcp47Alpha(String string, int lowerBound, int upperBound) {
   1929         final int length = string.length();
   1930         if (length < lowerBound || length > upperBound) {
   1931             return false;
   1932         }
   1933 
   1934         for (int i = 0; i < length; ++i) {
   1935             final char character = string.charAt(i);
   1936             if (!(character >= 'a' && character <= 'z' ||
   1937                     character >= 'A' && character <= 'Z')) {
   1938                 return false;
   1939             }
   1940         }
   1941 
   1942         return true;
   1943     }
   1944 
   1945     /**
   1946      * A UN M.49 is a 3 digit numeric code.
   1947      */
   1948     private static boolean isUnM49AreaCode(String code) {
   1949         if (code.length() != 3) {
   1950             return false;
   1951         }
   1952 
   1953         for (int i = 0; i < 3; ++i) {
   1954             final char character = code.charAt(i);
   1955             if (!(character >= '0' && character <= '9')) {
   1956                 return false;
   1957             }
   1958         }
   1959 
   1960         return true;
   1961     }
   1962     // END Android-changed: Use ICU; documentation; added private helper methods.
   1963 
   1964     /**
   1965      * Returns a name for the locale's variant code that is appropriate for display to the
   1966      * user.  If possible, the name will be localized for the default
   1967      * {@link Locale.Category#DISPLAY DISPLAY} locale.  If the locale
   1968      * doesn't specify a variant code, this function returns the empty string.
   1969      *
   1970      * @return The name of the display variant code appropriate to the locale.
   1971      */
   1972     public final String getDisplayVariant() {
   1973         return getDisplayVariant(getDefault(Category.DISPLAY));
   1974     }
   1975 
   1976     /**
   1977      * Returns a name for the locale's variant code that is appropriate for display to the
   1978      * user.  If possible, the name will be localized for inLocale.  If the locale
   1979      * doesn't specify a variant code, this function returns the empty string.
   1980      *
   1981      * @param inLocale The locale for which to retrieve the display variant code.
   1982      * @return The name of the display variant code appropriate to the given locale.
   1983      * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
   1984      */
   1985     // BEGIN Android-changed: Use ICU; added private helper methods.
   1986     public String getDisplayVariant(Locale inLocale) {
   1987         String variantCode = baseLocale.getVariant();
   1988         if (variantCode.isEmpty()) {
   1989             return "";
   1990         }
   1991 
   1992         try {
   1993             normalizeAndValidateVariant(variantCode);
   1994         } catch (IllformedLocaleException ilfe) {
   1995             return variantCode;
   1996         }
   1997 
   1998         String result = ICU.getDisplayVariant(this, inLocale);
   1999         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
   2000             result = ICU.getDisplayVariant(this, Locale.getDefault());
   2001         }
   2002 
   2003         // The "old style" locale constructors allow us to pass in variants that aren't
   2004         // valid BCP-47 variant subtags. When that happens, toLanguageTag will not emit
   2005         // them. Note that we know variantCode.length() > 0 due to the isEmpty check at
   2006         // the beginning of this function.
   2007         if (result.isEmpty()) {
   2008             return variantCode;
   2009         }
   2010         return result;
   2011     }
   2012 
   2013     private static String normalizeAndValidateVariant(String variant) {
   2014         if (variant == null || variant.isEmpty()) {
   2015             return "";
   2016         }
   2017 
   2018         // Note that unlike extensions, we canonicalize to lower case alphabets
   2019         // and underscores instead of hyphens.
   2020         final String normalizedVariant = variant.replace('-', '_');
   2021         String[] subTags = normalizedVariant.split("_");
   2022 
   2023         for (String subTag : subTags) {
   2024             if (!isValidVariantSubtag(subTag)) {
   2025                 throw new IllformedLocaleException("Invalid variant: " + variant);
   2026             }
   2027         }
   2028 
   2029         return normalizedVariant;
   2030     }
   2031 
   2032     private static boolean isValidVariantSubtag(String subTag) {
   2033         // The BCP-47 spec states that :
   2034         // - Subtags can be between [5, 8] alphanumeric chars in length.
   2035         // - Subtags that start with a number are allowed to be 4 chars in length.
   2036         if (subTag.length() >= 5 && subTag.length() <= 8) {
   2037             if (isAsciiAlphaNum(subTag)) {
   2038                 return true;
   2039             }
   2040         } else if (subTag.length() == 4) {
   2041             final char firstChar = subTag.charAt(0);
   2042             if ((firstChar >= '0' && firstChar <= '9') && isAsciiAlphaNum(subTag)) {
   2043                 return true;
   2044             }
   2045         }
   2046 
   2047         return false;
   2048     }
   2049     // END Android-changed
   2050 
   2051     /**
   2052      * Returns a name for the locale that is appropriate for display to the
   2053      * user. This will be the values returned by getDisplayLanguage(),
   2054      * getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled
   2055      * into a single string. The the non-empty values are used in order,
   2056      * with the second and subsequent names in parentheses.  For example:
   2057      * <blockquote>
   2058      * language (script, country, variant)<br>
   2059      * language (country)<br>
   2060      * language (variant)<br>
   2061      * script (country)<br>
   2062      * country<br>
   2063      * </blockquote>
   2064      * depending on which fields are specified in the locale.  If the
   2065      * language, script, country, and variant fields are all empty,
   2066      * this function returns the empty string.
   2067      *
   2068      * @return The name of the locale appropriate to display.
   2069      */
   2070     public final String getDisplayName() {
   2071         return getDisplayName(getDefault(Category.DISPLAY));
   2072     }
   2073 
   2074     // BEGIN Android-changed: Use ICU.
   2075     /**
   2076      * Returns this locale's language name, country name, and variant, localized
   2077      * to {@code locale}. The exact output form depends on whether this locale
   2078      * corresponds to a specific language, script, country and variant.
   2079      *
   2080      * <p>For example:
   2081      * <ul>
   2082      * <li>{@code new Locale("en").getDisplayName(Locale.US)} -> {@code English}
   2083      * <li>{@code new Locale("en", "US").getDisplayName(Locale.US)} -> {@code English (United States)}
   2084      * <li>{@code new Locale("en", "US", "POSIX").getDisplayName(Locale.US)} -> {@code English (United States,Computer)}
   2085      * <li>{@code Locale.fromLanguageTag("zh-Hant-CN").getDisplayName(Locale.US)} -> {@code Chinese (Traditional Han,China)}
   2086      * <li>{@code new Locale("en").getDisplayName(Locale.FRANCE)} -> {@code anglais}
   2087      * <li>{@code new Locale("en", "US").getDisplayName(Locale.FRANCE)} -> {@code anglais (tats-Unis)}
   2088      * <li>{@code new Locale("en", "US", "POSIX").getDisplayName(Locale.FRANCE)} -> {@code anglais (tats-Unis,informatique)}.
   2089      * </ul>
   2090      */
   2091     public String getDisplayName(Locale locale) {
   2092         int count = 0;
   2093         StringBuilder buffer = new StringBuilder();
   2094         String languageCode = baseLocale.getLanguage();
   2095         if (!languageCode.isEmpty()) {
   2096             String displayLanguage = getDisplayLanguage(locale);
   2097             buffer.append(displayLanguage.isEmpty() ? languageCode : displayLanguage);
   2098             ++count;
   2099         }
   2100         String scriptCode = baseLocale.getScript();
   2101         if (!scriptCode.isEmpty()) {
   2102             if (count == 1) {
   2103                 buffer.append(" (");
   2104             }
   2105             String displayScript = getDisplayScript(locale);
   2106             buffer.append(displayScript.isEmpty() ? scriptCode : displayScript);
   2107             ++count;
   2108         }
   2109         String countryCode = baseLocale.getRegion();
   2110         if (!countryCode.isEmpty()) {
   2111             if (count == 1) {
   2112                 buffer.append(" (");
   2113             } else if (count == 2) {
   2114                 buffer.append(",");
   2115             }
   2116             String displayCountry = getDisplayCountry(locale);
   2117             buffer.append(displayCountry.isEmpty() ? countryCode : displayCountry);
   2118             ++count;
   2119         }
   2120         String variantCode = baseLocale.getVariant();
   2121         if (!variantCode.isEmpty()) {
   2122             if (count == 1) {
   2123                 buffer.append(" (");
   2124             } else if (count == 2 || count == 3) {
   2125                 buffer.append(",");
   2126             }
   2127             String displayVariant = getDisplayVariant(locale);
   2128             buffer.append(displayVariant.isEmpty() ? variantCode : displayVariant);
   2129             ++count;
   2130         }
   2131         if (count > 1) {
   2132             buffer.append(")");
   2133         }
   2134         return buffer.toString();
   2135     }
   2136     // END Android-changed: Use ICU.
   2137 
   2138     /**
   2139      * Overrides Cloneable.
   2140      */
   2141     @Override
   2142     public Object clone()
   2143     {
   2144         try {
   2145             Locale that = (Locale)super.clone();
   2146             return that;
   2147         } catch (CloneNotSupportedException e) {
   2148             throw new InternalError(e);
   2149         }
   2150     }
   2151 
   2152     /**
   2153      * Override hashCode.
   2154      * Since Locales are often used in hashtables, caches the value
   2155      * for speed.
   2156      */
   2157     @Override
   2158     public int hashCode() {
   2159         int hc = hashCodeValue;
   2160         if (hc == 0) {
   2161             hc = baseLocale.hashCode();
   2162             if (localeExtensions != null) {
   2163                 hc ^= localeExtensions.hashCode();
   2164             }
   2165             hashCodeValue = hc;
   2166         }
   2167         return hc;
   2168     }
   2169 
   2170     // Overrides
   2171 
   2172     /**
   2173      * Returns true if this Locale is equal to another object.  A Locale is
   2174      * deemed equal to another Locale with identical language, script, country,
   2175      * variant and extensions, and unequal to all other objects.
   2176      *
   2177      * @return true if this Locale is equal to the specified object.
   2178      */
   2179     @Override
   2180     public boolean equals(Object obj) {
   2181         if (this == obj)                      // quick check
   2182             return true;
   2183         if (!(obj instanceof Locale))
   2184             return false;
   2185         BaseLocale otherBase = ((Locale)obj).baseLocale;
   2186         if (!baseLocale.equals(otherBase)) {
   2187             return false;
   2188         }
   2189         if (localeExtensions == null) {
   2190             return ((Locale)obj).localeExtensions == null;
   2191         }
   2192         return localeExtensions.equals(((Locale)obj).localeExtensions);
   2193     }
   2194 
   2195     // ================= privates =====================================
   2196 
   2197     private transient BaseLocale baseLocale;
   2198     private transient LocaleExtensions localeExtensions;
   2199 
   2200     /**
   2201      * Calculated hashcode
   2202      */
   2203     private transient volatile int hashCodeValue = 0;
   2204 
   2205     // Android-changed: Add NoImagePreloadHolder to allow compile-time initialization.
   2206     private static class NoImagePreloadHolder {
   2207         public volatile static Locale defaultLocale = initDefault();
   2208     }
   2209     private volatile static Locale defaultDisplayLocale = null;
   2210     private volatile static Locale defaultFormatLocale = null;
   2211 
   2212     private transient volatile String languageTag;
   2213 
   2214     /**
   2215      * Format a list using given pattern strings.
   2216      * If either of the patterns is null, then a the list is
   2217      * formatted by concatenation with the delimiter ','.
   2218      * @param stringList the list of strings to be formatted.
   2219      * @param listPattern should create a MessageFormat taking 0-3 arguments
   2220      * and formatting them into a list.
   2221      * @param listCompositionPattern should take 2 arguments
   2222      * and is used by composeList.
   2223      * @return a string representing the list.
   2224      */
   2225     private static String formatList(String[] stringList, String listPattern, String listCompositionPattern) {
   2226         // If we have no list patterns, compose the list in a simple,
   2227         // non-localized way.
   2228         if (listPattern == null || listCompositionPattern == null) {
   2229             StringBuilder result = new StringBuilder();
   2230             for (int i = 0; i < stringList.length; ++i) {
   2231                 if (i > 0) {
   2232                     result.append(',');
   2233                 }
   2234                 result.append(stringList[i]);
   2235             }
   2236             return result.toString();
   2237         }
   2238 
   2239         // Compose the list down to three elements if necessary
   2240         if (stringList.length > 3) {
   2241             MessageFormat format = new MessageFormat(listCompositionPattern);
   2242             stringList = composeList(format, stringList);
   2243         }
   2244 
   2245         // Rebuild the argument list with the list length as the first element
   2246         Object[] args = new Object[stringList.length + 1];
   2247         System.arraycopy(stringList, 0, args, 1, stringList.length);
   2248         args[0] = new Integer(stringList.length);
   2249 
   2250         // Format it using the pattern in the resource
   2251         MessageFormat format = new MessageFormat(listPattern);
   2252         return format.format(args);
   2253     }
   2254 
   2255     /**
   2256      * Given a list of strings, return a list shortened to three elements.
   2257      * Shorten it by applying the given format to the first two elements
   2258      * recursively.
   2259      * @param format a format which takes two arguments
   2260      * @param list a list of strings
   2261      * @return if the list is three elements or shorter, the same list;
   2262      * otherwise, a new list of three elements.
   2263      */
   2264     private static String[] composeList(MessageFormat format, String[] list) {
   2265         if (list.length <= 3) return list;
   2266 
   2267         // Use the given format to compose the first two elements into one
   2268         String[] listItems = { list[0], list[1] };
   2269         String newItem = format.format(listItems);
   2270 
   2271         // Form a new list one element shorter
   2272         String[] newList = new String[list.length-1];
   2273         System.arraycopy(list, 2, newList, 1, newList.length-1);
   2274         newList[0] = newItem;
   2275 
   2276         // Recurse
   2277         return composeList(format, newList);
   2278     }
   2279 
   2280     // Duplicate of sun.util.locale.UnicodeLocaleExtension.isKey in order to
   2281     // avoid its class loading.
   2282     private static boolean isUnicodeExtensionKey(String s) {
   2283         // 2alphanum
   2284         return (s.length() == 2) && LocaleUtils.isAlphaNumericString(s);
   2285     }
   2286 
   2287     /**
   2288      * @serialField language    String
   2289      *      language subtag in lower case. (See <a href="java/util/Locale.html#getLanguage()">getLanguage()</a>)
   2290      * @serialField country     String
   2291      *      country subtag in upper case. (See <a href="java/util/Locale.html#getCountry()">getCountry()</a>)
   2292      * @serialField variant     String
   2293      *      variant subtags separated by LOWLINE characters. (See <a href="java/util/Locale.html#getVariant()">getVariant()</a>)
   2294      * @serialField hashcode    int
   2295      *      deprecated, for forward compatibility only
   2296      * @serialField script      String
   2297      *      script subtag in title case (See <a href="java/util/Locale.html#getScript()">getScript()</a>)
   2298      * @serialField extensions  String
   2299      *      canonical representation of extensions, that is,
   2300      *      BCP47 extensions in alphabetical order followed by
   2301      *      BCP47 private use subtags, all in lower case letters
   2302      *      separated by HYPHEN-MINUS characters.
   2303      *      (See <a href="java/util/Locale.html#getExtensionKeys()">getExtensionKeys()</a>,
   2304      *      <a href="java/util/Locale.html#getExtension(char)">getExtension(char)</a>)
   2305      */
   2306     private static final ObjectStreamField[] serialPersistentFields = {
   2307         new ObjectStreamField("language", String.class),
   2308         new ObjectStreamField("country", String.class),
   2309         new ObjectStreamField("variant", String.class),
   2310         new ObjectStreamField("hashcode", int.class),
   2311         new ObjectStreamField("script", String.class),
   2312         new ObjectStreamField("extensions", String.class),
   2313     };
   2314 
   2315     /**
   2316      * Serializes this <code>Locale</code> to the specified <code>ObjectOutputStream</code>.
   2317      * @param out the <code>ObjectOutputStream</code> to write
   2318      * @throws IOException
   2319      * @since 1.7
   2320      */
   2321     private void writeObject(ObjectOutputStream out) throws IOException {
   2322         ObjectOutputStream.PutField fields = out.putFields();
   2323         fields.put("language", baseLocale.getLanguage());
   2324         fields.put("script", baseLocale.getScript());
   2325         fields.put("country", baseLocale.getRegion());
   2326         fields.put("variant", baseLocale.getVariant());
   2327         fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
   2328         fields.put("hashcode", -1); // place holder just for backward support
   2329         out.writeFields();
   2330     }
   2331 
   2332     /**
   2333      * Deserializes this <code>Locale</code>.
   2334      * @param in the <code>ObjectInputStream</code> to read
   2335      * @throws IOException
   2336      * @throws ClassNotFoundException
   2337      * @throws IllformedLocaleException
   2338      * @since 1.7
   2339      */
   2340     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
   2341         ObjectInputStream.GetField fields = in.readFields();
   2342         String language = (String)fields.get("language", "");
   2343         String script = (String)fields.get("script", "");
   2344         String country = (String)fields.get("country", "");
   2345         String variant = (String)fields.get("variant", "");
   2346         String extStr = (String)fields.get("extensions", "");
   2347         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
   2348         // Android-changed: Handle null for backwards compatible deserialization. http://b/26387905
   2349         // if (extStr.length() > 0) {
   2350         if (extStr != null && extStr.length() > 0) {
   2351             try {
   2352                 InternalLocaleBuilder bldr = new InternalLocaleBuilder();
   2353                 bldr.setExtensions(extStr);
   2354                 localeExtensions = bldr.getLocaleExtensions();
   2355             } catch (LocaleSyntaxException e) {
   2356                 throw new IllformedLocaleException(e.getMessage());
   2357             }
   2358         } else {
   2359             localeExtensions = null;
   2360         }
   2361     }
   2362 
   2363     /**
   2364      * Returns a cached <code>Locale</code> instance equivalent to
   2365      * the deserialized <code>Locale</code>. When serialized
   2366      * language, country and variant fields read from the object data stream
   2367      * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
   2368      * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>
   2369      * "ca"/"japanese" (calendar type is "japanese") or "nu"/"thai" (number script
   2370      * type is "thai"). See <a href="Locale.html#special_cases_constructor">Special Cases</a>
   2371      * for more information.
   2372      *
   2373      * @return an instance of <code>Locale</code> equivalent to
   2374      * the deserialized <code>Locale</code>.
   2375      * @throws java.io.ObjectStreamException
   2376      */
   2377     private Object readResolve() throws java.io.ObjectStreamException {
   2378         return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
   2379                 baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
   2380     }
   2381 
   2382     private static volatile String[] isoLanguages = null;
   2383 
   2384     private static volatile String[] isoCountries = null;
   2385 
   2386     private static String convertOldISOCodes(String language) {
   2387         // we accept both the old and the new ISO codes for the languages whose ISO
   2388         // codes have changed, but we always store the OLD code, for backward compatibility
   2389         language = LocaleUtils.toLowerString(language).intern();
   2390         if (language == "he") {
   2391             return "iw";
   2392         } else if (language == "yi") {
   2393             return "ji";
   2394         } else if (language == "id") {
   2395             return "in";
   2396         } else {
   2397             return language;
   2398         }
   2399     }
   2400 
   2401     private static LocaleExtensions getCompatibilityExtensions(String language,
   2402                                                                String script,
   2403                                                                String country,
   2404                                                                String variant) {
   2405         LocaleExtensions extensions = null;
   2406         // Special cases for backward compatibility support
   2407         if (LocaleUtils.caseIgnoreMatch(language, "ja")
   2408                 && script.length() == 0
   2409                 && LocaleUtils.caseIgnoreMatch(country, "jp")
   2410                 && "JP".equals(variant)) {
   2411             // ja_JP_JP -> u-ca-japanese (calendar = japanese)
   2412             extensions = LocaleExtensions.CALENDAR_JAPANESE;
   2413         } else if (LocaleUtils.caseIgnoreMatch(language, "th")
   2414                 && script.length() == 0
   2415                 && LocaleUtils.caseIgnoreMatch(country, "th")
   2416                 && "TH".equals(variant)) {
   2417             // th_TH_TH -> u-nu-thai (numbersystem = thai)
   2418             extensions = LocaleExtensions.NUMBER_THAI;
   2419         }
   2420         return extensions;
   2421     }
   2422 
   2423     // Android-removed: Drop nested private class LocaleNameGetter.
   2424     // BEGIN Android-added: Add adjustLanguageCode(); for internal use only.
   2425     /** @hide for internal use only. */
   2426     public static String adjustLanguageCode(String languageCode) {
   2427         String adjusted = languageCode.toLowerCase(Locale.US);
   2428         // Map new language codes to the obsolete language
   2429         // codes so the correct resource bundles will be used.
   2430         if (languageCode.equals("he")) {
   2431             adjusted = "iw";
   2432         } else if (languageCode.equals("id")) {
   2433             adjusted = "in";
   2434         } else if (languageCode.equals("yi")) {
   2435             adjusted = "ji";
   2436         }
   2437 
   2438         return adjusted;
   2439     }
   2440     // END Android-added
   2441 
   2442     /**
   2443      * Enum for locale categories.  These locale categories are used to get/set
   2444      * the default locale for the specific functionality represented by the
   2445      * category.
   2446      *
   2447      * @see #getDefault(Locale.Category)
   2448      * @see #setDefault(Locale.Category, Locale)
   2449      * @since 1.7
   2450      */
   2451     public enum Category {
   2452 
   2453         /**
   2454          * Category used to represent the default locale for
   2455          * displaying user interfaces.
   2456          */
   2457         DISPLAY("user.language.display",
   2458                 "user.script.display",
   2459                 "user.country.display",
   2460                 "user.variant.display"),
   2461 
   2462         /**
   2463          * Category used to represent the default locale for
   2464          * formatting dates, numbers, and/or currencies.
   2465          */
   2466         FORMAT("user.language.format",
   2467                "user.script.format",
   2468                "user.country.format",
   2469                "user.variant.format");
   2470 
   2471         Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
   2472             this.languageKey = languageKey;
   2473             this.scriptKey = scriptKey;
   2474             this.countryKey = countryKey;
   2475             this.variantKey = variantKey;
   2476         }
   2477 
   2478         final String languageKey;
   2479         final String scriptKey;
   2480         final String countryKey;
   2481         final String variantKey;
   2482     }
   2483 
   2484     /**
   2485      * <code>Builder</code> is used to build instances of <code>Locale</code>
   2486      * from values configured by the setters.  Unlike the <code>Locale</code>
   2487      * constructors, the <code>Builder</code> checks if a value configured by a
   2488      * setter satisfies the syntax requirements defined by the <code>Locale</code>
   2489      * class.  A <code>Locale</code> object created by a <code>Builder</code> is
   2490      * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
   2491      * without losing information.
   2492      *
   2493      * <p><b>Note:</b> The <code>Locale</code> class does not provide any
   2494      * syntactic restrictions on variant, while BCP 47 requires each variant
   2495      * subtag to be 5 to 8 alphanumerics or a single numeric followed by 3
   2496      * alphanumerics.  The method <code>setVariant</code> throws
   2497      * <code>IllformedLocaleException</code> for a variant that does not satisfy
   2498      * this restriction. If it is necessary to support such a variant, use a
   2499      * Locale constructor.  However, keep in mind that a <code>Locale</code>
   2500      * object created this way might lose the variant information when
   2501      * transformed to a BCP 47 language tag.
   2502      *
   2503      * <p>The following example shows how to create a <code>Locale</code> object
   2504      * with the <code>Builder</code>.
   2505      * <blockquote>
   2506      * <pre>
   2507      *     Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
   2508      * </pre>
   2509      * </blockquote>
   2510      *
   2511      * <p>Builders can be reused; <code>clear()</code> resets all
   2512      * fields to their default values.
   2513      *
   2514      * @see Locale#forLanguageTag
   2515      * @since 1.7
   2516      */
   2517     public static final class Builder {
   2518         private final InternalLocaleBuilder localeBuilder;
   2519 
   2520         /**
   2521          * Constructs an empty Builder. The default value of all
   2522          * fields, extensions, and private use information is the
   2523          * empty string.
   2524          */
   2525         public Builder() {
   2526             localeBuilder = new InternalLocaleBuilder();
   2527         }
   2528 
   2529         /**
   2530          * Resets the <code>Builder</code> to match the provided
   2531          * <code>locale</code>.  Existing state is discarded.
   2532          *
   2533          * <p>All fields of the locale must be well-formed, see {@link Locale}.
   2534          *
   2535          * <p>Locales with any ill-formed fields cause
   2536          * <code>IllformedLocaleException</code> to be thrown, except for the
   2537          * following three cases which are accepted for compatibility
   2538          * reasons:<ul>
   2539          * <li>Locale("ja", "JP", "JP") is treated as "ja-JP-u-ca-japanese"
   2540          * <li>Locale("th", "TH", "TH") is treated as "th-TH-u-nu-thai"
   2541          * <li>Locale("no", "NO", "NY") is treated as "nn-NO"</ul>
   2542          *
   2543          * @param locale the locale
   2544          * @return This builder.
   2545          * @throws IllformedLocaleException if <code>locale</code> has
   2546          * any ill-formed fields.
   2547          * @throws NullPointerException if <code>locale</code> is null.
   2548          */
   2549         public Builder setLocale(Locale locale) {
   2550             try {
   2551                 localeBuilder.setLocale(locale.baseLocale, locale.localeExtensions);
   2552             } catch (LocaleSyntaxException e) {
   2553                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2554             }
   2555             return this;
   2556         }
   2557 
   2558         /**
   2559          * Resets the Builder to match the provided IETF BCP 47
   2560          * language tag.  Discards the existing state.  Null and the
   2561          * empty string cause the builder to be reset, like {@link
   2562          * #clear}.  Grandfathered tags (see {@link
   2563          * Locale#forLanguageTag}) are converted to their canonical
   2564          * form before being processed.  Otherwise, the language tag
   2565          * must be well-formed (see {@link Locale}) or an exception is
   2566          * thrown (unlike <code>Locale.forLanguageTag</code>, which
   2567          * just discards ill-formed and following portions of the
   2568          * tag).
   2569          *
   2570          * @param languageTag the language tag
   2571          * @return This builder.
   2572          * @throws IllformedLocaleException if <code>languageTag</code> is ill-formed
   2573          * @see Locale#forLanguageTag(String)
   2574          */
   2575         public Builder setLanguageTag(String languageTag) {
   2576             ParseStatus sts = new ParseStatus();
   2577             LanguageTag tag = LanguageTag.parse(languageTag, sts);
   2578             if (sts.isError()) {
   2579                 throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
   2580             }
   2581             localeBuilder.setLanguageTag(tag);
   2582             return this;
   2583         }
   2584 
   2585         /**
   2586          * Sets the language.  If <code>language</code> is the empty string or
   2587          * null, the language in this <code>Builder</code> is removed.  Otherwise,
   2588          * the language must be <a href="./Locale.html#def_language">well-formed</a>
   2589          * or an exception is thrown.
   2590          *
   2591          * <p>The typical language value is a two or three-letter language
   2592          * code as defined in ISO639.
   2593          *
   2594          * @param language the language
   2595          * @return This builder.
   2596          * @throws IllformedLocaleException if <code>language</code> is ill-formed
   2597          */
   2598         public Builder setLanguage(String language) {
   2599             try {
   2600                 localeBuilder.setLanguage(language);
   2601             } catch (LocaleSyntaxException e) {
   2602                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2603             }
   2604             return this;
   2605         }
   2606 
   2607         /**
   2608          * Sets the script. If <code>script</code> is null or the empty string,
   2609          * the script in this <code>Builder</code> is removed.
   2610          * Otherwise, the script must be <a href="./Locale.html#def_script">well-formed</a> or an
   2611          * exception is thrown.
   2612          *
   2613          * <p>The typical script value is a four-letter script code as defined by ISO 15924.
   2614          *
   2615          * @param script the script
   2616          * @return This builder.
   2617          * @throws IllformedLocaleException if <code>script</code> is ill-formed
   2618          */
   2619         public Builder setScript(String script) {
   2620             try {
   2621                 localeBuilder.setScript(script);
   2622             } catch (LocaleSyntaxException e) {
   2623                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2624             }
   2625             return this;
   2626         }
   2627 
   2628         /**
   2629          * Sets the region.  If region is null or the empty string, the region
   2630          * in this <code>Builder</code> is removed.  Otherwise,
   2631          * the region must be <a href="./Locale.html#def_region">well-formed</a> or an
   2632          * exception is thrown.
   2633          *
   2634          * <p>The typical region value is a two-letter ISO 3166 code or a
   2635          * three-digit UN M.49 area code.
   2636          *
   2637          * <p>The country value in the <code>Locale</code> created by the
   2638          * <code>Builder</code> is always normalized to upper case.
   2639          *
   2640          * @param region the region
   2641          * @return This builder.
   2642          * @throws IllformedLocaleException if <code>region</code> is ill-formed
   2643          */
   2644         public Builder setRegion(String region) {
   2645             try {
   2646                 localeBuilder.setRegion(region);
   2647             } catch (LocaleSyntaxException e) {
   2648                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2649             }
   2650             return this;
   2651         }
   2652 
   2653         /**
   2654          * Sets the variant.  If variant is null or the empty string, the
   2655          * variant in this <code>Builder</code> is removed.  Otherwise, it
   2656          * must consist of one or more <a href="./Locale.html#def_variant">well-formed</a>
   2657          * subtags, or an exception is thrown.
   2658          *
   2659          * <p><b>Note:</b> This method checks if <code>variant</code>
   2660          * satisfies the IETF BCP 47 variant subtag's syntax requirements,
   2661          * and normalizes the value to lowercase letters.  However,
   2662          * the <code>Locale</code> class does not impose any syntactic
   2663          * restriction on variant, and the variant value in
   2664          * <code>Locale</code> is case sensitive.  To set such a variant,
   2665          * use a Locale constructor.
   2666          *
   2667          * @param variant the variant
   2668          * @return This builder.
   2669          * @throws IllformedLocaleException if <code>variant</code> is ill-formed
   2670          */
   2671         public Builder setVariant(String variant) {
   2672             try {
   2673                 localeBuilder.setVariant(variant);
   2674             } catch (LocaleSyntaxException e) {
   2675                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2676             }
   2677             return this;
   2678         }
   2679 
   2680         /**
   2681          * Sets the extension for the given key. If the value is null or the
   2682          * empty string, the extension is removed.  Otherwise, the extension
   2683          * must be <a href="./Locale.html#def_extensions">well-formed</a> or an exception
   2684          * is thrown.
   2685          *
   2686          * <p><b>Note:</b> The key {@link Locale#UNICODE_LOCALE_EXTENSION
   2687          * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension.
   2688          * Setting a value for this key replaces any existing Unicode locale key/type
   2689          * pairs with those defined in the extension.
   2690          *
   2691          * <p><b>Note:</b> The key {@link Locale#PRIVATE_USE_EXTENSION
   2692          * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be
   2693          * well-formed, the value for this key needs only to have subtags of one to
   2694          * eight alphanumeric characters, not two to eight as in the general case.
   2695          *
   2696          * @param key the extension key
   2697          * @param value the extension value
   2698          * @return This builder.
   2699          * @throws IllformedLocaleException if <code>key</code> is illegal
   2700          * or <code>value</code> is ill-formed
   2701          * @see #setUnicodeLocaleKeyword(String, String)
   2702          */
   2703         public Builder setExtension(char key, String value) {
   2704             try {
   2705                 localeBuilder.setExtension(key, value);
   2706             } catch (LocaleSyntaxException e) {
   2707                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2708             }
   2709             return this;
   2710         }
   2711 
   2712         /**
   2713          * Sets the Unicode locale keyword type for the given key.  If the type
   2714          * is null, the Unicode keyword is removed.  Otherwise, the key must be
   2715          * non-null and both key and type must be <a
   2716          * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
   2717          * is thrown.
   2718          *
   2719          * <p>Keys and types are converted to lower case.
   2720          *
   2721          * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension}
   2722          * replaces all Unicode locale keywords with those defined in the
   2723          * extension.
   2724          *
   2725          * @param key the Unicode locale key
   2726          * @param type the Unicode locale type
   2727          * @return This builder.
   2728          * @throws IllformedLocaleException if <code>key</code> or <code>type</code>
   2729          * is ill-formed
   2730          * @throws NullPointerException if <code>key</code> is null
   2731          * @see #setExtension(char, String)
   2732          */
   2733         public Builder setUnicodeLocaleKeyword(String key, String type) {
   2734             try {
   2735                 localeBuilder.setUnicodeLocaleKeyword(key, type);
   2736             } catch (LocaleSyntaxException e) {
   2737                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2738             }
   2739             return this;
   2740         }
   2741 
   2742         /**
   2743          * Adds a unicode locale attribute, if not already present, otherwise
   2744          * has no effect.  The attribute must not be null and must be <a
   2745          * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
   2746          * is thrown.
   2747          *
   2748          * @param attribute the attribute
   2749          * @return This builder.
   2750          * @throws NullPointerException if <code>attribute</code> is null
   2751          * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
   2752          * @see #setExtension(char, String)
   2753          */
   2754         public Builder addUnicodeLocaleAttribute(String attribute) {
   2755             try {
   2756                 localeBuilder.addUnicodeLocaleAttribute(attribute);
   2757             } catch (LocaleSyntaxException e) {
   2758                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2759             }
   2760             return this;
   2761         }
   2762 
   2763         /**
   2764          * Removes a unicode locale attribute, if present, otherwise has no
   2765          * effect.  The attribute must not be null and must be <a
   2766          * href="./Locale.html#def_locale_extension">well-formed</a> or an exception
   2767          * is thrown.
   2768          *
   2769          * <p>Attribute comparision for removal is case-insensitive.
   2770          *
   2771          * @param attribute the attribute
   2772          * @return This builder.
   2773          * @throws NullPointerException if <code>attribute</code> is null
   2774          * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
   2775          * @see #setExtension(char, String)
   2776          */
   2777         public Builder removeUnicodeLocaleAttribute(String attribute) {
   2778             // BEGIN Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE
   2779             if (attribute == null) {
   2780                 throw new NullPointerException("attribute == null");
   2781             }
   2782             // END Android-added: removeUnicodeLocaleAttribute(null) is documented to throw NPE
   2783 
   2784             try {
   2785                 localeBuilder.removeUnicodeLocaleAttribute(attribute);
   2786             } catch (LocaleSyntaxException e) {
   2787                 throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
   2788             }
   2789             return this;
   2790         }
   2791 
   2792         /**
   2793          * Resets the builder to its initial, empty state.
   2794          *
   2795          * @return This builder.
   2796          */
   2797         public Builder clear() {
   2798             localeBuilder.clear();
   2799             return this;
   2800         }
   2801 
   2802         /**
   2803          * Resets the extensions to their initial, empty state.
   2804          * Language, script, region and variant are unchanged.
   2805          *
   2806          * @return This builder.
   2807          * @see #setExtension(char, String)
   2808          */
   2809         public Builder clearExtensions() {
   2810             localeBuilder.clearExtensions();
   2811             return this;
   2812         }
   2813 
   2814         /**
   2815          * Returns an instance of <code>Locale</code> created from the fields set
   2816          * on this builder.
   2817          *
   2818          * <p>This applies the conversions listed in {@link Locale#forLanguageTag}
   2819          * when constructing a Locale. (Grandfathered tags are handled in
   2820          * {@link #setLanguageTag}.)
   2821          *
   2822          * @return A Locale.
   2823          */
   2824         public Locale build() {
   2825             BaseLocale baseloc = localeBuilder.getBaseLocale();
   2826             LocaleExtensions extensions = localeBuilder.getLocaleExtensions();
   2827             if (extensions == null && baseloc.getVariant().length() > 0) {
   2828                 extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(),
   2829                         baseloc.getRegion(), baseloc.getVariant());
   2830             }
   2831             return Locale.getInstance(baseloc, extensions);
   2832         }
   2833     }
   2834 
   2835     /**
   2836      * This enum provides constants to select a filtering mode for locale
   2837      * matching. Refer to <a href="http://tools.ietf.org/html/rfc4647">RFC 4647
   2838      * Matching of Language Tags</a> for details.
   2839      *
   2840      * <p>As an example, think of two Language Priority Lists each of which
   2841      * includes only one language range and a set of following language tags:
   2842      *
   2843      * <pre>
   2844      *    de (German)
   2845      *    de-DE (German, Germany)
   2846      *    de-Deva (German, in Devanagari script)
   2847      *    de-Deva-DE (German, in Devanagari script, Germany)
   2848      *    de-DE-1996 (German, Germany, orthography of 1996)
   2849      *    de-Latn-DE (German, in Latin script, Germany)
   2850      *    de-Latn-DE-1996 (German, in Latin script, Germany, orthography of 1996)
   2851      * </pre>
   2852      *
   2853      * The filtering method will behave as follows:
   2854      *
   2855      * <table cellpadding=2 summary="Filtering method behavior">
   2856      * <tr>
   2857      * <th>Filtering Mode</th>
   2858      * <th>Language Priority List: {@code "de-DE"}</th>
   2859      * <th>Language Priority List: {@code "de-*-DE"}</th>
   2860      * </tr>
   2861      * <tr>
   2862      * <td valign=top>
   2863      * {@link FilteringMode#AUTOSELECT_FILTERING AUTOSELECT_FILTERING}
   2864      * </td>
   2865      * <td valign=top>
   2866      * Performs <em>basic</em> filtering and returns {@code "de-DE"} and
   2867      * {@code "de-DE-1996"}.
   2868      * </td>
   2869      * <td valign=top>
   2870      * Performs <em>extended</em> filtering and returns {@code "de-DE"},
   2871      * {@code "de-Deva-DE"}, {@code "de-DE-1996"}, {@code "de-Latn-DE"}, and
   2872      * {@code "de-Latn-DE-1996"}.
   2873      * </td>
   2874      * </tr>
   2875      * <tr>
   2876      * <td valign=top>
   2877      * {@link FilteringMode#EXTENDED_FILTERING EXTENDED_FILTERING}
   2878      * </td>
   2879      * <td valign=top>
   2880      * Performs <em>extended</em> filtering and returns {@code "de-DE"},
   2881      * {@code "de-Deva-DE"}, {@code "de-DE-1996"}, {@code "de-Latn-DE"}, and
   2882      * {@code "de-Latn-DE-1996"}.
   2883      * </td>
   2884      * <td valign=top>Same as above.</td>
   2885      * </tr>
   2886      * <tr>
   2887      * <td valign=top>
   2888      * {@link FilteringMode#IGNORE_EXTENDED_RANGES IGNORE_EXTENDED_RANGES}
   2889      * </td>
   2890      * <td valign=top>
   2891      * Performs <em>basic</em> filtering and returns {@code "de-DE"} and
   2892      * {@code "de-DE-1996"}.
   2893      * </td>
   2894      * <td valign=top>
   2895      * Performs <em>basic</em> filtering and returns {@code null} because
   2896      * nothing matches.
   2897      * </td>
   2898      * </tr>
   2899      * <tr>
   2900      * <td valign=top>
   2901      * {@link FilteringMode#MAP_EXTENDED_RANGES MAP_EXTENDED_RANGES}
   2902      * </td>
   2903      * <td valign=top>Same as above.</td>
   2904      * <td valign=top>
   2905      * Performs <em>basic</em> filtering and returns {@code "de-DE"} and
   2906      * {@code "de-DE-1996"} because {@code "de-*-DE"} is mapped to
   2907      * {@code "de-DE"}.
   2908      * </td>
   2909      * </tr>
   2910      * <tr>
   2911      * <td valign=top>
   2912      * {@link FilteringMode#REJECT_EXTENDED_RANGES REJECT_EXTENDED_RANGES}
   2913      * </td>
   2914      * <td valign=top>Same as above.</td>
   2915      * <td valign=top>
   2916      * Throws {@link IllegalArgumentException} because {@code "de-*-DE"} is
   2917      * not a valid basic language range.
   2918      * </td>
   2919      * </tr>
   2920      * </table>
   2921      *
   2922      * @see #filter(List, Collection, FilteringMode)
   2923      * @see #filterTags(List, Collection, FilteringMode)
   2924      *
   2925      * @since 1.8
   2926      */
   2927     public static enum FilteringMode {
   2928         /**
   2929          * Specifies automatic filtering mode based on the given Language
   2930          * Priority List consisting of language ranges. If all of the ranges
   2931          * are basic, basic filtering is selected. Otherwise, extended
   2932          * filtering is selected.
   2933          */
   2934         AUTOSELECT_FILTERING,
   2935 
   2936         /**
   2937          * Specifies extended filtering.
   2938          */
   2939         EXTENDED_FILTERING,
   2940 
   2941         /**
   2942          * Specifies basic filtering: Note that any extended language ranges
   2943          * included in the given Language Priority List are ignored.
   2944          */
   2945         IGNORE_EXTENDED_RANGES,
   2946 
   2947         /**
   2948          * Specifies basic filtering: If any extended language ranges are
   2949          * included in the given Language Priority List, they are mapped to the
   2950          * basic language range. Specifically, a language range starting with a
   2951          * subtag {@code "*"} is treated as a language range {@code "*"}. For
   2952          * example, {@code "*-US"} is treated as {@code "*"}. If {@code "*"} is
   2953          * not the first subtag, {@code "*"} and extra {@code "-"} are removed.
   2954          * For example, {@code "ja-*-JP"} is mapped to {@code "ja-JP"}.
   2955          */
   2956         MAP_EXTENDED_RANGES,
   2957 
   2958         /**
   2959          * Specifies basic filtering: If any extended language ranges are
   2960          * included in the given Language Priority List, the list is rejected
   2961          * and the filtering method throws {@link IllegalArgumentException}.
   2962          */
   2963         REJECT_EXTENDED_RANGES
   2964     };
   2965 
   2966     /**
   2967      * This class expresses a <em>Language Range</em> defined in
   2968      * <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 Matching of
   2969      * Language Tags</a>. A language range is an identifier which is used to
   2970      * select language tag(s) meeting specific requirements by using the
   2971      * mechanisms described in <a href="Locale.html#LocaleMatching">Locale
   2972      * Matching</a>. A list which represents a user's preferences and consists
   2973      * of language ranges is called a <em>Language Priority List</em>.
   2974      *
   2975      * <p>There are two types of language ranges: basic and extended. In RFC
   2976      * 4647, the syntax of language ranges is expressed in
   2977      * <a href="http://tools.ietf.org/html/rfc4234">ABNF</a> as follows:
   2978      * <blockquote>
   2979      * <pre>
   2980      *     basic-language-range    = (1*8ALPHA *("-" 1*8alphanum)) / "*"
   2981      *     extended-language-range = (1*8ALPHA / "*")
   2982      *                               *("-" (1*8alphanum / "*"))
   2983      *     alphanum                = ALPHA / DIGIT
   2984      * </pre>
   2985      * </blockquote>
   2986      * For example, {@code "en"} (English), {@code "ja-JP"} (Japanese, Japan),
   2987      * {@code "*"} (special language range which matches any language tag) are
   2988      * basic language ranges, whereas {@code "*-CH"} (any languages,
   2989      * Switzerland), {@code "es-*"} (Spanish, any regions), and
   2990      * {@code "zh-Hant-*"} (Traditional Chinese, any regions) are extended
   2991      * language ranges.
   2992      *
   2993      * @see #filter
   2994      * @see #filterTags
   2995      * @see #lookup
   2996      * @see #lookupTag
   2997      *
   2998      * @since 1.8
   2999      */
   3000     public static final class LanguageRange {
   3001 
   3002        /**
   3003         * A constant holding the maximum value of weight, 1.0, which indicates
   3004         * that the language range is a good fit for the user.
   3005         */
   3006         public static final double MAX_WEIGHT = 1.0;
   3007 
   3008        /**
   3009         * A constant holding the minimum value of weight, 0.0, which indicates
   3010         * that the language range is not a good fit for the user.
   3011         */
   3012         public static final double MIN_WEIGHT = 0.0;
   3013 
   3014         private final String range;
   3015         private final double weight;
   3016 
   3017         private volatile int hash = 0;
   3018 
   3019         /**
   3020          * Constructs a {@code LanguageRange} using the given {@code range}.
   3021          * Note that no validation is done against the IANA Language Subtag
   3022          * Registry at time of construction.
   3023          *
   3024          * <p>This is equivalent to {@code LanguageRange(range, MAX_WEIGHT)}.
   3025          *
   3026          * @param range a language range
   3027          * @throws NullPointerException if the given {@code range} is
   3028          *     {@code null}
   3029          */
   3030         public LanguageRange(String range) {
   3031             this(range, MAX_WEIGHT);
   3032         }
   3033 
   3034         /**
   3035          * Constructs a {@code LanguageRange} using the given {@code range} and
   3036          * {@code weight}. Note that no validation is done against the IANA
   3037          * Language Subtag Registry at time of construction.
   3038          *
   3039          * @param range  a language range
   3040          * @param weight a weight value between {@code MIN_WEIGHT} and
   3041          *     {@code MAX_WEIGHT}
   3042          * @throws NullPointerException if the given {@code range} is
   3043          *     {@code null}
   3044          * @throws IllegalArgumentException if the given {@code weight} is less
   3045          *     than {@code MIN_WEIGHT} or greater than {@code MAX_WEIGHT}
   3046          */
   3047         public LanguageRange(String range, double weight) {
   3048             if (range == null) {
   3049                 throw new NullPointerException();
   3050             }
   3051             if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) {
   3052                 throw new IllegalArgumentException("weight=" + weight);
   3053             }
   3054 
   3055             range = range.toLowerCase();
   3056 
   3057             // Do syntax check.
   3058             boolean isIllFormed = false;
   3059             String[] subtags = range.split("-");
   3060             if (isSubtagIllFormed(subtags[0], true)
   3061                 || range.endsWith("-")) {
   3062                 isIllFormed = true;
   3063             } else {
   3064                 for (int i = 1; i < subtags.length; i++) {
   3065                     if (isSubtagIllFormed(subtags[i], false)) {
   3066                         isIllFormed = true;
   3067                         break;
   3068                     }
   3069                 }
   3070             }
   3071             if (isIllFormed) {
   3072                 throw new IllegalArgumentException("range=" + range);
   3073             }
   3074 
   3075             this.range = range;
   3076             this.weight = weight;
   3077         }
   3078 
   3079         private static boolean isSubtagIllFormed(String subtag,
   3080                                                  boolean isFirstSubtag) {
   3081             if (subtag.equals("") || subtag.length() > 8) {
   3082                 return true;
   3083             } else if (subtag.equals("*")) {
   3084                 return false;
   3085             }
   3086             char[] charArray = subtag.toCharArray();
   3087             if (isFirstSubtag) { // ALPHA
   3088                 for (char c : charArray) {
   3089                     if (c < 'a' || c > 'z') {
   3090                         return true;
   3091                     }
   3092                 }
   3093             } else { // ALPHA / DIGIT
   3094                 for (char c : charArray) {
   3095                     if (c < '0' || (c > '9' && c < 'a') || c > 'z') {
   3096                         return true;
   3097                     }
   3098                 }
   3099             }
   3100             return false;
   3101         }
   3102 
   3103         /**
   3104          * Returns the language range of this {@code LanguageRange}.
   3105          *
   3106          * @return the language range.
   3107          */
   3108         public String getRange() {
   3109             return range;
   3110         }
   3111 
   3112         /**
   3113          * Returns the weight of this {@code LanguageRange}.
   3114          *
   3115          * @return the weight value.
   3116          */
   3117         public double getWeight() {
   3118             return weight;
   3119         }
   3120 
   3121         /**
   3122          * Parses the given {@code ranges} to generate a Language Priority List.
   3123          *
   3124          * <p>This method performs a syntactic check for each language range in
   3125          * the given {@code ranges} but doesn't do validation using the IANA
   3126          * Language Subtag Registry.
   3127          *
   3128          * <p>The {@code ranges} to be given can take one of the following
   3129          * forms:
   3130          *
   3131          * <pre>
   3132          *   "Accept-Language: ja,en;q=0.4"  (weighted list with Accept-Language prefix)
   3133          *   "ja,en;q=0.4"                   (weighted list)
   3134          *   "ja,en"                         (prioritized list)
   3135          * </pre>
   3136          *
   3137          * In a weighted list, each language range is given a weight value.
   3138          * The weight value is identical to the "quality value" in
   3139          * <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>, and it
   3140          * expresses how much the user prefers  the language. A weight value is
   3141          * specified after a corresponding language range followed by
   3142          * {@code ";q="}, and the default weight value is {@code MAX_WEIGHT}
   3143          * when it is omitted.
   3144          *
   3145          * <p>Unlike a weighted list, language ranges in a prioritized list
   3146          * are sorted in the descending order based on its priority. The first
   3147          * language range has the highest priority and meets the user's
   3148          * preference most.
   3149          *
   3150          * <p>In either case, language ranges are sorted in descending order in
   3151          * the Language Priority List based on priority or weight. If a
   3152          * language range appears in the given {@code ranges} more than once,
   3153          * only the first one is included on the Language Priority List.
   3154          *
   3155          * <p>The returned list consists of language ranges from the given
   3156          * {@code ranges} and their equivalents found in the IANA Language
   3157          * Subtag Registry. For example, if the given {@code ranges} is
   3158          * {@code "Accept-Language: iw,en-us;q=0.7,en;q=0.3"}, the elements in
   3159          * the list to be returned are:
   3160          *
   3161          * <pre>
   3162          *  <b>Range</b>                                   <b>Weight</b>
   3163          *    "iw" (older tag for Hebrew)             1.0
   3164          *    "he" (new preferred code for Hebrew)    1.0
   3165          *    "en-us" (English, United States)        0.7
   3166          *    "en" (English)                          0.3
   3167          * </pre>
   3168          *
   3169          * Two language ranges, {@code "iw"} and {@code "he"}, have the same
   3170          * highest priority in the list. By adding {@code "he"} to the user's
   3171          * Language Priority List, locale-matching method can find Hebrew as a
   3172          * matching locale (or language tag) even if the application or system
   3173          * offers only {@code "he"} as a supported locale (or language tag).
   3174          *
   3175          * @param ranges a list of comma-separated language ranges or a list of
   3176          *     language ranges in the form of the "Accept-Language" header
   3177          *     defined in <a href="http://tools.ietf.org/html/rfc2616">RFC
   3178          *     2616</a>
   3179          * @return a Language Priority List consisting of language ranges
   3180          *     included in the given {@code ranges} and their equivalent
   3181          *     language ranges if available. The list is modifiable.
   3182          * @throws NullPointerException if {@code ranges} is null
   3183          * @throws IllegalArgumentException if a language range or a weight
   3184          *     found in the given {@code ranges} is ill-formed
   3185          */
   3186         public static List<LanguageRange> parse(String ranges) {
   3187             return LocaleMatcher.parse(ranges);
   3188         }
   3189 
   3190         /**
   3191          * Parses the given {@code ranges} to generate a Language Priority
   3192          * List, and then customizes the list using the given {@code map}.
   3193          * This method is equivalent to
   3194          * {@code mapEquivalents(parse(ranges), map)}.
   3195          *
   3196          * @param ranges a list of comma-separated language ranges or a list
   3197          *     of language ranges in the form of the "Accept-Language" header
   3198          *     defined in <a href="http://tools.ietf.org/html/rfc2616">RFC
   3199          *     2616</a>
   3200          * @param map a map containing information to customize language ranges
   3201          * @return a Language Priority List with customization. The list is
   3202          *     modifiable.
   3203          * @throws NullPointerException if {@code ranges} is null
   3204          * @throws IllegalArgumentException if a language range or a weight
   3205          *     found in the given {@code ranges} is ill-formed
   3206          * @see #parse(String)
   3207          * @see #mapEquivalents
   3208          */
   3209         public static List<LanguageRange> parse(String ranges,
   3210                                                 Map<String, List<String>> map) {
   3211             return mapEquivalents(parse(ranges), map);
   3212         }
   3213 
   3214         /**
   3215          * Generates a new customized Language Priority List using the given
   3216          * {@code priorityList} and {@code map}. If the given {@code map} is
   3217          * empty, this method returns a copy of the given {@code priorityList}.
   3218          *
   3219          * <p>In the map, a key represents a language range whereas a value is
   3220          * a list of equivalents of it. {@code '*'} cannot be used in the map.
   3221          * Each equivalent language range has the same weight value as its
   3222          * original language range.
   3223          *
   3224          * <pre>
   3225          *  An example of map:
   3226          *    <b>Key</b>                            <b>Value</b>
   3227          *      "zh" (Chinese)                 "zh",
   3228          *                                     "zh-Hans"(Simplified Chinese)
   3229          *      "zh-HK" (Chinese, Hong Kong)   "zh-HK"
   3230          *      "zh-TW" (Chinese, Taiwan)      "zh-TW"
   3231          * </pre>
   3232          *
   3233          * The customization is performed after modification using the IANA
   3234          * Language Subtag Registry.
   3235          *
   3236          * <p>For example, if a user's Language Priority List consists of five
   3237          * language ranges ({@code "zh"}, {@code "zh-CN"}, {@code "en"},
   3238          * {@code "zh-TW"}, and {@code "zh-HK"}), the newly generated Language
   3239          * Priority List which is customized using the above map example will
   3240          * consists of {@code "zh"}, {@code "zh-Hans"}, {@code "zh-CN"},
   3241          * {@code "zh-Hans-CN"}, {@code "en"}, {@code "zh-TW"}, and
   3242          * {@code "zh-HK"}.
   3243          *
   3244          * <p>{@code "zh-HK"} and {@code "zh-TW"} aren't converted to
   3245          * {@code "zh-Hans-HK"} nor {@code "zh-Hans-TW"} even if they are
   3246          * included in the Language Priority List. In this example, mapping
   3247          * is used to clearly distinguish Simplified Chinese and Traditional
   3248          * Chinese.
   3249          *
   3250          * <p>If the {@code "zh"}-to-{@code "zh"} mapping isn't included in the
   3251          * map, a simple replacement will be performed and the customized list
   3252          * won't include {@code "zh"} and {@code "zh-CN"}.
   3253          *
   3254          * @param priorityList user's Language Priority List
   3255          * @param map a map containing information to customize language ranges
   3256          * @return a new Language Priority List with customization. The list is
   3257          *     modifiable.
   3258          * @throws NullPointerException if {@code priorityList} is {@code null}
   3259          * @see #parse(String, Map)
   3260          */
   3261         public static List<LanguageRange> mapEquivalents(
   3262                                               List<LanguageRange>priorityList,
   3263                                               Map<String, List<String>> map) {
   3264             return LocaleMatcher.mapEquivalents(priorityList, map);
   3265         }
   3266 
   3267         /**
   3268          * Returns a hash code value for the object.
   3269          *
   3270          * @return  a hash code value for this object.
   3271          */
   3272         @Override
   3273         public int hashCode() {
   3274             if (hash == 0) {
   3275                 int result = 17;
   3276                 result = 37*result + range.hashCode();
   3277                 long bitsWeight = Double.doubleToLongBits(weight);
   3278                 result = 37*result + (int)(bitsWeight ^ (bitsWeight >>> 32));
   3279                 hash = result;
   3280             }
   3281             return hash;
   3282         }
   3283 
   3284         /**
   3285          * Compares this object to the specified object. The result is true if
   3286          * and only if the argument is not {@code null} and is a
   3287          * {@code LanguageRange} object that contains the same {@code range}
   3288          * and {@code weight} values as this object.
   3289          *
   3290          * @param obj the object to compare with
   3291          * @return  {@code true} if this object's {@code range} and
   3292          *     {@code weight} are the same as the {@code obj}'s; {@code false}
   3293          *     otherwise.
   3294          */
   3295         @Override
   3296         public boolean equals(Object obj) {
   3297             if (this == obj) {
   3298                 return true;
   3299             }
   3300             if (!(obj instanceof LanguageRange)) {
   3301                 return false;
   3302             }
   3303             LanguageRange other = (LanguageRange)obj;
   3304             return hash == other.hash
   3305                    && range.equals(other.range)
   3306                    && weight == other.weight;
   3307         }
   3308     }
   3309 
   3310     /**
   3311      * Returns a list of matching {@code Locale} instances using the filtering
   3312      * mechanism defined in RFC 4647.
   3313      *
   3314      * @param priorityList user's Language Priority List in which each language
   3315      *     tag is sorted in descending order based on priority or weight
   3316      * @param locales {@code Locale} instances used for matching
   3317      * @param mode filtering mode
   3318      * @return a list of {@code Locale} instances for matching language tags
   3319      *     sorted in descending order based on priority or weight, or an empty
   3320      *     list if nothing matches. The list is modifiable.
   3321      * @throws NullPointerException if {@code priorityList} or {@code locales}
   3322      *     is {@code null}
   3323      * @throws IllegalArgumentException if one or more extended language ranges
   3324      *     are included in the given list when
   3325      *     {@link FilteringMode#REJECT_EXTENDED_RANGES} is specified
   3326      *
   3327      * @since 1.8
   3328      */
   3329     public static List<Locale> filter(List<LanguageRange> priorityList,
   3330                                       Collection<Locale> locales,
   3331                                       FilteringMode mode) {
   3332         return LocaleMatcher.filter(priorityList, locales, mode);
   3333     }
   3334 
   3335     /**
   3336      * Returns a list of matching {@code Locale} instances using the filtering
   3337      * mechanism defined in RFC 4647. This is equivalent to
   3338      * {@link #filter(List, Collection, FilteringMode)} when {@code mode} is
   3339      * {@link FilteringMode#AUTOSELECT_FILTERING}.
   3340      *
   3341      * @param priorityList user's Language Priority List in which each language
   3342      *     tag is sorted in descending order based on priority or weight
   3343      * @param locales {@code Locale} instances used for matching
   3344      * @return a list of {@code Locale} instances for matching language tags
   3345      *     sorted in descending order based on priority or weight, or an empty
   3346      *     list if nothing matches. The list is modifiable.
   3347      * @throws NullPointerException if {@code priorityList} or {@code locales}
   3348      *     is {@code null}
   3349      *
   3350      * @since 1.8
   3351      */
   3352     public static List<Locale> filter(List<LanguageRange> priorityList,
   3353                                       Collection<Locale> locales) {
   3354         return filter(priorityList, locales, FilteringMode.AUTOSELECT_FILTERING);
   3355     }
   3356 
   3357     /**
   3358      * Returns a list of matching languages tags using the basic filtering
   3359      * mechanism defined in RFC 4647.
   3360      *
   3361      * @param priorityList user's Language Priority List in which each language
   3362      *     tag is sorted in descending order based on priority or weight
   3363      * @param tags language tags
   3364      * @param mode filtering mode
   3365      * @return a list of matching language tags sorted in descending order
   3366      *     based on priority or weight, or an empty list if nothing matches.
   3367      *     The list is modifiable.
   3368      * @throws NullPointerException if {@code priorityList} or {@code tags} is
   3369      *     {@code null}
   3370      * @throws IllegalArgumentException if one or more extended language ranges
   3371      *     are included in the given list when
   3372      *     {@link FilteringMode#REJECT_EXTENDED_RANGES} is specified
   3373      *
   3374      * @since 1.8
   3375      */
   3376     public static List<String> filterTags(List<LanguageRange> priorityList,
   3377                                           Collection<String> tags,
   3378                                           FilteringMode mode) {
   3379         return LocaleMatcher.filterTags(priorityList, tags, mode);
   3380     }
   3381 
   3382     /**
   3383      * Returns a list of matching languages tags using the basic filtering
   3384      * mechanism defined in RFC 4647. This is equivalent to
   3385      * {@link #filterTags(List, Collection, FilteringMode)} when {@code mode}
   3386      * is {@link FilteringMode#AUTOSELECT_FILTERING}.
   3387      *
   3388      * @param priorityList user's Language Priority List in which each language
   3389      *     tag is sorted in descending order based on priority or weight
   3390      * @param tags language tags
   3391      * @return a list of matching language tags sorted in descending order
   3392      *     based on priority or weight, or an empty list if nothing matches.
   3393      *     The list is modifiable.
   3394      * @throws NullPointerException if {@code priorityList} or {@code tags} is
   3395      *     {@code null}
   3396      *
   3397      * @since 1.8
   3398      */
   3399     public static List<String> filterTags(List<LanguageRange> priorityList,
   3400                                           Collection<String> tags) {
   3401         return filterTags(priorityList, tags, FilteringMode.AUTOSELECT_FILTERING);
   3402     }
   3403 
   3404     /**
   3405      * Returns a {@code Locale} instance for the best-matching language
   3406      * tag using the lookup mechanism defined in RFC 4647.
   3407      *
   3408      * @param priorityList user's Language Priority List in which each language
   3409      *     tag is sorted in descending order based on priority or weight
   3410      * @param locales {@code Locale} instances used for matching
   3411      * @return the best matching <code>Locale</code> instance chosen based on
   3412      *     priority or weight, or {@code null} if nothing matches.
   3413      * @throws NullPointerException if {@code priorityList} or {@code tags} is
   3414      *     {@code null}
   3415      *
   3416      * @since 1.8
   3417      */
   3418     public static Locale lookup(List<LanguageRange> priorityList,
   3419                                 Collection<Locale> locales) {
   3420         return LocaleMatcher.lookup(priorityList, locales);
   3421     }
   3422 
   3423     /**
   3424      * Returns the best-matching language tag using the lookup mechanism
   3425      * defined in RFC 4647.
   3426      *
   3427      * @param priorityList user's Language Priority List in which each language
   3428      *     tag is sorted in descending order based on priority or weight
   3429      * @param tags language tangs used for matching
   3430      * @return the best matching language tag chosen based on priority or
   3431      *     weight, or {@code null} if nothing matches.
   3432      * @throws NullPointerException if {@code priorityList} or {@code tags} is
   3433      *     {@code null}
   3434      *
   3435      * @since 1.8
   3436      */
   3437     public static String lookupTag(List<LanguageRange> priorityList,
   3438                                    Collection<String> tags) {
   3439         return LocaleMatcher.lookupTag(priorityList, tags);
   3440     }
   3441 
   3442 }
   3443