Home » openjdk-7 » java » util » [javadoc | source]

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

Home » openjdk-7 » java » util » [javadoc | source]