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