12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 6f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Copyright (C) 2001-2016, International Business Machines Corporation and 7f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * others. All Rights Reserved. 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl; 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collections; 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Locale; 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Set; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 191537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller/** 201537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * @hide Only a subset of ICU is exposed in Android 21836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller */ 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class ICULocaleService extends ICUService { 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private ULocale fallbackLocale; 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String fallbackLocaleName; 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct an ICULocaleService. 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ICULocaleService() { 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct an ICULocaleService with a name (useful for debugging). 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ICULocaleService(String name) { 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super(name); 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience override for callers using locales. This calls 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * get(ULocale, int, ULocale[]) with KIND_ANY for kind and null for 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * actualReturn. 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object get(ULocale locale) { 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return get(locale, LocaleKey.KIND_ANY, null); 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience override for callers using locales. This calls 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * get(ULocale, int, ULocale[]) with a null actualReturn. 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object get(ULocale locale, int kind) { 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return get(locale, kind, null); 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience override for callers using locales. This calls 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * get(ULocale, int, ULocale[]) with KIND_ANY for kind. 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object get(ULocale locale, ULocale[] actualReturn) { 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return get(locale, LocaleKey.KIND_ANY, actualReturn); 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience override for callers using locales. This uses 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * createKey(ULocale.toString(), kind) to create a key, calls getKey, and then 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if actualReturn is not null, returns the actualResult from 68f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * getKey (stripping any prefix) into a ULocale. 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object get(ULocale locale, int kind, ULocale[] actualReturn) { 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Key key = createKey(locale, kind); 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (actualReturn == null) { 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getKey(key); 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String[] temp = new String[1]; 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object result = getKey(key, temp); 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (result != null) { 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int n = temp[0].indexOf("/"); 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (n >= 0) { 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp[0] = temp[0].substring(n+1); 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller actualReturn[0] = new ULocale(temp[0]); 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience override for callers using locales. This calls 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * registerObject(Object, ULocale, int kind, boolean visible) 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * passing KIND_ANY for the kind, and true for the visibility. 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Factory registerObject(Object obj, ULocale locale) { 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return registerObject(obj, locale, LocaleKey.KIND_ANY, true); 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience override for callers using locales. This calls 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * registerObject(Object, ULocale, int kind, boolean visible) 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * passing KIND_ANY for the kind. 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Factory registerObject(Object obj, ULocale locale, boolean visible) { 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return registerObject(obj, locale, LocaleKey.KIND_ANY, visible); 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience function for callers using locales. This calls 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * registerObject(Object, ULocale, int kind, boolean visible) 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * passing true for the visibility. 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Factory registerObject(Object obj, ULocale locale, int kind) { 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return registerObject(obj, locale, kind, true); 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience function for callers using locales. This instantiates 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a SimpleLocaleKeyFactory, and registers the factory. 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Factory registerObject(Object obj, ULocale locale, int kind, boolean visible) { 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Factory factory = new SimpleLocaleKeyFactory(obj, locale, kind, visible); 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return registerFactory(factory); 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience method for callers using locales. This returns the standard 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Locale list, built from the Set of visible ids. 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Locale[] getAvailableLocales() { 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // TODO make this wrap getAvailableULocales later 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<String> visIDs = getVisibleIDs(); 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Locale[] locales = new Locale[visIDs.size()]; 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int n = 0; 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (String id : visIDs) { 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Locale loc = LocaleUtility.getLocaleFromName(id); 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller locales[n++] = loc; 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return locales; 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience method for callers using locales. This returns the standard 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ULocale list, built from the Set of visible ids. 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ULocale[] getAvailableULocales() { 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<String> visIDs = getVisibleIDs(); 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale[] locales = new ULocale[visIDs.size()]; 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int n = 0; 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (String id : visIDs) { 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller locales[n++] = new ULocale(id); 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return locales; 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 153f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A subclass of Key that implements a locale fallback mechanism. 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The first locale to search for is the locale provided by the 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * client, and the fallback locale to search for is the current 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * default locale. If a prefix is present, the currentDescriptor 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * includes it before the locale proper, separated by "/". This 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is the default key instantiated by ICULocaleService.</p> 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Canonicalization adjusts the locale string so that the 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * section before the first understore is in lower case, and the rest 164f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * is in upper case, with no trailing underscores.</p> 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static class LocaleKey extends ICUService.Key { 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int kind; 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int varstart; 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String primaryID; 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String fallbackID; 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String currentID; 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final int KIND_ANY = -1; 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Create a LocaleKey with canonical primary and fallback IDs. 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static LocaleKey createWithCanonicalFallback(String primaryID, String canonicalFallbackID) { 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY); 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 181f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Create a LocaleKey with canonical primary and fallback IDs. 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static LocaleKey createWithCanonicalFallback(String primaryID, String canonicalFallbackID, int kind) { 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (primaryID == null) { 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String canonicalPrimaryID = ULocale.getName(primaryID); 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new LocaleKey(primaryID, canonicalPrimaryID, canonicalFallbackID, kind); 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 192f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Create a LocaleKey with canonical primary and fallback IDs. 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static LocaleKey createWithCanonical(ULocale locale, String canonicalFallbackID, int kind) { 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (locale == null) { 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String canonicalPrimaryID = locale.getName(); 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new LocaleKey(canonicalPrimaryID, canonicalPrimaryID, canonicalFallbackID, kind); 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 203f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * PrimaryID is the user's requested locale string, 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * canonicalPrimaryID is this string in canonical form, 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fallbackID is the current default locale's string in 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * canonical form. 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected LocaleKey(String primaryID, String canonicalPrimaryID, String canonicalFallbackID, int kind) { 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super(primaryID); 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.kind = kind; 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (canonicalPrimaryID == null || canonicalPrimaryID.equalsIgnoreCase("root")) { 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.primaryID = ""; 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.fallbackID = null; 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int idx = canonicalPrimaryID.indexOf('@'); 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (idx == 4 && canonicalPrimaryID.regionMatches(true, 0, "root", 0, 4)) { 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.primaryID = canonicalPrimaryID.substring(4); 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.varstart = 0; 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.fallbackID = null; 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.primaryID = canonicalPrimaryID; 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.varstart = idx; 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (canonicalFallbackID == null || this.primaryID.equals(canonicalFallbackID)) { 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.fallbackID = ""; 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.fallbackID = canonicalFallbackID; 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.currentID = varstart == -1 ? this.primaryID : this.primaryID.substring(0, varstart); 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the prefix associated with the kind, or null if the kind is KIND_ANY. 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String prefix() { 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return kind == KIND_ANY ? null : Integer.toString(kind()); 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the kind code associated with this key. 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int kind() { 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return kind; 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the (canonical) original ID. 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 255f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String canonicalID() { 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return primaryID; 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the (canonical) current ID, or null if no current id. 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 263f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String currentID() { 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return currentID; 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the (canonical) current descriptor, or null if no current id. 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Includes the keywords, whereas the ID does not include keywords. 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 272f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String currentDescriptor() { 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String result = currentID(); 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (result != null) { 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder buf = new StringBuilder(); // default capacity 16 is usually good enough 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (kind != KIND_ANY) { 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(prefix()); 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append('/'); 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (varstart != -1) { 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(primaryID.substring(varstart, primaryID.length())); 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = buf.toString(); 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience method to return the locale corresponding to the (canonical) original ID. 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ULocale canonicalLocale() { 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new ULocale(primaryID); 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience method to return the ulocale corresponding to the (canonical) currentID. 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ULocale currentLocale() { 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (varstart == -1) { 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new ULocale(currentID); 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new ULocale(currentID + primaryID.substring(varstart)); 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the key has a fallback, modify the key and return true, 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * otherwise return false.</p> 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>First falls back through the primary ID, then through 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the fallbackID. The final fallback is "" (root) 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * unless the primary id was "" (root), in which case 315f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * there is no fallback. 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 317f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean fallback() { 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int x = currentID.lastIndexOf('_'); 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (x != -1) { 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (--x >= 0 && currentID.charAt(x) == '_') { // handle zh__PINYIN 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller currentID = currentID.substring(0, x+1); 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fallbackID != null) { 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller currentID = fallbackID; 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fallbackID.length() == 0) { 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fallbackID = null; 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fallbackID = ""; 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller currentID = null; 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 340f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * If a key created from id would eventually fallback to match the 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * canonical ID of this key, return true. 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 343f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean isFallbackOf(String id) { 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return LocaleUtility.isFallbackOf(canonicalID(), id); 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A subclass of Factory that uses LocaleKeys. If 'visible' the 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * factory reports its IDs. 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static abstract class LocaleKeyFactory implements Factory { 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected final String name; 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected final boolean visible; 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final boolean VISIBLE = true; 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final boolean INVISIBLE = false; 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructor used by subclasses. 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected LocaleKeyFactory(boolean visible) { 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.visible = visible; 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.name = null; 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructor used by subclasses. 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected LocaleKeyFactory(boolean visible, String name) { 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.visible = visible; 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.name = name; 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Implement superclass abstract method. This checks the currentID of 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the key against the supported IDs, and passes the canonicalLocale and 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * kind off to handleCreate (which subclasses must implement). 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 381f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object create(Key key, ICUService service) { 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (handlesKey(key)) { 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller LocaleKey lkey = (LocaleKey)key; 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int kind = lkey.kind(); 386f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale uloc = lkey.currentLocale(); 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return handleCreate(uloc, kind, service); 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // System.out.println("factory: " + this + " did not support id: " + key.currentID()); 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // System.out.println("supported ids: " + getSupportedIDs()); 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected boolean handlesKey(Key key) { 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (key != null) { 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String id = key.currentID(); 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<String> supported = getSupportedIDs(); 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return supported.contains(id); 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Override of superclass method. 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 408f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void updateVisibleIDs(Map<String, Factory> result) { 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<String> cache = getSupportedIDs(); 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (String id : cache) { 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (visible) { 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.put(id, this); 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.remove(id); 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return a localized name for the locale represented by id. 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 423f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String getDisplayName(String id, ULocale locale) { 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // assume if the user called this on us, we must have handled some fallback of this id 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if (isSupportedID(id)) { 4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (locale == null) { 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return id; 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale loc = new ULocale(id); 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return loc.getDisplayName(locale); 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // } 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // return null; 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ///CLOVER:OFF 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Utility method used by create(Key, ICUService). Subclasses can 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * implement this instead of create. 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected Object handleCreate(ULocale loc, int kind, ICUService service) { 4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ///CLOVER:ON 4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 447f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Return true if this id is one the factory supports (visible or 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * otherwise). 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected boolean isSupportedID(String id) { 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getSupportedIDs().contains(id); 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 453f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 455f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Return the set of ids that this factory supports (visible or 4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * otherwise). This can be called often and might need to be 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * cached if it is expensive to create. 4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected Set<String> getSupportedIDs() { 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collections.emptySet(); 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For debugging. 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 466f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() { 4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder buf = new StringBuilder(super.toString()); 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (name != null) { 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(", name: "); 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(name); 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(", visible: "); 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(visible); 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return buf.toString(); 4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A LocaleKeyFactory that just returns a single object for a kind/locale. 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static class SimpleLocaleKeyFactory extends LocaleKeyFactory { 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final Object obj; 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final String id; 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final int kind; 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // TODO: remove when we no longer need this 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleLocaleKeyFactory(Object obj, ULocale locale, int kind, boolean visible) { 4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(obj, locale, kind, visible, null); 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleLocaleKeyFactory(Object obj, ULocale locale, int kind, boolean visible, String name) { 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super(visible, name); 494f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.obj = obj; 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.id = locale.getBaseName(); 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.kind = kind; 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the service object if kind/locale match. Service is not used. 5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 503f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object create(Key key, ICUService service) { 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!(key instanceof LocaleKey)) { 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 508f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller LocaleKey lkey = (LocaleKey)key; 5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (kind != LocaleKey.KIND_ANY && kind != lkey.kind()) { 5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!id.equals(lkey.currentID())) { 5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 516f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return obj; 5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 520f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected boolean isSupportedID(String idToCheck) { 5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this.id.equals(idToCheck); 5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 525f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void updateVisibleIDs(Map<String, Factory> result) { 5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (visible) { 5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.put(id, this); 5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.remove(id); 5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 534f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() { 5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder buf = new StringBuilder(super.toString()); 5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(", id: "); 5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(id); 5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(", kind: "); 5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(kind); 5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return buf.toString(); 5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A LocaleKeyFactory that creates a service based on the ICU locale data. 5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is a base class for most ICU factories. Subclasses instantiate it 5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with a constructor that takes a bundle name, which determines the supported 5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * IDs. Subclasses then override handleCreate to create the actual service 5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * object. The default implementation returns a resource bundle. 5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static class ICUResourceBundleFactory extends LocaleKeyFactory { 5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected final String bundleName; 5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Convenience constructor that uses the main ICU bundle name. 5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ICUResourceBundleFactory() { 559f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert this(ICUData.ICU_BASE_NAME); 5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A service factory based on ICU resource data in resources 5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with the given name. 5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ICUResourceBundleFactory(String bundleName) { 5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super(true); 5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.bundleName = bundleName; 5702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the supported IDs. This is the set of all locale names for the bundleName. 5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 575f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected Set<String> getSupportedIDs() { 577f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert return ICUResourceBundle.getFullLocaleNameSet(bundleName, loader()); 5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Override of superclass method. 5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 583f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void updateVisibleIDs(Map<String, Factory> result) { 5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<String> visibleIDs = ICUResourceBundle.getAvailableLocaleNameSet(bundleName, loader()); // only visible ids 5862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (String id : visibleIDs) { 5872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.put(id, this); 5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Create the service. The default implementation returns the resource bundle 5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for the locale, ignoring kind, and service. 5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 595f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 5962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected Object handleCreate(ULocale loc, int kind, ICUService service) { 5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ICUResourceBundle.getBundleInstance(bundleName, loc, loader()); 5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected ClassLoader loader() { 6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ClassLoaderUtil.getClassLoader(getClass()); 6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 604f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() { 6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return super.toString() + ", bundle: " + bundleName; 6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return the name of the current fallback locale. If it has changed since this was 6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * last accessed, the service cache is cleared. 6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String validateFallbackLocale() { 6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale loc = ULocale.getDefault(); 6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (loc != fallbackLocale) { 6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller synchronized (this) { 6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (loc != fallbackLocale) { 6192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fallbackLocale = loc; 6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fallbackLocaleName = loc.getBaseName(); 6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller clearServiceCache(); 6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return fallbackLocaleName; 6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 628f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Key createKey(String id) { 6302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return LocaleKey.createWithCanonicalFallback(id, validateFallbackLocale()); 6312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Key createKey(String id, int kind) { 6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return LocaleKey.createWithCanonicalFallback(id, validateFallbackLocale(), kind); 6352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Key createKey(ULocale l, int kind) { 6382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return LocaleKey.createWithCanonical(l, validateFallbackLocale(), kind); 6392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 641