📄 resourcebundle.java
字号:
* provided: MyResources.class, MyResources_fr_CH.properties, * MyResources_fr_CH.class, MyResources_fr.properties, * MyResources_en.properties, and MyResources_es_ES.class. The contents of * all files are valid (that is, public non-abstract subclasses of * ResourceBundle with public nullary constructors for the ".class" files, * syntactically correct ".properties" files). The default locale is * Locale("en", "UK"). * * <p>Calling getBundle with the shown locale argument values instantiates * resource bundles from the following sources:<ul> * <li>Locale("fr", "CH"): result MyResources_fr_CH.class, parent * MyResources_fr.properties, parent MyResources.class</li> * <li>Locale("fr", "FR"): result MyResources_fr.properties, parent * MyResources.class</li> * <li>Locale("de", "DE"): result MyResources_en.properties, parent * MyResources.class</li> * <li>Locale("en", "US"): result MyResources_en.properties, parent * MyResources.class</li> * <li>Locale("es", "ES"): result MyResources_es_ES.class, parent * MyResources.class</li> * </ul> * The file MyResources_fr_CH.properties is never used because it is hidden * by MyResources_fr_CH.class. * * @param baseName the name of the ResourceBundle * @param locale A locale * @param classloader a ClassLoader * @return the desired resource bundle * @throws MissingResourceException if the resource bundle can't be found * @throws NullPointerException if any argument is null * @since 1.2 */ // This method is synchronized so that the cache is properly // handled. public static final synchronized ResourceBundle getBundle (String baseName, Locale locale, ClassLoader classLoader) { // This implementation searches the bundle in the reverse direction // and builds the parent chain on the fly. Locale defaultLocale = Locale.getDefault(); if (defaultLocale != lastDefaultLocale) { resourceBundleCache = new HashMap(); lastDefaultLocale = defaultLocale; } HashMap cache = (HashMap) resourceBundleCache.get(classLoader); StringBuffer sb = new StringBuffer(60); sb.append(baseName).append('_').append(locale); String name = sb.toString(); if (cache == null) { cache = new HashMap(); resourceBundleCache.put(classLoader, cache); } else if (cache.containsKey(name)) { Reference ref = (Reference) cache.get(name); ResourceBundle result = null; // If REF is null, that means that we added a `null' value to // the hash map. That means we failed to find the bundle // previously, and we cached that fact. The JDK does this, so // it must be ok. if (ref == null) throw new MissingResourceException("Bundle " + baseName + " not found", baseName, ""); else { ResourceBundle rb = (ResourceBundle) ref.get(); if (rb != null) { // RB should already have the right parent, except if // something very strange happened. return rb; } // If RB is null, then we previously found it but it was // collected. So we try again. } } // It is ok if this returns null. We aren't required to have the // base bundle. ResourceBundle baseBundle = tryBundle(baseName, emptyLocale, classLoader, null, cache); // Now use our locale, followed by the default locale. We only // need to try the default locale if our locale is different, and // if our locale failed to yield a result other than the base // bundle. ResourceBundle bundle = tryLocalBundle(baseName, locale, classLoader, baseBundle, cache); if (bundle == baseBundle && !locale.equals(defaultLocale)) { bundle = tryLocalBundle(baseName, defaultLocale, classLoader, baseBundle, cache); // We need to record that the argument locale maps to the // bundle we just found. If we didn't find a bundle, record // that instead. if (bundle == null) cache.put(name, null); else cache.put(name, new SoftReference(bundle)); } if (bundle == null) throw new MissingResourceException("Bundle " + baseName + " not found", baseName, ""); return bundle; } /** * Override this method to provide the resource for a keys. This gets * called by <code>getObject</code>. If you don't have a resource * for the given key, you should return null instead throwing a * MissingResourceException. You don't have to ask the parent, getObject() * already does this; nor should you throw a MissingResourceException. * * @param key the key of the resource * @return the resource for the key, or null if not in bundle * @throws NullPointerException if key is null */ protected abstract Object handleGetObject(String key); /** * This method should return all keys for which a resource exists; you * should include the enumeration of any parent's keys, after filtering out * duplicates. * * @return an enumeration of the keys */ public abstract Enumeration getKeys(); /** * Tries to load a class or a property file with the specified name. * * @param localizedName the name * @param locale the locale, that must be used exactly * @param classloader the classloader * @param bundle the backup (parent) bundle * @return the resource bundle if it was loaded, otherwise the backup */ private static final ResourceBundle tryBundle(String localizedName, Locale locale, ClassLoader classloader, ResourceBundle bundle, HashMap cache) { // First look into the cache. if (cache.containsKey(localizedName)) { Reference ref = (Reference) cache.get(localizedName); ResourceBundle result = null; // If REF is null, that means that we added a `null' value to // the hash map. That means we failed to find the bundle // previously, and we cached that fact. The JDK does this, so // it must be ok. if (ref == null) return null; else { ResourceBundle rb = (ResourceBundle) ref.get(); if (rb != null) { // RB should already have the right parent, except if // something very strange happened. return rb; } // If RB is null, then we previously found it but it was // collected. So we try again. } } // foundBundle holds exact matches for the localizedName resource // bundle, which may later be cached. ResourceBundle foundBundle = null; try { Class rbClass; if (classloader == null) rbClass = Class.forName(localizedName); else rbClass = classloader.loadClass(localizedName); foundBundle = (ResourceBundle) rbClass.newInstance(); foundBundle.parent = bundle; foundBundle.locale = locale; } catch (Exception ex) { // ignore them all } if (foundBundle == null) { try { InputStream is; final String resourceName = localizedName.replace('.', '/') + ".properties"; if (classloader == null) is = ClassLoader.getSystemResourceAsStream(resourceName); else is = classloader.getResourceAsStream(resourceName); if (is != null) { foundBundle = new PropertyResourceBundle(is); foundBundle.parent = bundle; foundBundle.locale = locale; } } catch (IOException ex) { } } // Put the result into the hash table. If we didn't find anything // here, we record our parent bundle. If we record `null' that means // nothing, not even the base, was found. if (foundBundle == null) foundBundle = bundle; if (foundBundle == null) cache.put(localizedName, null); else cache.put(localizedName, new SoftReference(foundBundle)); return foundBundle; } /** * Tries to load a the bundle for a given locale, also loads the backup * locales with the same language. * * @param name the name * @param locale the locale * @param classloader the classloader * @param bundle the backup (parent) bundle * @return the resource bundle if it was loaded, otherwise the backup */ private static final ResourceBundle tryLocalBundle(String baseName, Locale locale, ClassLoader classloader, ResourceBundle bundle, HashMap cache) { final String language = locale.getLanguage(); final String country = locale.getCountry(); final String variant = locale.getVariant(); StringBuffer sb = new StringBuffer(60); sb.append(baseName); sb.append('_'); if (language.length() > 0) { sb.append(language); bundle = tryBundle(sb.toString(), new Locale(language), classloader, bundle, cache); } // If LANGUAGE was empty, we still need to try the other // components, and the `_' is required. sb.append('_'); if (country.length() > 0) { sb.append(country); bundle = tryBundle(sb.toString(), new Locale(language, country), classloader, bundle, cache); } sb.append('_'); if (variant.length() > 0) { sb.append(variant); bundle = tryBundle(sb.toString(), locale, classloader, bundle, cache); } return bundle; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -