12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */
22ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/*
32ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (C) 2004-2014, International Business Machines Corporation and
52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved.
62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*/
82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.util;
92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.ParseException;
112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.ArrayList;
122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Arrays;
132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.BitSet;
142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Date;
152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.HashMap;
162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.List;
172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map;
182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.MissingResourceException;
192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.ResourceBundle;
202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.Utility;
222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.BreakIterator;
232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.Collator;
242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.DateFormat;
252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.NumberFormat;
262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.SimpleDateFormat;
272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/**
292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This convenience class provides a mechanism for bundling together different
302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * globalization preferences. It includes:
312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ul>
322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>A list of locales/languages in preference order</li>
332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>A territory</li>
342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>A currency</li>
352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>A timezone</li>
362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>A calendar</li>
372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>A collator (for language-sensitive sorting, searching, and matching).</li>
382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>Explicit overrides for date/time formats, etc.</li>
392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ul>
402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The class will heuristically compute implicit, heuristic values for the above
412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * based on available data if explicit values are not supplied. These implicit
422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * values can be presented to users for confirmation, or replacement if the
432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * values are incorrect.
442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * To reset any explicit field so that it will get heuristic values, pass in
462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * null. For example, myPreferences.setLocale(null);
472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * All of the heuristics can be customized by subclasses, by overriding
492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getTerritory(), guessCollator(), etc.
502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The class also supplies display names for languages, scripts, territories,
522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * currencies, timezones, etc. These are computed according to the
532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * locale/language preference list. Thus, if the preference is Breton; French;
542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * English, then the display name for a language will be returned in Breton if
552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * available, otherwise in French if available, otherwise in English.
562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The codes used to reference territory, currency, etc. are as defined elsewhere
582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in ICU, and are taken from CLDR (which reflects RFC 3066bis usage, ISO 4217,
592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and the TZ Timezone database identifiers).
602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <b>This is at a prototype stage, and has not incorporated all the design
622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * changes that we would like yet; further feedback is welcome.</b></p>
632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Note:
642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ul>
652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>to get the display name for the first day of the week, use the calendar +
662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * display names.</li>
672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>to get the work days, ask the calendar (when that is available).</li>
682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>to get papersize / measurement system/bidi-orientation, ask the locale
692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (when that is available there)</li>
702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>to get the field order in a date, and whether a time is 24hour or not,
712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ask the DateFormat (when that is available there)</li>
722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>it will support HOST locale when it becomes available (it is a special
732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * locale that will ask the services to use the host platform's values).</li>
742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ul>
752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
76836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android
77836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android
782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//TODO:
812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// - Add Holidays
822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// - Add convenience to get/take Locale as well as ULocale.
832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// - Add Lenient datetime formatting when that is available.
842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// - Should this be serializable?
852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// - Other utilities?
862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class GlobalizationPreferences implements Freezable<GlobalizationPreferences> {
882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Default constructor
91836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences(){}
942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Number Format type
96836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final int
992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NF_NUMBER = 0,      // NumberFormat.NUMBERSTYLE
1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NF_CURRENCY = 1,    // NumberFormat.CURRENCYSTYLE
1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NF_PERCENT = 2,     // NumberFormat.PERCENTSTYLE
1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NF_SCIENTIFIC = 3,  // NumberFormat.SCIENTIFICSTYLE
1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NF_INTEGER = 4;     // NumberFormat.INTEGERSTYLE
1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final int NF_LIMIT = NF_INTEGER + 1;
1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Date Format type
109836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final int
1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DF_FULL = DateFormat.FULL,      // 0
1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DF_LONG = DateFormat.LONG,      // 1
1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DF_MEDIUM = DateFormat.MEDIUM,  // 2
1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DF_SHORT = DateFormat.SHORT,    // 3
1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DF_NONE = 4;
1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final int DF_LIMIT = DF_NONE + 1;
1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * For selecting a choice of display names
122836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final int
1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_LOCALE = 0,
1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_LANGUAGE = 1,
1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_SCRIPT = 2,
1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_TERRITORY = 3,
1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_VARIANT = 4,
1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_KEYWORD = 5,
1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_KEYWORD_VALUE = 6,
1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_CURRENCY = 7,
1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_CURRENCY_SYMBOL = 8,
1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ID_TIMEZONE = 9;
1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    //private static final int ID_LIMIT = ID_TIMEZONE + 1;
1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Break iterator type
140836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final int
1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BI_CHARACTER = BreakIterator.KIND_CHARACTER,    // 0
1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BI_WORD = BreakIterator.KIND_WORD,              // 1
1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BI_LINE = BreakIterator.KIND_LINE,              // 2
1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BI_SENTENCE = BreakIterator.KIND_SENTENCE,      // 3
1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BI_TITLE = BreakIterator.KIND_TITLE;            // 4
1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final int BI_LIMIT = BI_TITLE + 1;
1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the language/locale priority list. If other information is
1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * not (yet) available, this is used to to produce a default value
1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * for the appropriate territory, currency, timezone, etc.  The
1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * user should be given the opportunity to correct those defaults
1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * in case they are incorrect.
1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param inputLocales list of locales in priority order, eg {"be", "fr"}
1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *     for Breton first, then French if that fails.
1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
161836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setLocales(List<ULocale> inputLocales) {
1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        locales = processLocales(inputLocales);
1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get a copy of the language/locale priority list
1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a copy of the language/locale priority list.
175836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public List<ULocale> getLocales() {
1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        List<ULocale> result;
1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (locales == null) {
1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = guessLocales();
1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = new ArrayList<ULocale>();
1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.addAll(locales);
1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Convenience function for getting the locales in priority order
1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param index The index (0..n) of the desired item.
1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return desired item. null if index is out of range
192836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public ULocale getLocale(int index) {
1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        List<ULocale> lcls = locales;
1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (lcls == null) {
1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            lcls = guessLocales();
1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (index >= 0 && index < lcls.size()) {
2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return lcls.get(index);
2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return null;
2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Convenience routine for setting the language/locale priority
2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * list from an array.
2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setLocales(List locales)
2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param uLocales list of locales in an array
2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
212836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setLocales(ULocale[] uLocales) {
2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return setLocales(Arrays.asList(uLocales));
2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Convenience routine for setting the language/locale priority
2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * list from a single locale/language.
2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setLocales(List locales)
2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param uLocale single locale
2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
228836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setLocale(ULocale uLocale) {
2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return setLocales(new ULocale[]{uLocale});
2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Convenience routine for setting the locale priority list from
2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * an Accept-Language string.
2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @see #setLocales(List locales)
2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param acceptLanguageString Accept-Language list, as defined by
2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *     Section 14.4 of the RFC 2616 (HTTP 1.1)
2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
244836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setLocales(String acceptLanguageString) {
2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] acceptLocales = null;
2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        try {
2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            acceptLocales = ULocale.parseAcceptLanguage(acceptLanguageString, true);
2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } catch (ParseException pe) {
2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //TODO: revisit after 3.8
2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Invalid Accept-Language string");
2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return setLocales(acceptLocales);
2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Convenience function to get a ResourceBundle instance using
2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the specified base name based on the language/locale priority list
2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * stored in this object.
2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param baseName the base name of the resource bundle, a fully qualified
2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * class name
2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a resource bundle for the given base name and locale based on the
2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * language/locale priority list stored in this object
269836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public ResourceBundle getResourceBundle(String baseName) {
2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return getResourceBundle(baseName, null);
2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Convenience function to get a ResourceBundle instance using
2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the specified base name and class loader based on the language/locale
2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * priority list stored in this object.
2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param baseName the base name of the resource bundle, a fully qualified
2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * class name
2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param loader the class object from which to load the resource bundle
2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a resource bundle for the given base name and locale based on the
2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * language/locale priority list stored in this object
285836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public ResourceBundle getResourceBundle(String baseName, ClassLoader loader) {
2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        UResourceBundle urb = null;
2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        UResourceBundle candidate = null;
2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String actualLocaleName = null;
2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        List<ULocale> fallbacks = getLocales();
2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < fallbacks.size(); i++) {
2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String localeName = (fallbacks.get(i)).toString();
2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (actualLocaleName != null && localeName.equals(actualLocaleName)) {
2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // Actual locale name in the previous round may exactly matches
2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // with the next fallback locale
2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                urb = candidate;
2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            try {
3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (loader == null) {
3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    candidate = UResourceBundle.getBundleInstance(baseName, localeName);
3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                else {
3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    candidate = UResourceBundle.getBundleInstance(baseName, localeName, loader);
3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (candidate != null) {
3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    actualLocaleName = candidate.getULocale().getName();
3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (actualLocaleName.equals(localeName)) {
3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        urb = candidate;
3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        break;
3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (urb == null) {
3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        // Preserve the available bundle as the last resort
3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        urb = candidate;
3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } catch (MissingResourceException mre) {
3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                actualLocaleName = null;
3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                continue;
3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (urb == null) {
3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new MissingResourceException("Can't find bundle for base name "
3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    + baseName, baseName, "");
3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return urb;
3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the territory, which is a valid territory according to for
3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * RFC 3066 (or successor).  If not otherwise set, default
3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * currency and timezone values will be set from this.  The user
3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * should be given the opportunity to correct those defaults in
3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * case they are incorrect.
3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param territory code
3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
339836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setTerritory(String territory) {
3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.territory = territory; // immutable, so don't need to clone
3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Gets the territory setting. If it wasn't explicitly set, it is
3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * computed from the general locale setting.
3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return territory code, explicit or implicit.
354836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String getTerritory() {
3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (territory == null) {
3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return guessTerritory();
3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return territory; // immutable, so don't need to clone
3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the currency code. If this has not been set, uses default for territory.
3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param currency Valid ISO 4217 currency code.
3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
368836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setCurrency(Currency currency) {
3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.currency = currency; // immutable, so don't need to clone
3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get a copy of the currency computed according to the settings.
3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return currency code, explicit or implicit.
382836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Currency getCurrency() {
3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (currency == null) {
3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return guessCurrency();
3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return currency; // immutable, so don't have to clone
3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the calendar. If this has not been set, uses default for territory.
3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param calendar arbitrary calendar
3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
396836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setCalendar(Calendar calendar) {
3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.calendar = (Calendar) calendar.clone(); // clone for safety
4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get a copy of the calendar according to the settings.
4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return calendar explicit or implicit.
410836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Calendar getCalendar() {
4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (calendar == null) {
4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return guessCalendar();
4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Calendar temp = (Calendar) calendar.clone(); // clone for safety
4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        temp.setTimeZone(getTimeZone());
4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        temp.setTimeInMillis(System.currentTimeMillis());
4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return temp;
4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets the timezone ID.  If this has not been set, uses default for territory.
4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param timezone a valid TZID (see UTS#35).
4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
427836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setTimeZone(TimeZone timezone) {
4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.timezone = (TimeZone) timezone.clone(); // clone for safety;
4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get the timezone. It was either explicitly set, or is
4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * heuristically computed from other settings.
4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return timezone, either implicitly or explicitly set
442836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public TimeZone getTimeZone() {
4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (timezone == null) {
4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return guessTimeZone();
4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return timezone.cloneAsThawed(); // clone for safety
4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get a copy of the collator according to the settings.
4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return collator explicit or implicit.
455836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Collator getCollator() {
4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (collator == null) {
4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return guessCollator();
4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        try {
4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return (Collator) collator.clone();  // clone for safety
4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } catch (CloneNotSupportedException e) {
4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new ICUCloneNotSupportedException("Error in cloning collator", e);
4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Explicitly set the collator for this object.
4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param collator The collator object to be passed.
4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
472836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setCollator(Collator collator) {
4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        try {
4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.collator = (Collator) collator.clone(); // clone for safety
4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } catch (CloneNotSupportedException e) {
4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new ICUCloneNotSupportedException("Error in cloning collator", e);
4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get a copy of the break iterator for the specified type according to the
4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * settings.
4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type break type - BI_CHARACTER or BI_WORD, BI_LINE, BI_SENTENCE, BI_TITLE
4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return break iterator explicit or implicit
492836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public BreakIterator getBreakIterator(int type) {
4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (type < BI_CHARACTER || type >= BI_LIMIT) {
4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Illegal break iterator type");
4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (breakIterators == null || breakIterators[type] == null) {
4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return guessBreakIterator(type);
5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return (BreakIterator) breakIterators[type].clone(); // clone for safety
5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Explicitly set the break iterator for this object.
5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type break type - BI_CHARACTER or BI_WORD, BI_LINE, BI_SENTENCE, BI_TITLE
5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param iterator a break iterator
5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
510836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setBreakIterator(int type, BreakIterator iterator) {
5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (type < BI_CHARACTER || type >= BI_LIMIT) {
5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Illegal break iterator type");
5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (breakIterators == null)
5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            breakIterators = new BreakIterator[BI_LIMIT];
5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        breakIterators[type] = (BreakIterator) iterator.clone(); // clone for safety
5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Get the display name for an ID: language, script, territory, currency, timezone...
5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Uses the language priority list to do so.
5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param id language code, script code, ...
5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type specifies the type of the ID: ID_LANGUAGE, etc.
5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the display name
532836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String getDisplayName(String id, int type) {
5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String result = id;
5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (ULocale locale : getLocales()) {
5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (!isAvailableLocale(locale, TYPE_GENERIC)) {
5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                continue;
5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            switch (type) {
5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_LOCALE:
5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayName(id, locale);
5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_LANGUAGE:
5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayLanguage(id, locale);
5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_SCRIPT:
5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayScript("und-" + id, locale);
5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_TERRITORY:
5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayCountry("und-" + id, locale);
5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_VARIANT:
5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // TODO fix variant parsing
5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayVariant("und-QQ-" + id, locale);
5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_KEYWORD:
5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayKeyword(id, locale);
5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_KEYWORD_VALUE:
5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String[] parts = new String[2];
5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                Utility.split(id,'=',parts);
5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = ULocale.getDisplayKeywordValue("und@"+id, parts[0], locale);
5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // TODO fix to tell when successful
5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (result.equals(parts[1])) {
5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    continue;
5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_CURRENCY_SYMBOL:
5702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_CURRENCY:
5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                Currency temp = new Currency(id);
5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result =temp.getName(locale, type==ID_CURRENCY
5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                     ? Currency.LONG_NAME
5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                     : Currency.SYMBOL_NAME, new boolean[1]);
5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // TODO: have method that doesn't take parameter. Add
5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // function to determine whether string is choice
5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // format.
5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // TODO: have method that doesn't require us
5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // to create a currency
5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case ID_TIMEZONE:
5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                SimpleDateFormat dtf = new SimpleDateFormat("vvvv",locale);
5832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                dtf.setTimeZone(TimeZone.getFrozenTimeZone(id));
5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = dtf.format(new Date());
5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // TODO, have method that doesn't require us to create a timezone
5862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // fix other hacks
5872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // hack for couldn't match
5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                boolean isBadStr = false;
5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // Matcher badTimeZone = Pattern.compile("[A-Z]{2}|.*\\s\\([A-Z]{2}\\)").matcher("");
5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // badtzstr = badTimeZone.reset(result).matches();
5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String teststr = result;
5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int sidx = result.indexOf('(');
5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int eidx = result.indexOf(')');
5952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (sidx != -1 && eidx != -1 && (eidx - sidx) == 3) {
5962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    teststr = result.substring(sidx+1, eidx);
5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (teststr.length() == 2) {
5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    isBadStr = true;
6002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    for (int i = 0; i < 2; i++) {
6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        char c = teststr.charAt(i);
6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (c < 'A' || 'Z' < c) {
6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            isBadStr = false;
6042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            break;
6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (isBadStr) {
6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    continue;
6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            default:
6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new IllegalArgumentException("Unknown type: " + type);
6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // TODO need better way of seeing if we fell back to root!!
6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // This will not work at all for lots of stuff
6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (!id.equals(result)) {
6192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return result;
6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Set an explicit date format. Overrides the locale priority list for
6272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * a particular combination of dateStyle and timeStyle. DF_NONE should
6282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * be used if for the style, where only the date or time format individually
6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * is being set.
6302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
6312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param dateStyle DF_FULL, DF_LONG, DF_MEDIUM, DF_SHORT or DF_NONE
6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param timeStyle DF_FULL, DF_LONG, DF_MEDIUM, DF_SHORT or DF_NONE
6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param format The date format
6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
635836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
6362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setDateFormat(int dateStyle, int timeStyle, DateFormat format) {
6382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
6392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
6402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (dateFormats == null) {
6422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            dateFormats = new DateFormat[DF_LIMIT][DF_LIMIT];
6432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        dateFormats[dateStyle][timeStyle] = (DateFormat) format.clone(); // for safety
6452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
6462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
6472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Gets a date format according to the current settings. If there
6502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * is an explicit (non-null) date/time format set, a copy of that
6512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * is returned. Otherwise, the language priority list is used.
6522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * DF_NONE should be used for the style, where only the date or
6532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * time format individually is being gotten.
6542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
6552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param dateStyle DF_FULL, DF_LONG, DF_MEDIUM, DF_SHORT or DF_NONE
6562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param timeStyle DF_FULL, DF_LONG, DF_MEDIUM, DF_SHORT or DF_NONE
6572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a DateFormat, according to the above description
658836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
6592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public DateFormat getDateFormat(int dateStyle, int timeStyle) {
6612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (dateStyle == DF_NONE && timeStyle == DF_NONE
6622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                || dateStyle < 0 || dateStyle >= DF_LIMIT
6632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                || timeStyle < 0 || timeStyle >= DF_LIMIT) {
6642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Illegal date format style arguments");
6652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DateFormat result = null;
6672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (dateFormats != null) {
6682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = dateFormats[dateStyle][timeStyle];
6692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (result != null) {
6712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = (DateFormat) result.clone(); // clone for safety
6722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // Not sure overriding configuration is what we really want...
6732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.setTimeZone(getTimeZone());
6742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
6752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = guessDateFormat(dateStyle, timeStyle);
6762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
6782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
6792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
6812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Gets a number format according to the current settings.  If
6822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * there is an explicit (non-null) number format set, a copy of
6832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * that is returned.  Otherwise, the language priority list is
6842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * used.
6852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
6862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param style NF_NUMBER, NF_CURRENCY, NF_PERCENT, NF_SCIENTIFIC, NF_INTEGER
687836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
6882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
6892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public NumberFormat getNumberFormat(int style) {
6902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (style < 0 || style >= NF_LIMIT) {
6912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Illegal number format type");
6922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NumberFormat result = null;
6942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (numberFormats != null) {
6952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = numberFormats[style];
6962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (result != null) {
6982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = (NumberFormat) result.clone(); // clone for safety (later optimize)
6992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
7002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = guessNumberFormat(style);
7012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
7032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
7042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
7062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Sets a number format explicitly. Overrides the general locale settings.
7072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
7082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param style NF_NUMBER, NF_CURRENCY, NF_PERCENT, NF_SCIENTIFIC, NF_INTEGER
7092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param format The number format
7102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
711836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
7122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
7132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences setNumberFormat(int style, NumberFormat format) {
7142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
7152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
7162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (numberFormats == null) {
7182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            numberFormats = new NumberFormat[NF_LIMIT];
7192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        numberFormats[style] = (NumberFormat) format.clone(); // for safety
7212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
7222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
7232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
7252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Restore the object to the initial state.
7262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
7272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return this, for chaining
728836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
7292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
7302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences reset() {
7312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isFrozen()) {
7322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new UnsupportedOperationException("Attempt to modify immutable object");
7332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        locales = null;
7352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        territory = null;
7362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        calendar = null;
7372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        collator = null;
7382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        breakIterators = null;
7392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        timezone = null;
7402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        currency = null;
7412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        dateFormats = null;
7422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        numberFormats = null;
7432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        implicitLocales = null;
7442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
7452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
7462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
7482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Process a language/locale priority list specified via <code>setLocales</code>.
7492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The input locale list may be expanded or re-ordered to represent the prioritized
7502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * language/locale order actually used by this object by the algorithm explained
7512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * below.
7522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>Step 1</b>: Move later occurrence of more specific locale before earlier
7552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * occurrence of less specific locale.
7562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Before: en, fr_FR, en_US, en_GB
7582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * After: en_US, en_GB, en, fr_FR
7602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>Step 2</b>: Append a fallback locale to each locale.
7632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Before: en_US, en_GB, en, fr_FR
7652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * After: en_US, en, en_GB, en, en, fr_FR, fr
7672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>Step 3</b>: Remove earlier occurrence of duplicated locale entries.
7702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Before: en_US, en, en_GB, en, en, fr_FR, fr
7722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * After: en_US, en_GB, en, fr_FR, fr
7742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <br>
7762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The final locale list is used to produce a default value for the appropriate territory,
7772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * currency, timezone, etc.  The list also represents the lookup order used in
7782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <code>getResourceBundle</code> for this object.  A subclass may override this method
7792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * to customize the algorithm used for populating the locale list.
7802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
7812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param inputLocales The list of input locales
782836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
7832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
7842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected List<ULocale> processLocales(List<ULocale> inputLocales) {
7852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        List<ULocale> result = new ArrayList<ULocale>();
7862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /*
7872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Step 1: Relocate later occurrence of more specific locale
7882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * before earlier occurrence of less specific locale.
7892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *
7902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Example:
7912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   Before - en_US, fr_FR, zh, en_US_Boston, zh_TW, zh_Hant, fr_CA
7922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   After  - en_US_Boston, en_US, fr_FR, zh_TW, zh_Hant, zh, fr_CA
7932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < inputLocales.size(); i++) {
7952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ULocale uloc = inputLocales.get(i);
7962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String language = uloc.getLanguage();
7982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String script = uloc.getScript();
7992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String country = uloc.getCountry();
8002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String variant = uloc.getVariant();
8012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean bInserted = false;
8032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (int j = 0; j < result.size(); j++) {
8042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // Check if this locale is more specific
8052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // than existing locale entries already inserted
8062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // in the destination list
8072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ULocale u = result.get(j);
8082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (!u.getLanguage().equals(language)) {
8092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    continue;
8102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
8112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String s = u.getScript();
8122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String c = u.getCountry();
8132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String v = u.getVariant();
8142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (!s.equals(script)) {
8152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (s.length() == 0 && c.length() == 0 && v.length() == 0) {
8162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        result.add(j, uloc);
8172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        bInserted = true;
8182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        break;
8192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    } else if (s.length() == 0 && c.equals(country)) {
8202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        // We want to see zh_Hant_HK before zh_HK
8212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        result.add(j, uloc);
8222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        bInserted = true;
8232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        break;
8242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    } else if (script.length() == 0 && country.length() > 0 && c.length() == 0) {
8252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        // We want to see zh_HK before zh_Hant
8262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        result.add(j, uloc);
8272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        bInserted = true;
8282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        break;
8292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
8302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    continue;
8312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
8322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (!c.equals(country)) {
8332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (c.length() == 0 && v.length() == 0) {
8342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        result.add(j, uloc);
8352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        bInserted = true;
8362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        break;
8372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
8382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
8392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (!v.equals(variant) && v.length() == 0) {
8402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    result.add(j, uloc);
8412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    bInserted = true;
8422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
8432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
8442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (!bInserted) {
8462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // Add this locale at the end of the list
8472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result.add(uloc);
8482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // TODO: Locale aliases might be resolved here
8522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // For example, zh_Hant_TW = zh_TW
8532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /*
8552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Step 2: Append fallback locales for each entry
8562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *
8572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Example:
8582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   Before - en_US_Boston, en_US, fr_FR, zh_TW, zh_Hant, zh, fr_CA
8592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   After  - en_US_Boston, en_US, en, en_US, en, fr_FR, fr,
8602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            zh_TW, zn, zh_Hant, zh, zh, fr_CA, fr
8612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int index = 0;
8632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        while (index < result.size()) {
8642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ULocale uloc = result.get(index);
8652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            while (true) {
8662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                uloc = uloc.getFallback();
8672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (uloc.getLanguage().length() == 0) {
8682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
8692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
8702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                index++;
8712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result.add(index, uloc);
8722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            index++;
8742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /*
8772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Step 3: Remove earlier occurrence of duplicated locales
8782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *
8792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Example:
8802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   Before - en_US_Boston, en_US, en, en_US, en, fr_FR, fr,
8812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            zh_TW, zn, zh_Hant, zh, zh, fr_CA, fr
8822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   After  - en_US_Boston, en_US, en, fr_FR, zh_TW, zh_Hant,
8832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            zh, fr_CA, fr
8842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        index = 0;
8862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        while (index < result.size() - 1) {
8872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ULocale uloc = result.get(index);
8882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean bRemoved = false;
8892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (int i = index + 1; i < result.size(); i++) {
8902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (uloc.equals(result.get(i))) {
8912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    // Remove earlier one
8922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    result.remove(index);
8932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    bRemoved = true;
8942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
8952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
8962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (!bRemoved) {
8982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                index++;
8992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
9002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
9022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
9032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
9062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
9072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
9082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
9092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
9102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param dateStyle
9112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param timeStyle
912836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
9132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
9142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected DateFormat guessDateFormat(int dateStyle, int timeStyle) {
9152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DateFormat result;
9162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale dfLocale = getAvailableLocale(TYPE_DATEFORMAT);
9172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (dfLocale == null) {
9182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            dfLocale = ULocale.ROOT;
9192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (timeStyle == DF_NONE) {
9212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = DateFormat.getDateInstance(getCalendar(), dateStyle, dfLocale);
9222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else if (dateStyle == DF_NONE) {
9232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = DateFormat.getTimeInstance(getCalendar(), timeStyle, dfLocale);
9242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
9252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = DateFormat.getDateTimeInstance(getCalendar(), dateStyle, timeStyle, dfLocale);
9262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
9282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
9292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
9312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
9322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
9332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
9342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
9352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param style
936836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
9372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
9382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected NumberFormat guessNumberFormat(int style) {
9392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        NumberFormat result;
9402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale nfLocale = getAvailableLocale(TYPE_NUMBERFORMAT);
9412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (nfLocale == null) {
9422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            nfLocale = ULocale.ROOT;
9432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        switch (style) {
9452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case NF_NUMBER:
9462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = NumberFormat.getInstance(nfLocale);
9472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
9482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case NF_SCIENTIFIC:
9492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = NumberFormat.getScientificInstance(nfLocale);
9502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
9512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case NF_INTEGER:
9522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = NumberFormat.getIntegerInstance(nfLocale);
9532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
9542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case NF_PERCENT:
9552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = NumberFormat.getPercentInstance(nfLocale);
9562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
9572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case NF_CURRENCY:
9582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = NumberFormat.getCurrencyInstance(nfLocale);
9592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.setCurrency(getCurrency());
9602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
9612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        default:
9622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Unknown number format style");
9632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
9652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
9662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
9682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
9692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
970836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
9712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
9722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected String guessTerritory() {
9732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String result;
9742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // pass through locales to see if there is a territory.
9752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (ULocale locale : getLocales()) {
9762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = locale.getCountry();
9772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (result.length() != 0) {
9782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return result;
9792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
9802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // if not, guess from the first language tag, or maybe from
9822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // intersection of languages, eg nl + fr => BE
9832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // TODO: fix using real data
9842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // for now, just use fixed values
9852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale firstLocale = getLocale(0);
9862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String language = firstLocale.getLanguage();
9872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String script = firstLocale.getScript();
9882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        result = null;
9892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (script.length() != 0) {
9902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = language_territory_hack_map.get(language + "_" + script);
9912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (result == null) {
9932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = language_territory_hack_map.get(language);
9942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (result == null) {
9962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result = "US"; // need *some* default
9972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
9992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
10002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
10022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics
10032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1004836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
10052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
10062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected Currency guessCurrency() {
10072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Currency.getInstance(new ULocale("und-" + getTerritory()));
10082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
10092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
10112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics
10122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
10132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
10142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1015836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
10162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
10172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected List<ULocale> guessLocales() {
10182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (implicitLocales == null) {
10192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            List<ULocale> result = new ArrayList<ULocale>(1);
10202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.add(ULocale.getDefault());
10212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            implicitLocales = processLocales(result);
10222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return implicitLocales;
10242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
10252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
10272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
10282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
10292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
10302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1031836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
10322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
10332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected Collator guessCollator() {
10342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale collLocale = getAvailableLocale(TYPE_COLLATOR);
10352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (collLocale == null) {
10362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            collLocale = ULocale.ROOT;
10372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Collator.getInstance(collLocale);
10392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
10402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
10422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
10432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
10442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
10452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
10462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type
1047836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
10482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
10492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected BreakIterator guessBreakIterator(int type) {
10502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BreakIterator bitr = null;
10512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale brkLocale = getAvailableLocale(TYPE_BREAKITERATOR);
10522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (brkLocale == null) {
10532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            brkLocale = ULocale.ROOT;
10542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        switch (type) {
10562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case BI_CHARACTER:
10572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bitr = BreakIterator.getCharacterInstance(brkLocale);
10582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
10592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case BI_TITLE:
10602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bitr = BreakIterator.getTitleInstance(brkLocale);
10612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
10622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case BI_WORD:
10632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bitr = BreakIterator.getWordInstance(brkLocale);
10642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
10652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case BI_LINE:
10662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bitr = BreakIterator.getLineInstance(brkLocale);
10672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
10682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case BI_SENTENCE:
10692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bitr = BreakIterator.getSentenceInstance(brkLocale);
10702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
10712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        default:
10722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Unknown break iterator type");
10732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return bitr;
10752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
10762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
10782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
10792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
10802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
10812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1082836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
10832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
10842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected TimeZone guessTimeZone() {
10852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // TODO fix using real data
10862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // for single-zone countries, pick that zone
10872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // for others, pick the most populous zone
10882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // for now, just use fixed value
10892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // NOTE: in a few cases can do better by looking at language.
10902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Eg haw+US should go to Pacific/Honolulu
10912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // fr+CA should go to America/Montreal
10922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String timezoneString = territory_tzid_hack_map.get(getTerritory());
10932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (timezoneString == null) {
10942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String[] attempt = TimeZone.getAvailableIDs(getTerritory());
10952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (attempt.length == 0) {
10962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                timezoneString = "Etc/GMT"; // gotta do something
10972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
10982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int i;
10992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // this all needs to be fixed to use real data. But for now, do slightly better by skipping cruft
11002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                for (i = 0; i < attempt.length; ++i) {
11012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (attempt[i].indexOf("/") >= 0) break;
11022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
11032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (i > attempt.length) i = 0;
11042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                timezoneString = attempt[i];
11052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return TimeZone.getTimeZone(timezoneString);
11082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
11112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * This function can be overridden by subclasses to use different heuristics.
11122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <b>It MUST return a 'safe' value,
11132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * one whose modification will not affect this object.</b>
11142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
1115836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
11162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
11172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    protected Calendar guessCalendar() {
11182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale calLocale = getAvailableLocale(TYPE_CALENDAR);
11192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (calLocale == null) {
11202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            calLocale = ULocale.US;
11212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Calendar.getInstance(getTimeZone(), calLocale);
11232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // PRIVATES
11262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private List<ULocale> locales;
11282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private String territory;
11292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private Currency currency;
11302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private TimeZone timezone;
11312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private Calendar calendar;
11322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private Collator collator;
11332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private BreakIterator[] breakIterators;
11342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private DateFormat[][] dateFormats;
11352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private NumberFormat[] numberFormats;
11362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private List<ULocale> implicitLocales;
11372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    {
11392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        reset();
11402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private ULocale getAvailableLocale(int type) {
11442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        List<ULocale> locs = getLocales();
11452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale result = null;
11462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < locs.size(); i++) {
11472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ULocale l = locs.get(i);
11482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (isAvailableLocale(l, type)) {
11492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = l;
11502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                break;
11512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
11542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private boolean isAvailableLocale(ULocale loc, int type) {
11572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BitSet bits = available_locales.get(loc);
11582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (bits != null && bits.get(type)) {
11592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return true;
11602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return false;
11622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
11652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Available locales for service types
11662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
11672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final HashMap<ULocale, BitSet> available_locales = new HashMap<ULocale, BitSet>();
11682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final int
11692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_GENERIC = 0,
11702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_CALENDAR = 1,
11712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_DATEFORMAT= 2,
11722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_NUMBERFORMAT = 3,
11732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_COLLATOR = 4,
11742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_BREAKITERATOR = 5,
11752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        TYPE_LIMIT = TYPE_BREAKITERATOR + 1;
11762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static {
11782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BitSet bits;
11792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] allLocales = ULocale.getAvailableLocales();
11802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < allLocales.length; i++) {
11812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits = new BitSet(TYPE_LIMIT);
11822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            available_locales.put(allLocales[i], bits);
11832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits.set(TYPE_GENERIC);
11842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] calLocales = Calendar.getAvailableULocales();
11872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < calLocales.length; i++) {
11882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits = available_locales.get(calLocales[i]);
11892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (bits == null) {
11902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                bits = new BitSet(TYPE_LIMIT);
11912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                available_locales.put(allLocales[i], bits);
11922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits.set(TYPE_CALENDAR);
11942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] dateLocales = DateFormat.getAvailableULocales();
11972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < dateLocales.length; i++) {
11982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits = available_locales.get(dateLocales[i]);
11992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (bits == null) {
12002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                bits = new BitSet(TYPE_LIMIT);
12012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                available_locales.put(allLocales[i], bits);
12022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
12032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits.set(TYPE_DATEFORMAT);
12042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
12052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] numLocales = NumberFormat.getAvailableULocales();
12072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < numLocales.length; i++) {
12082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits = available_locales.get(numLocales[i]);
12092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (bits == null) {
12102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                bits = new BitSet(TYPE_LIMIT);
12112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                available_locales.put(allLocales[i], bits);
12122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
12132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits.set(TYPE_NUMBERFORMAT);
12142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
12152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] collLocales = Collator.getAvailableULocales();
12172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < collLocales.length; i++) {
12182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits = available_locales.get(collLocales[i]);
12192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (bits == null) {
12202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                bits = new BitSet(TYPE_LIMIT);
12212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                available_locales.put(allLocales[i], bits);
12222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
12232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits.set(TYPE_COLLATOR);
12242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
12252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ULocale[] brkLocales = BreakIterator.getAvailableULocales();
12272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < brkLocales.length; i++) {
12282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits = available_locales.get(brkLocales[i]);
12292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            bits.set(TYPE_BREAKITERATOR);
12302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
12312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
12322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /** WARNING: All of this data is temporary, until we start importing from CLDR!!!
12342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
12352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
12362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final Map<String, String> language_territory_hack_map = new HashMap<String, String>();
12372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final String[][] language_territory_hack = {
12382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"af", "ZA"},
12392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"am", "ET"},
12402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ar", "SA"},
12412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"as", "IN"},
12422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ay", "PE"},
12432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"az", "AZ"},
12442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"bal", "PK"},
12452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"be", "BY"},
12462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"bg", "BG"},
12472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"bn", "IN"},
12482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"bs", "BA"},
12492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ca", "ES"},
12502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ch", "MP"},
12512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"cpe", "SL"},
12522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"cs", "CZ"},
12532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"cy", "GB"},
12542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"da", "DK"},
12552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"de", "DE"},
12562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"dv", "MV"},
12572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"dz", "BT"},
12582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"el", "GR"},
12592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"en", "US"},
12602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"es", "ES"},
12612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"et", "EE"},
12622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"eu", "ES"},
12632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"fa", "IR"},
12642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"fi", "FI"},
12652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"fil", "PH"},
12662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"fj", "FJ"},
12672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"fo", "FO"},
12682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"fr", "FR"},
12692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ga", "IE"},
12702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"gd", "GB"},
12712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"gl", "ES"},
12722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"gn", "PY"},
12732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"gu", "IN"},
12742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"gv", "GB"},
12752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ha", "NG"},
12762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"he", "IL"},
12772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"hi", "IN"},
12782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ho", "PG"},
12792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"hr", "HR"},
12802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ht", "HT"},
12812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"hu", "HU"},
12822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"hy", "AM"},
12832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"id", "ID"},
12842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"is", "IS"},
12852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"it", "IT"},
12862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ja", "JP"},
12872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ka", "GE"},
12882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"kk", "KZ"},
12892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"kl", "GL"},
12902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"km", "KH"},
12912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"kn", "IN"},
12922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ko", "KR"},
12932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"kok", "IN"},
12942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ks", "IN"},
12952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ku", "TR"},
12962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ky", "KG"},
12972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"la", "VA"},
12982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"lb", "LU"},
12992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ln", "CG"},
13002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"lo", "LA"},
13012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"lt", "LT"},
13022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"lv", "LV"},
13032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mai", "IN"},
13042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"men", "GN"},
13052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mg", "MG"},
13062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mh", "MH"},
13072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mk", "MK"},
13082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ml", "IN"},
13092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mn", "MN"},
13102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mni", "IN"},
13112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mo", "MD"},
13122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mr", "IN"},
13132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ms", "MY"},
13142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"mt", "MT"},
13152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"my", "MM"},
13162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"na", "NR"},
13172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"nb", "NO"},
13182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"nd", "ZA"},
13192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ne", "NP"},
13202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"niu", "NU"},
13212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"nl", "NL"},
13222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"nn", "NO"},
13232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"no", "NO"},
13242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"nr", "ZA"},
13252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"nso", "ZA"},
13262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ny", "MW"},
13272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"om", "KE"},
13282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"or", "IN"},
13292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"pa", "IN"},
13302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"pau", "PW"},
13312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"pl", "PL"},
13322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ps", "PK"},
13332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"pt", "BR"},
13342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"qu", "PE"},
13352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"rn", "BI"},
13362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ro", "RO"},
13372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ru", "RU"},
13382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"rw", "RW"},
13392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sd", "IN"},
13402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sg", "CF"},
13412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"si", "LK"},
13422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sk", "SK"},
13432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sl", "SI"},
13442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sm", "WS"},
13452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"so", "DJ"},
13462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sq", "CS"},
13472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sr", "CS"},
13482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ss", "ZA"},
13492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"st", "ZA"},
13502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sv", "SE"},
13512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sw", "KE"},
13522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ta", "IN"},
13532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"te", "IN"},
13542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tem", "SL"},
13552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tet", "TL"},
13562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"th", "TH"},
13572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ti", "ET"},
13582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tg", "TJ"},
13592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tk", "TM"},
13602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tkl", "TK"},
13612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tvl", "TV"},
13622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tl", "PH"},
13632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tn", "ZA"},
13642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"to", "TO"},
13652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tpi", "PG"},
13662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tr", "TR"},
13672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ts", "ZA"},
13682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"uk", "UA"},
13692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ur", "IN"},
13702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"uz", "UZ"},
13712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ve", "ZA"},
13722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"vi", "VN"},
13732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"wo", "SN"},
13742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"xh", "ZA"},
13752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"zh", "CN"},
13762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"zh_Hant", "TW"},
13772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"zu", "ZA"},
13782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"aa", "ET"},
13792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"byn", "ER"},
13802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"eo", "DE"},
13812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"gez", "ET"},
13822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"haw", "US"},
13832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"iu", "CA"},
13842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"kw", "GB"},
13852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sa", "IN"},
13862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sh", "HR"},
13872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"sid", "ET"},
13882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"syr", "SY"},
13892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tig", "ER"},
13902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"tt", "RU"},
13912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"wal", "ET"},  };
13922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static {
13932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < language_territory_hack.length; ++i) {
13942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            language_territory_hack_map.put(language_territory_hack[i][0],language_territory_hack[i][1]);
13952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
13962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
13972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Map<String, String> territory_tzid_hack_map = new HashMap<String, String>();
13992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final String[][] territory_tzid_hack = {
14002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"AQ", "Antarctica/McMurdo"},
14012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"AR", "America/Buenos_Aires"},
14022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"AU", "Australia/Sydney"},
14032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"BR", "America/Sao_Paulo"},
14042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"CA", "America/Toronto"},
14052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"CD", "Africa/Kinshasa"},
14062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"CL", "America/Santiago"},
14072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"CN", "Asia/Shanghai"},
14082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"EC", "America/Guayaquil"},
14092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ES", "Europe/Madrid"},
14102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"GB", "Europe/London"},
14112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"GL", "America/Godthab"},
14122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ID", "Asia/Jakarta"},
14132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"ML", "Africa/Bamako"},
14142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"MX", "America/Mexico_City"},
14152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"MY", "Asia/Kuala_Lumpur"},
14162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"NZ", "Pacific/Auckland"},
14172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"PT", "Europe/Lisbon"},
14182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"RU", "Europe/Moscow"},
14192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"UA", "Europe/Kiev"},
14202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"US", "America/New_York"},
14212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"UZ", "Asia/Tashkent"},
14222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"PF", "Pacific/Tahiti"},
14232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"FM", "Pacific/Kosrae"},
14242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"KI", "Pacific/Tarawa"},
14252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"KZ", "Asia/Almaty"},
14262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"MH", "Pacific/Majuro"},
14272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"MN", "Asia/Ulaanbaatar"},
14282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"SJ", "Arctic/Longyearbyen"},
14292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        {"UM", "Pacific/Midway"},
14302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    };
14312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static {
14322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < territory_tzid_hack.length; ++i) {
14332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            territory_tzid_hack_map.put(territory_tzid_hack[i][0],territory_tzid_hack[i][1]);
14342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
14362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // Freezable implementation
14382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private volatile boolean frozen;
14402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1442836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
14432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
14442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean isFrozen() {
14452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return frozen;
14462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
14472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1449836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
14502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
14512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences freeze() {
14522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        frozen = true;
14532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return this;
14542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
14552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1457836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
14582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
14592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public GlobalizationPreferences cloneAsThawed() {
14602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        try {
14612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            GlobalizationPreferences result = (GlobalizationPreferences) clone();
14622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.frozen = false;
14632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result;
14642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } catch (CloneNotSupportedException e) {
14652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // will always work
14662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
14672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
14692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}
14702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1471