rt/emul/compact/src/main/java/java/util/ResourceBundle.java
changeset 1337 c794024954b5
parent 1334 588d5bf7a560
     1.1 --- a/rt/emul/compact/src/main/java/java/util/ResourceBundle.java	Thu Oct 03 15:40:35 2013 +0200
     1.2 +++ b/rt/emul/compact/src/main/java/java/util/ResourceBundle.java	Thu Oct 03 17:36:44 2013 +0200
     1.3 @@ -45,19 +45,7 @@
     1.4  import java.lang.ref.ReferenceQueue;
     1.5  import java.lang.ref.SoftReference;
     1.6  import java.lang.ref.WeakReference;
     1.7 -import java.net.JarURLConnection;
     1.8  import java.net.URL;
     1.9 -import java.net.URLConnection;
    1.10 -import java.security.AccessController;
    1.11 -import java.security.PrivilegedAction;
    1.12 -import java.security.PrivilegedActionException;
    1.13 -import java.security.PrivilegedExceptionAction;
    1.14 -import java.util.concurrent.ConcurrentHashMap;
    1.15 -import java.util.concurrent.ConcurrentMap;
    1.16 -import java.util.jar.JarEntry;
    1.17 -
    1.18 -import sun.util.locale.BaseLocale;
    1.19 -import sun.util.locale.LocaleObjectCache;
    1.20  
    1.21  
    1.22  /**
    1.23 @@ -288,8 +276,8 @@
    1.24       * This variable would be better named "cache", but we keep the old
    1.25       * name for compatibility with some workarounds for bug 4212439.
    1.26       */
    1.27 -    private static final ConcurrentMap<CacheKey, BundleReference> cacheList
    1.28 -        = new ConcurrentHashMap<>(INITIAL_CACHE_SIZE);
    1.29 +    private static final Map<CacheKey, BundleReference> cacheList
    1.30 +        = new HashMap<>(INITIAL_CACHE_SIZE);
    1.31  
    1.32      /**
    1.33       * Queue for reference objects referring to class loaders or bundles.
    1.34 @@ -410,65 +398,6 @@
    1.35          return locale;
    1.36      }
    1.37  
    1.38 -    /*
    1.39 -     * Automatic determination of the ClassLoader to be used to load
    1.40 -     * resources on behalf of the client.  N.B. The client is getLoader's
    1.41 -     * caller's caller.
    1.42 -     */
    1.43 -    private static ClassLoader getLoader() {
    1.44 -        Class[] stack = getClassContext();
    1.45 -        /* Magic number 2 identifies our caller's caller */
    1.46 -        Class c = stack[2];
    1.47 -        ClassLoader cl = (c == null) ? null : c.getClassLoader();
    1.48 -        if (cl == null) {
    1.49 -            // When the caller's loader is the boot class loader, cl is null
    1.50 -            // here. In that case, ClassLoader.getSystemClassLoader() may
    1.51 -            // return the same class loader that the application is
    1.52 -            // using. We therefore use a wrapper ClassLoader to create a
    1.53 -            // separate scope for bundles loaded on behalf of the Java
    1.54 -            // runtime so that these bundles cannot be returned from the
    1.55 -            // cache to the application (5048280).
    1.56 -            cl = RBClassLoader.INSTANCE;
    1.57 -        }
    1.58 -        return cl;
    1.59 -    }
    1.60 -
    1.61 -    private static native Class[] getClassContext();
    1.62 -
    1.63 -    /**
    1.64 -     * A wrapper of ClassLoader.getSystemClassLoader().
    1.65 -     */
    1.66 -    private static class RBClassLoader extends ClassLoader {
    1.67 -        private static final RBClassLoader INSTANCE = AccessController.doPrivileged(
    1.68 -                    new PrivilegedAction<RBClassLoader>() {
    1.69 -                        public RBClassLoader run() {
    1.70 -                            return new RBClassLoader();
    1.71 -                        }
    1.72 -                    });
    1.73 -        private static final ClassLoader loader = ClassLoader.getSystemClassLoader();
    1.74 -
    1.75 -        private RBClassLoader() {
    1.76 -        }
    1.77 -        public Class<?> loadClass(String name) throws ClassNotFoundException {
    1.78 -            if (loader != null) {
    1.79 -                return loader.loadClass(name);
    1.80 -            }
    1.81 -            return Class.forName(name);
    1.82 -        }
    1.83 -        public URL getResource(String name) {
    1.84 -            if (loader != null) {
    1.85 -                return loader.getResource(name);
    1.86 -            }
    1.87 -            return ClassLoader.getSystemResource(name);
    1.88 -        }
    1.89 -        public InputStream getResourceAsStream(String name) {
    1.90 -            if (loader != null) {
    1.91 -                return loader.getResourceAsStream(name);
    1.92 -            }
    1.93 -            return ClassLoader.getSystemResourceAsStream(name);
    1.94 -        }
    1.95 -    }
    1.96 -
    1.97      /**
    1.98       * Sets the parent bundle of this bundle.
    1.99       * The parent bundle is searched by {@link #getObject getObject}
   1.100 @@ -492,7 +421,6 @@
   1.101          // These three are the actual keys for lookup in Map.
   1.102          private String name;
   1.103          private Locale locale;
   1.104 -        private LoaderReference loaderRef;
   1.105  
   1.106          // bundle format which is necessary for calling
   1.107          // Control.needsReload().
   1.108 @@ -515,14 +443,9 @@
   1.109          // of this instance.
   1.110          private int hashCodeCache;
   1.111  
   1.112 -        CacheKey(String baseName, Locale locale, ClassLoader loader) {
   1.113 +        CacheKey(String baseName, Locale locale) {
   1.114              this.name = baseName;
   1.115              this.locale = locale;
   1.116 -            if (loader == null) {
   1.117 -                this.loaderRef = null;
   1.118 -            } else {
   1.119 -                loaderRef = new LoaderReference(loader, referenceQueue, this);
   1.120 -            }
   1.121              calculateHashCode();
   1.122          }
   1.123  
   1.124 @@ -550,10 +473,6 @@
   1.125              return this;
   1.126          }
   1.127  
   1.128 -        ClassLoader getLoader() {
   1.129 -            return (loaderRef != null) ? loaderRef.get() : null;
   1.130 -        }
   1.131 -
   1.132          public boolean equals(Object other) {
   1.133              if (this == other) {
   1.134                  return true;
   1.135 @@ -572,17 +491,7 @@
   1.136                  if (!locale.equals(otherEntry.locale)) {
   1.137                      return false;
   1.138                  }
   1.139 -                //are refs (both non-null) or (both null)?
   1.140 -                if (loaderRef == null) {
   1.141 -                    return otherEntry.loaderRef == null;
   1.142 -                }
   1.143 -                ClassLoader loader = loaderRef.get();
   1.144 -                return (otherEntry.loaderRef != null)
   1.145 -                        // with a null reference we can no longer find
   1.146 -                        // out which class loader was referenced; so
   1.147 -                        // treat it as unequal
   1.148 -                        && (loader != null)
   1.149 -                        && (loader == otherEntry.loaderRef.get());
   1.150 +                return true;
   1.151              } catch (NullPointerException e) {
   1.152              } catch (ClassCastException e) {
   1.153              }
   1.154 @@ -596,19 +505,11 @@
   1.155          private void calculateHashCode() {
   1.156              hashCodeCache = name.hashCode() << 3;
   1.157              hashCodeCache ^= locale.hashCode();
   1.158 -            ClassLoader loader = getLoader();
   1.159 -            if (loader != null) {
   1.160 -                hashCodeCache ^= loader.hashCode();
   1.161 -            }
   1.162          }
   1.163  
   1.164          public Object clone() {
   1.165              try {
   1.166                  CacheKey clone = (CacheKey) super.clone();
   1.167 -                if (loaderRef != null) {
   1.168 -                    clone.loaderRef = new LoaderReference(loaderRef.get(),
   1.169 -                                                          referenceQueue, clone);
   1.170 -                }
   1.171                  // Clear the reference to a Throwable
   1.172                  clone.cause = null;
   1.173                  return clone;
   1.174 @@ -651,7 +552,7 @@
   1.175                      l = "\"\"";
   1.176                  }
   1.177              }
   1.178 -            return "CacheKey[" + name + ", lc=" + l + ", ldr=" + getLoader()
   1.179 +            return "CacheKey[" + name + ", lc=" + l
   1.180                  + "(format=" + format + ")]";
   1.181          }
   1.182      }
   1.183 @@ -665,25 +566,6 @@
   1.184      }
   1.185  
   1.186      /**
   1.187 -     * References to class loaders are weak references, so that they can be
   1.188 -     * garbage collected when nobody else is using them. The ResourceBundle
   1.189 -     * class has no reason to keep class loaders alive.
   1.190 -     */
   1.191 -    private static final class LoaderReference extends WeakReference<ClassLoader>
   1.192 -                                               implements CacheKeyReference {
   1.193 -        private CacheKey cacheKey;
   1.194 -
   1.195 -        LoaderReference(ClassLoader referent, ReferenceQueue q, CacheKey key) {
   1.196 -            super(referent, q);
   1.197 -            cacheKey = key;
   1.198 -        }
   1.199 -
   1.200 -        public CacheKey getCacheKey() {
   1.201 -            return cacheKey;
   1.202 -        }
   1.203 -    }
   1.204 -
   1.205 -    /**
   1.206       * References to bundles are soft references so that they can be garbage
   1.207       * collected when they have no hard references.
   1.208       */
   1.209 @@ -722,8 +604,6 @@
   1.210      public static final ResourceBundle getBundle(String baseName)
   1.211      {
   1.212          return getBundleImpl(baseName, Locale.getDefault(),
   1.213 -                             /* must determine loader here, else we break stack invariant */
   1.214 -                             getLoader(),
   1.215                               Control.INSTANCE);
   1.216      }
   1.217  
   1.218 @@ -765,7 +645,6 @@
   1.219                                                   Control control) {
   1.220          return getBundleImpl(baseName, Locale.getDefault(),
   1.221                               /* must determine loader here, else we break stack invariant */
   1.222 -                             getLoader(),
   1.223                               control);
   1.224      }
   1.225  
   1.226 @@ -795,7 +674,6 @@
   1.227      {
   1.228          return getBundleImpl(baseName, locale,
   1.229                               /* must determine loader here, else we break stack invariant */
   1.230 -                             getLoader(),
   1.231                               Control.INSTANCE);
   1.232      }
   1.233  
   1.234 @@ -840,7 +718,6 @@
   1.235                                                   Control control) {
   1.236          return getBundleImpl(baseName, targetLocale,
   1.237                               /* must determine loader here, else we break stack invariant */
   1.238 -                             getLoader(),
   1.239                               control);
   1.240      }
   1.241  
   1.242 @@ -1025,7 +902,7 @@
   1.243          if (loader == null) {
   1.244              throw new NullPointerException();
   1.245          }
   1.246 -        return getBundleImpl(baseName, locale, loader, Control.INSTANCE);
   1.247 +        return getBundleImpl(baseName, locale, Control.INSTANCE);
   1.248      }
   1.249  
   1.250      /**
   1.251 @@ -1243,11 +1120,11 @@
   1.252          if (loader == null || control == null) {
   1.253              throw new NullPointerException();
   1.254          }
   1.255 -        return getBundleImpl(baseName, targetLocale, loader, control);
   1.256 +        return getBundleImpl(baseName, targetLocale, control);
   1.257      }
   1.258  
   1.259      private static ResourceBundle getBundleImpl(String baseName, Locale locale,
   1.260 -                                                ClassLoader loader, Control control) {
   1.261 +                                                Control control) {
   1.262          if (locale == null || control == null) {
   1.263              throw new NullPointerException();
   1.264          }
   1.265 @@ -1256,7 +1133,7 @@
   1.266          // name and loader will never change during the bundle loading
   1.267          // process. We have to make sure that the locale is set before
   1.268          // using it as a cache key.
   1.269 -        CacheKey cacheKey = new CacheKey(baseName, locale, loader);
   1.270 +        CacheKey cacheKey = new CacheKey(baseName, locale);
   1.271          ResourceBundle bundle = null;
   1.272  
   1.273          // Quick lookup of the cache.
   1.274 @@ -1388,7 +1265,7 @@
   1.275                  // the same bundles having different parents.
   1.276                  BundleReference bundleRef = cacheList.get(cacheKey);
   1.277                  if (bundleRef != null && bundleRef.get() == bundle) {
   1.278 -                    cacheList.remove(cacheKey, bundleRef);
   1.279 +                    cacheList.remove(cacheKey);
   1.280                  }
   1.281              }
   1.282          }
   1.283 @@ -1434,7 +1311,7 @@
   1.284              String format = formats.get(i);
   1.285              try {
   1.286                  bundle = control.newBundle(cacheKey.getName(), targetLocale, format,
   1.287 -                                           cacheKey.getLoader(), reload);
   1.288 +                                           null, reload);
   1.289              } catch (LinkageError error) {
   1.290                  // We need to handle the LinkageError case due to
   1.291                  // inconsistent case-sensitivity in ClassLoader.
   1.292 @@ -1562,7 +1439,7 @@
   1.293              assert bundle != NONEXISTENT_BUNDLE;
   1.294              bundle.expired = true;
   1.295              bundle.cacheKey = null;
   1.296 -            cacheList.remove(cacheKey, bundleRef);
   1.297 +            cacheList.remove(cacheKey);
   1.298              bundle = null;
   1.299          } else {
   1.300              CacheKey key = bundleRef.getCacheKey();
   1.301 @@ -1581,7 +1458,7 @@
   1.302                                  bundle.expired = control.needsReload(key.getName(),
   1.303                                                                       key.getLocale(),
   1.304                                                                       key.getFormat(),
   1.305 -                                                                     key.getLoader(),
   1.306 +                                                                     null,
   1.307                                                                       bundle,
   1.308                                                                       key.loadTime);
   1.309                              } catch (Exception e) {
   1.310 @@ -1593,7 +1470,7 @@
   1.311                                  // return the bundle with the expired flag
   1.312                                  // on.
   1.313                                  bundle.cacheKey = null;
   1.314 -                                cacheList.remove(cacheKey, bundleRef);
   1.315 +                                cacheList.remove(cacheKey);
   1.316                              } else {
   1.317                                  // Update the expiration control info. and reuse
   1.318                                  // the same bundle instance
   1.319 @@ -1603,7 +1480,7 @@
   1.320                      }
   1.321                  } else {
   1.322                      // We just remove NONEXISTENT_BUNDLE from the cache.
   1.323 -                    cacheList.remove(cacheKey, bundleRef);
   1.324 +                    cacheList.remove(cacheKey);
   1.325                      bundle = null;
   1.326                  }
   1.327              }
   1.328 @@ -1630,7 +1507,7 @@
   1.329              bundle.cacheKey = key;
   1.330  
   1.331              // Put the bundle in the cache if it's not been in the cache.
   1.332 -            BundleReference result = cacheList.putIfAbsent(key, bundleRef);
   1.333 +            BundleReference result = cacheList.put(key, bundleRef);
   1.334  
   1.335              // If someone else has put the same bundle in the cache before
   1.336              // us and it has not expired, we should use the one in the cache.
   1.337 @@ -1677,7 +1554,7 @@
   1.338       * @see ResourceBundle.Control#getTimeToLive(String,Locale)
   1.339       */
   1.340      public static final void clearCache() {
   1.341 -        clearCache(getLoader());
   1.342 +        clearCache(null);
   1.343      }
   1.344  
   1.345      /**
   1.346 @@ -1695,9 +1572,7 @@
   1.347          }
   1.348          Set<CacheKey> set = cacheList.keySet();
   1.349          for (CacheKey key : set) {
   1.350 -            if (key.getLoader() == loader) {
   1.351 -                set.remove(key);
   1.352 -            }
   1.353 +            set.remove(key);
   1.354          }
   1.355      }
   1.356  
   1.357 @@ -2300,13 +2175,25 @@
   1.358              if (baseName == null) {
   1.359                  throw new NullPointerException();
   1.360              }
   1.361 -            return new ArrayList<>(CANDIDATES_CACHE.get(locale.getBaseLocale()));
   1.362 +            return new ArrayList<>(CANDIDATES_CACHE.get(locale));
   1.363          }
   1.364  
   1.365          private static final CandidateListCache CANDIDATES_CACHE = new CandidateListCache();
   1.366  
   1.367 -        private static class CandidateListCache extends LocaleObjectCache<BaseLocale, List<Locale>> {
   1.368 -            protected List<Locale> createObject(BaseLocale base) {
   1.369 +        private static class CandidateListCache {
   1.370 +            private Locale prevQuery;
   1.371 +            private List<Locale> prevResult;
   1.372 +            
   1.373 +            public List<Locale> get(Locale l) {
   1.374 +                if (prevQuery == l) {
   1.375 +                    return prevResult;
   1.376 +                }
   1.377 +                prevResult = createObject(l);
   1.378 +                prevQuery = l;
   1.379 +                return prevResult;
   1.380 +            }
   1.381 +            
   1.382 +            protected List<Locale> createObject(Locale base) {
   1.383                  String language = base.getLanguage();
   1.384                  String script = base.getScript();
   1.385                  String region = base.getRegion();
   1.386 @@ -2563,7 +2450,9 @@
   1.387              if (format.equals("java.class")) {
   1.388                  try {
   1.389                      Class<? extends ResourceBundle> bundleClass
   1.390 -                        = (Class<? extends ResourceBundle>)loader.loadClass(bundleName);
   1.391 +                        = (Class<? extends ResourceBundle>)(loader != null ? 
   1.392 +                        loader.loadClass(bundleName) :
   1.393 +                        Class.forName(bundleName));
   1.394  
   1.395                      // If the class isn't a ResourceBundle subclass, throw a
   1.396                      // ClassCastException.
   1.397 @@ -2579,39 +2468,15 @@
   1.398                  final String resourceName = toResourceName(bundleName, "properties");
   1.399                  final ClassLoader classLoader = loader;
   1.400                  final boolean reloadFlag = reload;
   1.401 -                InputStream stream = null;
   1.402 -                try {
   1.403 -                    stream = AccessController.doPrivileged(
   1.404 -                        new PrivilegedExceptionAction<InputStream>() {
   1.405 -                            public InputStream run() throws IOException {
   1.406 -                                InputStream is = null;
   1.407 -                                if (reloadFlag) {
   1.408 -                                    URL url = classLoader.getResource(resourceName);
   1.409 -                                    if (url != null) {
   1.410 -                                        URLConnection connection = url.openConnection();
   1.411 -                                        if (connection != null) {
   1.412 -                                            // Disable caches to get fresh data for
   1.413 -                                            // reloading.
   1.414 -                                            connection.setUseCaches(false);
   1.415 -                                            is = connection.getInputStream();
   1.416 -                                        }
   1.417 -                                    }
   1.418 -                                } else {
   1.419 -                                    is = classLoader.getResourceAsStream(resourceName);
   1.420 -                                }
   1.421 -                                return is;
   1.422 -                            }
   1.423 -                        });
   1.424 -                } catch (PrivilegedActionException e) {
   1.425 -                    throw (IOException) e.getException();
   1.426 -                }
   1.427 +                InputStream stream = classLoader != null ? classLoader.getResourceAsStream(resourceName) :
   1.428 +                    ResourceBundle.class.getResourceAsStream("/" + resourceName);
   1.429                  if (stream != null) {
   1.430                      try {
   1.431                          bundle = new PropertyResourceBundle(stream);
   1.432                      } finally {
   1.433                          stream.close();
   1.434                      }
   1.435 -                }
   1.436 +                }   
   1.437              } else {
   1.438                  throw new IllegalArgumentException("unknown format: " + format);
   1.439              }
   1.440 @@ -2730,6 +2595,7 @@
   1.441              }
   1.442              boolean result = false;
   1.443              try {
   1.444 +/*
   1.445                  String resourceName = toResourceName(toBundleName(baseName, locale), format);
   1.446                  URL url = loader.getResource(resourceName);
   1.447                  if (url != null) {
   1.448 @@ -2752,6 +2618,7 @@
   1.449                      }
   1.450                      result = lastModified >= loadTime;
   1.451                  }
   1.452 +                */
   1.453              } catch (NullPointerException npe) {
   1.454                  throw npe;
   1.455              } catch (Exception e) {