]> granicus.if.org Git - icu/commitdiff
ICU-7434 switch UResourceBundle.BUNDLE_CACHE from SimpleCache to SoftCache, move...
authorMarkus Scherer <markus.icu@gmail.com>
Wed, 18 May 2016 20:29:26 +0000 (20:29 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 18 May 2016 20:29:26 +0000 (20:29 +0000)
X-SVN-Rev: 38751

icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java
icu4j/main/classes/core/src/com/ibm/icu/impl/ResourceBundleWrapper.java
icu4j/main/classes/core/src/com/ibm/icu/util/UResourceBundle.java

index 635e9841641a359b9729153d53d05d4bca07b672..410ed0bc15740eadfcbc843aee69d0bd23ee2ce2 100644 (file)
@@ -78,6 +78,19 @@ public  class ICUResourceBundle extends UResourceBundle {
     WholeBundle wholeBundle;
     private ICUResourceBundle container;
 
+    /** Loader for bundle instances, for caching. */
+    private static abstract class Loader {
+        abstract ICUResourceBundle load();
+    }
+
+    private static CacheBase<String, ICUResourceBundle, Loader> BUNDLE_CACHE =
+            new SoftCache<String, ICUResourceBundle, Loader>() {
+        @Override
+        protected ICUResourceBundle createInstance(String unusedKey, Loader loader) {
+            return loader.load();
+        }
+    };
+
     /**
      * Returns a functionally equivalent locale, considering keywords as well, for the specified keyword.
      * @param baseName resource specifier
@@ -139,7 +152,7 @@ public  class ICUResourceBundle extends UResourceBundle {
                 // Ignore error and continue search.
             }
             if (defLoc == null) {
-                r = (ICUResourceBundle) r.getParent();
+                r = r.getParent();
                 defDepth++;
             }
         } while ((r != null) && (defLoc == null));
@@ -165,7 +178,7 @@ public  class ICUResourceBundle extends UResourceBundle {
                 // Ignore error,
             }
             if (fullBase == null) {
-                r = (ICUResourceBundle) r.getParent();
+                r = r.getParent();
                 resDepth++;
             }
         } while ((r != null) && (fullBase == null));
@@ -182,14 +195,14 @@ public  class ICUResourceBundle extends UResourceBundle {
             do {
                 try {
                     ICUResourceBundle irb = (ICUResourceBundle)r.get(resName);
-                    UResourceBundle urb = irb.get(kwVal);
+                    ICUResourceBundle urb = (ICUResourceBundle)irb.get(kwVal);
 
                     // if we didn't fail before this..
                     fullBase = r.getULocale();
 
                     // If the fetched item (urb) is in a different locale than our outer locale (r/fullBase)
                     // then we are in a 'fallback' situation. treat as a missing resource situation.
-                    if(!fullBase.toString().equals(urb.getLocale().toString())) {
+                    if(!fullBase.getBaseName().equals(urb.getULocale().getBaseName())) {
                         fullBase = null; // fallback condition. Loop and try again.
                     }
 
@@ -204,7 +217,7 @@ public  class ICUResourceBundle extends UResourceBundle {
                     // Ignore error, continue search.
                 }
                 if (fullBase == null) {
-                    r = (ICUResourceBundle) r.getParent();
+                    r = r.getParent();
                     resDepth++;
                 }
             } while ((r != null) && (fullBase == null));
@@ -221,7 +234,7 @@ public  class ICUResourceBundle extends UResourceBundle {
             && resDepth <= defDepth) { // default was set in same locale or child
             return fullBase; // Keyword value is default - no keyword needed in locale
         } else {
-            return new ULocale(fullBase.toString() + "@" + keyword + "=" + kwVal);
+            return new ULocale(fullBase.getBaseName() + "@" + keyword + "=" + kwVal);
         }
     }
 
@@ -848,7 +861,7 @@ public  class ICUResourceBundle extends UResourceBundle {
                 base = sub;
             }
             // Try the parent bundle of the last-found resource.
-            ICUResourceBundle nextBase = (ICUResourceBundle)base.getParent();
+            ICUResourceBundle nextBase = base.getParent();
             if (nextBase == null) {
                 return null;
             }
@@ -961,7 +974,7 @@ public  class ICUResourceBundle extends UResourceBundle {
                 }
             }
             // Try the parent bundle of the last-found resource.
-            ICUResourceBundle nextBase = (ICUResourceBundle)base.getParent();
+            ICUResourceBundle nextBase = base.getParent();
             if (nextBase == null) {
                 return null;
             }
@@ -1100,37 +1113,34 @@ public  class ICUResourceBundle extends UResourceBundle {
     };
 
     // This method is for super class's instantiateBundle method
-    public static UResourceBundle getBundleInstance(String baseName, String localeID,
-                                                    ClassLoader root, boolean disableFallback){
-        UResourceBundle b = instantiateBundle(baseName, localeID, root,
-                disableFallback ? OpenType.DIRECT : OpenType.LOCALE_DEFAULT_ROOT);
-        if(b==null){
-            throw new MissingResourceException("Could not find the bundle "+ baseName+"/"+ localeID+".res","","");
-        }
-        return b;
-    }
-
-    protected static UResourceBundle instantiateBundle(String baseName, String localeID,
-            ClassLoader root, boolean disableFallback){
-        return instantiateBundle(baseName, localeID, root,
+    public static ICUResourceBundle getBundleInstance(String baseName, String localeID,
+            ClassLoader root, boolean disableFallback) {
+        return getBundleInstance(baseName, localeID, root,
                 disableFallback ? OpenType.DIRECT : OpenType.LOCALE_DEFAULT_ROOT);
     }
 
-    public static UResourceBundle getBundleInstance(
+    public static ICUResourceBundle getBundleInstance(
             String baseName, ULocale locale, OpenType openType) {
         if (locale == null) {
             locale = ULocale.getDefault();
         }
-        return getBundleInstance(baseName, locale.toString(),
+        return getBundleInstance(baseName, locale.getBaseName(),
                 ICUResourceBundle.ICU_DATA_CLASS_LOADER, openType);
     }
 
-    public static UResourceBundle getBundleInstance(String baseName, String localeID,
+    public static ICUResourceBundle getBundleInstance(String baseName, String localeID,
             ClassLoader root, OpenType openType) {
         if (baseName == null) {
             baseName = ICUData.ICU_BASE_NAME;
         }
-        UResourceBundle b = instantiateBundle(baseName, localeID, root, openType);
+        localeID = ULocale.getBaseName(localeID);
+        ICUResourceBundle b;
+        if (openType == OpenType.LOCALE_DEFAULT_ROOT) {
+            b = instantiateBundle(baseName, localeID, ULocale.getDefault().getBaseName(),
+                    root, openType);
+        } else {
+            b = instantiateBundle(baseName, localeID, null, root, openType);
+        }
         if(b==null){
             throw new MissingResourceException(
                     "Could not find the bundle "+ baseName+"/"+ localeID+".res","","");
@@ -1138,33 +1148,35 @@ public  class ICUResourceBundle extends UResourceBundle {
         return b;
     }
 
-    //  recursively build bundle
-    private synchronized static UResourceBundle instantiateBundle(String baseName, String localeID,
-            ClassLoader root, OpenType openType) {
-        ULocale defaultLocale = ULocale.getDefault();
-        String localeName = localeID;
-        if(localeName.indexOf('@')>=0){
-            localeName = ULocale.getBaseName(localeID);
-        }
-        String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
-        ICUResourceBundle b = (ICUResourceBundle)loadFromCache(fullName, defaultLocale);
-
-        // here we assume that java type resource bundle organization
-        // is required then the base name contains '.' else
-        // the resource organization is of ICU type
-        // so clients can instantiate resources of the type
-        // com.mycompany.data.MyLocaleElements_en.res and
-        // com.mycompany.data.MyLocaleElements.res
-        //
-        final String rootLocale = (baseName.indexOf('.')==-1) ? "root" : "";
-        final String defaultID = defaultLocale.getBaseName();
-
-        if(localeName.equals("")){
-            localeName = rootLocale;
-        }
-        if(DEBUG) System.out.println("Creating "+fullName+ " currently b is "+b);
-        if (b == null) {
-            b = ICUResourceBundle.createBundle(baseName, localeName, root);
+    private static boolean localeIDStartsWithLangSubtag(String localeID, String lang) {
+        return localeID.startsWith(lang) &&
+                (localeID.length() == lang.length() || localeID.charAt(lang.length()) == '_');
+    }
+
+    private static ICUResourceBundle instantiateBundle(
+            final String baseName, final String localeID, final String defaultID,
+            final ClassLoader root, final OpenType openType) {
+        assert localeID.indexOf('@') < 0;
+        assert defaultID == null || defaultID.indexOf('@') < 0;
+        final String fullName = ICUResourceBundleReader.getFullName(baseName, localeID);
+        char openTypeChar = (char)('0' + openType.ordinal());
+        String cacheKey = openType != OpenType.LOCALE_DEFAULT_ROOT ?
+                fullName + '#' + openTypeChar :
+                    fullName + '#' + openTypeChar + '#' + defaultID;
+        return BUNDLE_CACHE.getInstance(cacheKey, new Loader() {
+                @Override
+                public ICUResourceBundle load() {
+            if(DEBUG) System.out.println("Creating "+fullName);
+            // here we assume that java type resource bundle organization
+            // is required then the base name contains '.' else
+            // the resource organization is of ICU type
+            // so clients can instantiate resources of the type
+            // com.mycompany.data.MyLocaleElements_en.res and
+            // com.mycompany.data.MyLocaleElements.res
+            //
+            final String rootLocale = (baseName.indexOf('.')==-1) ? "root" : "";
+            String localeName = localeID.isEmpty() ? rootLocale : localeID;
+            ICUResourceBundle b = ICUResourceBundle.createBundle(baseName, localeName, root);
 
             if(DEBUG)System.out.println("The bundle created is: "+b+" and openType="+openType+" and bundle.getNoFallback="+(b!=null && b.getNoFallback()));
             if (openType == OpenType.DIRECT || (b != null && b.getNoFallback())) {
@@ -1179,7 +1191,7 @@ public  class ICUResourceBundle extends UResourceBundle {
                 // for a bundle that does not have nofallback.
                 // Are the relevant test cases just disabled?
                 // Do item aliases not get followed via "direct" loading?
-                return addToCache(fullName, defaultLocale, b);
+                return b;
             }
 
             // fallback to locale ID parent
@@ -1188,13 +1200,13 @@ public  class ICUResourceBundle extends UResourceBundle {
                 if (i != -1) {
                     // Chop off the last underscore and the subtag after that.
                     String temp = localeName.substring(0, i);
-                    b = (ICUResourceBundle)instantiateBundle(baseName, temp, root, openType);
+                    b = instantiateBundle(baseName, temp, defaultID, root, openType);
                 }else{
                     // No underscore, only a base language subtag.
                     if(openType == OpenType.LOCALE_DEFAULT_ROOT &&
-                            !defaultLocale.getLanguage().equals(localeName)) {
+                            !localeIDStartsWithLangSubtag(defaultID, localeName)) {
                         // Go to the default locale before root.
-                        b = (ICUResourceBundle)instantiateBundle(baseName, defaultID, root, openType);
+                        b = instantiateBundle(baseName, defaultID, defaultID, root, openType);
                     } else if(openType != OpenType.LOCALE_ONLY && !rootLocale.isEmpty()) {
                         // Ultimately go to root.
                         b = ICUResourceBundle.createBundle(baseName, rootLocale, root);
@@ -1205,32 +1217,31 @@ public  class ICUResourceBundle extends UResourceBundle {
                 localeName = b.getLocaleID();
                 int i = localeName.lastIndexOf('_');
 
-                b = (ICUResourceBundle)addToCache(fullName, defaultLocale, b);
-
                 // TODO: C++ uresbund.cpp also checks for %%ParentIsRoot. Why not Java?
                 String parentLocaleName = ((ICUResourceBundleImpl.ResourceTable)b).findString("%%Parent");
                 if (parentLocaleName != null) {
-                    parent = instantiateBundle(baseName, parentLocaleName, root, openType);
+                    parent = instantiateBundle(baseName, parentLocaleName, defaultID, root, openType);
                 } else if (i != -1) {
-                    parent = instantiateBundle(baseName, localeName.substring(0, i), root, openType);
+                    parent = instantiateBundle(baseName, localeName.substring(0, i), defaultID, root, openType);
                 } else if (!localeName.equals(rootLocale)){
-                    parent = instantiateBundle(baseName, rootLocale, root, true);
+                    parent = instantiateBundle(baseName, rootLocale, defaultID, root, openType);
                 }
 
                 if (!b.equals(parent)){
                     b.setParent(parent);
                 }
             }
-        }
-        return b;
+            return b;
+        }});
     }
-    UResourceBundle get(String aKey, HashMap<String, String> aliasesVisited, UResourceBundle requested) {
+
+    ICUResourceBundle get(String aKey, HashMap<String, String> aliasesVisited, UResourceBundle requested) {
         ICUResourceBundle obj = (ICUResourceBundle)handleGet(aKey, aliasesVisited, requested);
         if (obj == null) {
-            obj = (ICUResourceBundle)getParent();
+            obj = getParent();
             if (obj != null) {
                 //call the get method to recursively fetch the resource
-                obj = (ICUResourceBundle)obj.get(aKey, aliasesVisited, requested);
+                obj = obj.get(aKey, aliasesVisited, requested);
             }
             if (obj == null) {
                 String fullName = ICUResourceBundleReader.getFullName(getBaseName(), getLocaleID());
@@ -1319,8 +1330,8 @@ public  class ICUResourceBundle extends UResourceBundle {
         return wholeBundle.localeID.isEmpty() || wholeBundle.localeID.equals("root");
     }
 
-    public UResourceBundle getParent() {
-        return (UResourceBundle) parent;
+    public ICUResourceBundle getParent() {
+        return (ICUResourceBundle) parent;
     }
 
     protected void setParent(ResourceBundle parent) {
@@ -1462,11 +1473,9 @@ public  class ICUResourceBundle extends UResourceBundle {
         }else{
             if (locale == null) {
                 // {dlf} must use requestor's class loader to get resources from same jar
-                bundle = (ICUResourceBundle) getBundleInstance(bundleName, "",
-                         loaderToUse, false);
+                bundle = getBundleInstance(bundleName, "", loaderToUse, false);
             } else {
-                bundle = (ICUResourceBundle) getBundleInstance(bundleName, locale,
-                         loaderToUse, false);
+                bundle = getBundleInstance(bundleName, locale, loaderToUse, false);
             }
 
             int numKeys;
@@ -1488,7 +1497,7 @@ public  class ICUResourceBundle extends UResourceBundle {
             if (numKeys > 0) {
                 sub = bundle;
                 for (int i = 0; sub != null && i < numKeys; ++i) {
-                    sub = (ICUResourceBundle)sub.get(keys[i], aliasesVisited, requested);
+                    sub = sub.get(keys[i], aliasesVisited, requested);
                 }
             }
         }
index 3c4419ad100a4b9925e935037972cfc22d7d4ece..2cc8493c9a50b052f260b87097e2dfb259262de2 100644 (file)
@@ -24,12 +24,25 @@ import com.ibm.icu.util.UResourceBundle;
  * @author ram
  *
  */
-public class ResourceBundleWrapper extends UResourceBundle {
+public final class ResourceBundleWrapper extends UResourceBundle {
     private ResourceBundle bundle = null;
     private String localeID = null;
     private String baseName = null;
     private List<String> keys = null;
 
+    /** Loader for bundle instances, for caching. */
+    private static abstract class Loader {
+        abstract ResourceBundleWrapper load();
+    }
+
+    private static CacheBase<String, ResourceBundleWrapper, Loader> BUNDLE_CACHE =
+            new SoftCache<String, ResourceBundleWrapper, Loader>() {
+        @Override
+        protected ResourceBundleWrapper createInstance(String unusedKey, Loader loader) {
+            return loader.load();
+        }
+    };
+
     private ResourceBundleWrapper(ResourceBundle bundle){
         this.bundle=bundle;
     }
@@ -93,9 +106,18 @@ public class ResourceBundleWrapper extends UResourceBundle {
     private static final boolean DEBUG = ICUDebug.enabled("resourceBundleWrapper");
     
     // This method is for super class's instantiateBundle method
-    public static UResourceBundle getBundleInstance(String baseName, String localeID, 
-                                                    ClassLoader root, boolean disableFallback){
-        UResourceBundle b = instantiateBundle(baseName, localeID, root, disableFallback);
+    public static ResourceBundleWrapper getBundleInstance(String baseName, String localeID,
+            ClassLoader root, boolean disableFallback) {
+        if (root == null) {
+            root = ClassLoaderUtil.getClassLoader();
+        }
+        ResourceBundleWrapper b;
+        if (disableFallback) {
+            b = instantiateBundle(baseName, localeID, null, root, disableFallback);
+        } else {
+            b = instantiateBundle(baseName, localeID, ULocale.getDefault().getBaseName(),
+                    root, disableFallback);
+        }
         if(b==null){
             String separator ="_";
             if(baseName.indexOf('/')>=0){
@@ -105,47 +127,43 @@ public class ResourceBundleWrapper extends UResourceBundle {
         }
         return b;
     }
-    // recursively build bundle and override the super-class method
-     protected static synchronized UResourceBundle instantiateBundle(String baseName, String localeID,
-                                                                    ClassLoader root, boolean disableFallback) {
-        if (root == null) {
-            root = ClassLoaderUtil.getClassLoader();
-        }
-        final ClassLoader cl = root;
-        String name = baseName;
-        ULocale defaultLocale = ULocale.getDefault();
-        if (localeID.length() != 0) {
-            name = name + "_" + localeID;
-        }
 
-        ResourceBundleWrapper b = (ResourceBundleWrapper)loadFromCache(name, defaultLocale);
-        if(b==null){
+    private static boolean localeIDStartsWithLangSubtag(String localeID, String lang) {
+        return localeID.startsWith(lang) &&
+                (localeID.length() == lang.length() || localeID.charAt(lang.length()) == '_');
+    }
+
+    private static ResourceBundleWrapper instantiateBundle(
+             final String baseName, final String localeID, final String defaultID,
+             final ClassLoader root, final boolean disableFallback) {
+        final String name = localeID.isEmpty() ? baseName : baseName + '_' + localeID;
+        String cacheKey = disableFallback ? name : name + '#' + defaultID;
+        return BUNDLE_CACHE.getInstance(cacheKey, new Loader() {
+                @Override
+                public ResourceBundleWrapper load() {
             ResourceBundleWrapper parent = null;
             int i = localeID.lastIndexOf('_');
-    
+
             boolean loadFromProperties = false;
+            boolean parentIsRoot = false;
             if (i != -1) {
                 String locName = localeID.substring(0, i);
-                parent = (ResourceBundleWrapper)loadFromCache(baseName+"_"+locName,defaultLocale);
-                if(parent == null){
-                    parent = (ResourceBundleWrapper)instantiateBundle(baseName, locName , cl, disableFallback);
-                }
-            }else if(localeID.length()>0){
-                parent = (ResourceBundleWrapper)loadFromCache(baseName,defaultLocale);
-                if(parent==null){
-                    parent = (ResourceBundleWrapper)instantiateBundle(baseName, "", cl, disableFallback);
-                }
+                parent = instantiateBundle(baseName, locName, defaultID, root, disableFallback);
+            }else if(!localeID.isEmpty()){
+                parent = instantiateBundle(baseName, "", defaultID, root, disableFallback);
+                parentIsRoot = true;
             }
+            ResourceBundleWrapper b = null;
             try {
-                Class<? extends ResourceBundle> cls = cl.loadClass(name).asSubclass(ResourceBundle.class);
+                Class<? extends ResourceBundle> cls =
+                        root.loadClass(name).asSubclass(ResourceBundle.class);
                 ResourceBundle bx = cls.newInstance();
                 b = new ResourceBundleWrapper(bx);
                 if (parent != null) {
                     b.setParent(parent);
                 }
                 b.baseName=baseName;
-                b.localeID = localeID;            
-    
+                b.localeID = localeID;
             } catch (ClassNotFoundException e) {
                 loadFromProperties = true;
             } catch (NoClassDefFoundError e) {
@@ -163,11 +181,7 @@ public class ResourceBundleWrapper extends UResourceBundle {
                     InputStream stream = java.security.AccessController.doPrivileged(
                         new java.security.PrivilegedAction<InputStream>() {
                             public InputStream run() {
-                                if (cl != null) {
-                                    return cl.getResourceAsStream(resName);
-                                } else {
-                                    return ClassLoader.getSystemResourceAsStream(resName);
-                                }
+                                return root.getResourceAsStream(resName);
                             }
                         }
                     );
@@ -191,22 +205,19 @@ public class ResourceBundleWrapper extends UResourceBundle {
                             }
                         }
                     }
-        
+
                     // if a bogus locale is passed then the parent should be
                     // the default locale not the root locale!
-                    if (b==null) {
-                        String defaultName = defaultLocale.toString();
-                        if (localeID.length()>0 && localeID.indexOf('_')< 0 && defaultName.indexOf(localeID) == -1) {
-                            b = (ResourceBundleWrapper)loadFromCache(baseName+"_"+defaultName, defaultLocale);
-                            if(b==null){
-                                b = (ResourceBundleWrapper)instantiateBundle(baseName , defaultName, cl, disableFallback);
-                            }
-                        }
+                    if (b == null && !disableFallback &&
+                            !localeID.isEmpty() && localeID.indexOf('_') < 0 &&
+                            !localeIDStartsWithLangSubtag(defaultID, localeID)) {
+                        // localeID is only a language subtag, different from the default language.
+                        b = instantiateBundle(baseName, defaultID, defaultID, root, disableFallback);
                     }
                     // if still could not find the bundle then return the parent
-                    if(b==null){
+                    if(b==null && (!parentIsRoot || !disableFallback)){
                         b=parent;
-                    }                
+                    }
                 } catch (Exception e) {
                     if (DEBUG)
                         System.out.println("failure");
@@ -214,15 +225,12 @@ public class ResourceBundleWrapper extends UResourceBundle {
                         System.out.println(e);
                 }
             }
-            b = (ResourceBundleWrapper)addToCache(name, defaultLocale, b);
-        }
-
-        if(b!=null){
-            b.initKeysVector();
-        }else{
-            if(DEBUG)System.out.println("Returning null for "+baseName+"_"+localeID);
-        }
-        
-        return b;
+            if(b!=null){
+                b.initKeysVector();
+            }else{
+                if(DEBUG)System.out.println("Returning null for "+baseName+"_"+localeID);
+            }
+            return b;
+        }});
     }
 }
index 7456590ec53d583bca4b653ae595927573c5f071..55ce1f5456cab1a3a9ec2a2ca9ca4601fb2fd57b 100644 (file)
@@ -19,12 +19,10 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 
-import com.ibm.icu.impl.ICUCache;
 import com.ibm.icu.impl.ICUData;
 import com.ibm.icu.impl.ICUResourceBundle;
 import com.ibm.icu.impl.ICUResourceBundleReader;
 import com.ibm.icu.impl.ResourceBundleWrapper;
-import com.ibm.icu.impl.SimpleCache;
 
 /**
  * {@icuenhanced java.util.ResourceBundle}.{@icu _usage_}
@@ -98,7 +96,8 @@ public abstract class UResourceBundle extends ResourceBundle {
     /**
      * {@icu} 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 baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
      * @param localeName the locale for which a resource bundle is desired
      * @throws MissingResourceException If no resource bundle for the specified base name
      * can be found
@@ -113,7 +112,8 @@ public abstract class UResourceBundle extends ResourceBundle {
     /**
      * {@icu} 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 baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
      * @param localeName the locale for which a resource bundle is desired
      * @param root the class object from which to load the resource bundle
      * @throws MissingResourceException If no resource bundle for the specified base name
@@ -130,7 +130,8 @@ public abstract class UResourceBundle extends ResourceBundle {
      * {@icu} 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 baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
      * @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.
@@ -167,15 +168,15 @@ public abstract class UResourceBundle extends ResourceBundle {
         if (locale==null) {
             locale = ULocale.getDefault();
         }
-        return getBundleInstance(ICUData.ICU_BASE_NAME, locale.toString(), 
+        return getBundleInstance(ICUData.ICU_BASE_NAME, locale.getBaseName(),
                                  ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
     }
 
     /**
      * {@icu} 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.
+     * @param baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
      * @return a resource bundle for the given base name and default locale
      * @stable ICU 3.0
      */
@@ -184,15 +185,15 @@ public abstract class UResourceBundle extends ResourceBundle {
             baseName = ICUData.ICU_BASE_NAME;
         }
         ULocale uloc = ULocale.getDefault();
-        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, 
+        return getBundleInstance(baseName, uloc.getBaseName(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, 
                                  false);
     }
 
     /**
      * {@icu} 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 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
@@ -205,8 +206,8 @@ public abstract class UResourceBundle extends ResourceBundle {
         }
         ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);
 
-        return getBundleInstance(baseName, uloc.toString(), ICUResourceBundle.ICU_DATA_CLASS_LOADER, 
-                                 false);
+        return getBundleInstance(baseName, uloc.getBaseName(),
+                                 ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
     }
 
     /**
@@ -226,15 +227,15 @@ public abstract class UResourceBundle extends ResourceBundle {
         if (locale == null) {
             locale = ULocale.getDefault();
         }
-        return getBundleInstance(baseName, locale.toString(), 
+        return getBundleInstance(baseName, locale.getBaseName(),
                                  ICUResourceBundle.ICU_DATA_CLASS_LOADER, false);
     }
 
     /**
      * {@icu} 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 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
@@ -247,7 +248,7 @@ public abstract class UResourceBundle extends ResourceBundle {
             baseName = ICUData.ICU_BASE_NAME;
         }
         ULocale uloc = locale == null ? ULocale.getDefault() : ULocale.forLocale(locale);
-        return getBundleInstance(baseName, uloc.toString(), loader, false);
+        return getBundleInstance(baseName, uloc.getBaseName(), loader, false);
     }
 
     /**
@@ -272,7 +273,7 @@ public abstract class UResourceBundle extends ResourceBundle {
         if (locale == null) {
             locale = ULocale.getDefault();
         }
-        return getBundleInstance(baseName, locale.toString(), loader, false);
+        return getBundleInstance(baseName, locale.getBaseName(), loader, false);
     }
 
     /**
@@ -317,122 +318,6 @@ public abstract class UResourceBundle extends ResourceBundle {
         return getULocale().toLocale();
     }
 
-    // Cache for ResourceBundle instantiation
-    private static ICUCache<ResourceCacheKey, UResourceBundle> BUNDLE_CACHE =
-        new SimpleCache<ResourceCacheKey, UResourceBundle>();
-
-    /**
-     * Method used by subclasses to add a resource bundle object to the managed
-     * cache.  Works like a putIfAbsent(): If the cache already contains a matching
-     * bundle, that one will be retained and returned.
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    protected static UResourceBundle addToCache(String fullName, ULocale defaultLocale, UResourceBundle b) {
-        synchronized(cacheKey){
-            cacheKey.setKeyValues(fullName, defaultLocale);
-            UResourceBundle cachedBundle = BUNDLE_CACHE.get(cacheKey);
-            if (cachedBundle != null) {
-                return cachedBundle;
-            }
-            BUNDLE_CACHE.put((ResourceCacheKey)cacheKey.clone(), b);
-            return b;
-        }
-    }
-
-    /**
-     * Method used by sub classes to load a resource bundle object from the managed cache
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    protected static UResourceBundle loadFromCache(String fullName, ULocale defaultLocale) {
-        synchronized(cacheKey){
-            cacheKey.setKeyValues(fullName, defaultLocale);
-            return BUNDLE_CACHE.get(cacheKey);
-        }
-    }
-
-    /**
-     * Key used for cached resource bundles.  The key checks
-     * the resource name and the default
-     * locale to determine if the resource is a match to the
-     * requested one. The default locale may be null, but the
-     * searchName 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 String searchName;
-        private ULocale defaultLocale;
-        private int hashCodeCache;
-        ///CLOVER:OFF
-        public boolean equals(Object other) {
-            if (other == null) {
-                return false;
-            }
-            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;
-                    }
-                }
-                return true;
-            } 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 ICUCloneNotSupportedException(e);
-            }
-        }
-
-        ///CLOVER:ON
-        private synchronized void setKeyValues(String searchName, ULocale defaultLocale) {
-            this.searchName = searchName;
-            hashCodeCache = searchName.hashCode();
-            this.defaultLocale = defaultLocale;
-            if (defaultLocale != null) {
-                hashCodeCache ^= defaultLocale.hashCode();
-            }
-        }
-        /*private void clear() {
-            setKeyValues(null, "", null);
-        }*/
-    }
-
-    private static final ResourceCacheKey cacheKey = new ResourceCacheKey();
-
     private enum RootType { MISSING, ICU, JAVA }
 
     private static Map<String, RootType> ROOT_CACHE = new ConcurrentHashMap<String, RootType>();
@@ -468,7 +353,8 @@ public abstract class UResourceBundle extends ResourceBundle {
     /**
      * {@icu} Loads a new resource bundle for the given 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 baseName string containing the name of the data package.
+     *                    If null the default ICU package name is used.
      * @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
@@ -479,26 +365,11 @@ public abstract class UResourceBundle extends ResourceBundle {
      */
     protected static UResourceBundle instantiateBundle(String baseName, String localeName,
                                                        ClassLoader root, boolean disableFallback) {
-        UResourceBundle b = null;
         RootType rootType = getRootType(baseName, root);
 
-        ULocale defaultLocale = ULocale.getDefault();
-
         switch (rootType) {
         case ICU:
-            if(disableFallback) {
-                String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
-                b = loadFromCache(fullName, defaultLocale);
-                if (b == null) {
-                    b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, 
-                                                            disableFallback);
-                }
-            } else {
-                b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, 
-                                                        disableFallback);
-            }
-
-            return b;
+            return ICUResourceBundle.getBundleInstance(baseName, localeName, root, disableFallback);
 
         case JAVA:
             return ResourceBundleWrapper.getBundleInstance(baseName, localeName, root, 
@@ -506,6 +377,7 @@ public abstract class UResourceBundle extends ResourceBundle {
 
         case MISSING:
         default:
+            UResourceBundle b;
             try{
                 b = ICUResourceBundle.getBundleInstance(baseName, localeName, root, 
                                                         disableFallback);