- /*
 - * @(#)InitialContext.java 1.8 00/02/02
 - *
 - * Copyright 1999, 2000 Sun Microsystems, Inc. All Rights Reserved.
 - *
 - * This software is the proprietary information of Sun Microsystems, Inc.
 - * Use is subject to license terms.
 - *
 - */
 - 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
 - * @version 1.8 00/02/02
 - *
 - * @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 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.
 - *
 - * @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();
 - }
 - }
 - 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 list(String name) throws NamingException {
 - return (getURLOrDefaultInitCtx(name).list(name));
 - }
 - public NamingEnumeration list(Name name) throws NamingException {
 - return (getURLOrDefaultInitCtx(name).list(name));
 - }
 - public NamingEnumeration listBindings(String name)
 - throws NamingException {
 - return getURLOrDefaultInitCtx(name).listBindings(name);
 - }
 - public NamingEnumeration 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();
 - }
 - };