/*
 * Copyright (c) 1999, 2009, 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 javax.naming;

import java.util.Hashtable;
import javax.naming.spi.NamingManager;
import com.sun.naming.internal.ResourceManager;

/**
 * This class is the starting context for performing naming operations.
 *<p>
 * All naming operations are relative to a context.
 * The initial context implements the Context interface and
 * provides the starting point for resolution of names.
 *<p>
 * <a name=ENVIRONMENT></a>
 * When the initial context is constructed, its environment
 * is initialized with properties defined in the environment parameter
 * passed to the constructor, and in any
 * <a href=Context.html#RESOURCEFILES>application resource files</a>.
 * In addition, a small number of standard JNDI properties may
 * be specified as system properties or as applet parameters
 * (through the use of {@link Context#APPLET}).
 * These special properties are listed in the field detail sections of the
 * <a href=Context.html#field_detail><tt>Context</tt></a> and
 * <a href=ldap/LdapContext.html#field_detail><tt>LdapContext</tt></a>
 * interface documentation.
 *<p>
 * JNDI determines each property's value by merging
 * the values from the following two sources, in order:
 * <ol>
 * <li>
 * The first occurrence of the property from the constructor's
 * environment parameter and (for appropriate properties) the applet
 * parameters and system properties.
 * <li>
 * The application resource files (<tt>jndi.properties</tt>).
 * </ol>
 * For each property found in both of these two sources, or in
 * more than one application resource file, the property's value
 * is determined as follows.  If the property is
 * one of the standard JNDI properties that specify a list of JNDI
 * factories (see <a href=Context.html#LISTPROPS><tt>Context</tt></a>),
 * all of the values are
 * concatenated into a single colon-separated list.  For other
 * properties, only the first value found is used.
 *
 *<p>
 * The initial context implementation is determined at runtime.
 * The default policy uses the environment property
 * "{@link Context#INITIAL_CONTEXT_FACTORY java.naming.factory.initial}",
 * which contains the class name of the initial context factory.
 * An exception to this policy is made when resolving URL strings, as described
 * below.
 *<p>
 * When a URL string (a <tt>String</tt> of the form
 * <em>scheme_id:rest_of_name</em>) is passed as a name parameter to
 * any method, a URL context factory for handling that scheme is
 * located and used to resolve the URL.  If no such factory is found,
 * the initial context specified by
 * <tt>"java.naming.factory.initial"</tt> is used.  Similarly, when a
 * <tt>CompositeName</tt> object whose first component is a URL string is
 * passed as a name parameter to any method, a URL context factory is
 * located and used to resolve the first name component.
 * See {@link NamingManager#getURLContext
 * <tt>NamingManager.getURLContext()</tt>} for a description of how URL
 * context factories are located.
 *<p>
 * This default policy of locating the initial context and URL context
 * factories may be overridden
 * by calling
 * <tt>NamingManager.setInitialContextFactoryBuilder()</tt>.
 *<p>
 * NoInitialContextException is thrown when an initial context cannot
 * be instantiated. This exception can be thrown during any interaction
 * with the InitialContext, not only when the InitialContext is constructed.
 * For example, the implementation of the initial context might lazily
 * retrieve the context only when actual methods are invoked on it.
 * The application should not have any dependency on when the existence
 * of an initial context is determined.
 *<p>
 * When the environment property "java.naming.factory.initial" is
 * non-null, the InitialContext constructor will attempt to create the
 * initial context specified therein. At that time, the initial context factory
 * involved might throw an exception if a problem is encountered. However,
 * it is provider implementation-dependent when it verifies and indicates
 * to the users of the initial context any environment property- or
 * connection- related problems. It can do so lazily--delaying until
 * an operation is performed on the context, or eagerly, at the time
 * the context is constructed.
 *<p>
 * An InitialContext instance is not synchronized against concurrent
 * access by multiple threads. Multiple threads each manipulating a
 * different InitialContext instance need not synchronize.
 * Threads that need to access a single InitialContext instance
 * concurrently should synchronize amongst themselves and provide the
 * necessary locking.
 *
 * @author Rosanna Lee
 * @author Scott Seligman
 *
 * @see Context
 * @see NamingManager#setInitialContextFactoryBuilder
 *      NamingManager.setInitialContextFactoryBuilder
 * @since JNDI 1.1 / Java 2 Platform, Standard Edition, v 1.3
 */

public class InitialContext implements Context {

    /**
     * The environment associated with this InitialContext.
     * It is initialized to null and is updated by the constructor
     * that accepts an environment or by the <tt>init()</tt> method.
     * @see #addToEnvironment
     * @see #removeFromEnvironment
     * @see #getEnvironment
     */
    protected Hashtable<Object,Object> myProps = null;

    /**
     * Field holding the result of calling NamingManager.getInitialContext().
     * It is set by getDefaultInitCtx() the first time getDefaultInitCtx()
     * is called. Subsequent invocations of getDefaultInitCtx() return
     * the value of defaultInitCtx.
     * @see #getDefaultInitCtx
     */
    protected Context defaultInitCtx = null;

    /**
     * Field indicating whether the initial context has been obtained
     * by calling NamingManager.getInitialContext().
     * If true, its result is in <code>defaultInitCtx</code>.
     */
    protected boolean gotDefault = false;

    /**
     * Constructs an initial context with the option of not
     * initializing it.  This may be used by a constructor in
     * a subclass when the value of the environment parameter
     * is not yet known at the time the <tt>InitialContext</tt>
     * constructor is called.  The subclass's constructor will
     * call this constructor, compute the value of the environment,
     * and then call <tt>init()</tt> before returning.
     *
     * @param lazy
     *          true means do not initialize the initial context; false
     *          is equivalent to calling <tt>new InitialContext()</tt>
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #init(Hashtable)
     * @since 1.3
     */
    protected InitialContext(boolean lazy) throws NamingException {
        if (!lazy) {
            init(null);
        }
    }

    /**
     * Constructs an initial context.
     * No environment properties are supplied.
     * Equivalent to <tt>new InitialContext(null)</tt>.
     *
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #InitialContext(Hashtable)
     */
    public InitialContext() throws NamingException {
        init(null);
    }

    /**
     * Constructs an initial context using the supplied environment.
     * Environment properties are discussed in the class description.
     *
     * <p> This constructor will not modify <tt>environment</tt>
     * or save a reference to it, but may save a clone.
     * Caller should not modify mutable keys and values in
     * <tt>environment</tt> after it has been passed to the constructor.
     *
     * @param environment
     *          environment used to create the initial context.
     *          Null indicates an empty environment.
     *
     * @throws  NamingException if a naming exception is encountered
     */
    public InitialContext(Hashtable<?,?> environment)
        throws NamingException
    {
        if (environment != null) {
            environment = (Hashtable)environment.clone();
        }
        init(environment);
    }

    /**
     * Initializes the initial context using the supplied environment.
     * Environment properties are discussed in the class description.
     *
     * <p> This method will modify <tt>environment</tt> and save
     * a reference to it.  The caller may no longer modify it.
     *
     * @param environment
     *          environment used to create the initial context.
     *          Null indicates an empty environment.
     *
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #InitialContext(boolean)
     * @since 1.3
     */
    protected void init(Hashtable<?,?> environment)
        throws NamingException
    {
        myProps = ResourceManager.getInitialEnvironment(environment);

        if (myProps.get(Context.INITIAL_CONTEXT_FACTORY) != null) {
            // user has specified initial context factory; try to get it
            getDefaultInitCtx();
        }
    }

    /**
     * A static method to retrieve the named object.
     * This is a shortcut method equivalent to invoking:
     * <p>
     * <code>
     *        InitialContext ic = new InitialContext();
     *        Object obj = ic.lookup();
     * </code>
     * <p> If <tt>name</tt> is empty, returns a new instance of this context
     * (which represents the same naming context as this context, but its
     * environment may be modified independently and it may be accessed
     * concurrently).
     *
     * @param name
     *          the name of the object to look up
     * @return  the object bound to <tt>name</tt>
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #doLookup(String)
     * @see #lookup(Name)
     * @since 1.6
     */
    public static <T> T doLookup(Name name)
        throws NamingException {
        return (T) (new InitialContext()).lookup(name);
    }

   /**
     * A static method to retrieve the named object.
     * See {@link #doLookup(Name)} for details.
     * @param name
     *          the name of the object to look up
     * @return  the object bound to <tt>name</tt>
     * @throws  NamingException if a naming exception is encountered
      * @since 1.6
     */
    public static <T> T doLookup(String name)
        throws NamingException {
        return (T) (new InitialContext()).lookup(name);
    }

    private static String getURLScheme(String str) {
        int colon_posn = str.indexOf(':');
        int slash_posn = str.indexOf('/');

        if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))
            return str.substring(0, colon_posn);
        return null;
    }

    /**
     * Retrieves the initial context by calling
     * <code>NamingManager.getInitialContext()</code>
     * and cache it in defaultInitCtx.
     * Set <code>gotDefault</code> so that we know we've tried this before.
     * @return The non-null cached initial context.
     * @exception NoInitialContextException If cannot find an initial context.
     * @exception NamingException If a naming exception was encountered.
     */
    protected Context getDefaultInitCtx() throws NamingException{
        if (!gotDefault) {
            defaultInitCtx = NamingManager.getInitialContext(myProps);
            gotDefault = true;
        }
        if (defaultInitCtx == null)
            throw new NoInitialContextException();

        return defaultInitCtx;
    }

    /**
     * Retrieves a context for resolving the string name <code>name</code>.
     * If <code>name</code> name is a URL string, then attempt
     * to find a URL context for it. If none is found, or if
     * <code>name</code> is not a URL string, then return
     * <code>getDefaultInitCtx()</code>.
     *<p>
     * See getURLOrDefaultInitCtx(Name) for description
     * of how a subclass should use this method.
     * @param name The non-null name for which to get the context.
     * @return A URL context for <code>name</code> or the cached
     *         initial context. The result cannot be null.
     * @exception NoInitialContextException If cannot find an initial context.
     * @exception NamingException In a naming exception is encountered.
     * @see javax.naming.spi.NamingManager#getURLContext
     */
    protected Context getURLOrDefaultInitCtx(String name)
        throws NamingException {
        if (NamingManager.hasInitialContextFactoryBuilder()) {
            return getDefaultInitCtx();
        }
        String scheme = getURLScheme(name);
        if (scheme != null) {
            Context ctx = NamingManager.getURLContext(scheme, myProps);
            if (ctx != null) {
                return ctx;
            }
        }
        return getDefaultInitCtx();
    }

    /**
     * Retrieves a context for resolving <code>name</code>.
     * If the first component of <code>name</code> name is a URL string,
     * then attempt to find a URL context for it. If none is found, or if
     * the first component of <code>name</code> is not a URL string,
     * then return <code>getDefaultInitCtx()</code>.
     *<p>
     * When creating a subclass of InitialContext, use this method as
     * follows.
     * Define a new method that uses this method to get an initial
     * context of the desired subclass.
     * <p><blockquote><pre>
     * protected XXXContext getURLOrDefaultInitXXXCtx(Name name)
     * throws NamingException {
     *  Context answer = getURLOrDefaultInitCtx(name);
     *  if (!(answer instanceof XXXContext)) {
     *    if (answer == null) {
     *      throw new NoInitialContextException();
     *    } else {
     *      throw new NotContextException("Not an XXXContext");
     *    }
     *  }
     *  return (XXXContext)answer;
     * }
     * </pre></blockquote>
     * When providing implementations for the new methods in the subclass,
     * use this newly defined method to get the initial context.
     * <p><blockquote><pre>
     * public Object XXXMethod1(Name name, ...) {
     *  throws NamingException {
     *    return getURLOrDefaultInitXXXCtx(name).XXXMethod1(name, ...);
     * }
     * </pre></blockquote>
     *
     * @param name The non-null name for which to get the context.
     * @return A URL context for <code>name</code> or the cached
     *         initial context. The result cannot be null.
     * @exception NoInitialContextException If cannot find an initial context.
     * @exception NamingException In a naming exception is encountered.
     *
     * @see javax.naming.spi.NamingManager#getURLContext
     */
    protected Context getURLOrDefaultInitCtx(Name name)
        throws NamingException {
        if (NamingManager.hasInitialContextFactoryBuilder()) {
            return getDefaultInitCtx();
        }
        if (name.size() > 0) {
            String first = name.get(0);
            String scheme = getURLScheme(first);
            if (scheme != null) {
                Context ctx = NamingManager.getURLContext(scheme, myProps);
                if (ctx != null) {
                    return ctx;
                }
            }
        }
        return getDefaultInitCtx();
    }

// Context methods
// Most Javadoc is deferred to the Context interface.

    public Object lookup(String name) throws NamingException {
        return getURLOrDefaultInitCtx(name).lookup(name);
    }

    public Object lookup(Name name) throws NamingException {
        return getURLOrDefaultInitCtx(name).lookup(name);
    }

    public void bind(String name, Object obj) throws NamingException {
        getURLOrDefaultInitCtx(name).bind(name, obj);
    }

    public void bind(Name name, Object obj) throws NamingException {
        getURLOrDefaultInitCtx(name).bind(name, obj);
    }

    public void rebind(String name, Object obj) throws NamingException {
        getURLOrDefaultInitCtx(name).rebind(name, obj);
    }

    public void rebind(Name name, Object obj) throws NamingException {
        getURLOrDefaultInitCtx(name).rebind(name, obj);
    }

    public void unbind(String name) throws NamingException  {
        getURLOrDefaultInitCtx(name).unbind(name);
    }

    public void unbind(Name name) throws NamingException  {
        getURLOrDefaultInitCtx(name).unbind(name);
    }

    public void rename(String oldName, String newName) throws NamingException {
        getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
    }

    public void rename(Name oldName, Name newName)
        throws NamingException
    {
        getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
    }

    public NamingEnumeration<NameClassPair> list(String name)
        throws NamingException
    {
        return (getURLOrDefaultInitCtx(name).list(name));
    }

    public NamingEnumeration<NameClassPair> list(Name name)
        throws NamingException
    {
        return (getURLOrDefaultInitCtx(name).list(name));
    }

    public NamingEnumeration<Binding> listBindings(String name)
            throws NamingException  {
        return getURLOrDefaultInitCtx(name).listBindings(name);
    }

    public NamingEnumeration<Binding> listBindings(Name name)
            throws NamingException  {
        return getURLOrDefaultInitCtx(name).listBindings(name);
    }

    public void destroySubcontext(String name) throws NamingException  {
        getURLOrDefaultInitCtx(name).destroySubcontext(name);
    }

    public void destroySubcontext(Name name) throws NamingException  {
        getURLOrDefaultInitCtx(name).destroySubcontext(name);
    }

    public Context createSubcontext(String name) throws NamingException  {
        return getURLOrDefaultInitCtx(name).createSubcontext(name);
    }

    public Context createSubcontext(Name name) throws NamingException  {
        return getURLOrDefaultInitCtx(name).createSubcontext(name);
    }

    public Object lookupLink(String name) throws NamingException  {
        return getURLOrDefaultInitCtx(name).lookupLink(name);
    }

    public Object lookupLink(Name name) throws NamingException {
        return getURLOrDefaultInitCtx(name).lookupLink(name);
    }

    public NameParser getNameParser(String name) throws NamingException {
        return getURLOrDefaultInitCtx(name).getNameParser(name);
    }

    public NameParser getNameParser(Name name) throws NamingException {
        return getURLOrDefaultInitCtx(name).getNameParser(name);
    }

    /**
     * Composes the name of this context with a name relative to
     * this context.
     * Since an initial context may never be named relative
     * to any context other than itself, the value of the
     * <tt>prefix</tt> parameter must be an empty name (<tt>""</tt>).
     */
    public String composeName(String name, String prefix)
            throws NamingException {
        return name;
    }

    /**
     * Composes the name of this context with a name relative to
     * this context.
     * Since an initial context may never be named relative
     * to any context other than itself, the value of the
     * <tt>prefix</tt> parameter must be an empty name.
     */
    public Name composeName(Name name, Name prefix)
        throws NamingException
    {
        return (Name)name.clone();
    }

    public Object addToEnvironment(String propName, Object propVal)
            throws NamingException {
        myProps.put(propName, propVal);
        return getDefaultInitCtx().addToEnvironment(propName, propVal);
    }

    public Object removeFromEnvironment(String propName)
            throws NamingException {
        myProps.remove(propName);
        return getDefaultInitCtx().removeFromEnvironment(propName);
    }

    public Hashtable<?,?> getEnvironment() throws NamingException {
        return getDefaultInitCtx().getEnvironment();
    }

    public void close() throws NamingException {
        myProps = null;
        if (defaultInitCtx != null) {
            defaultInitCtx.close();
            defaultInitCtx = null;
        }
        gotDefault = false;
    }

    public String getNameInNamespace() throws NamingException {
        return getDefaultInitCtx().getNameInNamespace();
    }
};
