resourcebundle.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,150 行 · 第 1/4 页
JAVA
1,150 行
/** * Remove any entries this thread may have in the construction list. * This is done as cleanup in the case where a bundle can't be * constructed. */ private static void cleanUpConstructionList() { synchronized (cacheList) { final Collection entries = underConstruction.values(); final Thread thisThread = Thread.currentThread(); while (entries.remove(thisThread)) { } } } /** * Find a bundle in the cache or load it via the loader or a property file. * If the bundle isn't found, an entry is put in the constructionCache * and null is returned. If null is returned, the caller must define the bundle * by calling putBundleInCache. This routine also propagates NOT_FOUND values * from parent to child bundles when the parent is NOT_FOUND. * @param loader the loader to use when loading a bundle * @param bundleName the complete bundle name including locale extension * @param defaultLocale the default locale at the time getBundle was called * @param parent the parent of the resource bundle being loaded. null if * the bundle is a root bundle * @return the bundle or null if the bundle could not be found in the cache * or loaded. */ private static Object findBundle(ClassLoader loader, String bundleName, Locale defaultLocale, String baseName, Object parent) { Object result; synchronized (cacheList) { // Before we do the real work of this method, see // whether we need to do some housekeeping: // If references to class loaders have been nulled out, // remove all related information from the cache Reference ref = referenceQueue.poll(); while (ref != null) { cacheList.remove(((LoaderReference) ref).getCacheKey()); ref = referenceQueue.poll(); } //check for bundle in cache cacheKey.setKeyValues(loader, bundleName, defaultLocale); result = cacheList.get(cacheKey); if (result != null) { cacheKey.clear(); return result; } // check to see if some other thread is building this bundle. // Note that there is a rare chance that this thread is already // working on this bundle, and in the process getBundle was called // again, in which case we can't wait (4300693) Thread builder = (Thread) underConstruction.get(cacheKey); boolean beingBuilt = (builder != null && builder != Thread.currentThread()); //if some other thread is building the bundle... if (beingBuilt) { //while some other thread is building the bundle... while (beingBuilt) { cacheKey.clear(); try { //Wait until the bundle is complete cacheList.wait(); } catch (InterruptedException e) { } cacheKey.setKeyValues(loader, bundleName, defaultLocale); beingBuilt = underConstruction.containsKey(cacheKey); } //if someone constructed the bundle for us, return it result = cacheList.get(cacheKey); if (result != null) { cacheKey.clear(); return result; } } //The bundle isn't in the cache, so we are now responsible for //loading it and adding it to the cache. final Object key = cacheKey.clone(); underConstruction.put(key, Thread.currentThread()); //the bundle is removed from the cache by putBundleInCache cacheKey.clear(); } //try loading the bundle via the class loader result = loadBundle(loader, bundleName, defaultLocale); if (result != null) { // check whether we're still responsible for construction - // a recursive call to getBundle might have handled it (4300693) boolean constructing; synchronized (cacheList) { cacheKey.setKeyValues(loader, bundleName, defaultLocale); constructing = underConstruction.get(cacheKey) == Thread.currentThread(); cacheKey.clear(); } if (constructing) { // set the bundle's parent and put it in the cache final ResourceBundle bundle = (ResourceBundle)result; if (parent != NOT_FOUND && bundle.parent == null) { bundle.setParent((ResourceBundle) parent); } bundle.setLocale(baseName, bundleName); putBundleInCache(loader, bundleName, defaultLocale, result); } } return result; } /** * Calculate the bundles along the search path from the base bundle to the * bundle specified by baseName and locale. * @param baseName the base bundle name * @param locale the locale * @param names the vector used to return the names of the bundles along * the search path. * */ private static Vector calculateBundleNames(String baseName, Locale locale) { final Vector result = new Vector(MAX_BUNDLES_SEARCHED); final String language = locale.getLanguage(); final int languageLength = language.length(); final String country = locale.getCountry(); final int countryLength = country.length(); final String variant = locale.getVariant(); final int variantLength = variant.length(); if (languageLength + countryLength + variantLength == 0) { //The locale is "", "", "". return result; } final StringBuffer temp = new StringBuffer(baseName); temp.append('_'); temp.append(language); if (languageLength > 0) { result.addElement(temp.toString()); } if (countryLength + variantLength == 0) { return result; } temp.append('_'); temp.append(country); if (countryLength > 0) { result.addElement(temp.toString()); } if (variantLength == 0) { return result; } temp.append('_'); temp.append(variant); result.addElement(temp.toString()); return result; } /** * Find a bundle in the cache. * @param loader the class loader that is responsible for loading the bundle. * @param bundleName the complete name of the bundle including locale extension. * ex. sun.text.resources.LocaleElements_fr_BE * @param defaultLocale the default locale at the time getBundle was called * @return the cached bundle. null if the bundle is not in the cache. */ private static Object findBundleInCache(ClassLoader loader, String bundleName, Locale defaultLocale) { //Synchronize access to cacheList, cacheKey, and underConstruction synchronized (cacheList) { cacheKey.setKeyValues(loader, bundleName, defaultLocale); Object result = cacheList.get(cacheKey); cacheKey.clear(); return result; } } /** * Put a new bundle in the cache and notify waiting threads that a new * bundle has been put in the cache. * @param defaultLocale the default locale at the time getBundle was called */ private static void putBundleInCache(ClassLoader loader, String bundleName, Locale defaultLocale, Object value) { //we use a static shared cacheKey but we use the lock in cacheList since //the key is only used to interact with cacheList. synchronized (cacheList) { cacheKey.setKeyValues(loader, bundleName, defaultLocale); cacheList.put(cacheKey.clone(), value); underConstruction.remove(cacheKey); cacheKey.clear(); //notify waiters that we're done constructing the bundle cacheList.notifyAll(); } } /** * Load a bundle through either the specified ClassLoader or from a ".properties" file * and return the loaded bundle. * @param loader the ClassLoader to use to load the bundle. If null, the system * ClassLoader is used. * @param bundleName the name of the resource to load. The name should be complete * including a qualified class name followed by the locale extension. * ex. sun.text.resources.LocaleElements_fr_BE * @param defaultLocale the default locale at the time getBundle was called * @return the bundle or null if none could be found. */ private static Object loadBundle(final ClassLoader loader, String bundleName, Locale defaultLocale) { // replace any '/'s with '.'s for the bug-for-bug compatible // ClassLoader behavior. (5077272, see also 4872868) String correctedBundleName = bundleName.replace('/', '.'); // Search for class file using class loader try { Class bundleClass; if (loader != null) { bundleClass = loader.loadClass(correctedBundleName); } else { bundleClass = Class.forName(correctedBundleName); } if (ResourceBundle.class.isAssignableFrom(bundleClass)) { Object myBundle = bundleClass.newInstance(); // Creating the instance may have triggered a recursive call to getBundle, // in which case the bundle created by the recursive call would be in the // cache now (4300693). For consistency, we'd then return the bundle from the cache. Object otherBundle = findBundleInCache(loader, bundleName, defaultLocale); if (otherBundle != null) { return otherBundle; } else { return myBundle; } } } catch (Exception e) { } catch (LinkageError e) { } // Next search for a Properties file. final String resName = bundleName.replace('.', '/') + ".properties"; InputStream stream = (InputStream)java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { if (loader != null) { return loader.getResourceAsStream(resName); } else { return ClassLoader.getSystemResourceAsStream(resName); } } } ); if (stream != null) { // make sure it is buffered stream = new java.io.BufferedInputStream(stream); try { return new PropertyResourceBundle(stream); } catch (Exception e) { } finally { try { stream.close(); } catch (Exception e) { // to avoid propagating an IOException back into the caller // (I'm assuming this is never going to happen, and if it does, // I'm obeying the precedent of swallowing exceptions set by the // existing code above) } } } return null; } /** * Gets an object for the given key from this resource bundle. * Returns null if this resource bundle does not contain an * object for the given key. * * @param key the key for the desired object * @exception NullPointerException if <code>key</code> is <code>null</code> * @return the object for the given key, or null */ protected abstract Object handleGetObject(String key); /** * Returns an enumeration of the keys. * */ public abstract Enumeration getKeys();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?