ResourceManagerpublic final class ResourceManager extends Object The ResourceManager class facilitates the reading of JNDI resource files. |
Fields Summary |
---|
private static final String | PROVIDER_RESOURCE_FILE_NAME | private static final String | APP_RESOURCE_FILE_NAME | private static final String | JRELIB_PROPERTY_FILE_NAME | private static final String[] | listProperties | private static final VersionHelper | helper | private static final WeakHashMap | propertiesCache | private static final WeakHashMap | factoryCache | private static final WeakHashMap | urlFactoryCache | private static final WeakReference | NO_FACTORY |
Constructors Summary |
---|
private ResourceManager()
// There should be no instances of this class.
|
Methods Summary |
---|
private static java.util.Hashtable | getApplicationResources()
ClassLoader cl = helper.getContextClassLoader();
synchronized (propertiesCache) {
Hashtable result = (Hashtable)propertiesCache.get(cl);
if (result != null) {
return result;
}
try {
NamingEnumeration resources =
helper.getResources(cl, APP_RESOURCE_FILE_NAME);
while (resources.hasMore()) {
Properties props = new Properties();
props.load((InputStream)resources.next());
if (result == null) {
result = props;
} else {
mergeTables(result, props);
}
}
// Merge in properties from file in <java.home>/lib.
InputStream istream =
helper.getJavaHomeLibStream(JRELIB_PROPERTY_FILE_NAME);
if (istream != null) {
Properties props = new Properties();
props.load(istream);
if (result == null) {
result = props;
} else {
mergeTables(result, props);
}
}
} catch (IOException e) {
NamingException ne = new ConfigurationException(
"Error reading application resource file");
ne.setRootCause(e);
throw ne;
}
if (result == null) {
result = new Hashtable(11);
}
propertiesCache.put(cl, result);
return result;
}
| public static com.sun.naming.internal.FactoryEnumeration | getFactories(java.lang.String propName, java.util.Hashtable env, javax.naming.Context ctx)Retrieves an enumeration of factory classes/object specified by a
property.
The property is gotten from the environment and the provider
resource file associated with the given context and concantenated.
See getProperty(). The resulting property value is a list of class names.
This method then loads each class using the current thread's context
class loader and keeps them in a list. Any class that cannot be loaded
is ignored. The resulting list is then cached in a two-level
hash table, keyed first by the context class loader and then by
the property's value.
The next time threads of the same context class loader call this
method, they can use the cached list.
After obtaining the list either from the cache or by creating one from
the property value, this method then creates and returns a
FactoryEnumeration using the list. As the FactoryEnumeration is
traversed, the cached Class object in the list is instantiated and
replaced by an instance of the factory object itself. Both class
objects and factories are wrapped in weak references so as not to
prevent GC of the class loader.
Note that multiple threads can be accessing the same cached list
via FactoryEnumeration, which locks the list during each next().
The size of the list will not change,
but a cached Class object might be replaced by an instantiated factory
object.
String facProp = getProperty(propName, env, ctx, true);
if (facProp == null)
return null; // no classes specified; return null
// Cache is based on context class loader and property val
ClassLoader loader = helper.getContextClassLoader();
Map perLoaderCache = null;
synchronized (factoryCache) {
perLoaderCache = (Map) factoryCache.get(loader);
if (perLoaderCache == null) {
perLoaderCache = new HashMap(11);
factoryCache.put(loader, perLoaderCache);
}
}
synchronized (perLoaderCache) {
List factories = (List) perLoaderCache.get(facProp);
if (factories != null) {
// Cached list
return factories.size() == 0 ? null
: new FactoryEnumeration(factories, loader);
} else {
// Populate list with classes named in facProp; skipping
// those that we cannot load
StringTokenizer parser = new StringTokenizer(facProp, ":");
factories = new ArrayList(5);
while (parser.hasMoreTokens()) {
try {
// System.out.println("loading");
String className = parser.nextToken();
Class c = helper.loadClass(className, loader);
factories.add(new NamedWeakReference(c, className));
} catch (Exception e) {
// ignore ClassNotFoundException, IllegalArgumentException
}
}
// System.out.println("adding to cache: " + factories);
perLoaderCache.put(facProp, factories);
return new FactoryEnumeration(factories, loader);
}
}
| public static java.lang.Object | getFactory(java.lang.String propName, java.util.Hashtable env, javax.naming.Context ctx, java.lang.String classSuffix, java.lang.String defaultPkgPrefix)Retrieves a factory from a list of packages specified in a
property.
The property is gotten from the environment and the provider
resource file associated with the given context and concatenated.
classSuffix is added to the end of this list.
See getProperty(). The resulting property value is a list of package
prefixes.
This method then constructs a list of class names by concatenating
each package prefix with classSuffix and attempts to load and
instantiate the class until one succeeds.
Any class that cannot be loaded is ignored.
The resulting object is then cached in a two-level hash table,
keyed first by the context class loader and then by the property's
value and classSuffix.
The next time threads of the same context class loader call this
method, they use the cached factory.
If no factory can be loaded, NO_FACTORY is recorded in the table
so that next time it'll return quickly.
// Merge property with provider property and supplied default
String facProp = getProperty(propName, env, ctx, true);
if (facProp != null)
facProp += (":" + defaultPkgPrefix);
else
facProp = defaultPkgPrefix;
// Cache factory based on context class loader, class name, and
// property val
ClassLoader loader = helper.getContextClassLoader();
String key = classSuffix + " " + facProp;
Map perLoaderCache = null;
synchronized (urlFactoryCache) {
perLoaderCache = (Map) urlFactoryCache.get(loader);
if (perLoaderCache == null) {
perLoaderCache = new HashMap(11);
urlFactoryCache.put(loader, perLoaderCache);
}
}
synchronized (perLoaderCache) {
Object factory = null;
WeakReference factoryRef = (WeakReference) perLoaderCache.get(key);
if (factoryRef == NO_FACTORY) {
return null;
} else if (factoryRef != null) {
factory = factoryRef.get();
if (factory != null) { // check if weak ref has been cleared
return factory;
}
}
// Not cached; find first factory and cache
StringTokenizer parser = new StringTokenizer(facProp, ":");
String className;
while (factory == null && parser.hasMoreTokens()) {
className = parser.nextToken() + classSuffix;
try {
// System.out.println("loading " + className);
factory = helper.loadClass(className, loader).newInstance();
} catch (InstantiationException e) {
NamingException ne =
new NamingException("Cannot instantiate " + className);
ne.setRootCause(e);
throw ne;
} catch (IllegalAccessException e) {
NamingException ne =
new NamingException("Cannot access " + className);
ne.setRootCause(e);
throw ne;
} catch (Exception e) {
// ignore ClassNotFoundException, IllegalArgumentException,
// etc.
}
}
// Cache it.
perLoaderCache.put(key, (factory != null)
? new WeakReference(factory)
: NO_FACTORY);
return factory;
}
| public static java.util.Hashtable | getInitialEnvironment(java.util.Hashtable env)
String[] props = VersionHelper.PROPS; // system/applet properties
if (env == null) {
env = new Hashtable(11);
}
Applet applet = (Applet)env.get(Context.APPLET);
// Merge property values from env param, applet params, and system
// properties. The first value wins: there's no concatenation of
// colon-separated lists.
// Read system properties by first trying System.getProperties(),
// and then trying System.getProperty() if that fails. The former
// is more efficient due to fewer permission checks.
//
String[] jndiSysProps = helper.getJndiProperties();
for (int i = 0; i < props.length; i++) {
Object val = env.get(props[i]);
if (val == null) {
if (applet != null) {
val = applet.getParameter(props[i]);
}
if (val == null) {
// Read system property.
val = (jndiSysProps != null)
? jndiSysProps[i]
: helper.getJndiProperty(i);
}
if (val != null) {
env.put(props[i], val);
}
}
}
// Merge the above with the values read from all application
// resource files. Colon-separated lists are concatenated.
mergeTables(env, getApplicationResources());
return env;
| public static java.lang.String | getProperty(java.lang.String propName, java.util.Hashtable env, javax.naming.Context ctx, boolean concat)Retrieves the property from the environment, or from the provider
resource file associated with the given context. The environment
may in turn contain values that come from applet parameters,
system properties, or application resource files.
If concat is true and both the environment and the provider
resource file contain the property, the two values are concatenated
(with a ':' separator).
Returns null if no value is found.
String val1 = (env != null) ? (String)env.get(propName) : null;
if ((ctx == null) ||
((val1 != null) && !concat)) {
return val1;
}
String val2 = (String)getProviderResource(ctx).get(propName);
if (val1 == null) {
return val2;
} else if ((val2 == null) || !concat) {
return val1;
} else {
return (val1 + ":" + val2);
}
| private static java.util.Hashtable | getProviderResource(java.lang.Object obj)
if (obj == null) {
return (new Hashtable(1));
}
synchronized (propertiesCache) {
Class c = obj.getClass();
Hashtable props = (Hashtable)propertiesCache.get(c);
if (props != null) {
return props;
}
props = new Properties();
InputStream istream =
helper.getResourceAsStream(c, PROVIDER_RESOURCE_FILE_NAME);
if (istream != null) {
try {
((Properties)props).load(istream);
} catch (IOException e) {
NamingException ne = new ConfigurationException(
"Error reading provider resource file for " + c);
ne.setRootCause(e);
throw ne;
}
}
propertiesCache.put(c, props);
return props;
}
| private static boolean | isListProperty(java.lang.String prop)
prop = prop.intern();
for (int i = 0; i < listProperties.length; i++) {
if (prop == listProperties[i]) {
return true;
}
}
return false;
| private static void | mergeTables(java.util.Hashtable props1, java.util.Hashtable props2)
Enumeration keys = props2.keys();
while (keys.hasMoreElements()) {
String prop = (String)keys.nextElement();
Object val1 = props1.get(prop);
if (val1 == null) {
props1.put(prop, props2.get(prop));
} else if (isListProperty(prop)) {
String val2 = (String)props2.get(prop);
props1.put(prop, ((String)val1) + ":" + val2);
}
}
|
|