/*
 * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

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;
import java.util.List;
import java.util.ArrayList;
import java.util.WeakHashMap;

import javax.naming.*;

/**
  * The ResourceManager class facilitates the reading of JNDI resource files.
  *
  * @author Rosanna Lee
  * @author Scott Seligman
  */

public final class ResourceManager {

    /*
     * Name of provider resource files (without the package-name prefix.)
     */
    private static final String PROVIDER_RESOURCE_FILE_NAME =
            "jndiprovider.properties";

    /*
     * Name of application resource files.
     */
    private static final String APP_RESOURCE_FILE_NAME = "jndi.properties";

    /*
     * Name of properties file in <java.home>/lib.
     */
    private static final String JRELIB_PROPERTY_FILE_NAME = "jndi.properties";

    /*
     * The standard JNDI properties that specify colon-separated lists.
     */
    private static final String[] listProperties = {
        Context.OBJECT_FACTORIES,
        Context.URL_PKG_PREFIXES,
        Context.STATE_FACTORIES,
        // The following shouldn't create a runtime dependence on ldap package.
        javax.naming.ldap.LdapContext.CONTROL_FACTORIES
    };

    private static final VersionHelper helper =
            VersionHelper.getVersionHelper();

    /*
     * A cache of the properties that have been constructed by
     * 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.
     */
    private static class AppletParameter {
        private static final Class<?> clazz = getClass("java.applet.Applet");
        private static final Method getMethod =
            getMethod(clazz, "getParameter", String.class);
        private static Class<?> getClass(String name) {
            try {
                return Class.forName(name, true, null);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }
        private static Method getMethod(Class<?> clazz,
                                        String name,
                                        Class<?>... paramTypes)
        {
            if (clazz != null) {
                try {
                    return clazz.getMethod(name, paramTypes);
                } catch (NoSuchMethodException e) {
                    throw new AssertionError(e);
                }
            } else {
                return null;
            }
        }

        /**
         * Returns the value of the applet's named parameter.
         */
        static Object get(Object applet, String name) {
            // 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.
    private ResourceManager() {
    }


    // ---------- Public methods ----------

    /*
     * Given the environment parameter passed to the initial context
     * constructor, returns the full environment for that initial
     * context (never null).  This is based on the environment
     * parameter, the applet parameters (where appropriate), the
     * system properties, and all application resource files.
     *
     * <p> This method will modify <tt>env</tt> and save
     * a reference to it.  The caller may no longer modify it.
     *
     * @param env       environment passed to initial context constructor.
     *                  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
        // 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 = AppletParameter.get(applet, 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;
    }

    /**
      * 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 <tt>concat</tt> 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.
      *
      * @param propName The non-null property name
      * @param env      The possibly null environment properties
      * @param ctx      The possibly null context
      * @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) ||
            ((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);
        }
    }

    /**
     * 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.
     *<p>
     * 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.
     *<p>
     * 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.
     *<p>
     * 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.
     *
     * @param propName  The non-null property name
     * @param env       The possibly null environment properties
     * @param ctx       The possibly null context
     * @return An enumeration of factory classes/objects; null if none.
     * @exception NamingException If encounter problem while reading the provider
     * property file.
     * @see javax.naming.spi.NamingManager#getObjectInstance
     * @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);
                perLoaderCache.put(facProp, factories);
                return new FactoryEnumeration(factories, loader);
            }
        }
    }

    /**
     * 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.
     *<p>
     * 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.
     *
     * @param propName  The non-null property name
     * @param env       The possibly null environment properties
     * @param ctx       The possibly null context
     * @param classSuffix The non-null class name
     *                  (e.g. ".ldap.ldapURLContextFactory).
     * @param defaultPkgPrefix The non-null default package prefix.
     *        (e.g., "com.sun.jndi.url").
     * @return An factory object; null if none.
     * @exception NamingException If encounter problem while reading the provider
     * 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);
        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;
        }
    }


    // ---------- Private methods ----------

    /*
     * Returns the properties contained in the provider resource file
     * of an object's package.  Returns an empty hash table if the
     * 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();

            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;
        }
    }


    /*
     * Returns the Hashtable (never null) that results from merging
     * all application resource files available to this thread's
     * context class loader.  The properties file in <java.home>/lib
     * is also merged in.  The results are cached.
     *
     * SECURITY NOTES:
     * 1.  JNDI needs permission to read the application resource files.
     * 2.  Any class will be able to use JNDI to view the contents of
     * the application resource files in its own classpath.  Give
     * careful consideration to this before storing sensitive
     * 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);
                    }
                }

                // 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;
        }
    }

    /*
     * Merge the properties from one hash table into another.  Each
     * 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);
                props1.put(prop, ((String)val1) + ":" + val2);
            }
        }
    }

    /*
     * Is a property one of the standard JNDI properties that specify
     * colon-separated lists?
     */
    private static boolean isListProperty(String prop) {
        prop = prop.intern();
        for (int i = 0; i < listProperties.length; i++) {
            if (prop == listProperties[i]) {
                return true;
            }
        }
        return false;
    }
}
