]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-4_2_1-src/src/com/ibm/icu/util/UResourceBundle.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / util / UResourceBundle.java
old mode 100755 (executable)
new mode 100644 (file)
index 832ff5d..a6b77a7
-//##header\r
-/*\r
- *******************************************************************************\r
- * Copyright (C) 2004-2009, International Business Machines Corporation and    *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-\r
-package com.ibm.icu.util;\r
-\r
-import java.lang.ref.SoftReference;\r
-import java.util.Enumeration;\r
-import java.util.HashMap;\r
-import java.util.Locale;\r
-import java.util.Map;\r
-import java.util.MissingResourceException;\r
-import java.util.ResourceBundle;\r
-import java.util.Vector;\r
-\r
-import com.ibm.icu.impl.ICUCache;\r
-import com.ibm.icu.impl.ICUResourceBundle;\r
-import com.ibm.icu.impl.ICUResourceBundleReader;\r
-import com.ibm.icu.impl.ResourceBundleWrapper;\r
-import com.ibm.icu.impl.SimpleCache;\r
-import com.ibm.icu.util.ULocale;\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13) || defined(ECLIPSE_FRAGMENT)\r
-//##import com.ibm.icu.impl.ByteBuffer;\r
-//#else\r
-import java.nio.ByteBuffer;\r
-//#endif\r
-\r
-/**\r
- * A class representing a collection of resource information pertaining to a given\r
- * locale. A resource bundle provides a way of accessing locale- specific information in\r
- * a data file. You create a resource bundle that manages the resources for a given\r
- * locale and then ask it for individual resources.\r
- * <P>\r
- * In ResourceBundle class, an object is created\r
- * and the sub items are fetched using getString, getObject methods.\r
- * In UResourceBundle,each individual element of a resource is a resource by itself.\r
- *\r
- * <P>\r
- * Resource bundles in ICU are currently defined using text files which conform to the following\r
- * <a href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF definition</a>.\r
- * More on resource bundle concepts and syntax can be found in the\r
- * <a href="http://www.icu-project.org/userguide/ResourceManagement.html">Users Guide</a>.\r
- * <P>\r
- *\r
- * The packaging of ICU *.res files can be of two types\r
- * ICU4C:\r
- * <pre>\r
- *       root.res\r
- *         |\r
- *      --------\r
- *     |        |\r
- *   fr.res  en.res\r
- *     |\r
- *   --------\r
- *  |        |\r
- * fr_CA.res fr_FR.res\r
- * </pre>\r
- * JAVA/JDK:\r
- * <pre>\r
- *    LocaleElements.res\r
- *         |\r
- *      -------------------\r
- *     |                   |\r
- * LocaleElements_fr.res  LocaleElements_en.res\r
- *     |\r
- *   ---------------------------\r
- *  |                            |\r
- * LocaleElements_fr_CA.res   LocaleElements_fr_FR.res\r
- * </pre>\r
- * Depending on the organization of your resources, the syntax to getBundleInstance will change.\r
- * To open ICU style organization use:\r
- * <pre>\r
- *      UResourceBundle bundle = UResourceBundle.getBundleInstance("com/mycompany/resources", "en_US", myClassLoader);\r
- * </pre>\r
- * To open Java/JDK style organization use:\r
- * <pre>\r
- *      UResourceBundle bundle = UResourceBundle.getBundleInstance("com.mycompany.resources.LocaleElements", "en_US", myClassLoader);\r
- * </pre>\r
- * <note>\r
- * Please use pass a class loader for loading non-ICU resources. Java security does not\r
- * allow loading of resources across jar files. You must provide your class loader\r
- * to load the resources\r
- * </note>\r
- * @stable ICU 3.0\r
- * @author ram\r
- */\r
-public abstract class UResourceBundle extends ResourceBundle{\r
-\r
-\r
-    /**\r
-     * Creates a resource bundle using the specified base name and locale.\r
-     * ICU_DATA_CLASS is used as the default root.\r
-     * @param baseName the base name of the resource bundle, a fully qualified class name\r
-     * @param localeName the locale for which a resource bundle is desired\r
-     * @exception MissingResourceException\r
-     *     if no resource bundle for the specified base name can be found\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.0\r
-     */\r
-    public static UResourceBundle getBundleInstance(String baseName, String localeName){\r
-        return getBundleInstance(baseName, localeName, ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a resource bundle using the specified base name, locale, and class root.\r
-     *\r
-     * @param baseName the base name of the resource bundle, a fully qualified class name\r
-     * @param localeName the locale for which a resource bundle is desired\r
-     * @param root the class object from which to load the resource bundle\r
-     * @exception MissingResourceException\r
-     *     if no resource bundle for the specified base name can be found\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.0\r
-     */\r
-    public static UResourceBundle getBundleInstance(String baseName, String localeName, ClassLoader root){\r
-        return getBundleInstance(baseName, localeName, root, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a resource bundle using the specified base name, locale, and class root.\r
-     *\r
-     * @param baseName the base name of the resource bundle, a fully qualified class name\r
-     * @param localeName the locale for which a resource bundle is desired\r
-     * @param root the class object from which to load the resource bundle\r
-     * @param disableFallback Option to disable locale inheritence.\r
-     *                          If true the fallback chain will not be built.\r
-     * @exception MissingResourceException\r
-     *     if no resource bundle for the specified base name can be found\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.0\r
-     *\r
-     */\r
-    protected static UResourceBundle getBundleInstance(String baseName, String localeName, ClassLoader root, boolean disableFallback) {\r
-        return instantiateBundle(baseName, localeName, root, disableFallback);\r
-    }\r
-\r
-    /**\r
-     * Sole constructor.  (For invocation by subclass constructors, typically\r
-     * implicit.)  This is public for compatibility with Java, whose compiler\r
-     * will generate public default constructors for an abstract class.\r
-     * @stable ICU 3.0\r
-     */\r
-    public UResourceBundle() {\r
-    }\r
-\r
-    /**\r
-     * Creates a UResourceBundle for the locale specified, from which users can extract resources by using\r
-     * their corresponding keys.\r
-     * @param locale  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @return a resource bundle for the given locale\r
-     * @stable ICU 3.0\r
-     */\r
-    public static UResourceBundle getBundleInstance(ULocale locale) {\r
-        if (locale==null) {\r
-            locale = ULocale.getDefault();\r
-        }\r
-        return getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a UResourceBundle for the default locale and specified base name,\r
-     * from which users can extract resources by using their corresponding keys.\r
-     * @param baseName  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @return a resource bundle for the given base name and default locale\r
-     * @stable ICU 3.0\r
-     */\r
-    public static UResourceBundle getBundleInstance(String baseName) {\r
-        if (baseName == null) {\r
-            baseName = ICUResourceBundle.ICU_BASE_NAME;\r
-        }\r
-        ULocale uloc = ULocale.getDefault();\r
-        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a UResourceBundle for the specified locale and specified base name,\r
-     * from which users can extract resources by using their corresponding keys.\r
-     * @param baseName  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @param locale  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.0\r
-     */\r
-\r
-    public static UResourceBundle getBundleInstance(String baseName, Locale locale) {\r
-        if (baseName == null) {\r
-            baseName = ICUResourceBundle.ICU_BASE_NAME;\r
-        }\r
-        ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);\r
-\r
-        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a UResourceBundle, from which users can extract resources by using\r
-     * their corresponding keys.\r
-     * @param baseName string containing the name of the data package.\r
-     *                    If null the default ICU package name is used.\r
-     * @param locale  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.0\r
-     */\r
-    public static UResourceBundle getBundleInstance(String baseName, ULocale locale) {\r
-        if (baseName == null) {\r
-            baseName = ICUResourceBundle.ICU_BASE_NAME;\r
-        }\r
-        if (locale == null) {\r
-            locale = ULocale.getDefault();\r
-        }\r
-        return getBundleInstance(baseName, locale.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a UResourceBundle for the specified locale and specified base name,\r
-     * from which users can extract resources by using their corresponding keys.\r
-     * @param baseName  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @param locale  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @param loader  the loader to use\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.8\r
-     */\r
-    public static UResourceBundle getBundleInstance(String baseName, Locale locale, ClassLoader loader) {\r
-        if (baseName == null) {\r
-            baseName = ICUResourceBundle.ICU_BASE_NAME;\r
-        }\r
-        ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);\r
-        return getBundleInstance(baseName, uloc.toString(), loader, false);\r
-    }\r
-\r
-    /**\r
-     * Creates a UResourceBundle, from which users can extract resources by using\r
-     * their corresponding keys.<br><br>\r
-     * Note: Please use this API for loading non-ICU resources. Java security does not\r
-     * allow loading of resources across jar files. You must provide your class loader\r
-     * to load the resources\r
-     * @param baseName string containing the name of the data package.\r
-     *                    If null the default ICU package name is used.\r
-     * @param locale  specifies the locale for which we want to open the resource.\r
-     *                If null the bundle for default locale is opened.\r
-     * @param loader  the loader to use\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.8\r
-     */\r
-    public static UResourceBundle getBundleInstance(String baseName, ULocale locale, ClassLoader loader) {\r
-        if (baseName == null) {\r
-            baseName = ICUResourceBundle.ICU_BASE_NAME;\r
-        }\r
-        if (locale == null) {\r
-            locale = ULocale.getDefault();\r
-        }\r
-        return getBundleInstance(baseName, locale.toString(), loader, false);\r
-    }\r
-\r
-    /**\r
-     * Returns the RFC 3066 conformant locale id of this resource bundle.\r
-     * This method can be used after a call to getBundleInstance() to\r
-     * determine whether the resource bundle returned really\r
-     * corresponds to the requested locale or is a fallback.\r
-     *\r
-     * @return the locale of this resource bundle\r
-     * @stable ICU 3.0\r
-     */\r
-    public abstract ULocale getULocale();\r
-\r
-    /**\r
-     * Gets the localeID\r
-     * @return The string representation of the localeID\r
-     * @stable ICU 3.0\r
-     */\r
-    protected abstract String getLocaleID();\r
-    /**\r
-     * Gets the base name of the resource bundle\r
-     * @return The string representation of the base name\r
-     * @stable ICU 3.0\r
-     */\r
-    protected abstract String getBaseName();\r
-\r
-    /**\r
-     * Gets the parent bundle\r
-     * @return The parent bundle\r
-     * @stable ICU 3.0\r
-     */\r
-    protected abstract UResourceBundle getParent();\r
-\r
-\r
-    /**\r
-     * Get the locale of this bundle\r
-     * @return the locale of this resource bundle\r
-     * @stable ICU 3.0\r
-     */\r
-    public Locale getLocale(){\r
-        return getULocale().toLocale();\r
-    }\r
-\r
-    // Cache for ResourceBundle instantiation\r
-    private static ICUCache BUNDLE_CACHE = new SimpleCache();\r
-\r
-    /**\r
-     * @internal\r
-     */\r
-    public static void resetBundleCache()\r
-    {\r
-        /*\r
-         * A HACK!!!!!\r
-         * Currently if a resourcebundle with fallback turned ON is added to the cache\r
-         * and then a getBundleInstance() is called for a bundle with fallback turned OFF\r
-         * it will actually search the cache for any bundle of the same locale\r
-         * regaurdless of fallback status. This method has been created so that if\r
-         * The calling method KNOWS that instances of the other fallback state may be in the \r
-         * cache, the calling method may call this method to clear out the cache.\r
-         *\r
-         */\r
-        //TODO figure a way around this method(see method comment)\r
-        BUNDLE_CACHE = new SimpleCache();\r
-    }\r
-    \r
-    private static void addToCache(ResourceCacheKey key, UResourceBundle b) {\r
-        BUNDLE_CACHE.put(key, b);\r
-    }\r
-\r
-    /**\r
-     * Method used by subclasses to add the a particular resource bundle object to the managed cache\r
-     * @internal revisit for ICU 3.6\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected static void addToCache(ClassLoader cl, String fullName, ULocale defaultLocale,  UResourceBundle b){\r
-        synchronized(cacheKey){\r
-            cacheKey.setKeyValues(cl, fullName, defaultLocale);\r
-            addToCache((ResourceCacheKey)cacheKey.clone(), b);\r
-        }\r
-    }\r
-    /**\r
-     * Method used by sub classes to load a resource bundle object from the managed cache\r
-     * @internal revisit for ICU 3.6\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected static UResourceBundle loadFromCache(ClassLoader cl, String fullName, ULocale defaultLocale){\r
-        synchronized(cacheKey){\r
-            cacheKey.setKeyValues(cl, fullName, defaultLocale);\r
-            return loadFromCache(cacheKey);\r
-        }\r
-    }\r
-    private static UResourceBundle loadFromCache(ResourceCacheKey key) {\r
-        return (UResourceBundle)BUNDLE_CACHE.get(key);\r
-    }\r
-\r
-    /**\r
-     * Key used for cached resource bundles.  The key checks\r
-     * the resource name, the class root, and the default\r
-     * locale to determine if the resource is a match to the\r
-     * requested one. The root may be null, but the\r
-     * searchName and the default locale must have a non-null value.\r
-     * Note that the default locale may change over time, and\r
-     * lookup should always be based on the current default\r
-     * locale (if at all).\r
-     */\r
-    private static final class ResourceCacheKey implements Cloneable {\r
-        private SoftReference loaderRef;\r
-        private String searchName;\r
-        private ULocale defaultLocale;\r
-        private int hashCodeCache;\r
-        ///CLOVER:OFF\r
-        public boolean equals(Object other) {\r
-            if (this == other) {\r
-                return true;\r
-            }\r
-            try {\r
-                final ResourceCacheKey otherEntry = (ResourceCacheKey) other;\r
-                //quick check to see if they are not equal\r
-                if (hashCodeCache != otherEntry.hashCodeCache) {\r
-                    return false;\r
-                }\r
-                //are the names the same?\r
-                if (!searchName.equals(otherEntry.searchName)) {\r
-                    return false;\r
-                }\r
-                // are the default locales the same?\r
-                if (defaultLocale == null) {\r
-                    if (otherEntry.defaultLocale != null) {\r
-                        return false;\r
-                    }\r
-                } else {\r
-                    if (!defaultLocale.equals(otherEntry.defaultLocale)) {\r
-                        return false;\r
-                    }\r
-                }\r
-                //are refs (both non-null) or (both null)?\r
-                if (loaderRef == null) {\r
-                    return otherEntry.loaderRef == null;\r
-                } else {\r
-                    return (otherEntry.loaderRef != null)\r
-                            && (loaderRef.get() == otherEntry.loaderRef.get());\r
-                }\r
-            } catch (NullPointerException e) {\r
-                return false;\r
-            } catch (ClassCastException e) {\r
-                return false;\r
-            }\r
-        }\r
-        public int hashCode() {\r
-            return hashCodeCache;\r
-        }\r
-        public Object clone() {\r
-            try {\r
-                return super.clone();\r
-            } catch (CloneNotSupportedException e) {\r
-                //this should never happen\r
-                throw new IllegalStateException();\r
-            }\r
-        }\r
-        ///CLOVER:ON\r
-        private synchronized void setKeyValues(ClassLoader root, String searchName, ULocale defaultLocale) {\r
-            this.searchName = searchName;\r
-            hashCodeCache = searchName.hashCode();\r
-            this.defaultLocale = defaultLocale;\r
-            if (defaultLocale != null) {\r
-                hashCodeCache ^= defaultLocale.hashCode();\r
-            }\r
-            if (root == null) {\r
-                this.loaderRef = null;\r
-            } else {\r
-                loaderRef = new SoftReference(root);\r
-                hashCodeCache ^= root.hashCode();\r
-            }\r
-        }\r
-        /*private void clear() {\r
-            setKeyValues(null, "", null);\r
-        }*/\r
-    }\r
-\r
-    private static final ResourceCacheKey cacheKey = new ResourceCacheKey();\r
-\r
-    private static final int ROOT_MISSING = 0;\r
-    private static final int ROOT_ICU = 1;\r
-    private static final int ROOT_JAVA = 2;\r
-\r
-    private static SoftReference ROOT_CACHE;\r
-\r
-    private static int getRootType(String baseName, ClassLoader root)\r
-    {\r
-        Map m = null;\r
-        Integer rootType;\r
-\r
-        if (ROOT_CACHE != null) {\r
-            m = (Map) ROOT_CACHE.get();\r
-        }\r
-\r
-        if (m == null) {\r
-            m = new HashMap();\r
-            ROOT_CACHE = new SoftReference(m);\r
-        }\r
-\r
-        rootType = (Integer) m.get(baseName);\r
-\r
-        if (rootType == null) {\r
-            String rootLocale = (baseName.indexOf('.')==-1) ? "root" : "";\r
-            int rt = ROOT_MISSING; // value set on success\r
-            try{\r
-                ICUResourceBundle.getBundleInstance(baseName, rootLocale, root, true);\r
-                rt = ROOT_ICU;\r
-            }catch(MissingResourceException ex){\r
-                try{\r
-                    ResourceBundleWrapper.getBundleInstance(baseName, rootLocale, root, true);\r
-                    rt = ROOT_JAVA;\r
-                }catch(MissingResourceException e){\r
-                    //throw away the exception\r
-                }\r
-            }\r
-\r
-            rootType = new Integer(rt);\r
-            m.put(baseName, rootType);\r
-        }\r
-\r
-        return rootType.intValue();\r
-    }\r
-\r
-    private static void setRootType(String baseName, int rootType)\r
-    {\r
-        Integer rt = new Integer(rootType);\r
-        Map m = null;\r
-\r
-        if (ROOT_CACHE != null) {\r
-            m = (Map) ROOT_CACHE.get();\r
-        } else {\r
-            m = new HashMap();\r
-            ROOT_CACHE = new SoftReference(m);\r
-        }\r
-\r
-        m.put(baseName, rt);\r
-    }\r
-\r
-    /**\r
-     * Loads a new resource bundle for the give base name, locale and class loader.\r
-     * Optionally will disable loading of fallback bundles.\r
-     * @param baseName the base name of the resource bundle, a fully qualified class name\r
-     * @param localeName the locale for which a resource bundle is desired\r
-     * @param root the class object from which to load the resource bundle\r
-     * @param disableFallback disables loading of fallback lookup chain\r
-     * @exception MissingResourceException\r
-     *     if no resource bundle for the specified base name can be found\r
-     * @return a resource bundle for the given base name and locale\r
-     * @stable ICU 3.0\r
-     */\r
-    protected static UResourceBundle instantiateBundle(String baseName, String localeName,\r
-                                                       ClassLoader root, boolean disableFallback){\r
-        UResourceBundle b = null;\r
-        int rootType = getRootType(baseName, root);\r
-\r
-        ULocale defaultLocale = ULocale.getDefault();\r
-\r
-        switch (rootType)\r
-        {\r
-        case ROOT_ICU:\r
-            if(disableFallback) {\r
-                String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);\r
-                synchronized(cacheKey){\r
-                    cacheKey.setKeyValues(root, fullName, defaultLocale);\r
-                    b = loadFromCache(cacheKey);\r
-                }\r
-\r
-                if (b == null) {\r
-                    b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);\r
-                    //cacheKey.setKeyValues(root, fullName, defaultLocale);\r
-                    addToCache(cacheKey, b);\r
-                }\r
-            } else {\r
-                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);\r
-            }\r
-\r
-            return b;\r
-\r
-        case ROOT_JAVA:\r
-            return ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, disableFallback);\r
-\r
-        default:\r
-            try{\r
-                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);\r
-                setRootType(baseName, ROOT_ICU);\r
-            }catch(MissingResourceException ex){\r
-                b = ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, disableFallback);\r
-                setRootType(baseName, ROOT_JAVA);\r
-            }\r
-            return b;\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Returns a binary data from a binary resource.\r
-     *\r
-     * @return a pointer to a chuck of unsigned bytes which live in a memory mapped/DLL file.\r
-     * @see #getIntVector\r
-     * @see #getInt\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public ByteBuffer getBinary() {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a string from a string resource type\r
-     *\r
-     * @return a string\r
-     * @see #getBinary()\r
-     * @see #getIntVector\r
-     * @see #getInt\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public String getString() {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a string array from a array resource type\r
-     *\r
-     * @return a string\r
-     * @see #getString()\r
-     * @see #getIntVector\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public String[] getStringArray() {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a binary data from a binary resource.\r
-     *\r
-     * @param ba  The byte array to write the bytes to. A null variable is OK.\r
-     * @return an array bytes containing the binary data from the resource.\r
-     * @see #getIntVector\r
-     * @see #getInt\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public byte[] getBinary(byte[] ba) {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a 32 bit integer array from a resource.\r
-     *\r
-     * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file.\r
-     * @see #getBinary()\r
-     * @see #getInt\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public int[] getIntVector() {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a signed integer from a resource.\r
-     *\r
-     * @return an integer value\r
-     * @see #getIntVector\r
-     * @see #getBinary()\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public int getInt() {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a unsigned integer from a resource.\r
-     * This integer is originally 28 bit and the sign gets propagated.\r
-     *\r
-     * @return an integer value\r
-     * @see #getIntVector\r
-     * @see #getBinary()\r
-     * @throws MissingResourceException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public int getUInt() {\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns a resource in a given resource that has a given key.\r
-     *\r
-     * @param aKey               a key associated with the wanted resource\r
-     * @return                  a resource bundle object representing the resource\r
-     * @throws MissingResourceException\r
-     * @stable ICU 3.8\r
-     */\r
-    public UResourceBundle get(String aKey) {\r
-        UResourceBundle obj = handleGet(aKey, null, this);\r
-        if (obj == null) {\r
-            UResourceBundle res = this;\r
-            while ((res = res.getParent()) != null && obj == null) {\r
-                //call the get method to recursively fetch the resource\r
-                obj = res.handleGet(aKey, null, this);\r
-            }\r
-            if (obj == null) {\r
-                String fullName = ICUResourceBundleReader.getFullName(\r
-                        getBaseName(), getLocaleID());\r
-                throw new MissingResourceException(\r
-                        "Can't find resource for bundle " + fullName + ", key "\r
-                                + aKey, this.getClass().getName(), aKey);\r
-            }\r
-        }\r
-        ((ICUResourceBundle)obj).setLoadingStatus(getLocaleID());\r
-        return obj;\r
-    }\r
-\r
-    /**\r
-     * Returns the string in a given resource at the specified index.\r
-     *\r
-     * @param index            an index to the wanted string.\r
-     * @return                  a string which lives in the resource.\r
-     * @throws IndexOutOfBoundsException\r
-     * @throws UResourceTypeMismatchException\r
-     * @stable ICU 3.8\r
-     */\r
-    public String getString(int index) {\r
-        ICUResourceBundle temp = (ICUResourceBundle)get(index);\r
-        if (temp.getType() == STRING) {\r
-            return temp.getString();\r
-        }\r
-        throw new UResourceTypeMismatchException("");\r
-    }\r
-\r
-    /**\r
-     * Returns the resource in a given resource at the specified index.\r
-     *\r
-     * @param index             an index to the wanted resource.\r
-     * @return                  the sub resource UResourceBundle object\r
-     * @throws IndexOutOfBoundsException\r
-     * @throws MissingResourceException\r
-     * @stable ICU 3.8\r
-     */\r
-    public UResourceBundle get(int index) {\r
-        UResourceBundle obj = handleGet(index, null, this);\r
-        if (obj == null) {\r
-            obj = (ICUResourceBundle) getParent();\r
-            if (obj != null) {\r
-                obj = obj.get(index);\r
-            }\r
-            if (obj == null)\r
-                throw new MissingResourceException(\r
-                        "Can't find resource for bundle "\r
-                                + this.getClass().getName() + ", key "\r
-                                + getKey(), this.getClass().getName(), getKey());\r
-        }\r
-        ((ICUResourceBundle)obj).setLoadingStatus(getLocaleID());\r
-        return obj;\r
-    }\r
-    /**\r
-     * Returns the keys in this bundle as an enumeration\r
-     * @return an enumeration containing key strings\r
-     * @stable ICU 3.8\r
-     */\r
-    public Enumeration getKeys() {\r
-        initKeysVector();\r
-        return keys.elements();\r
-    }\r
-\r
-    private Vector keys = null;\r
-    private synchronized void initKeysVector(){\r
-        if(keys!=null){\r
-            return;\r
-        }\r
-        //ICUResourceBundle current = this;\r
-        keys = new Vector();\r
-        Enumeration e = this.handleGetKeys();\r
-        while(e.hasMoreElements()){\r
-            String elem = (String)e.nextElement();\r
-            if(!keys.contains(elem)){\r
-                keys.add(elem);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Returns the size of a resource. Size for scalar types is always 1,\r
-     * and for vector/table types is the number of child resources.\r
-     * <br><b><font color='red'>Warning: </font></b> Integer array is treated as a scalar type. There are no\r
-     *          APIs to access individual members of an integer array. It\r
-     *          is always returned as a whole.\r
-     * @return number of resources in a given resource.\r
-     * @stable ICU 3.8\r
-     */\r
-    public int getSize() {\r
-        return size;\r
-    }\r
-\r
-    /**\r
-     * Returns the type of a resource.\r
-     * Available types are {@link #INT INT}, {@link #ARRAY ARRAY},\r
-     * {@link #BINARY BINARY}, {@link #INT_VECTOR INT_VECTOR},\r
-     * {@link #STRING STRING}, {@link #TABLE TABLE}.\r
-     *\r
-     * @return type of the given resource.\r
-     * @stable ICU 3.8\r
-     */\r
-    public int getType() {\r
-        int type = ICUResourceBundle.RES_GET_TYPE(resource);\r
-        if(type==TABLE32){\r
-            return TABLE; //Mask the table32's real type\r
-        }\r
-        return type;\r
-    }\r
-\r
-    /**\r
-     * Return the version number associated with this UResourceBundle as an\r
-     * VersionInfo object.\r
-     * @return VersionInfo object containing the version of the bundle\r
-     * @stable ICU 3.8\r
-     */\r
-    public VersionInfo getVersion() {\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * Returns the iterator which iterates over this\r
-     * resource bundle\r
-     * @return UResourceBundleIterator that iterates over the resources in the bundle\r
-     * @stable ICU 3.8\r
-     */\r
-    public UResourceBundleIterator getIterator() {\r
-        return new UResourceBundleIterator(this);\r
-    }\r
-    /**\r
-     * Returns the key associated with a given resource. Not all the resources have a key - only\r
-     * those that are members of a table.\r
-     * @return a key associated to this resource, or null if it doesn't have a key\r
-     * @stable ICU 3.8\r
-     */\r
-    public String getKey() {\r
-        return key;\r
-    }\r
-    /**\r
-     * Resource type constant for "no resource".\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int NONE = -1;\r
-\r
-    /**\r
-     * Resource type constant for strings.\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int STRING = 0;\r
-\r
-    /**\r
-     * Resource type constant for binary data.\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int BINARY = 1;\r
-\r
-    /**\r
-     * Resource type constant for tables of key-value pairs.\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int TABLE = 2;\r
-\r
-    /**\r
-     * Resource type constant for aliases;\r
-     * internally stores a string which identifies the actual resource\r
-     * storing the data (can be in a different resource bundle).\r
-     * Resolved internally before delivering the actual resource through the API.\r
-     * @internal ICU 3.8\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected static final int ALIAS = 3;\r
-\r
-    /**\r
-     * Internal use only.\r
-     * Alternative resource type constant for tables of key-value pairs.\r
-     * Never returned by getType().\r
-     * @internal ICU 3.8\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected static final int TABLE32 = 4;\r
-\r
-    /**\r
-     * Resource type constant for a single 28-bit integer, interpreted as\r
-     * signed or unsigned by the getInt() function.\r
-     * @see #getInt\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int INT = 7;\r
-\r
-    /**\r
-     * Resource type constant for arrays of resources.\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int ARRAY = 8;\r
-\r
-    /**\r
-     * Resource type constant for vectors of 32-bit integers.\r
-     * @see #getIntVector\r
-     * @stable ICU 3.8\r
-     */\r
-    public static final int INT_VECTOR = 14;\r
-\r
-    //====== protected members ==============\r
-    /**\r
-     * Data member where the subclasses store the key\r
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected String key;\r
-    /**\r
-     * Data member where the subclasses store the size of resources\r
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected int size = 1;\r
-    /**\r
-     * Data member where the subclasses store the offset within resource data\r
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected long resource = RES_BOGUS;\r
-    /**\r
-     * Data member where the subclasses store whether the resource is top level\r
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected boolean isTopLevel = false;\r
-\r
-    private static final long RES_BOGUS = 0xffffffff;\r
-\r
-    /**\r
-     * Actual worker method for fetching a resource based on the given key.\r
-     * Sub classes must override this method if they support resources with keys.\r
-     * @param aKey the key string of the resource to be fetched\r
-     * @param table hashtable object to hold references of resources already seen\r
-     * @param requested the original resource bundle object on which the get method was invoked.\r
-     *                  The requested bundle and the bundle on which this method is invoked\r
-     *                  are the same, except in the cases where aliases are involved.\r
-     * @return UResourceBundle a resource associated with the key\r
-     * @stable ICU 3.8\r
-     */\r
-    protected UResourceBundle handleGet(String aKey, HashMap table, UResourceBundle requested) {\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * Actual worker method for fetching a resource based on the given index.\r
-     * Sub classes must override this method if they support arrays of resources.\r
-     * @param index the index of the resource to be fetched\r
-     * @param table hashtable object to hold references of resources already seen\r
-     * @param requested the original resource bundle object on which the get method was invoked.\r
-     *                  The requested bundle and the bundle on which this method is invoked\r
-     *                  are the same, except in the cases where aliases are involved.\r
-     * @return UResourceBundle a resource associated with the index\r
-     * @stable ICU 3.8\r
-     */\r
-    protected UResourceBundle handleGet(int index, HashMap table, UResourceBundle requested) {\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * Actual worker method for fetching the array of strings in a resource.\r
-     * Sub classes must override this method if they support arrays of strings.\r
-     * @return String[] An array of strings containing strings\r
-     * @stable ICU 3.8\r
-     */\r
-    protected String[] handleGetStringArray() {\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * Actual worker method for fetching the keys of resources contained in the resource.\r
-     * Sub classes must override this method if they support keys and associated resources.\r
-     *\r
-     * @return Enumeration An enumeration of all the keys in this resource.\r
-     * @stable ICU 3.8\r
-     */\r
-    protected Enumeration handleGetKeys(){\r
-        Vector resKeys = new Vector();\r
-        UResourceBundle item = null;\r
-        for (int i = 0; i < size; i++) {\r
-            item = get(i);\r
-            resKeys.add(item.getKey());\r
-        }\r
-        return resKeys.elements();\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     * @stable ICU 3.8\r
-     */\r
-    // this method is declared in ResourceBundle class\r
-    // so cannot change the signature\r
-    // Override this method\r
-    protected Object handleGetObject(String aKey) {\r
-        return handleGetObjectImpl(aKey, this);\r
-    }\r
-\r
-    /**\r
-     * Override the superclass method\r
-     */\r
-    // To facilitate XPath style aliases we need a way to pass the reference\r
-    // to requested locale. The only way I could figure out is to implement\r
-    // the look up logic here. This has a disadvantage that if the client\r
-    // loads an ICUResourceBundle, calls ResourceBundle.getObject method\r
-    // with a key that does not exist in the bundle then the lookup is\r
-    // done twice before throwing a MissingResourceExpection.\r
-    private Object handleGetObjectImpl(String aKey, UResourceBundle requested) {\r
-        Object obj = resolveObject(aKey, requested);\r
-        if (obj == null) {\r
-            UResourceBundle parentBundle = getParent();\r
-            if (parentBundle != null) {\r
-                obj = parentBundle.handleGetObjectImpl(aKey, requested);\r
-            }\r
-            if (obj == null)\r
-                throw new MissingResourceException(\r
-                    "Can't find resource for bundle "\r
-                    + this.getClass().getName() + ", key " + aKey,\r
-                    this.getClass().getName(), aKey);\r
-        }\r
-        return obj;\r
-    }\r
-\r
-    // Routine for figuring out the type of object to be returned\r
-    // string or string array\r
-    private Object resolveObject(String aKey, UResourceBundle requested) {\r
-        if (getType() == STRING) {\r
-            return getString();\r
-        }\r
-        UResourceBundle obj = handleGet(aKey, null, requested);\r
-        if (obj != null) {\r
-            if (obj.getType() == STRING) {\r
-                return obj.getString();\r
-            }\r
-            try {\r
-                if (obj.getType() == ARRAY) {\r
-                    return obj.handleGetStringArray();\r
-                }\r
-            } catch (UResourceTypeMismatchException ex) {\r
-                return obj;\r
-            }\r
-        }\r
-        return obj;\r
-    }\r
-\r
-    /**\r
-     * This method is for setting the loading status of the resource.\r
-     * The status is analogous to the warning status in ICU4C.\r
-     * @internal ICU 3.8\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected abstract void setLoadingStatus(int newStatus);\r
-}\r
+//##header J2SE15
+/*
+ *******************************************************************************
+ * Copyright (C) 2004-2009, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+
+package com.ibm.icu.util;
+
+import java.lang.ref.SoftReference;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+import com.ibm.icu.impl.ICUCache;
+import com.ibm.icu.impl.ICUResourceBundle;
+import com.ibm.icu.impl.ICUResourceBundleReader;
+import com.ibm.icu.impl.ResourceBundleWrapper;
+import com.ibm.icu.impl.SimpleCache;
+import com.ibm.icu.util.ULocale;
+
+//#if defined(FOUNDATION10) || defined(J2SE13) || defined(ECLIPSE_FRAGMENT)
+//##import com.ibm.icu.impl.ByteBuffer;
+//#else
+import java.nio.ByteBuffer;
+//#endif
+
+/**
+ * A class representing a collection of resource information pertaining to a given
+ * locale. A resource bundle provides a way of accessing locale- specific information in
+ * a data file. You create a resource bundle that manages the resources for a given
+ * locale and then ask it for individual resources.
+ * <P>
+ * In ResourceBundle class, an object is created
+ * and the sub items are fetched using getString, getObject methods.
+ * In UResourceBundle,each individual element of a resource is a resource by itself.
+ *
+ * <P>
+ * Resource bundles in ICU are currently defined using text files which conform to the following
+ * <a href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF definition</a>.
+ * More on resource bundle concepts and syntax can be found in the
+ * <a href="http://www.icu-project.org/userguide/ResourceManagement.html">Users Guide</a>.
+ * <P>
+ *
+ * The packaging of ICU *.res files can be of two types
+ * ICU4C:
+ * <pre>
+ *       root.res
+ *         |
+ *      --------
+ *     |        |
+ *   fr.res  en.res
+ *     |
+ *   --------
+ *  |        |
+ * fr_CA.res fr_FR.res
+ * </pre>
+ * JAVA/JDK:
+ * <pre>
+ *    LocaleElements.res
+ *         |
+ *      -------------------
+ *     |                   |
+ * LocaleElements_fr.res  LocaleElements_en.res
+ *     |
+ *   ---------------------------
+ *  |                            |
+ * LocaleElements_fr_CA.res   LocaleElements_fr_FR.res
+ * </pre>
+ * Depending on the organization of your resources, the syntax to getBundleInstance will change.
+ * To open ICU style organization use:
+ * <pre>
+ *      UResourceBundle bundle = UResourceBundle.getBundleInstance("com/mycompany/resources", "en_US", myClassLoader);
+ * </pre>
+ * To open Java/JDK style organization use:
+ * <pre>
+ *      UResourceBundle bundle = UResourceBundle.getBundleInstance("com.mycompany.resources.LocaleElements", "en_US", myClassLoader);
+ * </pre>
+ * <note>
+ * Please use pass a class loader for loading non-ICU resources. Java security does not
+ * allow loading of resources across jar files. You must provide your class loader
+ * to load the resources
+ * </note>
+ * @stable ICU 3.0
+ * @author ram
+ */
+public abstract class UResourceBundle extends ResourceBundle{
+
+
+    /**
+     * Creates a resource bundle using the specified base name and locale.
+     * ICU_DATA_CLASS is used as the default root.
+     * @param baseName the base name of the resource bundle, a fully qualified class name
+     * @param localeName the locale for which a resource bundle is desired
+     * @exception MissingResourceException
+     *     if no resource bundle for the specified base name can be found
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.0
+     */
+    public static UResourceBundle getBundleInstance(String baseName, String localeName){
+        return getBundleInstance(baseName, localeName, ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
+    }
+
+    /**
+     * Creates a resource bundle using the specified base name, locale, and class root.
+     *
+     * @param baseName the base name of the resource bundle, a fully qualified class name
+     * @param localeName the locale for which a resource bundle is desired
+     * @param root the class object from which to load the resource bundle
+     * @exception MissingResourceException
+     *     if no resource bundle for the specified base name can be found
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.0
+     */
+    public static UResourceBundle getBundleInstance(String baseName, String localeName, ClassLoader root){
+        return getBundleInstance(baseName, localeName, root, false);
+    }
+
+    /**
+     * Creates a resource bundle using the specified base name, locale, and class root.
+     *
+     * @param baseName the base name of the resource bundle, a fully qualified class name
+     * @param localeName the locale for which a resource bundle is desired
+     * @param root the class object from which to load the resource bundle
+     * @param disableFallback Option to disable locale inheritence.
+     *                          If true the fallback chain will not be built.
+     * @exception MissingResourceException
+     *     if no resource bundle for the specified base name can be found
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.0
+     *
+     */
+    protected static UResourceBundle getBundleInstance(String baseName, String localeName, ClassLoader root, boolean disableFallback) {
+        return instantiateBundle(baseName, localeName, root, disableFallback);
+    }
+
+    /**
+     * Sole constructor.  (For invocation by subclass constructors, typically
+     * implicit.)  This is public for compatibility with Java, whose compiler
+     * will generate public default constructors for an abstract class.
+     * @stable ICU 3.0
+     */
+    public UResourceBundle() {
+    }
+
+    /**
+     * Creates a UResourceBundle for the locale specified, from which users can extract resources by using
+     * their corresponding keys.
+     * @param locale  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @return a resource bundle for the given locale
+     * @stable ICU 3.0
+     */
+    public static UResourceBundle getBundleInstance(ULocale locale) {
+        if (locale==null) {
+            locale = ULocale.getDefault();
+        }
+        return getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
+    }
+
+    /**
+     * Creates a UResourceBundle for the default locale and specified base name,
+     * from which users can extract resources by using their corresponding keys.
+     * @param baseName  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @return a resource bundle for the given base name and default locale
+     * @stable ICU 3.0
+     */
+    public static UResourceBundle getBundleInstance(String baseName) {
+        if (baseName == null) {
+            baseName = ICUResourceBundle.ICU_BASE_NAME;
+        }
+        ULocale uloc = ULocale.getDefault();
+        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
+    }
+
+    /**
+     * Creates a UResourceBundle for the specified locale and specified base name,
+     * from which users can extract resources by using their corresponding keys.
+     * @param baseName  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @param locale  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.0
+     */
+
+    public static UResourceBundle getBundleInstance(String baseName, Locale locale) {
+        if (baseName == null) {
+            baseName = ICUResourceBundle.ICU_BASE_NAME;
+        }
+        ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);
+
+        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
+    }
+
+    /**
+     * Creates a UResourceBundle, from which users can extract resources by using
+     * their corresponding keys.
+     * @param baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
+     * @param locale  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.0
+     */
+    public static UResourceBundle getBundleInstance(String baseName, ULocale locale) {
+        if (baseName == null) {
+            baseName = ICUResourceBundle.ICU_BASE_NAME;
+        }
+        if (locale == null) {
+            locale = ULocale.getDefault();
+        }
+        return getBundleInstance(baseName, locale.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
+    }
+
+    /**
+     * Creates a UResourceBundle for the specified locale and specified base name,
+     * from which users can extract resources by using their corresponding keys.
+     * @param baseName  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @param locale  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @param loader  the loader to use
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.8
+     */
+    public static UResourceBundle getBundleInstance(String baseName, Locale locale, ClassLoader loader) {
+        if (baseName == null) {
+            baseName = ICUResourceBundle.ICU_BASE_NAME;
+        }
+        ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);
+        return getBundleInstance(baseName, uloc.toString(), loader, false);
+    }
+
+    /**
+     * Creates a UResourceBundle, from which users can extract resources by using
+     * their corresponding keys.<br><br>
+     * Note: Please use this API for loading non-ICU resources. Java security does not
+     * allow loading of resources across jar files. You must provide your class loader
+     * to load the resources
+     * @param baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
+     * @param locale  specifies the locale for which we want to open the resource.
+     *                If null the bundle for default locale is opened.
+     * @param loader  the loader to use
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.8
+     */
+    public static UResourceBundle getBundleInstance(String baseName, ULocale locale, ClassLoader loader) {
+        if (baseName == null) {
+            baseName = ICUResourceBundle.ICU_BASE_NAME;
+        }
+        if (locale == null) {
+            locale = ULocale.getDefault();
+        }
+        return getBundleInstance(baseName, locale.toString(), loader, false);
+    }
+
+    /**
+     * Returns the RFC 3066 conformant locale id of this resource bundle.
+     * This method can be used after a call to getBundleInstance() to
+     * determine whether the resource bundle returned really
+     * corresponds to the requested locale or is a fallback.
+     *
+     * @return the locale of this resource bundle
+     * @stable ICU 3.0
+     */
+    public abstract ULocale getULocale();
+
+    /**
+     * Gets the localeID
+     * @return The string representation of the localeID
+     * @stable ICU 3.0
+     */
+    protected abstract String getLocaleID();
+    /**
+     * Gets the base name of the resource bundle
+     * @return The string representation of the base name
+     * @stable ICU 3.0
+     */
+    protected abstract String getBaseName();
+
+    /**
+     * Gets the parent bundle
+     * @return The parent bundle
+     * @stable ICU 3.0
+     */
+    protected abstract UResourceBundle getParent();
+
+
+    /**
+     * Get the locale of this bundle
+     * @return the locale of this resource bundle
+     * @stable ICU 3.0
+     */
+    public Locale getLocale(){
+        return getULocale().toLocale();
+    }
+
+    // Cache for ResourceBundle instantiation
+    private static ICUCache BUNDLE_CACHE = new SimpleCache();
+
+    /**
+     * @internal
+     */
+    public static void resetBundleCache()
+    {
+        /*
+         * A HACK!!!!!
+         * Currently if a resourcebundle with fallback turned ON is added to the cache
+         * and then a getBundleInstance() is called for a bundle with fallback turned OFF
+         * it will actually search the cache for any bundle of the same locale
+         * regaurdless of fallback status. This method has been created so that if
+         * The calling method KNOWS that instances of the other fallback state may be in the 
+         * cache, the calling method may call this method to clear out the cache.
+         *
+         */
+        //TODO figure a way around this method(see method comment)
+        BUNDLE_CACHE = new SimpleCache();
+    }
+    
+    private static void addToCache(ResourceCacheKey key, UResourceBundle b) {
+        BUNDLE_CACHE.put(key, b);
+    }
+
+    /**
+     * Method used by subclasses to add the a particular resource bundle object to the managed cache
+     * @internal revisit for ICU 3.6
+     * @deprecated This API is ICU internal only.
+     */
+    protected static void addToCache(ClassLoader cl, String fullName, ULocale defaultLocale,  UResourceBundle b){
+        synchronized(cacheKey){
+            cacheKey.setKeyValues(cl, fullName, defaultLocale);
+            addToCache((ResourceCacheKey)cacheKey.clone(), b);
+        }
+    }
+    /**
+     * Method used by sub classes to load a resource bundle object from the managed cache
+     * @internal revisit for ICU 3.6
+     * @deprecated This API is ICU internal only.
+     */
+    protected static UResourceBundle loadFromCache(ClassLoader cl, String fullName, ULocale defaultLocale){
+        synchronized(cacheKey){
+            cacheKey.setKeyValues(cl, fullName, defaultLocale);
+            return loadFromCache(cacheKey);
+        }
+    }
+    private static UResourceBundle loadFromCache(ResourceCacheKey key) {
+        return (UResourceBundle)BUNDLE_CACHE.get(key);
+    }
+
+    /**
+     * Key used for cached resource bundles.  The key checks
+     * the resource name, the class root, and the default
+     * locale to determine if the resource is a match to the
+     * requested one. The root may be null, but the
+     * searchName and the default locale must have a non-null value.
+     * Note that the default locale may change over time, and
+     * lookup should always be based on the current default
+     * locale (if at all).
+     */
+    private static final class ResourceCacheKey implements Cloneable {
+        private SoftReference loaderRef;
+        private String searchName;
+        private ULocale defaultLocale;
+        private int hashCodeCache;
+        ///CLOVER:OFF
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+            try {
+                final ResourceCacheKey otherEntry = (ResourceCacheKey) other;
+                //quick check to see if they are not equal
+                if (hashCodeCache != otherEntry.hashCodeCache) {
+                    return false;
+                }
+                //are the names the same?
+                if (!searchName.equals(otherEntry.searchName)) {
+                    return false;
+                }
+                // are the default locales the same?
+                if (defaultLocale == null) {
+                    if (otherEntry.defaultLocale != null) {
+                        return false;
+                    }
+                } else {
+                    if (!defaultLocale.equals(otherEntry.defaultLocale)) {
+                        return false;
+                    }
+                }
+                //are refs (both non-null) or (both null)?
+                if (loaderRef == null) {
+                    return otherEntry.loaderRef == null;
+                } else {
+                    return (otherEntry.loaderRef != null)
+                            && (loaderRef.get() == otherEntry.loaderRef.get());
+                }
+            } catch (NullPointerException e) {
+                return false;
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+        public int hashCode() {
+            return hashCodeCache;
+        }
+        public Object clone() {
+            try {
+                return super.clone();
+            } catch (CloneNotSupportedException e) {
+                //this should never happen
+                throw new IllegalStateException();
+            }
+        }
+        ///CLOVER:ON
+        private synchronized void setKeyValues(ClassLoader root, String searchName, ULocale defaultLocale) {
+            this.searchName = searchName;
+            hashCodeCache = searchName.hashCode();
+            this.defaultLocale = defaultLocale;
+            if (defaultLocale != null) {
+                hashCodeCache ^= defaultLocale.hashCode();
+            }
+            if (root == null) {
+                this.loaderRef = null;
+            } else {
+                loaderRef = new SoftReference(root);
+                hashCodeCache ^= root.hashCode();
+            }
+        }
+        /*private void clear() {
+            setKeyValues(null, "", null);
+        }*/
+    }
+
+    private static final ResourceCacheKey cacheKey = new ResourceCacheKey();
+
+    private static final int ROOT_MISSING = 0;
+    private static final int ROOT_ICU = 1;
+    private static final int ROOT_JAVA = 2;
+
+    private static SoftReference ROOT_CACHE;
+
+    private static int getRootType(String baseName, ClassLoader root)
+    {
+        Map m = null;
+        Integer rootType;
+
+        if (ROOT_CACHE != null) {
+            m = (Map) ROOT_CACHE.get();
+        }
+
+        if (m == null) {
+            m = new HashMap();
+            ROOT_CACHE = new SoftReference(m);
+        }
+
+        rootType = (Integer) m.get(baseName);
+
+        if (rootType == null) {
+            String rootLocale = (baseName.indexOf('.')==-1) ? "root" : "";
+            int rt = ROOT_MISSING; // value set on success
+            try{
+                ICUResourceBundle.getBundleInstance(baseName, rootLocale, root, true);
+                rt = ROOT_ICU;
+            }catch(MissingResourceException ex){
+                try{
+                    ResourceBundleWrapper.getBundleInstance(baseName, rootLocale, root, true);
+                    rt = ROOT_JAVA;
+                }catch(MissingResourceException e){
+                    //throw away the exception
+                }
+            }
+
+            rootType = new Integer(rt);
+            m.put(baseName, rootType);
+        }
+
+        return rootType.intValue();
+    }
+
+    private static void setRootType(String baseName, int rootType)
+    {
+        Integer rt = new Integer(rootType);
+        Map m = null;
+
+        if (ROOT_CACHE != null) {
+            m = (Map) ROOT_CACHE.get();
+        } else {
+            m = new HashMap();
+            ROOT_CACHE = new SoftReference(m);
+        }
+
+        m.put(baseName, rt);
+    }
+
+    /**
+     * Loads a new resource bundle for the give base name, locale and class loader.
+     * Optionally will disable loading of fallback bundles.
+     * @param baseName the base name of the resource bundle, a fully qualified class name
+     * @param localeName the locale for which a resource bundle is desired
+     * @param root the class object from which to load the resource bundle
+     * @param disableFallback disables loading of fallback lookup chain
+     * @exception MissingResourceException
+     *     if no resource bundle for the specified base name can be found
+     * @return a resource bundle for the given base name and locale
+     * @stable ICU 3.0
+     */
+    protected static UResourceBundle instantiateBundle(String baseName, String localeName,
+                                                       ClassLoader root, boolean disableFallback){
+        UResourceBundle b = null;
+        int rootType = getRootType(baseName, root);
+
+        ULocale defaultLocale = ULocale.getDefault();
+
+        switch (rootType)
+        {
+        case ROOT_ICU:
+            if(disableFallback) {
+                String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
+                synchronized(cacheKey){
+                    cacheKey.setKeyValues(root, fullName, defaultLocale);
+                    b = loadFromCache(cacheKey);
+                }
+
+                if (b == null) {
+                    b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);
+                    //cacheKey.setKeyValues(root, fullName, defaultLocale);
+                    addToCache(cacheKey, b);
+                }
+            } else {
+                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);
+            }
+
+            return b;
+
+        case ROOT_JAVA:
+            return ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, disableFallback);
+
+        default:
+            try{
+                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);
+                setRootType(baseName, ROOT_ICU);
+            }catch(MissingResourceException ex){
+                b = ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, disableFallback);
+                setRootType(baseName, ROOT_JAVA);
+            }
+            return b;
+        }
+    }
+
+
+    /**
+     * Returns a binary data from a binary resource.
+     *
+     * @return a pointer to a chuck of unsigned bytes which live in a memory mapped/DLL file.
+     * @see #getIntVector
+     * @see #getInt
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public ByteBuffer getBinary() {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a string from a string resource type
+     *
+     * @return a string
+     * @see #getBinary()
+     * @see #getIntVector
+     * @see #getInt
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public String getString() {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a string array from a array resource type
+     *
+     * @return a string
+     * @see #getString()
+     * @see #getIntVector
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public String[] getStringArray() {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a binary data from a binary resource.
+     *
+     * @param ba  The byte array to write the bytes to. A null variable is OK.
+     * @return an array bytes containing the binary data from the resource.
+     * @see #getIntVector
+     * @see #getInt
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public byte[] getBinary(byte[] ba) {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a 32 bit integer array from a resource.
+     *
+     * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file.
+     * @see #getBinary()
+     * @see #getInt
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public int[] getIntVector() {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a signed integer from a resource.
+     *
+     * @return an integer value
+     * @see #getIntVector
+     * @see #getBinary()
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public int getInt() {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a unsigned integer from a resource.
+     * This integer is originally 28 bit and the sign gets propagated.
+     *
+     * @return an integer value
+     * @see #getIntVector
+     * @see #getBinary()
+     * @throws MissingResourceException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public int getUInt() {
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns a resource in a given resource that has a given key.
+     *
+     * @param aKey               a key associated with the wanted resource
+     * @return                  a resource bundle object representing the resource
+     * @throws MissingResourceException
+     * @stable ICU 3.8
+     */
+    public UResourceBundle get(String aKey) {
+        UResourceBundle obj = handleGet(aKey, null, this);
+        if (obj == null) {
+            UResourceBundle res = this;
+            while ((res = res.getParent()) != null && obj == null) {
+                //call the get method to recursively fetch the resource
+                obj = res.handleGet(aKey, null, this);
+            }
+            if (obj == null) {
+                String fullName = ICUResourceBundleReader.getFullName(
+                        getBaseName(), getLocaleID());
+                throw new MissingResourceException(
+                        "Can't find resource for bundle " + fullName + ", key "
+                                + aKey, this.getClass().getName(), aKey);
+            }
+        }
+        ((ICUResourceBundle)obj).setLoadingStatus(getLocaleID());
+        return obj;
+    }
+
+    /**
+     * Returns the string in a given resource at the specified index.
+     *
+     * @param index            an index to the wanted string.
+     * @return                  a string which lives in the resource.
+     * @throws IndexOutOfBoundsException
+     * @throws UResourceTypeMismatchException
+     * @stable ICU 3.8
+     */
+    public String getString(int index) {
+        ICUResourceBundle temp = (ICUResourceBundle)get(index);
+        if (temp.getType() == STRING) {
+            return temp.getString();
+        }
+        throw new UResourceTypeMismatchException("");
+    }
+
+    /**
+     * Returns the resource in a given resource at the specified index.
+     *
+     * @param index             an index to the wanted resource.
+     * @return                  the sub resource UResourceBundle object
+     * @throws IndexOutOfBoundsException
+     * @throws MissingResourceException
+     * @stable ICU 3.8
+     */
+    public UResourceBundle get(int index) {
+        UResourceBundle obj = handleGet(index, null, this);
+        if (obj == null) {
+            obj = (ICUResourceBundle) getParent();
+            if (obj != null) {
+                obj = obj.get(index);
+            }
+            if (obj == null)
+                throw new MissingResourceException(
+                        "Can't find resource for bundle "
+                                + this.getClass().getName() + ", key "
+                                + getKey(), this.getClass().getName(), getKey());
+        }
+        ((ICUResourceBundle)obj).setLoadingStatus(getLocaleID());
+        return obj;
+    }
+    /**
+     * Returns the keys in this bundle as an enumeration
+     * @return an enumeration containing key strings
+     * @stable ICU 3.8
+     */
+    public Enumeration getKeys() {
+        initKeysVector();
+        return keys.elements();
+    }
+
+    private Vector keys = null;
+    private synchronized void initKeysVector(){
+        if(keys!=null){
+            return;
+        }
+        //ICUResourceBundle current = this;
+        keys = new Vector();
+        Enumeration e = this.handleGetKeys();
+        while(e.hasMoreElements()){
+            String elem = (String)e.nextElement();
+            if(!keys.contains(elem)){
+                keys.add(elem);
+            }
+        }
+    }
+
+    /**
+     * Returns the size of a resource. Size for scalar types is always 1,
+     * and for vector/table types is the number of child resources.
+     * <br><b><font color='red'>Warning: </font></b> Integer array is treated as a scalar type. There are no
+     *          APIs to access individual members of an integer array. It
+     *          is always returned as a whole.
+     * @return number of resources in a given resource.
+     * @stable ICU 3.8
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Returns the type of a resource.
+     * Available types are {@link #INT INT}, {@link #ARRAY ARRAY},
+     * {@link #BINARY BINARY}, {@link #INT_VECTOR INT_VECTOR},
+     * {@link #STRING STRING}, {@link #TABLE TABLE}.
+     *
+     * @return type of the given resource.
+     * @stable ICU 3.8
+     */
+    public int getType() {
+        int type = ICUResourceBundle.RES_GET_TYPE(resource);
+        if(type==TABLE32){
+            return TABLE; //Mask the table32's real type
+        }
+        return type;
+    }
+
+    /**
+     * Return the version number associated with this UResourceBundle as an
+     * VersionInfo object.
+     * @return VersionInfo object containing the version of the bundle
+     * @stable ICU 3.8
+     */
+    public VersionInfo getVersion() {
+        return null;
+    }
+
+    /**
+     * Returns the iterator which iterates over this
+     * resource bundle
+     * @return UResourceBundleIterator that iterates over the resources in the bundle
+     * @stable ICU 3.8
+     */
+    public UResourceBundleIterator getIterator() {
+        return new UResourceBundleIterator(this);
+    }
+    /**
+     * Returns the key associated with a given resource. Not all the resources have a key - only
+     * those that are members of a table.
+     * @return a key associated to this resource, or null if it doesn't have a key
+     * @stable ICU 3.8
+     */
+    public String getKey() {
+        return key;
+    }
+    /**
+     * Resource type constant for "no resource".
+     * @stable ICU 3.8
+     */
+    public static final int NONE = -1;
+
+    /**
+     * Resource type constant for strings.
+     * @stable ICU 3.8
+     */
+    public static final int STRING = 0;
+
+    /**
+     * Resource type constant for binary data.
+     * @stable ICU 3.8
+     */
+    public static final int BINARY = 1;
+
+    /**
+     * Resource type constant for tables of key-value pairs.
+     * @stable ICU 3.8
+     */
+    public static final int TABLE = 2;
+
+    /**
+     * Resource type constant for aliases;
+     * internally stores a string which identifies the actual resource
+     * storing the data (can be in a different resource bundle).
+     * Resolved internally before delivering the actual resource through the API.
+     * @internal ICU 3.8
+     * @deprecated This API is ICU internal only.
+     */
+    protected static final int ALIAS = 3;
+
+    /**
+     * Internal use only.
+     * Alternative resource type constant for tables of key-value pairs.
+     * Never returned by getType().
+     * @internal ICU 3.8
+     * @deprecated This API is ICU internal only.
+     */
+    protected static final int TABLE32 = 4;
+
+    /**
+     * Resource type constant for a single 28-bit integer, interpreted as
+     * signed or unsigned by the getInt() function.
+     * @see #getInt
+     * @stable ICU 3.8
+     */
+    public static final int INT = 7;
+
+    /**
+     * Resource type constant for arrays of resources.
+     * @stable ICU 3.8
+     */
+    public static final int ARRAY = 8;
+
+    /**
+     * Resource type constant for vectors of 32-bit integers.
+     * @see #getIntVector
+     * @stable ICU 3.8
+     */
+    public static final int INT_VECTOR = 14;
+
+    //====== protected members ==============
+    /**
+     * Data member where the subclasses store the key
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    protected String key;
+    /**
+     * Data member where the subclasses store the size of resources
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    protected int size = 1;
+    /**
+     * Data member where the subclasses store the offset within resource data
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    protected long resource = RES_BOGUS;
+    /**
+     * Data member where the subclasses store whether the resource is top level
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    protected boolean isTopLevel = false;
+
+    private static final long RES_BOGUS = 0xffffffff;
+
+    /**
+     * Actual worker method for fetching a resource based on the given key.
+     * Sub classes must override this method if they support resources with keys.
+     * @param aKey the key string of the resource to be fetched
+     * @param table hashtable object to hold references of resources already seen
+     * @param requested the original resource bundle object on which the get method was invoked.
+     *                  The requested bundle and the bundle on which this method is invoked
+     *                  are the same, except in the cases where aliases are involved.
+     * @return UResourceBundle a resource associated with the key
+     * @stable ICU 3.8
+     */
+    protected UResourceBundle handleGet(String aKey, HashMap table, UResourceBundle requested) {
+        return null;
+    }
+
+    /**
+     * Actual worker method for fetching a resource based on the given index.
+     * Sub classes must override this method if they support arrays of resources.
+     * @param index the index of the resource to be fetched
+     * @param table hashtable object to hold references of resources already seen
+     * @param requested the original resource bundle object on which the get method was invoked.
+     *                  The requested bundle and the bundle on which this method is invoked
+     *                  are the same, except in the cases where aliases are involved.
+     * @return UResourceBundle a resource associated with the index
+     * @stable ICU 3.8
+     */
+    protected UResourceBundle handleGet(int index, HashMap table, UResourceBundle requested) {
+        return null;
+    }
+
+    /**
+     * Actual worker method for fetching the array of strings in a resource.
+     * Sub classes must override this method if they support arrays of strings.
+     * @return String[] An array of strings containing strings
+     * @stable ICU 3.8
+     */
+    protected String[] handleGetStringArray() {
+        return null;
+    }
+
+    /**
+     * Actual worker method for fetching the keys of resources contained in the resource.
+     * Sub classes must override this method if they support keys and associated resources.
+     *
+     * @return Enumeration An enumeration of all the keys in this resource.
+     * @stable ICU 3.8
+     */
+    protected Enumeration handleGetKeys(){
+        Vector resKeys = new Vector();
+        UResourceBundle item = null;
+        for (int i = 0; i < size; i++) {
+            item = get(i);
+            resKeys.add(item.getKey());
+        }
+        return resKeys.elements();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @stable ICU 3.8
+     */
+    // this method is declared in ResourceBundle class
+    // so cannot change the signature
+    // Override this method
+    protected Object handleGetObject(String aKey) {
+        return handleGetObjectImpl(aKey, this);
+    }
+
+    /**
+     * Override the superclass method
+     */
+    // To facilitate XPath style aliases we need a way to pass the reference
+    // to requested locale. The only way I could figure out is to implement
+    // the look up logic here. This has a disadvantage that if the client
+    // loads an ICUResourceBundle, calls ResourceBundle.getObject method
+    // with a key that does not exist in the bundle then the lookup is
+    // done twice before throwing a MissingResourceExpection.
+    private Object handleGetObjectImpl(String aKey, UResourceBundle requested) {
+        Object obj = resolveObject(aKey, requested);
+        if (obj == null) {
+            UResourceBundle parentBundle = getParent();
+            if (parentBundle != null) {
+                obj = parentBundle.handleGetObjectImpl(aKey, requested);
+            }
+            if (obj == null)
+                throw new MissingResourceException(
+                    "Can't find resource for bundle "
+                    + this.getClass().getName() + ", key " + aKey,
+                    this.getClass().getName(), aKey);
+        }
+        return obj;
+    }
+
+    // Routine for figuring out the type of object to be returned
+    // string or string array
+    private Object resolveObject(String aKey, UResourceBundle requested) {
+        if (getType() == STRING) {
+            return getString();
+        }
+        UResourceBundle obj = handleGet(aKey, null, requested);
+        if (obj != null) {
+            if (obj.getType() == STRING) {
+                return obj.getString();
+            }
+            try {
+                if (obj.getType() == ARRAY) {
+                    return obj.handleGetStringArray();
+                }
+            } catch (UResourceTypeMismatchException ex) {
+                return obj;
+            }
+        }
+        return obj;
+    }
+
+    /**
+     * This method is for setting the loading status of the resource.
+     * The status is analogous to the warning status in ICU4C.
+     * @internal ICU 3.8
+     * @deprecated This API is ICU internal only.
+     */
+    protected abstract void setLoadingStatus(int newStatus);
+}