src/share/classes/com/sun/naming/internal/ResourceManager.java
Print this page
*** 25,39 ****
package com.sun.naming.internal;
import java.io.InputStream;
import java.io.IOException;
- import java.net.URL;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
- import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
--- 25,37 ----
*** 87,119 ****
* the ResourceManager. A Hashtable from a provider resource
* file is keyed on a class in the resource file's package.
* One from application resource files is keyed on the thread's
* context class loader.
*/
! private static final WeakHashMap propertiesCache = new WeakHashMap(11);
/*
* A cache of factory objects (ObjectFactory, StateFactory, ControlFactory).
*
* A two-level cache keyed first on context class loader and then
* on propValue. Value is a list of class or factory objects,
* weakly referenced so as not to prevent GC of the class loader.
* Used in getFactories().
*/
! private static final WeakHashMap factoryCache = new WeakHashMap(11);
/*
* A cache of URL factory objects (ObjectFactory).
*
* A two-level cache keyed first on context class loader and then
* on classSuffix+propValue. Value is the factory itself (weakly
* referenced so as not to prevent GC of the class loader) or
* NO_FACTORY if a previous search revealed no factory. Used in
* getFactory().
*/
! private static final WeakHashMap urlFactoryCache = new WeakHashMap(11);
! private static final WeakReference NO_FACTORY = new WeakReference(null);
/**
* A class to allow JNDI properties be specified as applet parameters
* without creating a static dependency on java.applet.
*/
--- 85,124 ----
* the ResourceManager. A Hashtable from a provider resource
* file is keyed on a class in the resource file's package.
* One from application resource files is keyed on the thread's
* context class loader.
*/
! // WeakHashMap<Class | ClassLoader, Hashtable>
! private static final WeakHashMap<Object, Hashtable<? super String, Object>>
! propertiesCache = new WeakHashMap<>(11);
/*
* A cache of factory objects (ObjectFactory, StateFactory, ControlFactory).
*
* A two-level cache keyed first on context class loader and then
* on propValue. Value is a list of class or factory objects,
* weakly referenced so as not to prevent GC of the class loader.
* Used in getFactories().
*/
! private static final
! WeakHashMap<ClassLoader, Map<String, List<NamedWeakReference<Object>>>>
! factoryCache = new WeakHashMap<>(11);
/*
* A cache of URL factory objects (ObjectFactory).
*
* A two-level cache keyed first on context class loader and then
* on classSuffix+propValue. Value is the factory itself (weakly
* referenced so as not to prevent GC of the class loader) or
* NO_FACTORY if a previous search revealed no factory. Used in
* getFactory().
*/
! private static final
! WeakHashMap<ClassLoader, Map<String, WeakReference<Object>>>
! urlFactoryCache = new WeakHashMap<>(11);
! private static final WeakReference<Object> NO_FACTORY =
! new WeakReference<>(null);
/**
* A class to allow JNDI properties be specified as applet parameters
* without creating a static dependency on java.applet.
*/
*** 150,163 ****
// if clazz is null then applet cannot be an Applet.
if (clazz == null || !clazz.isInstance(applet))
throw new ClassCastException(applet.getClass().getName());
try {
return getMethod.invoke(applet, name);
! } catch (InvocationTargetException e) {
throw new AssertionError(e);
- } catch (IllegalAccessException iae) {
- throw new AssertionError(iae);
}
}
}
// There should be no instances of this class.
--- 155,167 ----
// if clazz is null then applet cannot be an Applet.
if (clazz == null || !clazz.isInstance(applet))
throw new ClassCastException(applet.getClass().getName());
try {
return getMethod.invoke(applet, name);
! } catch (InvocationTargetException |
! IllegalAccessException e) {
throw new AssertionError(e);
}
}
}
// There should be no instances of this class.
*** 181,196 ****
* Null indicates an empty environment.
*
* @throws NamingException if an error occurs while reading a
* resource file
*/
! public static Hashtable getInitialEnvironment(Hashtable env)
throws NamingException
{
String[] props = VersionHelper.PROPS; // system/applet properties
if (env == null) {
! env = new Hashtable(11);
}
Object 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
--- 185,202 ----
* Null indicates an empty environment.
*
* @throws NamingException if an error occurs while reading a
* resource file
*/
! @SuppressWarnings("unchecked")
! public static Hashtable<?, ?> getInitialEnvironment(
! Hashtable<?, ?> env)
throws NamingException
{
String[] props = VersionHelper.PROPS; // system/applet properties
if (env == null) {
! env = new Hashtable<>(11);
}
Object 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
*** 211,228 ****
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;
}
/**
* Retrieves the property from the environment, or from the provider
--- 217,234 ----
val = (jndiSysProps != null)
? jndiSysProps[i]
: helper.getJndiProperty(i);
}
if (val != null) {
! ((Hashtable<String, Object>)env).put(props[i], val);
}
}
}
// Merge the above with the values read from all application
// resource files. Colon-separated lists are concatenated.
! mergeTables((Hashtable<Object, Object>)env, getApplicationResources());
return env;
}
/**
* Retrieves the property from the environment, or from the provider
*** 242,252 ****
* @param concat True if multiple values should be concatenated
* @return the property value, or null is there is none.
* @throws NamingException if an error occurs while reading the provider
* resource file.
*/
! public static String getProperty(String propName, Hashtable env,
Context ctx, boolean concat)
throws NamingException {
String val1 = (env != null) ? (String)env.get(propName) : null;
if ((ctx == null) ||
--- 248,258 ----
* @param concat True if multiple values should be concatenated
* @return the property value, or null is there is none.
* @throws NamingException if an error occurs while reading the provider
* resource file.
*/
! public static String getProperty(String propName, Hashtable<?,?> env,
Context ctx, boolean concat)
throws NamingException {
String val1 = (env != null) ? (String)env.get(propName) : null;
if ((ctx == null) ||
*** 303,348 ****
* @see javax.naming.spi.NamingManager#getStateToBind
* @see javax.naming.spi.DirectoryManager#getObjectInstance
* @see javax.naming.spi.DirectoryManager#getStateToBind
* @see javax.naming.ldap.ControlFactory#getControlInstance
*/
! public static FactoryEnumeration getFactories(String propName, Hashtable env,
! Context ctx) throws NamingException {
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);
--- 309,355 ----
* @see javax.naming.spi.NamingManager#getStateToBind
* @see javax.naming.spi.DirectoryManager#getObjectInstance
* @see javax.naming.spi.DirectoryManager#getStateToBind
* @see javax.naming.ldap.ControlFactory#getControlInstance
*/
! public static FactoryEnumeration getFactories(String propName,
! Hashtable<?,?> env, Context ctx) throws NamingException {
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<String, List<NamedWeakReference<Object>>> perLoaderCache = null;
synchronized (factoryCache) {
! perLoaderCache = factoryCache.get(loader);
if (perLoaderCache == null) {
! perLoaderCache = new HashMap<>(11);
factoryCache.put(loader, perLoaderCache);
}
}
synchronized (perLoaderCache) {
! List<NamedWeakReference<Object>> factories =
! 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<Object>(c, className));
} catch (Exception e) {
// ignore ClassNotFoundException, IllegalArgumentException
}
}
// System.out.println("adding to cache: " + factories);
*** 386,397 ****
* property file, or problem instantiating the factory.
*
* @see javax.naming.spi.NamingManager#getURLContext
* @see javax.naming.spi.NamingManager#getURLObject
*/
! public static Object getFactory(String propName, Hashtable env, Context ctx,
! String classSuffix, String defaultPkgPrefix) throws NamingException {
// Merge property with provider property and supplied default
String facProp = getProperty(propName, env, ctx, true);
if (facProp != null)
facProp += (":" + defaultPkgPrefix);
--- 393,405 ----
* property file, or problem instantiating the factory.
*
* @see javax.naming.spi.NamingManager#getURLContext
* @see javax.naming.spi.NamingManager#getURLObject
*/
! public static Object getFactory(String propName, Hashtable<?,?> env,
! Context ctx, String classSuffix, String defaultPkgPrefix)
! throws NamingException {
// Merge property with provider property and supplied default
String facProp = getProperty(propName, env, ctx, true);
if (facProp != null)
facProp += (":" + defaultPkgPrefix);
*** 401,423 ****
// 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
--- 409,431 ----
// Cache factory based on context class loader, class name, and
// property val
ClassLoader loader = helper.getContextClassLoader();
String key = classSuffix + " " + facProp;
! Map<String, WeakReference<Object>> perLoaderCache = null;
synchronized (urlFactoryCache) {
! perLoaderCache = urlFactoryCache.get(loader);
if (perLoaderCache == null) {
! perLoaderCache = new HashMap<>(11);
urlFactoryCache.put(loader, perLoaderCache);
}
}
synchronized (perLoaderCache) {
Object factory = null;
! WeakReference<Object> factoryRef = 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
*** 449,459 ****
}
}
// Cache it.
perLoaderCache.put(key, (factory != null)
! ? new WeakReference(factory)
: NO_FACTORY);
return factory;
}
}
--- 457,467 ----
}
}
// Cache it.
perLoaderCache.put(key, (factory != null)
! ? new WeakReference<>(factory)
: NO_FACTORY);
return factory;
}
}
*** 466,485 ****
* object is null or the resource file cannot be found. The
* results are cached.
*
* @throws NamingException if an error occurs while reading the file.
*/
! private static Hashtable getProviderResource(Object obj)
throws NamingException
{
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();
--- 474,495 ----
* object is null or the resource file cannot be found. The
* results are cached.
*
* @throws NamingException if an error occurs while reading the file.
*/
! private static Hashtable<? super String, Object>
! getProviderResource(Object obj)
throws NamingException
{
if (obj == null) {
! return (new Hashtable<>(1));
}
synchronized (propertiesCache) {
! Class<?> c = obj.getClass();
! Hashtable<? super String, Object> props =
! propertiesCache.get(c);
if (props != null) {
return props;
}
props = new Properties();
*** 516,541 ****
* information there.
*
* @throws NamingException if an error occurs while reading a resource
* file.
*/
! private static Hashtable getApplicationResources() throws NamingException {
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);
--- 526,552 ----
* information there.
*
* @throws NamingException if an error occurs while reading a resource
* file.
*/
! private static Hashtable<? super String, Object> getApplicationResources()
! throws NamingException {
ClassLoader cl = helper.getContextClassLoader();
synchronized (propertiesCache) {
! Hashtable<? super String, Object> result = propertiesCache.get(cl);
if (result != null) {
return result;
}
try {
! NamingEnumeration<InputStream> resources =
helper.getResources(cl, APP_RESOURCE_FILE_NAME);
while (resources.hasMore()) {
Properties props = new Properties();
! props.load(resources.next());
if (result == null) {
result = props;
} else {
mergeTables(result, props);
*** 561,571 ****
"Error reading application resource file");
ne.setRootCause(e);
throw ne;
}
if (result == null) {
! result = new Hashtable(11);
}
propertiesCache.put(cl, result);
return result;
}
}
--- 572,582 ----
"Error reading application resource file");
ne.setRootCause(e);
throw ne;
}
if (result == null) {
! result = new Hashtable<>(11);
}
propertiesCache.put(cl, result);
return result;
}
}
*** 575,589 ****
* property in props2 that is not in props1 is added to props1.
* For each property in both hash tables that is one of the
* standard JNDI properties that specify colon-separated lists,
* the values are concatenated and stored in props1.
*/
! private static void mergeTables(Hashtable props1, 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);
--- 586,599 ----
* property in props2 that is not in props1 is added to props1.
* For each property in both hash tables that is one of the
* standard JNDI properties that specify colon-separated lists,
* the values are concatenated and stored in props1.
*/
! private static void mergeTables(Hashtable<? super String, Object> props1,
! Hashtable<? super String, Object> props2) {
! for (Object key : props2.keySet()) {
! String prop = (String)key;
Object val1 = props1.get(prop);
if (val1 == null) {
props1.put(prop, props2.get(prop));
} else if (isListProperty(prop)) {
String val2 = (String)props2.get(prop);