resourcebundle.java
来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 539 行 · 第 1/2 页
JAVA
539 行
/**
* Get an object from a ResourceBundle.
* @param key see class description.
*/
public final Object getObject(String key) throws MissingResourceException {
Object obj = handleGetObject(key);
if (obj == null) {
if (parent != null) {
obj = parent.getObject(key);
}
if (obj == null)
throw new MissingResourceException("Can't find resource",
this.getClass().getName(),
key);
}
return obj;
}
/**
* Get the appropriate ResourceBundle subclass.
* @param baseName see class description.
*/
public static final ResourceBundle getBundle(String baseName)
throws MissingResourceException
{
return getBundle(baseName, Locale.getDefault(),
/* must determine loader here, else we break stack invariant */
getLoader());
}
/**
* Get the appropriate ResourceBundle subclass.
* @param baseName see class description.
* @param locale see class description.
*/
public static final ResourceBundle getBundle(String baseName,
Locale locale)
{
return getBundle(baseName, locale, getLoader());
}
/*
* Automatic determination of the ClassLoader to be used to load
* resources on behalf of the client. N.B. The client is getLoader's
* caller's caller.
*/
private static ClassLoader getLoader() {
Class[] stack = getClassContext();
/* Magic number 2 identifies our caller's caller */
Class c = stack[2];
ClassLoader cl = (c == null) ? null : c.getClassLoader();
return (cl == null) ? systemClassLoader : cl;
}
private static native Class[] getClassContext();
private static SystemClassLoader systemClassLoader =
new SystemClassLoader();
/**
* Get the appropriate ResourceBundle subclass.
* @param baseName see class description.
* @param locale see class description.
*/
private static synchronized ResourceBundle
getBundle(String baseName, Locale locale, ClassLoader loader)
throws MissingResourceException
{
StringBuffer localeName
= new StringBuffer("_").append(locale.toString());
if (locale.toString().equals(""))
localeName.setLength(0);
ResourceBundle lookup = findBundle(baseName,localeName,loader,false);
if(lookup == null) {
localeName.setLength(0);
localeName.append("_").append( Locale.getDefault().toString() );
lookup = findBundle(baseName, localeName, loader, true);
if( lookup == null ) {
throw new MissingResourceException("can't find resource for "
+ baseName + "_" + locale,
baseName + "_" + locale,"");
}
}
// Setup lookup's ancestry. If we find an ancestor whose parent is null,
// we set up the ancestor's parent as well.
ResourceBundle child = lookup;
while( (child != null) && (child.parent == null) ) {
// Chop off the last component of the locale name and search for that
// as the parent locale. Use it to set the parent of current child.
int lastUnderbar = localeName.toString().lastIndexOf('_');
if( lastUnderbar != -1 ) {
localeName.setLength(lastUnderbar);
// debug("Searching for parent " + baseName + localeName);
child.setParent( findBundle(baseName,localeName,loader,true) );
}
child = child.parent;
}
return lookup;
}
/**
* Set the parent bundle of this bundle. The parent bundle is
* searched by getObject when this bundle does not contain a
* particular resource.
* @param parent this bundle's parent bundle.
*/
protected void setParent( ResourceBundle parent ) {
this.parent = parent;
}
/**
* The internal routine that does the real work of finding and loading
* the right ResourceBundle for a given name and locale.
*/
private static ResourceBundle findBundle(String baseName,
StringBuffer localeName,
ClassLoader loader,
boolean includeBase)
{
String localeStr = localeName.toString();
String baseFileName = baseName.replace('.', '/');
Object lookup = null;
String searchName;
Vector cacheCandidates = new Vector();
int lastUnderbar;
InputStream stream;
searchLoop:
while (true) {
searchName = baseName + localeStr;
String cacheName =
"["+Integer.toString(loader.hashCode())+"]" + searchName;
// First, look in the cache. We may either find the bundle we're
// looking for or we may find that the bundle was not found by a
// previous search.
lookup = cacheList.get(cacheName);
if( lookup == NOTFOUND ) {
// debug("Found " + searchName + " in cache as NOTFOUND");
localeName.setLength(0);
break searchLoop;
}
if( lookup != null ) {
// debug("Found " + searchName + " in cache");
localeName.setLength(0);
break searchLoop;
}
cacheCandidates.addElement( cacheName );
// Next search for a class
// debug("Searching for " + searchName );
try {
lookup = loader.loadClass(searchName).newInstance();
break searchLoop;
} catch( Exception e ){}
// Next search for a Properties file.
searchName = baseFileName + localeStr + ".properties";
// debug("Searching for " + searchName );
stream = loader.getResourceAsStream(searchName);
if( stream != null ) {
// make sure it is buffered
stream = new java.io.BufferedInputStream(stream);
try {
lookup = (Object)new PropertyResourceBundle( stream );
break searchLoop;
} catch (Exception e) {}
}
//Chop off the last part of the locale name string and try again.
lastUnderbar = localeStr.lastIndexOf('_');
if( ((lastUnderbar==0)&&(!includeBase)) || (lastUnderbar == -1) ) {
break;
}
localeStr = localeStr.substring(0,lastUnderbar);
localeName.setLength(lastUnderbar);
}
if( lookup != null ) {
// Add a positive result to the cache. The result may include
// NOTFOUND
for( int i=0; i<cacheCandidates.size(); i++ ) {
cacheList.put(cacheCandidates.elementAt(i), lookup);
// debug("Adding " + cacheCandidates.elementAt(i) + " to cache"
// + ((lookup == NOTFOUND)?" as NOTFOUND.":"."));
}
}
else {
// If we searched all the way to the base, then we can add
// the NOTFOUND result to the cache. Otherwise we can say
// nothing.
if( includeBase == true ) {
for( int i=0; i<cacheCandidates.size(); i++ ) {
cacheList.put(cacheCandidates.elementAt(i), NOTFOUND);
// debug("Adding " + cacheCandidates.elementAt(i)
// + " to cache as NOTFOUND.");
}
}
}
if( (lookup == NOTFOUND) || (lookup == null) )
return null;
else
return (ResourceBundle)lookup;
}
/** Get an object from a ResourceBundle.
* <STRONG>NOTE: </STRONG>Subclasses must override.
* @param key see class description.
*/
protected abstract Object handleGetObject(String key)
throws MissingResourceException;
/**
* Return an enumeration of the keys.
* <STRONG>NOTE: </STRONG>Subclasses must override.
*/
public abstract Enumeration getKeys();
/**
* For printf debugging.
*/
private static boolean debugFlag = false;
private static void debug(String str) {
if( debugFlag ) {
System.out.println("ResourceBundle: " + str);
}
}
/**
* The parent bundle is consulted by getObject when this bundle
* does not contain a particular resource.
*/
protected ResourceBundle parent = null;
private static final Integer NOTFOUND = new Integer(-1);
private static Hashtable cacheList = new Hashtable();
}
/**
* The SystemClassLoader loads system classes (those in your classpath).
* This is an attempt to unify the handling of system classes and ClassLoader
* classes.
*/
class SystemClassLoader extends java.lang.ClassLoader {
protected Class loadClass( String name, boolean resolve )
throws ClassNotFoundException
{
return findSystemClass( name );
}
public InputStream getResourceAsStream(String name) {
return ClassLoader.getSystemResourceAsStream(name);
}
public java.net.URL getResource(String name) {
return ClassLoader.getSystemResource(name);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?