| /* |
| ****************************************************************************** |
| * Copyright (C) 2003-2011, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ****************************************************************************** |
| */ |
| |
| package com.ibm.icu.util; |
| |
| import java.io.Serializable; |
| import java.text.ParseException; |
| import java.util.Iterator; |
| import java.util.Locale; |
| import java.util.MissingResourceException; |
| import java.util.Set; |
| import java.util.TreeMap; |
| |
| import com.ibm.icu.impl.ICUCache; |
| import com.ibm.icu.impl.LocaleIDParser; |
| import com.ibm.icu.impl.LocaleIDs; |
| import com.ibm.icu.impl.LocaleUtility; |
| import com.ibm.icu.impl.SimpleCache; |
| import com.ibm.icu.impl.locale.AsciiUtil; |
| |
| /** |
| * {@icuenhanced java.util.Locale}.{@icu _usage_} |
| * |
| * A class analogous to {@link java.util.Locale} that provides additional |
| * support for ICU protocol. In ICU 3.0 this class is enhanced to support |
| * RFC 3066 language identifiers. |
| * |
| * <p>Many classes and services in ICU follow a factory idiom, in |
| * which a factory method or object responds to a client request with |
| * an object. The request includes a locale (the <i>requested</i> |
| * locale), and the returned object is constructed using data for that |
| * locale. The system may lack data for the requested locale, in |
| * which case the locale fallback mechanism will be invoked until a |
| * populated locale is found (the <i>valid</i> locale). Furthermore, |
| * even when a populated locale is found (the <i>valid</i> locale), |
| * further fallback may be required to reach a locale containing the |
| * specific data required by the service (the <i>actual</i> locale). |
| * |
| * <p>ULocale performs <b>'normalization'</b> and <b>'canonicalization'</b> of locale ids. |
| * Normalization 'cleans up' ICU locale ids as follows: |
| * <ul> |
| * <li>language, script, country, variant, and keywords are properly cased<br> |
| * (lower, title, upper, upper, and lower case respectively)</li> |
| * <li>hyphens used as separators are converted to underscores</li> |
| * <li>three-letter language and country ids are converted to two-letter |
| * equivalents where available</li> |
| * <li>surrounding spaces are removed from keywords and values</li> |
| * <li>if there are multiple keywords, they are put in sorted order</li> |
| * </ul> |
| * Canonicalization additionally performs the following: |
| * <ul> |
| * <li>POSIX ids are converted to ICU format IDs</li> |
| * <li>'grandfathered' 3066 ids are converted to ICU standard form</li> |
| * <li>'PREEURO' and 'EURO' variants are converted to currency keyword form, |
| * with the currency |
| * id appropriate to the country of the locale (for PREEURO) or EUR (for EURO). |
| * </ul> |
| * All ULocale constructors automatically normalize the locale id. To handle |
| * POSIX ids, <code>canonicalize</code> can be called to convert the id |
| * to canonical form, or the <code>canonicalInstance</code> factory method |
| * can be called.</p> |
| * |
| * <p>This class provides selectors {@link #VALID_LOCALE} and {@link |
| * #ACTUAL_LOCALE} intended for use in methods named |
| * <tt>getLocale()</tt>. These methods exist in several ICU classes, |
| * including {@link com.ibm.icu.util.Calendar}, {@link |
| * com.ibm.icu.util.Currency}, {@link com.ibm.icu.text.UFormat}, |
| * {@link com.ibm.icu.text.BreakIterator}, |
| * <a href="../text/Collator.html" title="class in com.ibm.icu.text"><code>Collator</code></a>, |
| * {@link com.ibm.icu.text.DateFormatSymbols}, and {@link |
| * com.ibm.icu.text.DecimalFormatSymbols} and their subclasses, if |
| * any. Once an object of one of these classes has been created, |
| * <tt>getLocale()</tt> may be called on it to determine the valid and |
| * actual locale arrived at during the object's construction. |
| * |
| * <p>Note: The <i>actual</i> locale is returned correctly, but the <i>valid</i> |
| * locale is not, in most cases. |
| * |
| * @see java.util.Locale |
| * @author weiv |
| * @author Alan Liu |
| * @author Ram Viswanadha |
| * @stable ICU 2.8 |
| */ |
| public final class ULocale implements Serializable { |
| private static final long serialVersionUID = 1L; |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale ENGLISH = new ULocale("en", Locale.ENGLISH); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale FRENCH = new ULocale("fr", Locale.FRENCH); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale GERMAN = new ULocale("de", Locale.GERMAN); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale ITALIAN = new ULocale("it", Locale.ITALIAN); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale JAPANESE = new ULocale("ja", Locale.JAPANESE); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale KOREAN = new ULocale("ko", Locale.KOREAN); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale CHINESE = new ULocale("zh", Locale.CHINESE); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale SIMPLIFIED_CHINESE = new ULocale("zh_Hans", Locale.CHINESE); |
| |
| /** |
| * Useful constant for language. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale TRADITIONAL_CHINESE = new ULocale("zh_Hant", Locale.CHINESE); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale FRANCE = new ULocale("fr_FR", Locale.FRANCE); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale GERMANY = new ULocale("de_DE", Locale.GERMANY); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale ITALY = new ULocale("it_IT", Locale.ITALY); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale JAPAN = new ULocale("ja_JP", Locale.JAPAN); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale KOREA = new ULocale("ko_KR", Locale.KOREA); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale CHINA = new ULocale("zh_Hans_CN", Locale.CHINA); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale PRC = CHINA; |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale TAIWAN = new ULocale("zh_Hant_TW", Locale.TAIWAN); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale UK = new ULocale("en_GB", Locale.UK); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale US = new ULocale("en_US", Locale.US); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale CANADA = new ULocale("en_CA", Locale.CANADA); |
| |
| /** |
| * Useful constant for country/region. |
| * @stable ICU 3.0 |
| */ |
| public static final ULocale CANADA_FRENCH = new ULocale("fr_CA", Locale.CANADA_FRENCH); |
| |
| /** |
| * Handy constant. |
| */ |
| private static final String EMPTY_STRING = ""; |
| |
| // Used in both ULocale and LocaleIDParser, so moved up here. |
| private static final char UNDERSCORE = '_'; |
| |
| // default empty locale |
| private static final Locale EMPTY_LOCALE = new Locale("", ""); |
| |
| /** |
| * The root ULocale. |
| * @stable ICU 2.8 |
| */ |
| public static final ULocale ROOT = new ULocale("", EMPTY_LOCALE); |
| |
| private static final SimpleCache<Locale, ULocale> CACHE = new SimpleCache<Locale, ULocale>(); |
| |
| /** |
| * Cache the locale. |
| */ |
| private transient volatile Locale locale; |
| |
| /** |
| * The raw localeID that we were passed in. |
| */ |
| private String localeID; |
| |
| private static String[][] CANONICALIZE_MAP; |
| private static String[][] variantsToKeywords; |
| |
| private static void initCANONICALIZE_MAP() { |
| if (CANONICALIZE_MAP == null) { |
| /** |
| * This table lists pairs of locale ids for canonicalization. The |
| * The 1st item is the normalized id. The 2nd item is the |
| * canonicalized id. The 3rd is the keyword. The 4th is the keyword value. |
| */ |
| String[][] tempCANONICALIZE_MAP = { |
| // { EMPTY_STRING, "en_US_POSIX", null, null }, /* .NET name */ |
| { "C", "en_US_POSIX", null, null }, /* POSIX name */ |
| { "art_LOJBAN", "jbo", null, null }, /* registered name */ |
| { "az_AZ_CYRL", "az_Cyrl_AZ", null, null }, /* .NET name */ |
| { "az_AZ_LATN", "az_Latn_AZ", null, null }, /* .NET name */ |
| { "ca_ES_PREEURO", "ca_ES", "currency", "ESP" }, |
| { "cel_GAULISH", "cel__GAULISH", null, null }, /* registered name */ |
| { "de_1901", "de__1901", null, null }, /* registered name */ |
| { "de_1906", "de__1906", null, null }, /* registered name */ |
| { "de__PHONEBOOK", "de", "collation", "phonebook" }, /* Old ICU name */ |
| { "de_AT_PREEURO", "de_AT", "currency", "ATS" }, |
| { "de_DE_PREEURO", "de_DE", "currency", "DEM" }, |
| { "de_LU_PREEURO", "de_LU", "currency", "EUR" }, |
| { "el_GR_PREEURO", "el_GR", "currency", "GRD" }, |
| { "en_BOONT", "en__BOONT", null, null }, /* registered name */ |
| { "en_SCOUSE", "en__SCOUSE", null, null }, /* registered name */ |
| { "en_BE_PREEURO", "en_BE", "currency", "BEF" }, |
| { "en_IE_PREEURO", "en_IE", "currency", "IEP" }, |
| { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */ |
| { "es_ES_PREEURO", "es_ES", "currency", "ESP" }, |
| { "eu_ES_PREEURO", "eu_ES", "currency", "ESP" }, |
| { "fi_FI_PREEURO", "fi_FI", "currency", "FIM" }, |
| { "fr_BE_PREEURO", "fr_BE", "currency", "BEF" }, |
| { "fr_FR_PREEURO", "fr_FR", "currency", "FRF" }, |
| { "fr_LU_PREEURO", "fr_LU", "currency", "LUF" }, |
| { "ga_IE_PREEURO", "ga_IE", "currency", "IEP" }, |
| { "gl_ES_PREEURO", "gl_ES", "currency", "ESP" }, |
| { "hi__DIRECT", "hi", "collation", "direct" }, /* Old ICU name */ |
| { "it_IT_PREEURO", "it_IT", "currency", "ITL" }, |
| { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, |
| // { "nb_NO_NY", "nn_NO", null, null }, |
| { "nl_BE_PREEURO", "nl_BE", "currency", "BEF" }, |
| { "nl_NL_PREEURO", "nl_NL", "currency", "NLG" }, |
| { "pt_PT_PREEURO", "pt_PT", "currency", "PTE" }, |
| { "sl_ROZAJ", "sl__ROZAJ", null, null }, /* registered name */ |
| { "sr_SP_CYRL", "sr_Cyrl_RS", null, null }, /* .NET name */ |
| { "sr_SP_LATN", "sr_Latn_RS", null, null }, /* .NET name */ |
| { "sr_YU_CYRILLIC", "sr_Cyrl_RS", null, null }, /* Linux name */ |
| { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */ |
| { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", null, null }, /* Linux name */ |
| { "uz_UZ_CYRL", "uz_Cyrl_UZ", null, null }, /* .NET name */ |
| { "uz_UZ_LATN", "uz_Latn_UZ", null, null }, /* .NET name */ |
| { "zh_CHS", "zh_Hans", null, null }, /* .NET name */ |
| { "zh_CHT", "zh_Hant", null, null }, /* .NET name */ |
| { "zh_GAN", "zh__GAN", null, null }, /* registered name */ |
| { "zh_GUOYU", "zh", null, null }, /* registered name */ |
| { "zh_HAKKA", "zh__HAKKA", null, null }, /* registered name */ |
| { "zh_MIN", "zh__MIN", null, null }, /* registered name */ |
| { "zh_MIN_NAN", "zh__MINNAN", null, null }, /* registered name */ |
| { "zh_WUU", "zh__WUU", null, null }, /* registered name */ |
| { "zh_XIANG", "zh__XIANG", null, null }, /* registered name */ |
| { "zh_YUE", "zh__YUE", null, null } /* registered name */ |
| }; |
| |
| synchronized (ULocale.class) { |
| if (CANONICALIZE_MAP == null) { |
| CANONICALIZE_MAP = tempCANONICALIZE_MAP; |
| } |
| } |
| } |
| if (variantsToKeywords == null) { |
| /** |
| * This table lists pairs of locale ids for canonicalization. The |
| * The first item is the normalized variant id. |
| */ |
| String[][] tempVariantsToKeywords = { |
| { "EURO", "currency", "EUR" }, |
| { "PINYIN", "collation", "pinyin" }, /* Solaris variant */ |
| { "STROKE", "collation", "stroke" } /* Solaris variant */ |
| }; |
| |
| synchronized (ULocale.class) { |
| if (variantsToKeywords == null) { |
| variantsToKeywords = tempVariantsToKeywords; |
| } |
| } |
| } |
| } |
| |
| /* |
| * This table is used for mapping between ICU and special Java |
| * locales. When an ICU locale matches <minumum base> with |
| * <keyword>/<value>, the ICU locale is mapped to <Java> locale. |
| * For example, both ja_JP@calendar=japanese and ja@calendar=japanese |
| * are mapped to Java locale "ja_JP_JP". ICU locale "nn" is mapped |
| * to Java locale "no_NO_NY". |
| */ |
| private static final String[][] _javaLocaleMap = { |
| // { <Java>, <ICU base>, <keyword>, <value>, <minimum base> |
| { "ja_JP_JP", "ja_JP", "calendar", "japanese", "ja"}, |
| { "no_NO_NY", "nn_NO", null, null, "nn"}, |
| { "th_TH_TH", "th_TH", "numbers", "thai", "th"}, |
| }; |
| |
| /** |
| * Private constructor used by static initializers. |
| */ |
| private ULocale(String localeID, Locale locale) { |
| this.localeID = localeID; |
| this.locale = locale; |
| } |
| |
| /** |
| * Construct a ULocale object from a {@link java.util.Locale}. |
| * @param loc a JDK locale |
| */ |
| private ULocale(Locale loc) { |
| this.localeID = getName(forLocale(loc).toString()); |
| this.locale = loc; |
| } |
| |
| /** |
| * {@icu} Returns a ULocale object for a {@link java.util.Locale}. |
| * The ULocale is canonicalized. |
| * @param loc a JDK locale |
| * @stable ICU 3.2 |
| */ |
| public static ULocale forLocale(Locale loc) { |
| if (loc == null) { |
| return null; |
| } |
| ULocale result = CACHE.get(loc); |
| if (result == null) { |
| if (defaultULocale != null && loc == defaultULocale.locale) { |
| result = defaultULocale; |
| } else { |
| String locStr = loc.toString(); |
| if (locStr.length() == 0) { |
| result = ROOT; |
| } else { |
| for (int i = 0; i < _javaLocaleMap.length; i++) { |
| if (_javaLocaleMap[i][0].equals(locStr)) { |
| LocaleIDParser p = new LocaleIDParser(_javaLocaleMap[i][1]); |
| p.setKeywordValue(_javaLocaleMap[i][2], _javaLocaleMap[i][3]); |
| locStr = p.getName(); |
| break; |
| } |
| } |
| result = new ULocale(locStr, loc); |
| } |
| } |
| CACHE.put(loc, result); |
| } |
| return result; |
| } |
| |
| /** |
| * {@icu} Constructs a ULocale from a RFC 3066 locale ID. The locale ID consists |
| * of optional language, script, country, and variant fields in that order, |
| * separated by underscores, followed by an optional keyword list. The |
| * script, if present, is four characters long-- this distinguishes it |
| * from a country code, which is two characters long. Other fields |
| * are distinguished by position as indicated by the underscores. The |
| * start of the keyword list is indicated by '@', and consists of two |
| * or more keyword/value pairs separated by semicolons(';'). |
| * |
| * <p>This constructor does not canonicalize the localeID. So, for |
| * example, "zh__pinyin" remains unchanged instead of converting |
| * to "zh@collation=pinyin". By default ICU only recognizes the |
| * latter as specifying pinyin collation. Use {@link #createCanonical} |
| * or {@link #canonicalize} if you need to canonicalize the localeID. |
| * |
| * @param localeID string representation of the locale, e.g: |
| * "en_US", "sy_Cyrl_YU", "zh__pinyin", "es_ES@currency=EUR;collation=traditional" |
| * @stable ICU 2.8 |
| */ |
| public ULocale(String localeID) { |
| this.localeID = getName(localeID); |
| } |
| |
| /** |
| * Convenience overload of ULocale(String, String, String) for |
| * compatibility with java.util.Locale. |
| * @see #ULocale(String, String, String) |
| * @stable ICU 3.4 |
| */ |
| public ULocale(String a, String b) { |
| this(a, b, null); |
| } |
| |
| /** |
| * Constructs a ULocale from a localeID constructed from the three 'fields' a, b, and |
| * c. These fields are concatenated using underscores to form a localeID of the form |
| * a_b_c, which is then handled like the localeID passed to <code>ULocale(String |
| * localeID)</code>. |
| * |
| * <p>Java locale strings consisting of language, country, and |
| * variant will be handled by this form, since the country code |
| * (being shorter than four letters long) will not be interpreted |
| * as a script code. If a script code is present, the final |
| * argument ('c') will be interpreted as the country code. It is |
| * recommended that this constructor only be used to ease porting, |
| * and that clients instead use the single-argument constructor |
| * when constructing a ULocale from a localeID. |
| * @param a first component of the locale id |
| * @param b second component of the locale id |
| * @param c third component of the locale id |
| * @see #ULocale(String) |
| * @stable ICU 3.0 |
| */ |
| public ULocale(String a, String b, String c) { |
| localeID = getName(lscvToID(a, b, c, EMPTY_STRING)); |
| } |
| |
| /** |
| * {@icu} Creates a ULocale from the id by first canonicalizing the id. |
| * @param nonCanonicalID the locale id to canonicalize |
| * @return the locale created from the canonical version of the ID. |
| * @stable ICU 3.0 |
| */ |
| public static ULocale createCanonical(String nonCanonicalID) { |
| return new ULocale(canonicalize(nonCanonicalID), (Locale)null); |
| } |
| |
| private static String lscvToID(String lang, String script, String country, String variant) { |
| StringBuilder buf = new StringBuilder(); |
| |
| if (lang != null && lang.length() > 0) { |
| buf.append(lang); |
| } |
| if (script != null && script.length() > 0) { |
| buf.append(UNDERSCORE); |
| buf.append(script); |
| } |
| if (country != null && country.length() > 0) { |
| buf.append(UNDERSCORE); |
| buf.append(country); |
| } |
| if (variant != null && variant.length() > 0) { |
| if (country == null || country.length() == 0) { |
| buf.append(UNDERSCORE); |
| } |
| buf.append(UNDERSCORE); |
| buf.append(variant); |
| } |
| return buf.toString(); |
| } |
| |
| /** |
| * {@icu} Converts this ULocale object to a {@link java.util.Locale}. |
| * @return a JDK locale that either exactly represents this object |
| * or is the closest approximation. |
| * @stable ICU 2.8 |
| */ |
| public Locale toLocale() { |
| if (locale == null) { |
| LocaleIDParser p = new LocaleIDParser(localeID); |
| String base = p.getBaseName(); |
| for (int i = 0; i < _javaLocaleMap.length; i++) { |
| if (base.equals(_javaLocaleMap[i][1]) || base.equals(_javaLocaleMap[i][4])) { |
| if (_javaLocaleMap[i][2] != null) { |
| String val = p.getKeywordValue(_javaLocaleMap[i][2]); |
| if (val != null && val.equals(_javaLocaleMap[i][3])) { |
| p = new LocaleIDParser(_javaLocaleMap[i][0]); |
| break; |
| } |
| } else { |
| p = new LocaleIDParser(_javaLocaleMap[i][0]); |
| break; |
| } |
| } |
| } |
| String[] names = p.getLanguageScriptCountryVariant(); |
| locale = new Locale(names[0], names[2], names[3]); |
| } |
| return locale; |
| } |
| |
| private static ICUCache<String, String> nameCache = new SimpleCache<String, String>(); |
| /** |
| * Keep our own default ULocale. |
| */ |
| private static Locale defaultLocale = Locale.getDefault(); |
| private static ULocale defaultULocale = new ULocale(defaultLocale); |
| |
| /** |
| * Returns the current default ULocale. |
| * @stable ICU 2.8 |
| */ |
| public static ULocale getDefault() { |
| synchronized (ULocale.class) { |
| Locale currentDefault = Locale.getDefault(); |
| if (!defaultLocale.equals(currentDefault)) { |
| defaultLocale = currentDefault; |
| defaultULocale = new ULocale(defaultLocale); |
| } |
| return defaultULocale; |
| } |
| } |
| |
| /** |
| * {@icu} Sets the default ULocale. This also sets the default Locale. |
| * If the caller does not have write permission to the |
| * user.language property, a security exception will be thrown, |
| * and the default ULocale will remain unchanged. |
| * @param newLocale the new default locale |
| * @throws SecurityException if a security manager exists and its |
| * <code>checkPermission</code> method doesn't allow the operation. |
| * @throws NullPointerException if <code>newLocale</code> is null |
| * @see SecurityManager#checkPermission(java.security.Permission) |
| * @see java.util.PropertyPermission |
| * @stable ICU 3.0 |
| */ |
| public static synchronized void setDefault(ULocale newLocale){ |
| Locale.setDefault(newLocale.toLocale()); |
| defaultULocale = newLocale; |
| } |
| |
| /** |
| * This is for compatibility with Locale-- in actuality, since ULocale is |
| * immutable, there is no reason to clone it, so this API returns 'this'. |
| * @stable ICU 3.0 |
| */ |
| public Object clone() { |
| return this; |
| } |
| |
| /** |
| * Returns the hashCode. |
| * @stable ICU 3.0 |
| */ |
| public int hashCode() { |
| return localeID.hashCode(); |
| } |
| |
| /** |
| * Returns true if the other object is another ULocale with the |
| * same full name, or is a String localeID that matches the full name. |
| * Note that since names are not canonicalized, two ULocales that |
| * function identically might not compare equal. |
| * |
| * @return true if this Locale is equal to the specified object. |
| * @stable ICU 3.0 |
| */ |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj instanceof String) { |
| return localeID.equals((String)obj); |
| } |
| if (obj instanceof ULocale) { |
| return localeID.equals(((ULocale)obj).localeID); |
| } |
| return false; |
| } |
| |
| /** |
| * {@icunote} Unlike the Locale API, this returns an array of <code>ULocale</code>, |
| * not <code>Locale</code>. Returns a list of all installed locales. |
| * @stable ICU 3.0 |
| */ |
| public static ULocale[] getAvailableLocales() { |
| if (availableLocales == null) { |
| synchronized (ULocale.class) { |
| if (availableLocales == null) { |
| Locale[] locales = Locale.getAvailableLocales(); |
| availableLocales = new ULocale[locales.length]; |
| for (int i = 0; i < locales.length; i++) { |
| availableLocales[i] = ULocale.forLocale(locales[i]); |
| } |
| } |
| } |
| } |
| return availableLocales.clone(); |
| } |
| private static volatile ULocale[] availableLocales = null; |
| |
| /** |
| * Returns a list of all 2-letter country codes defined in ISO 3166. |
| * Can be used to create Locales. |
| * @stable ICU 3.0 |
| */ |
| public static String[] getISOCountries() { |
| return LocaleIDs.getISOCountries(); |
| } |
| |
| /** |
| * Returns a list of all 2-letter language codes defined in ISO 639. |
| * Can be used to create Locales. |
| * [NOTE: ISO 639 is not a stable standard-- some languages' codes have changed. |
| * The list this function returns includes both the new and the old codes for the |
| * languages whose codes have changed.] |
| * @stable ICU 3.0 |
| */ |
| public static String[] getISOLanguages() { |
| return LocaleIDs.getISOLanguages(); |
| } |
| |
| /** |
| * Returns the language code for this locale, which will either be the empty string |
| * or a lowercase ISO 639 code. |
| * @see #getDisplayLanguage() |
| * @see #getDisplayLanguage(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public String getLanguage() { |
| return getLanguage(localeID); |
| } |
| |
| /** |
| * Returns the language code for the locale ID, |
| * which will either be the empty string |
| * or a lowercase ISO 639 code. |
| * @see #getDisplayLanguage() |
| * @see #getDisplayLanguage(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public static String getLanguage(String localeID) { |
| return new LocaleIDParser(localeID).getLanguage(); |
| } |
| |
| /** |
| * {@icu} Returns the script code for this locale, which might be the empty string. |
| * @see #getDisplayScript() |
| * @see #getDisplayScript(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public String getScript() { |
| return getScript(localeID); |
| } |
| |
| /** |
| * {@icu} Returns the script code for the specified locale, which might be the empty |
| * string. |
| * @see #getDisplayScript() |
| * @see #getDisplayScript(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public static String getScript(String localeID) { |
| return new LocaleIDParser(localeID).getScript(); |
| } |
| |
| /** |
| * Returns the country/region code for this locale, which will either be the empty string |
| * or an uppercase ISO 3166 2-letter code. |
| * @see #getDisplayCountry() |
| * @see #getDisplayCountry(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public String getCountry() { |
| return getCountry(localeID); |
| } |
| |
| /** |
| * Returns the country/region code for this locale, which will either be the empty string |
| * or an uppercase ISO 3166 2-letter code. |
| * @param localeID The locale identification string. |
| * @see #getDisplayCountry() |
| * @see #getDisplayCountry(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public static String getCountry(String localeID) { |
| return new LocaleIDParser(localeID).getCountry(); |
| } |
| |
| /** |
| * Returns the variant code for this locale, which might be the empty string. |
| * @see #getDisplayVariant() |
| * @see #getDisplayVariant(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public String getVariant() { |
| return getVariant(localeID); |
| } |
| |
| /** |
| * Returns the variant code for the specified locale, which might be the empty string. |
| * @see #getDisplayVariant() |
| * @see #getDisplayVariant(ULocale) |
| * @stable ICU 3.0 |
| */ |
| public static String getVariant(String localeID) { |
| return new LocaleIDParser(localeID).getVariant(); |
| } |
| |
| /** |
| * {@icu} Returns the fallback locale for the specified locale, which might be the |
| * empty string. |
| * @stable ICU 3.2 |
| */ |
| public static String getFallback(String localeID) { |
| return getFallbackString(getName(localeID)); |
| } |
| |
| /** |
| * {@icu} Returns the fallback locale for this locale. If this locale is root, |
| * returns null. |
| * @stable ICU 3.2 |
| */ |
| public ULocale getFallback() { |
| if (localeID.length() == 0 || localeID.charAt(0) == '@') { |
| return null; |
| } |
| return new ULocale(getFallbackString(localeID), (Locale)null); |
| } |
| |
| /** |
| * Returns the given (canonical) locale id minus the last part before the tags. |
| */ |
| private static String getFallbackString(String fallback) { |
| int extStart = fallback.indexOf('@'); |
| if (extStart == -1) { |
| extStart = fallback.length(); |
| } |
| int last = fallback.lastIndexOf('_', extStart); |
| if (last == -1) { |
| last = 0; |
| } else { |
| // truncate empty segment |
| while (last > 0) { |
| if (fallback.charAt(last - 1) != '_') { |
| break; |
| } |
| last--; |
| } |
| } |
| return fallback.substring(0, last) + fallback.substring(extStart); |
| } |
| |
| /** |
| * {@icu} Returns the (normalized) base name for this locale. |
| * @return the base name as a String. |
| * @stable ICU 3.0 |
| */ |
| public String getBaseName() { |
| return getBaseName(localeID); |
| } |
| |
| /** |
| * {@icu} Returns the (normalized) base name for the specified locale. |
| * @param localeID the locale ID as a string |
| * @return the base name as a String. |
| * @stable ICU 3.0 |
| */ |
| public static String getBaseName(String localeID){ |
| if (localeID.indexOf('@') == -1) { |
| return localeID; |
| } |
| return new LocaleIDParser(localeID).getBaseName(); |
| } |
| |
| /** |
| * {@icu} Returns the (normalized) full name for this locale. |
| * |
| * @return String the full name of the localeID |
| * @stable ICU 3.0 |
| */ |
| public String getName() { |
| return localeID; // always normalized |
| } |
| |
| /** |
| * {@icu} Returns the (normalized) full name for the specified locale. |
| * |
| * @param localeID the localeID as a string |
| * @return String the full name of the localeID |
| * @stable ICU 3.0 |
| */ |
| public static String getName(String localeID){ |
| String name = nameCache.get(localeID); |
| if (name == null) { |
| name = new LocaleIDParser(localeID).getName(); |
| nameCache.put(localeID, name); |
| } |
| return name; |
| } |
| |
| /** |
| * Returns a string representation of this object. |
| * @stable ICU 3.0 |
| */ |
| public String toString() { |
| return localeID; |
| } |
| |
| /** |
| * {@icu} Returns an iterator over keywords for this locale. If there |
| * are no keywords, returns null. |
| * @return iterator over keywords, or null if there are no keywords. |
| * @stable ICU 3.0 |
| */ |
| public Iterator<String> getKeywords() { |
| return getKeywords(localeID); |
| } |
| |
| /** |
| * {@icu} Returns an iterator over keywords for the specified locale. If there |
| * are no keywords, returns null. |
| * @return an iterator over the keywords in the specified locale, or null |
| * if there are no keywords. |
| * @stable ICU 3.0 |
| */ |
| public static Iterator<String> getKeywords(String localeID){ |
| return new LocaleIDParser(localeID).getKeywords(); |
| } |
| |
| /** |
| * {@icu} Returns the value for a keyword in this locale. If the keyword is not |
| * defined, returns null. |
| * @param keywordName name of the keyword whose value is desired. Case insensitive. |
| * @return the value of the keyword, or null. |
| * @stable ICU 3.0 |
| */ |
| public String getKeywordValue(String keywordName){ |
| return getKeywordValue(localeID, keywordName); |
| } |
| |
| /** |
| * {@icu} Returns the value for a keyword in the specified locale. If the keyword is |
| * not defined, returns null. The locale name does not need to be normalized. |
| * @param keywordName name of the keyword whose value is desired. Case insensitive. |
| * @return String the value of the keyword as a string |
| * @stable ICU 3.0 |
| */ |
| public static String getKeywordValue(String localeID, String keywordName) { |
| return new LocaleIDParser(localeID).getKeywordValue(keywordName); |
| } |
| |
| /** |
| * {@icu} Returns the canonical name for the specified locale ID. This is used to |
| * convert POSIX and other grandfathered IDs to standard ICU form. |
| * @param localeID the locale id |
| * @return the canonicalized id |
| * @stable ICU 3.0 |
| */ |
| public static String canonicalize(String localeID){ |
| LocaleIDParser parser = new LocaleIDParser(localeID, true); |
| String baseName = parser.getBaseName(); |
| boolean foundVariant = false; |
| |
| // formerly, we always set to en_US_POSIX if the basename was empty, but |
| // now we require that the entire id be empty, so that "@foo=bar" |
| // will pass through unchanged. |
| // {dlf} I'd rather keep "" unchanged. |
| if (localeID.equals("")) { |
| return ""; |
| // return "en_US_POSIX"; |
| } |
| |
| // we have an ID in the form xx_Yyyy_ZZ_KKKKK |
| |
| initCANONICALIZE_MAP(); |
| |
| /* convert the variants to appropriate ID */ |
| for (int i = 0; i < variantsToKeywords.length; i++) { |
| String[] vals = variantsToKeywords[i]; |
| int idx = baseName.lastIndexOf("_" + vals[0]); |
| if (idx > -1) { |
| foundVariant = true; |
| |
| baseName = baseName.substring(0, idx); |
| if (baseName.endsWith("_")) { |
| baseName = baseName.substring(0, --idx); |
| } |
| parser.setBaseName(baseName); |
| parser.defaultKeywordValue(vals[1], vals[2]); |
| break; |
| } |
| } |
| |
| /* See if this is an already known locale */ |
| for (int i = 0; i < CANONICALIZE_MAP.length; i++) { |
| if (CANONICALIZE_MAP[i][0].equals(baseName)) { |
| foundVariant = true; |
| |
| String[] vals = CANONICALIZE_MAP[i]; |
| parser.setBaseName(vals[1]); |
| if (vals[2] != null) { |
| parser.defaultKeywordValue(vals[2], vals[3]); |
| } |
| break; |
| } |
| } |
| |
| /* total mondo hack for Norwegian, fortunately the main NY case is handled earlier */ |
| if (!foundVariant) { |
| if (parser.getLanguage().equals("nb") && parser.getVariant().equals("NY")) { |
| parser.setBaseName(lscvToID("nn", parser.getScript(), parser.getCountry(), null)); |
| } |
| } |
| |
| return parser.getName(); |
| } |
| |
| /** |
| * Given a keyword and a value, return a new locale with an updated |
| * keyword and value. If keyword is null, this removes all keywords from the locale id. |
| * Otherwise, if the value is null, this removes the value for this keyword from the |
| * locale id. Otherwise, this adds/replaces the value for this keyword in the locale id. |
| * The keyword and value must not be empty. |
| * @param keyword the keyword to add/remove, or null to remove all keywords. |
| * @param value the value to add/set, or null to remove this particular keyword. |
| * @return the updated locale |
| * @stable ICU 3.2 |
| */ |
| public ULocale setKeywordValue(String keyword, String value) { |
| return new ULocale(setKeywordValue(localeID, keyword, value), (Locale)null); |
| } |
| |
| /** |
| * Given a locale id, a keyword, and a value, return a new locale id with an updated |
| * keyword and value. If keyword is null, this removes all keywords from the locale id. |
| * Otherwise, if the value is null, this removes the value for this keyword from the |
| * locale id. Otherwise, this adds/replaces the value for this keyword in the locale id. |
| * The keyword and value must not be empty. |
| * @param localeID the locale id to modify |
| * @param keyword the keyword to add/remove, or null to remove all keywords. |
| * @param value the value to add/set, or null to remove this particular keyword. |
| * @return the updated locale id |
| * @stable ICU 3.2 |
| */ |
| public static String setKeywordValue(String localeID, String keyword, String value) { |
| LocaleIDParser parser = new LocaleIDParser(localeID); |
| parser.setKeywordValue(keyword, value); |
| return parser.getName(); |
| } |
| |
| /* |
| * Given a locale id, a keyword, and a value, return a new locale id with an updated |
| * keyword and value, if the keyword does not already have a value. The keyword and |
| * value must not be null or empty. |
| * @param localeID the locale id to modify |
| * @param keyword the keyword to add, if not already present |
| * @param value the value to add, if not already present |
| * @return the updated locale id |
| */ |
| /* private static String defaultKeywordValue(String localeID, String keyword, String value) { |
| LocaleIDParser parser = new LocaleIDParser(localeID); |
| parser.defaultKeywordValue(keyword, value); |
| return parser.getName(); |
| }*/ |
| |
| /** |
| * Returns a three-letter abbreviation for this locale's language. If the locale |
| * doesn't specify a language, returns the empty string. Otherwise, returns |
| * a lowercase ISO 639-2/T language code. |
| * The ISO 639-2 language codes can be found on-line at |
| * <a href="ftp://dkuug.dk/i18n/iso-639-2.txt"><code>ftp://dkuug.dk/i18n/iso-639-2.txt</code></a> |
| * @exception MissingResourceException Throws MissingResourceException if the |
| * three-letter language abbreviation is not available for this locale. |
| * @stable ICU 3.0 |
| */ |
| public String getISO3Language(){ |
| return getISO3Language(localeID); |
| } |
| |
| /** |
| * Returns a three-letter abbreviation for this locale's language. If the locale |
| * doesn't specify a language, returns the empty string. Otherwise, returns |
| * a lowercase ISO 639-2/T language code. |
| * The ISO 639-2 language codes can be found on-line at |
| * <a href="ftp://dkuug.dk/i18n/iso-639-2.txt"><code>ftp://dkuug.dk/i18n/iso-639-2.txt</code></a> |
| * @exception MissingResourceException Throws MissingResourceException if the |
| * three-letter language abbreviation is not available for this locale. |
| * @stable ICU 3.0 |
| */ |
| public static String getISO3Language(String localeID) { |
| return LocaleIDs.getISO3Language(getLanguage(localeID)); |
| } |
| |
| /** |
| * Returns a three-letter abbreviation for this locale's country/region. If the locale |
| * doesn't specify a country, returns the empty string. Otherwise, returns |
| * an uppercase ISO 3166 3-letter country code. |
| * @exception MissingResourceException Throws MissingResourceException if the |
| * three-letter country abbreviation is not available for this locale. |
| * @stable ICU 3.0 |
| */ |
| public String getISO3Country() { |
| return getISO3Country(localeID); |
| } |
| |
| /** |
| * Returns a three-letter abbreviation for this locale's country/region. If the locale |
| * doesn't specify a country, returns the empty string. Otherwise, returns |
| * an uppercase ISO 3166 3-letter country code. |
| * @exception MissingResourceException Throws MissingResourceException if the |
| * three-letter country abbreviation is not available for this locale. |
| * @stable ICU 3.0 |
| */ |
| public static String getISO3Country(String localeID) { |
| return LocaleIDs.getISO3Country(getCountry(localeID)); |
| } |
| |
| // display names |
| |
| /** |
| * Returns this locale's language localized for display in the default locale. |
| * @return the localized language name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayLanguage() { |
| return getDisplayLanguageInternal(this, getDefault(), false); |
| } |
| |
| /** |
| * {@icu} Returns this locale's language localized for display in the provided locale. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized language name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayLanguage(ULocale displayLocale) { |
| return getDisplayLanguageInternal(this, displayLocale, false); |
| } |
| |
| /** |
| * Returns a locale's language localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose language will be displayed |
| * @param displayLocaleID the id of the locale in which to display the name. |
| * @return the localized language name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayLanguage(String localeID, String displayLocaleID) { |
| return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID), |
| false); |
| } |
| |
| /** |
| * Returns a locale's language localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose language will be displayed. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized language name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayLanguage(String localeID, ULocale displayLocale) { |
| return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, false); |
| } |
| /** |
| * {@icu} Returns this locale's language localized for display in the default locale. |
| * If a dialect name is present in the data, then it is returned. |
| * @return the localized language name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String getDisplayLanguageWithDialect() { |
| return getDisplayLanguageInternal(this, getDefault(), true); |
| } |
| |
| /** |
| * {@icu} Returns this locale's language localized for display in the provided locale. |
| * If a dialect name is present in the data, then it is returned. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized language name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String getDisplayLanguageWithDialect(ULocale displayLocale) { |
| return getDisplayLanguageInternal(this, displayLocale, true); |
| } |
| |
| /** |
| * {@icu} Returns a locale's language localized for display in the provided locale. |
| * If a dialect name is present in the data, then it is returned. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose language will be displayed |
| * @param displayLocaleID the id of the locale in which to display the name. |
| * @return the localized language name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static String getDisplayLanguageWithDialect(String localeID, String displayLocaleID) { |
| return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID), |
| true); |
| } |
| |
| /** |
| * {@icu} Returns a locale's language localized for display in the provided locale. |
| * If a dialect name is present in the data, then it is returned. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose language will be displayed. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized language name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static String getDisplayLanguageWithDialect(String localeID, ULocale displayLocale) { |
| return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, true); |
| } |
| |
| private static String getDisplayLanguageInternal(ULocale locale, ULocale displayLocale, |
| boolean useDialect) { |
| // No dialect support |
| return locale.toLocale().getDisplayLanguage(displayLocale.toLocale()); |
| } |
| |
| /** |
| * {@icu} Returns this locale's script localized for display in the default locale. |
| * @return the localized script name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayScript() { |
| return getDisplayScriptInternal(this, getDefault()); |
| } |
| |
| /** |
| * {@icu} Returns this locale's script localized for display in the provided locale. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized script name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayScript(ULocale displayLocale) { |
| return getDisplayScriptInternal(this, displayLocale); |
| } |
| |
| /** |
| * {@icu} Returns a locale's script localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose script will be displayed |
| * @param displayLocaleID the id of the locale in which to display the name. |
| * @return the localized script name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayScript(String localeID, String displayLocaleID) { |
| return getDisplayScriptInternal(new ULocale(localeID), new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * {@icu} Returns a locale's script localized for display in the provided locale. |
| * @param localeID the id of the locale whose script will be displayed. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized script name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayScript(String localeID, ULocale displayLocale) { |
| return getDisplayScriptInternal(new ULocale(localeID), displayLocale); |
| } |
| |
| // displayLocaleID is canonical, localeID need not be since parsing will fix this. |
| private static String getDisplayScriptInternal(ULocale locale, ULocale displayLocale) { |
| // No localization, just return the script code |
| return locale.getScript(); |
| } |
| |
| /** |
| * Returns this locale's country localized for display in the default locale. |
| * @return the localized country name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayCountry() { |
| return getDisplayCountryInternal(this, getDefault()); |
| } |
| |
| /** |
| * Returns this locale's country localized for display in the provided locale. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized country name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayCountry(ULocale displayLocale){ |
| return getDisplayCountryInternal(this, displayLocale); |
| } |
| |
| /** |
| * Returns a locale's country localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose country will be displayed |
| * @param displayLocaleID the id of the locale in which to display the name. |
| * @return the localized country name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayCountry(String localeID, String displayLocaleID) { |
| return getDisplayCountryInternal(new ULocale(localeID), new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * Returns a locale's country localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose country will be displayed. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized country name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayCountry(String localeID, ULocale displayLocale) { |
| return getDisplayCountryInternal(new ULocale(localeID), displayLocale); |
| } |
| |
| // displayLocaleID is canonical, localeID need not be since parsing will fix this. |
| private static String getDisplayCountryInternal(ULocale locale, ULocale displayLocale) { |
| return locale.toLocale().getDisplayCountry(displayLocale.toLocale()); |
| } |
| |
| /** |
| * Returns this locale's variant localized for display in the default locale. |
| * @return the localized variant name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayVariant() { |
| return getDisplayVariantInternal(this, getDefault()); |
| } |
| |
| /** |
| * Returns this locale's variant localized for display in the provided locale. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized variant name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayVariant(ULocale displayLocale) { |
| return getDisplayVariantInternal(this, displayLocale); |
| } |
| |
| /** |
| * Returns a locale's variant localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose variant will be displayed |
| * @param displayLocaleID the id of the locale in which to display the name. |
| * @return the localized variant name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayVariant(String localeID, String displayLocaleID){ |
| return getDisplayVariantInternal(new ULocale(localeID), new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * Returns a locale's variant localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose variant will be displayed. |
| * @param displayLocale the locale in which to display the name. |
| * @return the localized variant name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayVariant(String localeID, ULocale displayLocale) { |
| return getDisplayVariantInternal(new ULocale(localeID), displayLocale); |
| } |
| |
| private static String getDisplayVariantInternal(ULocale locale, ULocale displayLocale) { |
| return locale.toLocale().getDisplayVariant(displayLocale.toLocale()); |
| } |
| |
| /** |
| * {@icu} Returns a keyword localized for display in the default locale. |
| * @param keyword the keyword to be displayed. |
| * @return the localized keyword name. |
| * @see #getKeywords() |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayKeyword(String keyword) { |
| return getDisplayKeywordInternal(keyword, getDefault()); |
| } |
| |
| /** |
| * {@icu} Returns a keyword localized for display in the specified locale. |
| * @param keyword the keyword to be displayed. |
| * @param displayLocaleID the id of the locale in which to display the keyword. |
| * @return the localized keyword name. |
| * @see #getKeywords(String) |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayKeyword(String keyword, String displayLocaleID) { |
| return getDisplayKeywordInternal(keyword, new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * {@icu} Returns a keyword localized for display in the specified locale. |
| * @param keyword the keyword to be displayed. |
| * @param displayLocale the locale in which to display the keyword. |
| * @return the localized keyword name. |
| * @see #getKeywords(String) |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayKeyword(String keyword, ULocale displayLocale) { |
| return getDisplayKeywordInternal(keyword, displayLocale); |
| } |
| |
| private static String getDisplayKeywordInternal(String keyword, ULocale displayLocale) { |
| // No localization |
| return keyword; |
| } |
| |
| /** |
| * {@icu} Returns a keyword value localized for display in the default locale. |
| * @param keyword the keyword whose value is to be displayed. |
| * @return the localized value name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayKeywordValue(String keyword) { |
| return getDisplayKeywordValueInternal(this, keyword, getDefault()); |
| } |
| |
| /** |
| * {@icu} Returns a keyword value localized for display in the specified locale. |
| * @param keyword the keyword whose value is to be displayed. |
| * @param displayLocale the locale in which to display the value. |
| * @return the localized value name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayKeywordValue(String keyword, ULocale displayLocale) { |
| return getDisplayKeywordValueInternal(this, keyword, displayLocale); |
| } |
| |
| /** |
| * {@icu} Returns a keyword value localized for display in the specified locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose keyword value is to be displayed. |
| * @param keyword the keyword whose value is to be displayed. |
| * @param displayLocaleID the id of the locale in which to display the value. |
| * @return the localized value name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayKeywordValue(String localeID, String keyword, |
| String displayLocaleID) { |
| return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, |
| new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * {@icu} Returns a keyword value localized for display in the specified locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the id of the locale whose keyword value is to be displayed. |
| * @param keyword the keyword whose value is to be displayed. |
| * @param displayLocale the id of the locale in which to display the value. |
| * @return the localized value name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayKeywordValue(String localeID, String keyword, |
| ULocale displayLocale) { |
| return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, displayLocale); |
| } |
| |
| // displayLocaleID is canonical, localeID need not be since parsing will fix this. |
| private static String getDisplayKeywordValueInternal(ULocale locale, String keyword, |
| ULocale displayLocale) { |
| keyword = AsciiUtil.toLowerString(keyword.trim()); |
| String value = locale.getKeywordValue(keyword); |
| return value; |
| } |
| |
| /** |
| * Returns this locale name localized for display in the default locale. |
| * @return the localized locale name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayName() { |
| return getDisplayNameInternal(this, getDefault()); |
| } |
| |
| /** |
| * Returns this locale name localized for display in the provided locale. |
| * @param displayLocale the locale in which to display the locale name. |
| * @return the localized locale name. |
| * @stable ICU 3.0 |
| */ |
| public String getDisplayName(ULocale displayLocale) { |
| return getDisplayNameInternal(this, displayLocale); |
| } |
| |
| /** |
| * Returns the locale ID localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the locale whose name is to be displayed. |
| * @param displayLocaleID the id of the locale in which to display the locale name. |
| * @return the localized locale name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayName(String localeID, String displayLocaleID) { |
| return getDisplayNameInternal(new ULocale(localeID), new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * Returns the locale ID localized for display in the provided locale. |
| * This is a cover for the ICU4C API. |
| * @param localeID the locale whose name is to be displayed. |
| * @param displayLocale the locale in which to display the locale name. |
| * @return the localized locale name. |
| * @stable ICU 3.0 |
| */ |
| public static String getDisplayName(String localeID, ULocale displayLocale) { |
| return getDisplayNameInternal(new ULocale(localeID), displayLocale); |
| } |
| |
| private static String getDisplayNameInternal(ULocale locale, ULocale displayLocale) { |
| // No localization, no script and keywords |
| return locale.toLocale().getDisplayName(displayLocale.toLocale()); |
| } |
| |
| /** |
| * {@icu} Returns this locale name localized for display in the default locale. |
| * If a dialect name is present in the locale data, then it is returned. |
| * @return the localized locale name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String getDisplayNameWithDialect() { |
| return getDisplayNameWithDialectInternal(this, getDefault()); |
| } |
| |
| /** |
| * {@icu} Returns this locale name localized for display in the provided locale. |
| * If a dialect name is present in the locale data, then it is returned. |
| * @param displayLocale the locale in which to display the locale name. |
| * @return the localized locale name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String getDisplayNameWithDialect(ULocale displayLocale) { |
| return getDisplayNameWithDialectInternal(this, displayLocale); |
| } |
| |
| /** |
| * {@icu} Returns the locale ID localized for display in the provided locale. |
| * If a dialect name is present in the locale data, then it is returned. |
| * This is a cover for the ICU4C API. |
| * @param localeID the locale whose name is to be displayed. |
| * @param displayLocaleID the id of the locale in which to display the locale name. |
| * @return the localized locale name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static String getDisplayNameWithDialect(String localeID, String displayLocaleID) { |
| return getDisplayNameWithDialectInternal(new ULocale(localeID), |
| new ULocale(displayLocaleID)); |
| } |
| |
| /** |
| * {@icu} Returns the locale ID localized for display in the provided locale. |
| * If a dialect name is present in the locale data, then it is returned. |
| * This is a cover for the ICU4C API. |
| * @param localeID the locale whose name is to be displayed. |
| * @param displayLocale the locale in which to display the locale name. |
| * @return the localized locale name. |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static String getDisplayNameWithDialect(String localeID, ULocale displayLocale) { |
| return getDisplayNameWithDialectInternal(new ULocale(localeID), displayLocale); |
| } |
| |
| private static String getDisplayNameWithDialectInternal(ULocale locale, ULocale displayLocale) { |
| // No dialect support, no script and keyword support |
| return locale.toLocale().getDisplayName(displayLocale.toLocale()); |
| } |
| |
| /** |
| * {@icu} Returns this locale's layout orientation for characters. The possible |
| * values are "left-to-right", "right-to-left", "top-to-bottom" or |
| * "bottom-to-top". |
| * @return The locale's layout orientation for characters. |
| * @stable ICU 4.0 |
| */ |
| public String getCharacterOrientation() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Returns this locale's layout orientation for lines. The possible |
| * values are "left-to-right", "right-to-left", "top-to-bottom" or |
| * "bottom-to-top". |
| * @return The locale's layout orientation for lines. |
| * @stable ICU 4.0 |
| */ |
| public String getLineOrientation() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Selector for <tt>getLocale()</tt> indicating the locale of the |
| * resource containing the data. This is always at or above the |
| * valid locale. If the valid locale does not contain the |
| * specific data being requested, then the actual locale will be |
| * above the valid locale. If the object was not constructed from |
| * locale data, then the valid locale is <i>null</i>. |
| * |
| * @draft ICU 2.8 (retain) |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static Type ACTUAL_LOCALE = new Type(); |
| |
| /** |
| * {@icu} Selector for <tt>getLocale()</tt> indicating the most specific |
| * locale for which any data exists. This is always at or above |
| * the requested locale, and at or below the actual locale. If |
| * the requested locale does not correspond to any resource data, |
| * then the valid locale will be above the requested locale. If |
| * the object was not constructed from locale data, then the |
| * actual locale is <i>null</i>. |
| * |
| * <p>Note: The valid locale will be returned correctly in ICU |
| * 3.0 or later. In ICU 2.8, it is not returned correctly. |
| * @draft ICU 2.8 (retain) |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static Type VALID_LOCALE = new Type(); |
| |
| /** |
| * Opaque selector enum for <tt>getLocale()</tt>. |
| * @see com.ibm.icu.util.ULocale |
| * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE |
| * @see com.ibm.icu.util.ULocale#VALID_LOCALE |
| * @draft ICU 2.8 (retainAll) |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static final class Type { |
| private Type() {} |
| } |
| |
| /** |
| * {@icu} Based on a HTTP formatted list of acceptable locales, determine an available |
| * locale for the user. NullPointerException is thrown if acceptLanguageList or |
| * availableLocales is null. If fallback is non-null, it will contain true if a |
| * fallback locale (one not in the acceptLanguageList) was returned. The value on |
| * entry is ignored. ULocale will be one of the locales in availableLocales, or the |
| * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in |
| * availableLocales matched). No ULocale array element should be null; behavior is |
| * undefined if this is the case. |
| * @param acceptLanguageList list in HTTP "Accept-Language:" format of acceptable locales |
| * @param availableLocales list of available locales. One of these will be returned. |
| * @param fallback if non-null, a 1-element array containing a boolean to be set with |
| * the fallback status |
| * @return one of the locales from the availableLocales list, or null if none match |
| * @stable ICU 3.4 |
| */ |
| public static ULocale acceptLanguage(String acceptLanguageList, ULocale[] availableLocales, |
| boolean[] fallback) { |
| if (acceptLanguageList == null) { |
| throw new NullPointerException(); |
| } |
| ULocale acceptList[] = null; |
| try { |
| acceptList = parseAcceptLanguage(acceptLanguageList, true); |
| } catch (ParseException pe) { |
| acceptList = null; |
| } |
| if (acceptList == null) { |
| return null; |
| } |
| return acceptLanguage(acceptList, availableLocales, fallback); |
| } |
| |
| /** |
| * {@icu} Based on a list of acceptable locales, determine an available locale for the |
| * user. NullPointerException is thrown if acceptLanguageList or availableLocales is |
| * null. If fallback is non-null, it will contain true if a fallback locale (one not |
| * in the acceptLanguageList) was returned. The value on entry is ignored. ULocale |
| * will be one of the locales in availableLocales, or the ROOT ULocale if if a ROOT |
| * locale was used as a fallback (because nothing else in availableLocales matched). |
| * No ULocale array element should be null; behavior is undefined if this is the case. |
| * @param acceptLanguageList list of acceptable locales |
| * @param availableLocales list of available locales. One of these will be returned. |
| * @param fallback if non-null, a 1-element array containing a boolean to be set with |
| * the fallback status |
| * @return one of the locales from the availableLocales list, or null if none match |
| * @stable ICU 3.4 |
| */ |
| |
| public static ULocale acceptLanguage(ULocale[] acceptLanguageList, ULocale[] |
| availableLocales, boolean[] fallback) { |
| // fallbacklist |
| int i,j; |
| if(fallback != null) { |
| fallback[0]=true; |
| } |
| for(i=0;i<acceptLanguageList.length;i++) { |
| ULocale aLocale = acceptLanguageList[i]; |
| boolean[] setFallback = fallback; |
| do { |
| for(j=0;j<availableLocales.length;j++) { |
| if(availableLocales[j].equals(aLocale)) { |
| if(setFallback != null) { |
| setFallback[0]=false; // first time with this locale - not a fallback. |
| } |
| return availableLocales[j]; |
| } |
| } |
| Locale loc = aLocale.toLocale(); |
| Locale parent = LocaleUtility.fallback(loc); |
| if(parent != null) { |
| aLocale = new ULocale(parent); |
| } else { |
| aLocale = null; |
| } |
| setFallback = null; // Do not set fallback in later iterations |
| } while (aLocale != null); |
| } |
| return null; |
| } |
| |
| /** |
| * {@icu} Based on a HTTP formatted list of acceptable locales, determine an available |
| * locale for the user. NullPointerException is thrown if acceptLanguageList or |
| * availableLocales is null. If fallback is non-null, it will contain true if a |
| * fallback locale (one not in the acceptLanguageList) was returned. The value on |
| * entry is ignored. ULocale will be one of the locales in availableLocales, or the |
| * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in |
| * availableLocales matched). No ULocale array element should be null; behavior is |
| * undefined if this is the case. This function will choose a locale from the |
| * ULocale.getAvailableLocales() list as available. |
| * @param acceptLanguageList list in HTTP "Accept-Language:" format of acceptable locales |
| * @param fallback if non-null, a 1-element array containing a boolean to be set with |
| * the fallback status |
| * @return one of the locales from the ULocale.getAvailableLocales() list, or null if |
| * none match |
| * @stable ICU 3.4 |
| */ |
| public static ULocale acceptLanguage(String acceptLanguageList, boolean[] fallback) { |
| return acceptLanguage(acceptLanguageList, ULocale.getAvailableLocales(), |
| fallback); |
| } |
| |
| /** |
| * {@icu} Based on an ordered array of acceptable locales, determine an available |
| * locale for the user. NullPointerException is thrown if acceptLanguageList or |
| * availableLocales is null. If fallback is non-null, it will contain true if a |
| * fallback locale (one not in the acceptLanguageList) was returned. The value on |
| * entry is ignored. ULocale will be one of the locales in availableLocales, or the |
| * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in |
| * availableLocales matched). No ULocale array element should be null; behavior is |
| * undefined if this is the case. This function will choose a locale from the |
| * ULocale.getAvailableLocales() list as available. |
| * @param acceptLanguageList ordered array of acceptable locales (preferred are listed first) |
| * @param fallback if non-null, a 1-element array containing a boolean to be set with |
| * the fallback status |
| * @return one of the locales from the ULocale.getAvailableLocales() list, or null if none match |
| * @stable ICU 3.4 |
| */ |
| public static ULocale acceptLanguage(ULocale[] acceptLanguageList, boolean[] fallback) { |
| return acceptLanguage(acceptLanguageList, ULocale.getAvailableLocales(), |
| fallback); |
| } |
| |
| /** |
| * Package local method used for parsing Accept-Language string |
| */ |
| static ULocale[] parseAcceptLanguage(String acceptLanguage, boolean isLenient) |
| throws ParseException { |
| class ULocaleAcceptLanguageQ implements Comparable<ULocaleAcceptLanguageQ> { |
| private double q; |
| private double serial; |
| public ULocaleAcceptLanguageQ(double theq, int theserial) { |
| q = theq; |
| serial = theserial; |
| } |
| public int compareTo(ULocaleAcceptLanguageQ other) { |
| if (q > other.q) { // reverse - to sort in descending order |
| return -1; |
| } else if (q < other.q) { |
| return 1; |
| } |
| if (serial < other.serial) { |
| return -1; |
| } else if (serial > other.serial) { |
| return 1; |
| } else { |
| return 0; // same object |
| } |
| } |
| } |
| |
| // parse out the acceptLanguage into an array |
| TreeMap<ULocaleAcceptLanguageQ, ULocale> map = |
| new TreeMap<ULocaleAcceptLanguageQ, ULocale>(); |
| StringBuilder languageRangeBuf = new StringBuilder(); |
| StringBuilder qvalBuf = new StringBuilder(); |
| int state = 0; |
| acceptLanguage += ","; // append comma to simplify the parsing code |
| int n; |
| boolean subTag = false; |
| boolean q1 = false; |
| for (n = 0; n < acceptLanguage.length(); n++) { |
| boolean gotLanguageQ = false; |
| char c = acceptLanguage.charAt(n); |
| switch (state) { |
| case 0: // before language-range start |
| if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { |
| // in language-range |
| languageRangeBuf.append(c); |
| state = 1; |
| subTag = false; |
| } else if (c == '*') { |
| languageRangeBuf.append(c); |
| state = 2; |
| } else if (c != ' ' && c != '\t') { |
| // invalid character |
| state = -1; |
| } |
| break; |
| case 1: // in language-range |
| if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { |
| languageRangeBuf.append(c); |
| } else if (c == '-') { |
| subTag = true; |
| languageRangeBuf.append(c); |
| } else if (c == '_') { |
| if (isLenient) { |
| subTag = true; |
| languageRangeBuf.append(c); |
| } else { |
| state = -1; |
| } |
| } else if ('0' <= c && c <= '9') { |
| if (subTag) { |
| languageRangeBuf.append(c); |
| } else { |
| // DIGIT is allowed only in language sub tag |
| state = -1; |
| } |
| } else if (c == ',') { |
| // language-q end |
| gotLanguageQ = true; |
| } else if (c == ' ' || c == '\t') { |
| // language-range end |
| state = 3; |
| } else if (c == ';') { |
| // before q |
| state = 4; |
| } else { |
| // invalid character for language-range |
| state = -1; |
| } |
| break; |
| case 2: // saw wild card range |
| if (c == ',') { |
| // language-q end |
| gotLanguageQ = true; |
| } else if (c == ' ' || c == '\t') { |
| // language-range end |
| state = 3; |
| } else if (c == ';') { |
| // before q |
| state = 4; |
| } else { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 3: // language-range end |
| if (c == ',') { |
| // language-q end |
| gotLanguageQ = true; |
| } else if (c == ';') { |
| // before q |
| state =4; |
| } else if (c != ' ' && c != '\t') { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 4: // before q |
| if (c == 'q') { |
| // before equal |
| state = 5; |
| } else if (c != ' ' && c != '\t') { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 5: // before equal |
| if (c == '=') { |
| // before q value |
| state = 6; |
| } else if (c != ' ' && c != '\t') { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 6: // before q value |
| if (c == '0') { |
| // q value start with 0 |
| q1 = false; |
| qvalBuf.append(c); |
| state = 7; |
| } else if (c == '1') { |
| // q value start with 1 |
| qvalBuf.append(c); |
| state = 7; |
| } else if (c == '.') { |
| if (isLenient) { |
| qvalBuf.append(c); |
| state = 8; |
| } else { |
| state = -1; |
| } |
| } else if (c != ' ' && c != '\t') { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 7: // q value start |
| if (c == '.') { |
| // before q value fraction part |
| qvalBuf.append(c); |
| state = 8; |
| } else if (c == ',') { |
| // language-q end |
| gotLanguageQ = true; |
| } else if (c == ' ' || c == '\t') { |
| // after q value |
| state = 10; |
| } else { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 8: // before q value fraction part |
| if ('0' <= c || c <= '9') { |
| if (q1 && c != '0' && !isLenient) { |
| // if q value starts with 1, the fraction part must be 0 |
| state = -1; |
| } else { |
| // in q value fraction part |
| qvalBuf.append(c); |
| state = 9; |
| } |
| } else { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 9: // in q value fraction part |
| if ('0' <= c && c <= '9') { |
| if (q1 && c != '0') { |
| // if q value starts with 1, the fraction part must be 0 |
| state = -1; |
| } else { |
| qvalBuf.append(c); |
| } |
| } else if (c == ',') { |
| // language-q end |
| gotLanguageQ = true; |
| } else if (c == ' ' || c == '\t') { |
| // after q value |
| state = 10; |
| } else { |
| // invalid |
| state = -1; |
| } |
| break; |
| case 10: // after q value |
| if (c == ',') { |
| // language-q end |
| gotLanguageQ = true; |
| } else if (c != ' ' && c != '\t') { |
| // invalid |
| state = -1; |
| } |
| break; |
| } |
| if (state == -1) { |
| // error state |
| throw new ParseException("Invalid Accept-Language", n); |
| } |
| if (gotLanguageQ) { |
| double q = 1.0; |
| if (qvalBuf.length() != 0) { |
| try { |
| q = Double.parseDouble(qvalBuf.toString()); |
| } catch (NumberFormatException nfe) { |
| // Already validated, so it should never happen |
| q = 1.0; |
| } |
| if (q > 1.0) { |
| q = 1.0; |
| } |
| } |
| if (languageRangeBuf.charAt(0) != '*') { |
| int serial = map.size(); |
| ULocaleAcceptLanguageQ entry = new ULocaleAcceptLanguageQ(q, serial); |
| // sort in reverse order.. 1.0, 0.9, 0.8 .. etc |
| map.put(entry, new ULocale(canonicalize(languageRangeBuf.toString()))); |
| } |
| |
| // reset buffer and parse state |
| languageRangeBuf.setLength(0); |
| qvalBuf.setLength(0); |
| state = 0; |
| } |
| } |
| if (state != 0) { |
| // Well, the parser should handle all cases. So just in case. |
| throw new ParseException("Invalid AcceptlLanguage", n); |
| } |
| |
| // pull out the map |
| ULocale acceptList[] = map.values().toArray(new ULocale[map.size()]); |
| return acceptList; |
| } |
| |
| /** |
| * {@icu} Adds the likely subtags for a provided locale ID, per the algorithm |
| * described in the following CLDR technical report: |
| * |
| * http://www.unicode.org/reports/tr35/#Likely_Subtags |
| * |
| * If the provided ULocale instance is already in the maximal form, or there is no |
| * data available available for maximization, it will be returned. For example, |
| * "und-Zzzz" cannot be maximized, since there is no reasonable maximization. |
| * Otherwise, a new ULocale instance with the maximal form is returned. |
| * |
| * Examples: |
| * |
| * "en" maximizes to "en_Latn_US" |
| * |
| * "de" maximizes to "de_Latn_US" |
| * |
| * "sr" maximizes to "sr_Cyrl_RS" |
| * |
| * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.) |
| * |
| * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.) |
| * |
| * @param loc The ULocale to maximize |
| * @return The maximized ULocale instance. |
| * @stable ICU 4.0 |
| */ |
| public static ULocale addLikelySubtags(ULocale loc) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Minimizes the subtags for a provided locale ID, per the algorithm described |
| * in the following CLDR technical report:<blockquote> |
| * |
| * <a href="http://www.unicode.org/reports/tr35/#Likely_Subtags" |
| *>http://www.unicode.org/reports/tr35/#Likely_Subtags</a></blockquote> |
| * |
| * If the provided ULocale instance is already in the minimal form, or there |
| * is no data available for minimization, it will be returned. Since the |
| * minimization algorithm relies on proper maximization, see the comments |
| * for addLikelySubtags for reasons why there might not be any data. |
| * |
| * Examples:<pre> |
| * |
| * "en_Latn_US" minimizes to "en" |
| * |
| * "de_Latn_US" minimizes to "de" |
| * |
| * "sr_Cyrl_RS" minimizes to "sr" |
| * |
| * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the |
| * script, and minimizing to "zh" would imply "zh_Hans_CN".) </pre> |
| * |
| * @param loc The ULocale to minimize |
| * @return The minimized ULocale instance. |
| * @stable ICU 4.0 |
| */ |
| public static ULocale minimizeSubtags(ULocale loc) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| // -------------------------------- |
| // BCP47/OpenJDK APIs |
| // -------------------------------- |
| |
| /** |
| * {@icu} The key for the private use locale extension ('x'). |
| * |
| * @see #getExtension(char) |
| * @see Builder#setExtension(char, String) |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static final char PRIVATE_USE_EXTENSION = 'x'; |
| |
| /** |
| * {@icu} The key for Unicode locale extension ('u'). |
| * |
| * @see #getExtension(char) |
| * @see Builder#setExtension(char, String) |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static final char UNICODE_LOCALE_EXTENSION = 'u'; |
| |
| /** |
| * {@icu} Returns the extension (or private use) value associated with |
| * the specified singleton key, or null if there is no extension |
| * associated with the key. To be valid, the key must be one |
| * of <code>[0-9A-Za-z]</code>. Keys are case-insensitive, so |
| * for example 'z' and 'Z' represent the same extension. |
| * |
| * @param key the extension key |
| * @return the extension, or null if this locale defines no |
| * extension for the specified key |
| * @throws IllegalArgumentException if the key is not valid |
| * @see #PRIVATE_USE_EXTENSION |
| * @see #UNICODE_LOCALE_EXTENSION |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String getExtension(char key) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Returns the set of extension keys associated with this locale, or the |
| * empty set if it has no extensions. The returned set is unmodifiable. |
| * |
| * @return the set of extension keys, or the empty set if this locale has |
| * no extensions |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Set<Character> getExtensionKeys() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Returns the Unicode locale type associated with the specified Unicode |
| * locale key for this locale. Unicode locale keywrods are specified |
| * by the 'u' extension and consist of key/type pairs. The key must be |
| * two alphanumeric characters in length, or an IllegalArgumentException |
| * is thrown. |
| * @param key the Unicode locale key |
| * @return the Unicode locale type associated with the key, or null if the |
| * locale does not define a value for the key. |
| * @throws IllegalArgumentException if the key is not valid. |
| * |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String getUnicodeLocaleType(String key) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Returns the set of keys for Unicode locale keywords defined by this locale, |
| * or null if this locale has no locale extension. The returned set is |
| * immutable. |
| * |
| * @return the set of the Unicode locale keys, or null |
| * |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Set<String> getUnicodeLocaleKeys() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Returns a well-formed IETF BCP 47 language tag representing |
| * this locale. |
| * |
| * <p> |
| * If this <code>ULocale</code> object has language, country, or variant |
| * that does not satisfy the IETF BCP 47 language tag syntax requirements, |
| * this method handles these fields as described below: |
| * <p> |
| * <b>Language:</b> If language is empty or ill-formed (for example "a" or "e2"), |
| * it will be emitted as "und" (Undetermined). |
| * <p> |
| * <b>Country:</b> If country is ill-formed (for example "12" or "USA"), it |
| * will be omitted. |
| * <p> |
| * <b>Variant:</b> Variant is treated as consisting of subtags separated by |
| * underscore and converted to lower case letters. 'Well-formed' subtags |
| * consist of either an ASCII letter followed by 4-7 ASCII characters, or an |
| * ASCII digit followed by 3-7 ASCII characters. If well-formed, the variant |
| * is emitted as each subtag in order (separated by hyphen). Otherwise: |
| * <ul> |
| * <li>if all sub-segments consist of 1 to 8 ASCII alphanumerics (for example |
| * "WIN", "WINDOWS_XP", "SOLARIS_10"), the first ill-formed variant subtag |
| * and all following sub-segments will be emitted as private use subtags prefixed |
| * by the special private use subtag "variant" followed by each subtag in order |
| * (separated by hyphen). For example, locale "en_US_WIN" is converted to language |
| * tag "en-US-x-variant-win", locale "de_WINDOWS_XP" is converted to language tag |
| * "de-windows-x-variant-xp". If this locale has a private use extension value, |
| * the special private use subtags prefixed by "variant" are appended after the |
| * locale's private use value. |
| * <li>if any subtag does not consist of 1 to 8 ASCII alphanumerics, the |
| * variant will be truncated and the problematic subtag and all following |
| * sub-segments will be omitted. If the remainder is non-empty, it will be |
| * emitted as a private use subtag as above (even if the remainder turns out |
| * to be well-formed). For example, "Solaris_isjustthecoolestthing" is emitted |
| * as "x-jvariant-Solaris", not as "solaris".</li> |
| * </ul> |
| * |
| * <p><b>Note:</b> Although the language tag created by this method |
| * satisfies the syntax requirements defined by the IETF BCP 47 |
| * specification, it is not always a valid BCP 47 language tag. |
| * For example, |
| * <pre> |
| * new ULocale("xx_YY").toLanguageTag(); |
| * </pre> |
| * will return "xx-YY", but the language subtag "xx" and the region subtag "YY" |
| * are invalid because they are not registered in the |
| * <a href="http://www.iana.org/assignments/language-subtag-registry"> |
| * IANA Language Subtag Registry</a>. |
| * |
| * @return a BCP47 language tag representing the locale |
| * @see #forLanguageTag(String) |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public String toLanguageTag() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * {@icu} Returns a locale for the specified IETF BCP 47 language tag string. |
| * If the specified language tag contains any ill-formed subtags, |
| * the first such subtag and all following subtags are ignored. |
| * |
| * <p>This implements the 'Language-Tag' production of BCP47, and |
| * so supports grandfathered (regular and irregular) as well as |
| * private use language tags. Stand alone private use tags are |
| * represented as empty language and extension 'x-whatever', |
| * and grandfathered tags are converted to their canonical replacements |
| * where they exist. Note that a few grandfathered tags have no |
| * modern replacement; these will be converted using the fallback |
| * described above so some information might be lost. |
| * |
| * <p>For a list of grandfathered tags, see the |
| * <a href="http://www.iana.org/assignments/language-subtag-registry"> |
| * IANA Language Subtag Registry</a>. |
| * |
| * <p><b>Notes:</b> This method converts private use subtags prefixed |
| * by "variant" to variant field in the result locale. For example, |
| * the code below will return "POSIX". |
| * <pre> |
| * ULocale.forLanguageTag("en-US-x-variant-posix).getVariant(); |
| * </pre> |
| * |
| * @param languageTag the language tag |
| * @return the locale that best represents the language tag |
| * @exception NullPointerException if <code>languageTag</code> is <code>null</code> |
| * @see #toLanguageTag() |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static ULocale forLanguageTag(String languageTag) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| |
| /** |
| * <code>Builder</code> is used to build instances of <code>ULocale</code> |
| * from values configured by the setter. Unlike the <code>ULocale</code> |
| * constructors, the <code>Builder</code> checks if a value configured by a |
| * setter satisfies the syntactical requirements defined by the <code>ULocale</code> |
| * class. A <code>ULocale</code> object created by a <code>Builder</code> is |
| * well-formed and can be transformed to a well-formed IETF BCP 47 language tag |
| * without losing information. |
| * |
| * <p> |
| * <b>Note:</b> The <code>ULocale</code> class does not provide |
| * any syntactical restrictions on variant, while BCP 47 |
| * requires each variant subtag to be 5 to 8 alphanumeric letters or a single |
| * numeric letter followed by 3 alphanumeric letters. By default, |
| * the <code>setVariant</code> method throws <code>IllformedLocaleException</code> |
| * for a variant that does not satisfy the syntax above. If it is |
| * necessary to support such a variant, you could use the constructor <code> |
| * Builder(boolean isLenientVariant)</code> passing <code>true</code> to |
| * skip the syntax validation for variant. However, you should keep in |
| * mind that a <code>Locale</code> object created this way might lose |
| * the variant information when transformed to a BCP 47 language tag. |
| * |
| * <p> |
| * The following example shows how to create a <code>ULocale</code> object |
| * with the <code>Builder</code>. |
| * <blockquote> |
| * <pre> |
| * ULocale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build(); |
| * </pre> |
| * </blockquote> |
| * |
| * <p>Builders can be reused; <code>clear()</code> resets all |
| * fields to their default values. |
| * |
| * @see ULocale#toLanguageTag() |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static final class Builder { |
| |
| /** |
| * Constructs an empty Builder. The default value of all |
| * fields, extensions, and private use information is the |
| * empty string. |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder() { |
| throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Constructs an empty Builder with an option whether to allow |
| * <code>setVariant</code> to accept a value that does not |
| * conform to the IETF BCP 47 variant subtag's syntax requirements. |
| * |
| * @param isLenientVariant When true, this <code>Builder</code> |
| * will accept an ill-formed variant. |
| * @see #setVariant(String) |
| * |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder(boolean isLenientVariant) { |
| throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Returns true if this <code>Builder</code> accepts a value that does |
| * not conform to the IETF BCP 47 variant subtag's syntax requirements |
| * in <code>setVariant</code> |
| * |
| * @return true if this <code>Build</code> accepts an ill-formed variant. |
| * |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public boolean isLenientVariant() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| |
| /** |
| * Resets the <code>Builder</code> to match the provided <code>locale</code>. |
| * The previous state of the builder is discarded. Fields that do |
| * not conform to the <code>ULocale</code> class specification, for example, |
| * a single letter language, are ill-formed. |
| * |
| * @param locale the locale |
| * @return this builder |
| * @throws IllformedLocaleException if <code>locale</code> has |
| * any ill-formed fields. |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setLocale(ULocale locale) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Resets the builder to match the provided IETF BCP 47 language tag. |
| * The previous state of the builder is discarded. |
| * |
| * @param languageTag the language tag |
| * @return this builder |
| * @throws IllformedLocaleException if <code>languageTag</code> is ill-formed. |
| * @throws NullPointerException if <code>languageTag</code> is null. |
| * @see ULocale#forLanguageTag(String) |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setLanguageTag(String languageTag) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Sets the language. If <code>language</code> is the empty string, |
| * the language in this <code>Builder</code> will be removed. |
| * Typical language value is a two or three-letter language |
| * code as defined in ISO639. |
| * Well-formed values are any string of two to eight alpha |
| * letters. This method accepts upper case alpha letters |
| * [A-Z], but the language value in the <code>ULocale</code> |
| * created by the <code>Builder</code> is always normalized |
| * to lower case letters. |
| * |
| * @param language the language |
| * @return this builder |
| * @throws IllformedLocaleException if <code>language</code> is ill-formed |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setLanguage(String language) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Sets the script. If <code>script</code> is the empty string, |
| * the script in this <code>Builder</code> is removed. |
| * Typical script value is a four-letter script code as defined by ISO 15924. |
| * Well-formed values are any string of four alpha letters. |
| * This method accepts both upper and lower case alpha letters [a-zA-Z], |
| * but the script value in the <code>ULocale</code> created by the |
| * <code>Builder</code> is always normalized to title case |
| * (the first letter is upper case and the rest of letters are lower case). |
| * |
| * @param script the script |
| * @return this builder |
| * @throws IllformedLocaleException if <code>script</code> is ill-formed |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setScript(String script) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Sets the region. If region is the empty string, the region |
| * in this <code>Builder</code> is removed. |
| * Typical region value is a two-letter ISO 3166 code or a three-digit UN M.49 |
| * area code. Well-formed values are any two-letter or three-digit string. |
| * This method accepts lower case letters [a-z], but the country value in |
| * the <code>ULocale</code> created by the <code>Builder</code> is always |
| * normalized to upper case. |
| * |
| * @param region the region |
| * @return this builder |
| * @throws IllformedLocaleException if <code>region</code> is ill-formed |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setRegion(String region) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Sets the variant. If variant is the empty string, the |
| * variant in this <code>Builder</code> is removed. |
| * <p> |
| * <b>Note:</b> By default, this method checks if <code>variant</code> |
| * satisfies the IETF BCP 47 variant subtag's syntax requirements. |
| * However, the <code>ULocale</code> class itself does not impose any syntactical |
| * restriction on variant. When a <code>Builder</code> is created by the |
| * constructor <code>Builder(boolean isLenientVariant)</code> |
| * with <code>true</code>, this method skips the syntax check. |
| * |
| * @param variant the variant |
| * @return this builder |
| * @throws IllformedLocaleException if <code>variant</code> is ill-formed |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setVariant(String variant) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Sets the extension for the given key. If the value is the |
| * empty string, the extension is removed. Legal keys are |
| * characters in the ranges <code>[0-9A-Za-z]</code>. Keys |
| * are case-insensitive, so for example 'z' and 'Z' represent |
| * the same extension. In general, well-formed values are any |
| * series of fields of two to eight alphanumeric characters, |
| * separated by hyphen or underscore. |
| * |
| * <p><b>Note:</b> The key {@link ULocale#UNICODE_LOCALE_EXTENSION |
| * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension. |
| * Setting a value for this key replaces any existing Unicode locale key/type |
| * pairs with those defined in the extension. |
| * To be well-formed, a value for this extension must meet the additional |
| * constraints that each locale key is two alphanumeric characters, |
| * followed by at least one locale type subtag represented by |
| * three to eight alphanumeric characters, and that the keys and types |
| * be legal Unicode locale keys and values. |
| * |
| * <p><b>Note:</b> The key {@link ULocale#PRIVATE_USE_EXTENSION |
| * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be |
| * well-formed, the value for this key needs only to have fields of one to |
| * eight alphanumeric characters, not two to eight as in the general case. |
| * |
| * @param key the extension key |
| * @param value the extension value |
| * @return this builder |
| * @throws IllformedLocaleException if <code>key</code> is illegal |
| * or <code>value</code> is ill-formed |
| * @see #setUnicodeLocaleKeyword(String, String) |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setExtension(char key, String value) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Sets the Unicode locale keyword type for the given key. If the |
| * value is the empty string, the Unicode keyword is removed. |
| * Well-formed keys are strings of two alphanumeric characters. |
| * Well-formed types are one or more subtags where each of them is |
| * three to eight alphanumeric characters. |
| * <p> |
| * <b>Note</b>:Setting the 'u' extension replaces all Unicode locale |
| * keywords with those defined in the extension. |
| * @param key the Unicode locale key |
| * @param type the Unicode locale type |
| * @return this builder |
| * @throws IllformedLocaleException if <code>key</code> or <code>type</code> |
| * is ill-formed |
| * @see #setExtension(char, String) |
| * |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder setUnicodeLocaleKeyword(String key, String type) { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Resets the builder to its initial, empty state. |
| * |
| * @return this builder |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder clear() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Resets the extensions to their initial, empty state. |
| * Language, script, region and variant are unchanged. |
| * |
| * @return this builder |
| * @see #setExtension(char, String) |
| * |
| * @draft ICU 4.2 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public Builder clearExtensions() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| |
| /** |
| * Returns an instance of Locale created from the fields set |
| * on this builder. |
| * |
| * @return a new Locale |
| * |
| * @draft ICU 4.4 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public ULocale build() { |
| throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base"); |
| } |
| } |
| } |