17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
3bee65486a185907111f3be60992433e133ec0e32Scott Russell * Copyright (C) 2004-2016, International Business Machines Corporation and
42c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert * others. All Rights Reserved.
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util;
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.ref.SoftReference;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.nio.ByteBuffer;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Collections;
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Enumeration;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.HashMap;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.MissingResourceException;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.ResourceBundle;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Set;
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.TreeSet;
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.concurrent.ConcurrentHashMap;
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUCache;
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUResourceBundle;
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUResourceBundleReader;
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ResourceBundleWrapper;
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.SimpleCache;
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * {@icuenhanced java.util.ResourceBundle}.{@icu _usage_}
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>A class representing a collection of resource information pertaining to a given
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * locale. A resource bundle provides a way of accessing locale- specific information in a
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * data file. You create a resource bundle that manages the resources for a given locale
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and then ask it for individual resources.
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>In ResourceBundle, an object is created and the sub-items are fetched using the
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * getString and getObject methods.  In UResourceBundle, each individual element of a
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * resource is a resource by itself.
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Resource bundles in ICU are currently defined using text files that conform to the
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * following <a
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * definition</a>.  More on resource bundle concepts and syntax can be found in the <a
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * href="http://www.icu-project.org/userguide/ResourceManagement.html">Users Guide</a>.
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>The packaging of ICU *.res files can be of two types
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ICU4C:
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <pre>
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *       root.res
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *         |
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      --------
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *     |        |
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *   fr.res  en.res
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *     |
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *   --------
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *  |        |
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * fr_CA.res fr_FR.res
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </pre>
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * JAVA/JDK:
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <pre>
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *    LocaleElements.res
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *         |
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      -------------------
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *     |                   |
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * LocaleElements_fr.res  LocaleElements_en.res
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *     |
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *   ---------------------------
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *  |                            |
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * LocaleElements_fr_CA.res   LocaleElements_fr_FR.res
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </pre>
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Depending on the organization of your resources, the syntax to getBundleInstance will
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * change.  To open ICU style organization use:
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <pre>
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      UResourceBundle bundle =
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *          UResourceBundle.getBundleInstance("com/mycompany/resources",
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *                                            "en_US", myClassLoader);
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </pre>
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * To open Java/JDK style organization use:
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <pre>
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      UResourceBundle bundle =
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *          UResourceBundle.getBundleInstance("com.mycompany.resources.LocaleElements",
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *                                            "en_US", myClassLoader);
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </pre>
86bee65486a185907111f3be60992433e133ec0e32Scott Russell *
87bee65486a185907111f3be60992433e133ec0e32Scott Russell * <p>Note: Please use pass a class loader for loading non-ICU resources. Java security does not
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * allow loading of resources across jar files. You must provide your class loader
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * to load the resources
90bee65486a185907111f3be60992433e133ec0e32Scott Russell
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.0
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author ram
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic abstract class UResourceBundle extends ResourceBundle {
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a resource bundle using the specified base name and locale.
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ICU_DATA_CLASS is used as the default root.
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName the base name of the resource bundle, a fully qualified class name
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param localeName the locale for which a resource bundle is desired
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If no resource bundle for the specified base name
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * can be found
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName, String localeName){
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, localeName, ICUResourceBundle.ICU_DATA_CLASS_LOADER,
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 false);
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a resource bundle using the specified base name, locale, and class root.
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName the base name of the resource bundle, a fully qualified class name
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param localeName the locale for which a resource bundle is desired
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param root the class object from which to load the resource bundle
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If no resource bundle for the specified base name
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * can be found
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName, String localeName,
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    ClassLoader root){
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, localeName, root, false);
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a resource bundle using the specified base name, locale, and class
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * root.
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName the base name of the resource bundle, a fully qualified class name
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param localeName the locale for which a resource bundle is desired
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param root the class object from which to load the resource bundle
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param disableFallback Option to disable locale inheritence.
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                          If true the fallback chain will not be built.
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *     if no resource bundle for the specified base name can be found
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected static UResourceBundle getBundleInstance(String baseName, String localeName,
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                       ClassLoader root, boolean disableFallback) {
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return instantiateBundle(baseName, localeName, root, disableFallback);
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Sole constructor.  (For invocation by subclass constructors, typically
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * implicit.)  This is public for compatibility with Java, whose compiler
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * will generate public default constructors for an abstract class.
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public UResourceBundle() {
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a UResourceBundle for the locale specified, from which users can extract
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * resources by using their corresponding keys.
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale  specifies the locale for which we want to open the resource.
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given locale
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(ULocale locale) {
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (locale==null) {
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            locale = ULocale.getDefault();
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale.toString(),
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a UResourceBundle for the default locale and specified base name,
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * from which users can extract resources by using their corresponding keys.
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName  specifies the locale for which we want to open the resource.
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and default locale
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName) {
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (baseName == null) {
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            baseName = ICUResourceBundle.ICU_BASE_NAME;
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale uloc = ULocale.getDefault();
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER,
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 false);
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a UResourceBundle for the specified locale and specified base name,
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * from which users can extract resources by using their corresponding keys.
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName  specifies the locale for which we want to open the resource.
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale  specifies the locale for which we want to open the resource.
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName, Locale locale) {
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (baseName == null) {
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            baseName = ICUResourceBundle.ICU_BASE_NAME;
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER,
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 false);
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a UResourceBundle, from which users can extract resources by using
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * their corresponding keys.
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName string containing the name of the data package.
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                    If null the default ICU package name is used.
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale  specifies the locale for which we want to open the resource.
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName, ULocale locale) {
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (baseName == null) {
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            baseName = ICUResourceBundle.ICU_BASE_NAME;
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (locale == null) {
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            locale = ULocale.getDefault();
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, locale.toString(),
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a UResourceBundle for the specified locale and specified base name,
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * from which users can extract resources by using their corresponding keys.
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName  specifies the locale for which we want to open the resource.
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale  specifies the locale for which we want to open the resource.
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param loader  the loader to use
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName, Locale locale,
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    ClassLoader loader) {
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (baseName == null) {
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            baseName = ICUResourceBundle.ICU_BASE_NAME;
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, uloc.toString(), loader, false);
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Creates a UResourceBundle, from which users can extract resources by using
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * their corresponding keys.<br><br>
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Note: Please use this API for loading non-ICU resources. Java security does not
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * allow loading of resources across jar files. You must provide your class loader
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * to load the resources
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName string containing the name of the data package.
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                    If null the default ICU package name is used.
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale  specifies the locale for which we want to open the resource.
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                If null the bundle for default locale is opened.
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param loader  the loader to use
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static UResourceBundle getBundleInstance(String baseName, ULocale locale,
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    ClassLoader loader) {
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (baseName == null) {
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            baseName = ICUResourceBundle.ICU_BASE_NAME;
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (locale == null) {
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            locale = ULocale.getDefault();
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getBundleInstance(baseName, locale.toString(), loader, false);
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the RFC 3066 conformant locale id of this resource bundle.
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This method can be used after a call to getBundleInstance() to
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * determine whether the resource bundle returned really
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * corresponds to the requested locale or is a fallback.
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return the locale of this resource bundle
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public abstract ULocale getULocale();
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the localeID
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The string representation of the localeID
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected abstract String getLocaleID();
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the base name of the resource bundle
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The string representation of the base name
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected abstract String getBaseName();
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the parent bundle
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return The parent bundle
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected abstract UResourceBundle getParent();
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the locale of this bundle
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return the locale of this resource bundle
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public Locale getLocale(){
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return getULocale().toLocale();
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Cache for ResourceBundle instantiation
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static ICUCache<ResourceCacheKey, UResourceBundle> BUNDLE_CACHE =
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SimpleCache<ResourceCacheKey, UResourceBundle>();
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static void resetBundleCache() {
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * A HACK!!!!!
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * Currently if a resourcebundle with fallback turned ON is added to the cache
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * and then a getBundleInstance() is called for a bundle with fallback turned OFF
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * it will actually search the cache for any bundle of the same locale
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * regaurdless of fallback status. This method has been created so that if
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * The calling method KNOWS that instances of the other fallback state may be in the
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * cache, the calling method may call this method to clear out the cache.
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         *
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //TODO figure a way around this method(see method comment)
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        BUNDLE_CACHE = new SimpleCache<ResourceCacheKey, UResourceBundle>();
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Method used by subclasses to add a resource bundle object to the managed
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * cache.  Works like a putIfAbsent(): If the cache already contains a matching
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * bundle, that one will be retained and returned.
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
3512c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert    protected static UResourceBundle addToCache(String fullName, ULocale defaultLocale, UResourceBundle b) {
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        synchronized(cacheKey){
3532c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert            cacheKey.setKeyValues(fullName, defaultLocale);
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            UResourceBundle cachedBundle = BUNDLE_CACHE.get(cacheKey);
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (cachedBundle != null) {
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return cachedBundle;
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            BUNDLE_CACHE.put((ResourceCacheKey)cacheKey.clone(), b);
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return b;
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Method used by sub classes to load a resource bundle object from the managed cache
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
3692c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert    protected static UResourceBundle loadFromCache(String fullName, ULocale defaultLocale) {
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        synchronized(cacheKey){
3712c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert            cacheKey.setKeyValues(fullName, defaultLocale);
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return BUNDLE_CACHE.get(cacheKey);
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Key used for cached resource bundles.  The key checks
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * the resource name, the class root, and the default
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * locale to determine if the resource is a match to the
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * requested one. The root may be null, but the
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * searchName and the default locale must have a non-null value.
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Note that the default locale may change over time, and
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * lookup should always be based on the current default
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * locale (if at all).
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class ResourceCacheKey implements Cloneable {
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private String searchName;
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private ULocale defaultLocale;
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private int hashCodeCache;
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ///CLOVER:OFF
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public boolean equals(Object other) {
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (other == null) {
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return false;
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (this == other) {
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return true;
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                final ResourceCacheKey otherEntry = (ResourceCacheKey) other;
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //quick check to see if they are not equal
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (hashCodeCache != otherEntry.hashCodeCache) {
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return false;
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //are the names the same?
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!searchName.equals(otherEntry.searchName)) {
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return false;
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // are the default locales the same?
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (defaultLocale == null) {
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (otherEntry.defaultLocale != null) {
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        return false;
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (!defaultLocale.equals(otherEntry.defaultLocale)) {
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        return false;
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4182c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert                return true;
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (NullPointerException e) {
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return false;
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (ClassCastException e) {
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return false;
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public int hashCode() {
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return hashCodeCache;
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public Object clone() {
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return super.clone();
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (CloneNotSupportedException e) {
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //this should never happen
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new ICUCloneNotSupportedException(e);
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ///CLOVER:ON
4402c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert        private synchronized void setKeyValues(String searchName, ULocale defaultLocale) {
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.searchName = searchName;
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            hashCodeCache = searchName.hashCode();
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.defaultLocale = defaultLocale;
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (defaultLocale != null) {
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                hashCodeCache ^= defaultLocale.hashCode();
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*private void clear() {
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            setKeyValues(null, "", null);
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }*/
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final ResourceCacheKey cacheKey = new ResourceCacheKey();
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int ROOT_MISSING = 0;
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int ROOT_ICU = 1;
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int ROOT_JAVA = 2;
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static SoftReference<ConcurrentHashMap<String, Integer>> ROOT_CACHE =
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new SoftReference<ConcurrentHashMap<String, Integer>>(new ConcurrentHashMap<String, Integer>());
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static int getRootType(String baseName, ClassLoader root) {
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ConcurrentHashMap<String, Integer> m = null;
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Integer rootType;
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        m = ROOT_CACHE.get();
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (m == null) {
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            synchronized(UResourceBundle.class) {
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                m = ROOT_CACHE.get();
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (m == null) {
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    m = new ConcurrentHashMap<String, Integer>();
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ROOT_CACHE = new SoftReference<ConcurrentHashMap<String, Integer>>(m);
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        rootType = m.get(baseName);
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rootType == null) {
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String rootLocale = (baseName.indexOf('.')==-1) ? "root" : "";
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int rt = ROOT_MISSING; // value set on success
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try{
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ICUResourceBundle.getBundleInstance(baseName, rootLocale, root, true);
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                rt = ROOT_ICU;
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }catch(MissingResourceException ex){
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try{
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ResourceBundleWrapper.getBundleInstance(baseName, rootLocale, root, true);
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    rt = ROOT_JAVA;
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }catch(MissingResourceException e){
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    //throw away the exception
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rootType = Integer.valueOf(rt);
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            m.putIfAbsent(baseName, rootType);
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return rootType.intValue();
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static void setRootType(String baseName, int rootType) {
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Integer rt = Integer.valueOf(rootType);
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ConcurrentHashMap<String, Integer> m = null;
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        m = ROOT_CACHE.get();
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (m == null) {
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            synchronized(UResourceBundle.class) {
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                m = ROOT_CACHE.get();
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (m == null) {
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    m = new ConcurrentHashMap<String, Integer>();
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ROOT_CACHE = new SoftReference<ConcurrentHashMap<String, Integer>>(m);
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        m.put(baseName, rt);
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Loads a new resource bundle for the given base name, locale and class loader.
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Optionally will disable loading of fallback bundles.
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param baseName the base name of the resource bundle, a fully qualified class name
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param localeName the locale for which a resource bundle is desired
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param root the class object from which to load the resource bundle
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param disableFallback disables loading of fallback lookup chain
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If no resource bundle for the specified base name
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * can be found
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a resource bundle for the given base name and locale
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.0
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected static UResourceBundle instantiateBundle(String baseName, String localeName,
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                       ClassLoader root, boolean disableFallback) {
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        UResourceBundle b = null;
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int rootType = getRootType(baseName, root);
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale defaultLocale = ULocale.getDefault();
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        switch (rootType)
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        case ROOT_ICU:
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(disableFallback) {
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
5432c6d0a07a72e8739a9c717a26690a9b711331d68Fredrik Roubert                b = loadFromCache(fullName, defaultLocale);
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (b == null) {
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    b = ICUResourceBundle.getBundleInstance(baseName, localeName, root,
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                            disableFallback);
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root,
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                        disableFallback);
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return b;
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        case ROOT_JAVA:
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return ResourceBundleWrapper.getBundleInstance(baseName, localeName, root,
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                           disableFallback);
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        default:
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try{
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root,
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                        disableFallback);
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                setRootType(baseName, ROOT_ICU);
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }catch(MissingResourceException ex){
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                b = ResourceBundleWrapper.getBundleInstance(baseName, localeName, root,
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                            disableFallback);
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                setRootType(baseName, ROOT_JAVA);
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return b;
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns a binary data item from a binary resource, as a read-only ByteBuffer.
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * file.
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getInt
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If no resource bundle can be found.
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If the resource has a type mismatch.
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public ByteBuffer getBinary() {
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a string from a string resource type
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a string
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getBinary()
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getInt
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle has a type mismatch.
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public String getString() {
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a string array from a array resource type
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a string
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getString()
6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle has a type mismatch.
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public String[] getStringArray() {
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns a binary data from a binary resource, as a byte array with a copy
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * of the bytes from the resource bundle.
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param ba  The byte array to write the bytes to. A null variable is OK.
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return an array of bytes containing the binary data from the resource.
6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getInt
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle has a type mismatch.
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public byte[] getBinary(byte[] ba) {
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns a 32 bit integer array from a resource.
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file.
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getBinary()
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getInt
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle has a type mismatch.
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int[] getIntVector() {
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns a signed integer from a resource.
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return an integer value
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getBinary()
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle type mismatch.
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int getInt() {
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns a unsigned integer from a resource.
6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This integer is originally 28 bit and the sign gets propagated.
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return an integer value
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getBinary()
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle type mismatch.
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int getUInt() {
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns a resource in a given resource that has a given key.
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aKey               a key associated with the wanted resource
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return                  a resource bundle object representing the resource
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If resource bundle is missing.
6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public UResourceBundle get(String aKey) {
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        UResourceBundle obj = findTopLevel(aKey);
6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (obj == null) {
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String fullName = ICUResourceBundleReader.getFullName(getBaseName(), getLocaleID());
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new MissingResourceException(
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    "Can't find resource for bundle " + fullName + ", key "
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    + aKey, this.getClass().getName(), aKey);
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return obj;
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a resource in a given resource that has a given key, or null if the
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * resource is not found.
6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aKey the key associated with the wanted resource
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return the resource, or null
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #get(String)
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected UResourceBundle findTopLevel(String aKey) {
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // NOTE: this only works for top-level resources.  For resources at lower
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // levels, it fails when you fall back to the parent, since you're now
7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // looking at root resources, not at the corresponding nested resource.
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (UResourceBundle res = this; res != null; res = res.getParent()) {
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            UResourceBundle obj = res.handleGet(aKey, null, this);
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (obj != null) {
7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ((ICUResourceBundle) obj).setLoadingStatus(getLocaleID());
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return obj;
7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the string in a given resource at the specified index.
7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param index an index to the wanted string.
7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a string which lives in the resource.
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IndexOutOfBoundsException If the index value is out of bounds of accepted values.
7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws UResourceTypeMismatchException If resource bundle type mismatch.
7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public String getString(int index) {
7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ICUResourceBundle temp = (ICUResourceBundle)get(index);
7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (temp.getType() == STRING) {
7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return temp.getString();
7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        throw new UResourceTypeMismatchException("");
7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the resource in a given resource at the specified index.
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param index an index to the wanted resource.
7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return the sub resource UResourceBundle object
7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws IndexOutOfBoundsException If the index value is out of bounds of accepted values.
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @throws MissingResourceException If the resource bundle is missing.
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public UResourceBundle get(int index) {
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        UResourceBundle obj = handleGet(index, null, this);
7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (obj == null) {
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            obj = (ICUResourceBundle) getParent();
7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (obj != null) {
7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                obj = obj.get(index);
7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (obj == null)
7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new MissingResourceException(
7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        "Can't find resource for bundle "
7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                + this.getClass().getName() + ", key "
7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                + getKey(), this.getClass().getName(), getKey());
7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ((ICUResourceBundle)obj).setLoadingStatus(getLocaleID());
7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return obj;
7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a resource in a given resource that has a given index, or null if the
7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * resource is not found.
7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param index the index of the resource
7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return the resource, or null
7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #get(int)
7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected UResourceBundle findTopLevel(int index) {
7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // NOTE: this _barely_ works for top-level resources.  For resources at lower
7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // levels, it fails when you fall back to the parent, since you're now
7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // looking at root resources, not at the corresponding nested resource.
7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Not only that, but unless the indices correspond 1-to-1, the index will
7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // lose meaning.  Essentially this only works if the child resource arrays
7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // are prefixes of their parent arrays.
7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (UResourceBundle res = this; res != null; res = res.getParent()) {
7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            UResourceBundle obj = res.handleGet(index, null, this);
7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (obj != null) {
7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ((ICUResourceBundle) obj).setLoadingStatus(getLocaleID());
7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return obj;
7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the keys in this bundle as an enumeration
7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return an enumeration containing key strings,
7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         which is empty if this is not a bundle or a table resource
7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public Enumeration<String> getKeys() {
7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return Collections.enumeration(keySet());
7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a Set of all keys contained in this ResourceBundle and its parent bundles.
8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a Set of all keys contained in this ResourceBundle and its parent bundles,
8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         which is empty if this is not a bundle or a table resource
8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public Set<String> keySet() {
8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // TODO: Java 6 ResourceBundle has keySet() which calls handleKeySet()
8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // and caches the results.
8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // When we upgrade to Java 6, we still need to check for isTopLevelResource().
8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Keep the else branch as is. The if body should just return super.keySet().
8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Remove then-redundant caching of the keys.
8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> keys = null;
8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ICUResourceBundle icurb = null;
8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(isTopLevelResource() && this instanceof ICUResourceBundle) {
8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // We do not cache the top-level keys in this base class so that
8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // not every string/int/binary... resource has to have a keys cache field.
8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            icurb = (ICUResourceBundle)this;
8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            keys = icurb.getTopLevelKeySet();
8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(keys == null) {
8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(isTopLevelResource()) {
8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                TreeSet<String> newKeySet;
8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(parent == null) {
8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newKeySet = new TreeSet<String>();
8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if(parent instanceof UResourceBundle) {
8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newKeySet = new TreeSet<String>(((UResourceBundle)parent).keySet());
8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // TODO: Java 6 ResourceBundle has keySet(); use it when we upgrade to Java 6
8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // and remove this else branch.
8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    newKeySet = new TreeSet<String>();
8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    Enumeration<String> parentKeys = parent.getKeys();
8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    while(parentKeys.hasMoreElements()) {
8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newKeySet.add(parentKeys.nextElement());
8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                newKeySet.addAll(handleKeySet());
8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                keys = Collections.unmodifiableSet(newKeySet);
8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(icurb != null) {
8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    icurb.setTopLevelKeySet(keys);
8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return handleKeySet();
8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return keys;
8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns a Set of the keys contained <i>only</i> in this ResourceBundle.
8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This does not include further keys from parent bundles.
8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a Set of the keys contained only in this ResourceBundle,
8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         which is empty if this is not a bundle or a table resource
8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected Set<String> handleKeySet() {
8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return Collections.emptySet();
8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the size of a resource. Size for scalar types is always 1, and for
8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * vector/table types is the number of child resources.
8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <br><b>Note:</b> Integer array is treated as a scalar type. There are no APIs to
8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * access individual members of an integer array. It is always returned as a whole.
8707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return number of resources in a given resource.
8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int getSize() {
8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return 1;
8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the type of a resource.
8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Available types are {@link #INT INT}, {@link #ARRAY ARRAY},
8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #BINARY BINARY}, {@link #INT_VECTOR INT_VECTOR},
8817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@link #STRING STRING}, {@link #TABLE TABLE}.
8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return type of the given resource.
8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public int getType() {
8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return NONE;
8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Return the version number associated with this UResourceBundle as an
8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * VersionInfo object.
8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return VersionInfo object containing the version of the bundle
8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public VersionInfo getVersion() {
8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the iterator which iterates over this
9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * resource bundle
9037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return UResourceBundleIterator that iterates over the resources in the bundle
9047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public UResourceBundleIterator getIterator() {
9077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new UResourceBundleIterator(this);
9087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Returns the key associated with a given resource. Not all the resources have
9127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * a key - only those that are members of a table.
9137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return a key associated to this resource, or null if it doesn't have a key
9147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public String getKey() {
9177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
9187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Resource type constant for "no resource".
9227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int NONE = -1;
9257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Resource type constant for strings.
9287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int STRING = 0;
9317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Resource type constant for binary data.
9347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int BINARY = 1;
9377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Resource type constant for tables of key-value pairs.
9407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int TABLE = 2;
9437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Resource type constant for a single 28-bit integer, interpreted as
9467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * signed or unsigned by the getInt() function.
9477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getInt
9487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int INT = 7;
9517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Resource type constant for arrays of resources.
9547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ARRAY = 8;
9577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Resource type constant for vectors of 32-bit integers.
9607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #getIntVector
9617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int INT_VECTOR = 14;
9647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //====== protected members ==============
9667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Actual worker method for fetching a resource based on the given key.
9697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Sub classes must override this method if they support resources with keys.
9707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aKey the key string of the resource to be fetched
9717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aliasesVisited hashtable object to hold references of resources already seen
9727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param requested the original resource bundle object on which the get method was invoked.
9737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  The requested bundle and the bundle on which this method is invoked
9747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  are the same, except in the cases where aliases are involved.
9757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return UResourceBundle a resource associated with the key
9767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected UResourceBundle handleGet(String aKey, HashMap<String, String> aliasesVisited,
9797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        UResourceBundle requested) {
9807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
9817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Actual worker method for fetching a resource based on the given index.
9857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Sub classes must override this method if they support arrays of resources.
9867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param index the index of the resource to be fetched
9877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aliasesVisited hashtable object to hold references of resources already seen
9887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param requested the original resource bundle object on which the get method was invoked.
9897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  The requested bundle and the bundle on which this method is invoked
9907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  are the same, except in the cases where aliases are involved.
9917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return UResourceBundle a resource associated with the index
9927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
9937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected UResourceBundle handleGet(int index, HashMap<String, String> aliasesVisited,
9957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        UResourceBundle requested) {
9967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
9977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
10007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Actual worker method for fetching the array of strings in a resource.
10017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Sub classes must override this method if they support arrays of strings.
10027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return String[] An array of strings containing strings
10037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
10047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected String[] handleGetStringArray() {
10067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
10077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
10107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@icu} Actual worker method for fetching the keys of resources contained in the resource.
10117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Sub classes must override this method if they support keys and associated resources.
10127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
10137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return Enumeration An enumeration of all the keys in this resource.
10147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
10157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected Enumeration<String> handleGetKeys(){
10177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return null;
10187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
10217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
10227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
10237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // this method is declared in ResourceBundle class
10257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // so cannot change the signature
10267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Override this method
10277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected Object handleGetObject(String aKey) {
10287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return handleGetObjectImpl(aKey, this);
10297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
10327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Override the superclass method
10337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // To facilitate XPath style aliases we need a way to pass the reference
10357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // to requested locale. The only way I could figure out is to implement
10367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // the look up logic here. This has a disadvantage that if the client
10377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // loads an ICUResourceBundle, calls ResourceBundle.getObject method
10387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // with a key that does not exist in the bundle then the lookup is
10397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // done twice before throwing a MissingResourceExpection.
10407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private Object handleGetObjectImpl(String aKey, UResourceBundle requested) {
10417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Object obj = resolveObject(aKey, requested);
10427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (obj == null) {
10437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            UResourceBundle parentBundle = getParent();
10447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (parentBundle != null) {
10457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                obj = parentBundle.handleGetObjectImpl(aKey, requested);
10467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (obj == null)
10487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new MissingResourceException(
10497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    "Can't find resource for bundle "
10507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    + this.getClass().getName() + ", key " + aKey,
10517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    this.getClass().getName(), aKey);
10527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return obj;
10547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Routine for figuring out the type of object to be returned
10577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // string or string array
10587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private Object resolveObject(String aKey, UResourceBundle requested) {
10597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (getType() == STRING) {
10607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return getString();
10617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        UResourceBundle obj = handleGet(aKey, null, requested);
10637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (obj != null) {
10647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (obj.getType() == STRING) {
10657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return obj.getString();
10667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
10687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (obj.getType() == ARRAY) {
10697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return obj.handleGetStringArray();
10707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
10717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (UResourceTypeMismatchException ex) {
10727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return obj;
10737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return obj;
10767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
10797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This method is for setting the loading status of the resource.
10807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The status is analogous to the warning status in ICU4C.
10817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
10827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
10837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
10857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected abstract void setLoadingStatus(int newStatus);
10867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
10887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Is this a top-level resource, that is, a whole bundle?
10897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return true if this is a top-level resource
10907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
10917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
10927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
10937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
10947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected boolean isTopLevelResource() {
10957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return true;
10967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
1098