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 + -
显示快捷键?