Home » openjdk-7 » javax » naming » [javadoc | source]

    1   /*
    2    * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.naming;
   27   
   28   import java.util.Hashtable;
   29   import javax.naming.spi.NamingManager;
   30   import com.sun.naming.internal.ResourceManager;
   31   
   32   /**
   33    * This class is the starting context for performing naming operations.
   34    *<p>
   35    * All naming operations are relative to a context.
   36    * The initial context implements the Context interface and
   37    * provides the starting point for resolution of names.
   38    *<p>
   39    * <a name=ENVIRONMENT></a>
   40    * When the initial context is constructed, its environment
   41    * is initialized with properties defined in the environment parameter
   42    * passed to the constructor, and in any
   43    * <a href=Context.html#RESOURCEFILES>application resource files</a>.
   44    * In addition, a small number of standard JNDI properties may
   45    * be specified as system properties or as applet parameters
   46    * (through the use of {@link Context#APPLET}).
   47    * These special properties are listed in the field detail sections of the
   48    * <a href=Context.html#field_detail><tt>Context</tt></a> and
   49    * <a href=ldap/LdapContext.html#field_detail><tt>LdapContext</tt></a>
   50    * interface documentation.
   51    *<p>
   52    * JNDI determines each property's value by merging
   53    * the values from the following two sources, in order:
   54    * <ol>
   55    * <li>
   56    * The first occurrence of the property from the constructor's
   57    * environment parameter and (for appropriate properties) the applet
   58    * parameters and system properties.
   59    * <li>
   60    * The application resource files (<tt>jndi.properties</tt>).
   61    * </ol>
   62    * For each property found in both of these two sources, or in
   63    * more than one application resource file, the property's value
   64    * is determined as follows.  If the property is
   65    * one of the standard JNDI properties that specify a list of JNDI
   66    * factories (see <a href=Context.html#LISTPROPS><tt>Context</tt></a>),
   67    * all of the values are
   68    * concatenated into a single colon-separated list.  For other
   69    * properties, only the first value found is used.
   70    *
   71    *<p>
   72    * The initial context implementation is determined at runtime.
   73    * The default policy uses the environment property
   74    * "{@link Context#INITIAL_CONTEXT_FACTORY java.naming.factory.initial}",
   75    * which contains the class name of the initial context factory.
   76    * An exception to this policy is made when resolving URL strings, as described
   77    * below.
   78    *<p>
   79    * When a URL string (a <tt>String</tt> of the form
   80    * <em>scheme_id:rest_of_name</em>) is passed as a name parameter to
   81    * any method, a URL context factory for handling that scheme is
   82    * located and used to resolve the URL.  If no such factory is found,
   83    * the initial context specified by
   84    * <tt>"java.naming.factory.initial"</tt> is used.  Similarly, when a
   85    * <tt>CompositeName</tt> object whose first component is a URL string is
   86    * passed as a name parameter to any method, a URL context factory is
   87    * located and used to resolve the first name component.
   88    * See {@link NamingManager#getURLContext
   89    * <tt>NamingManager.getURLContext()</tt>} for a description of how URL
   90    * context factories are located.
   91    *<p>
   92    * This default policy of locating the initial context and URL context
   93    * factories may be overridden
   94    * by calling
   95    * <tt>NamingManager.setInitialContextFactoryBuilder()</tt>.
   96    *<p>
   97    * NoInitialContextException is thrown when an initial context cannot
   98    * be instantiated. This exception can be thrown during any interaction
   99    * with the InitialContext, not only when the InitialContext is constructed.
  100    * For example, the implementation of the initial context might lazily
  101    * retrieve the context only when actual methods are invoked on it.
  102    * The application should not have any dependency on when the existence
  103    * of an initial context is determined.
  104    *<p>
  105    * When the environment property "java.naming.factory.initial" is
  106    * non-null, the InitialContext constructor will attempt to create the
  107    * initial context specified therein. At that time, the initial context factory
  108    * involved might throw an exception if a problem is encountered. However,
  109    * it is provider implementation-dependent when it verifies and indicates
  110    * to the users of the initial context any environment property- or
  111    * connection- related problems. It can do so lazily--delaying until
  112    * an operation is performed on the context, or eagerly, at the time
  113    * the context is constructed.
  114    *<p>
  115    * An InitialContext instance is not synchronized against concurrent
  116    * access by multiple threads. Multiple threads each manipulating a
  117    * different InitialContext instance need not synchronize.
  118    * Threads that need to access a single InitialContext instance
  119    * concurrently should synchronize amongst themselves and provide the
  120    * necessary locking.
  121    *
  122    * @author Rosanna Lee
  123    * @author Scott Seligman
  124    *
  125    * @see Context
  126    * @see NamingManager#setInitialContextFactoryBuilder
  127    *      NamingManager.setInitialContextFactoryBuilder
  128    * @since JNDI 1.1 / Java 2 Platform, Standard Edition, v 1.3
  129    */
  130   
  131   public class InitialContext implements Context {
  132   
  133       /**
  134        * The environment associated with this InitialContext.
  135        * It is initialized to null and is updated by the constructor
  136        * that accepts an environment or by the <tt>init()</tt> method.
  137        * @see #addToEnvironment
  138        * @see #removeFromEnvironment
  139        * @see #getEnvironment
  140        */
  141       protected Hashtable<Object,Object> myProps = null;
  142   
  143       /**
  144        * Field holding the result of calling NamingManager.getInitialContext().
  145        * It is set by getDefaultInitCtx() the first time getDefaultInitCtx()
  146        * is called. Subsequent invocations of getDefaultInitCtx() return
  147        * the value of defaultInitCtx.
  148        * @see #getDefaultInitCtx
  149        */
  150       protected Context defaultInitCtx = null;
  151   
  152       /**
  153        * Field indicating whether the initial context has been obtained
  154        * by calling NamingManager.getInitialContext().
  155        * If true, its result is in <code>defaultInitCtx</code>.
  156        */
  157       protected boolean gotDefault = false;
  158   
  159       /**
  160        * Constructs an initial context with the option of not
  161        * initializing it.  This may be used by a constructor in
  162        * a subclass when the value of the environment parameter
  163        * is not yet known at the time the <tt>InitialContext</tt>
  164        * constructor is called.  The subclass's constructor will
  165        * call this constructor, compute the value of the environment,
  166        * and then call <tt>init()</tt> before returning.
  167        *
  168        * @param lazy
  169        *          true means do not initialize the initial context; false
  170        *          is equivalent to calling <tt>new InitialContext()</tt>
  171        * @throws  NamingException if a naming exception is encountered
  172        *
  173        * @see #init(Hashtable)
  174        * @since 1.3
  175        */
  176       protected InitialContext(boolean lazy) throws NamingException {
  177           if (!lazy) {
  178               init(null);
  179           }
  180       }
  181   
  182       /**
  183        * Constructs an initial context.
  184        * No environment properties are supplied.
  185        * Equivalent to <tt>new InitialContext(null)</tt>.
  186        *
  187        * @throws  NamingException if a naming exception is encountered
  188        *
  189        * @see #InitialContext(Hashtable)
  190        */
  191       public InitialContext() throws NamingException {
  192           init(null);
  193       }
  194   
  195       /**
  196        * Constructs an initial context using the supplied environment.
  197        * Environment properties are discussed in the class description.
  198        *
  199        * <p> This constructor will not modify <tt>environment</tt>
  200        * or save a reference to it, but may save a clone.
  201        * Caller should not modify mutable keys and values in
  202        * <tt>environment</tt> after it has been passed to the constructor.
  203        *
  204        * @param environment
  205        *          environment used to create the initial context.
  206        *          Null indicates an empty environment.
  207        *
  208        * @throws  NamingException if a naming exception is encountered
  209        */
  210       public InitialContext(Hashtable<?,?> environment)
  211           throws NamingException
  212       {
  213           if (environment != null) {
  214               environment = (Hashtable)environment.clone();
  215           }
  216           init(environment);
  217       }
  218   
  219       /**
  220        * Initializes the initial context using the supplied environment.
  221        * Environment properties are discussed in the class description.
  222        *
  223        * <p> This method will modify <tt>environment</tt> and save
  224        * a reference to it.  The caller may no longer modify it.
  225        *
  226        * @param environment
  227        *          environment used to create the initial context.
  228        *          Null indicates an empty environment.
  229        *
  230        * @throws  NamingException if a naming exception is encountered
  231        *
  232        * @see #InitialContext(boolean)
  233        * @since 1.3
  234        */
  235       protected void init(Hashtable<?,?> environment)
  236           throws NamingException
  237       {
  238           myProps = ResourceManager.getInitialEnvironment(environment);
  239   
  240           if (myProps.get(Context.INITIAL_CONTEXT_FACTORY) != null) {
  241               // user has specified initial context factory; try to get it
  242               getDefaultInitCtx();
  243           }
  244       }
  245   
  246       /**
  247        * A static method to retrieve the named object.
  248        * This is a shortcut method equivalent to invoking:
  249        * <p>
  250        * <code>
  251        *        InitialContext ic = new InitialContext();
  252        *        Object obj = ic.lookup();
  253        * </code>
  254        * <p> If <tt>name</tt> is empty, returns a new instance of this context
  255        * (which represents the same naming context as this context, but its
  256        * environment may be modified independently and it may be accessed
  257        * concurrently).
  258        *
  259        * @param name
  260        *          the name of the object to look up
  261        * @return  the object bound to <tt>name</tt>
  262        * @throws  NamingException if a naming exception is encountered
  263        *
  264        * @see #doLookup(String)
  265        * @see #lookup(Name)
  266        * @since 1.6
  267        */
  268       public static <T> T doLookup(Name name)
  269           throws NamingException {
  270           return (T) (new InitialContext()).lookup(name);
  271       }
  272   
  273      /**
  274        * A static method to retrieve the named object.
  275        * See {@link #doLookup(Name)} for details.
  276        * @param name
  277        *          the name of the object to look up
  278        * @return  the object bound to <tt>name</tt>
  279        * @throws  NamingException if a naming exception is encountered
  280         * @since 1.6
  281        */
  282       public static <T> T doLookup(String name)
  283           throws NamingException {
  284           return (T) (new InitialContext()).lookup(name);
  285       }
  286   
  287       private static String getURLScheme(String str) {
  288           int colon_posn = str.indexOf(':');
  289           int slash_posn = str.indexOf('/');
  290   
  291           if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))
  292               return str.substring(0, colon_posn);
  293           return null;
  294       }
  295   
  296       /**
  297        * Retrieves the initial context by calling
  298        * <code>NamingManager.getInitialContext()</code>
  299        * and cache it in defaultInitCtx.
  300        * Set <code>gotDefault</code> so that we know we've tried this before.
  301        * @return The non-null cached initial context.
  302        * @exception NoInitialContextException If cannot find an initial context.
  303        * @exception NamingException If a naming exception was encountered.
  304        */
  305       protected Context getDefaultInitCtx() throws NamingException{
  306           if (!gotDefault) {
  307               defaultInitCtx = NamingManager.getInitialContext(myProps);
  308               gotDefault = true;
  309           }
  310           if (defaultInitCtx == null)
  311               throw new NoInitialContextException();
  312   
  313           return defaultInitCtx;
  314       }
  315   
  316       /**
  317        * Retrieves a context for resolving the string name <code>name</code>.
  318        * If <code>name</code> name is a URL string, then attempt
  319        * to find a URL context for it. If none is found, or if
  320        * <code>name</code> is not a URL string, then return
  321        * <code>getDefaultInitCtx()</code>.
  322        *<p>
  323        * See getURLOrDefaultInitCtx(Name) for description
  324        * of how a subclass should use this method.
  325        * @param name The non-null name for which to get the context.
  326        * @return A URL context for <code>name</code> or the cached
  327        *         initial context. The result cannot be null.
  328        * @exception NoInitialContextException If cannot find an initial context.
  329        * @exception NamingException In a naming exception is encountered.
  330        * @see javax.naming.spi.NamingManager#getURLContext
  331        */
  332       protected Context getURLOrDefaultInitCtx(String name)
  333           throws NamingException {
  334           if (NamingManager.hasInitialContextFactoryBuilder()) {
  335               return getDefaultInitCtx();
  336           }
  337           String scheme = getURLScheme(name);
  338           if (scheme != null) {
  339               Context ctx = NamingManager.getURLContext(scheme, myProps);
  340               if (ctx != null) {
  341                   return ctx;
  342               }
  343           }
  344           return getDefaultInitCtx();
  345       }
  346   
  347       /**
  348        * Retrieves a context for resolving <code>name</code>.
  349        * If the first component of <code>name</code> name is a URL string,
  350        * then attempt to find a URL context for it. If none is found, or if
  351        * the first component of <code>name</code> is not a URL string,
  352        * then return <code>getDefaultInitCtx()</code>.
  353        *<p>
  354        * When creating a subclass of InitialContext, use this method as
  355        * follows.
  356        * Define a new method that uses this method to get an initial
  357        * context of the desired subclass.
  358        * <p><blockquote><pre>
  359        * protected XXXContext getURLOrDefaultInitXXXCtx(Name name)
  360        * throws NamingException {
  361        *  Context answer = getURLOrDefaultInitCtx(name);
  362        *  if (!(answer instanceof XXXContext)) {
  363        *    if (answer == null) {
  364        *      throw new NoInitialContextException();
  365        *    } else {
  366        *      throw new NotContextException("Not an XXXContext");
  367        *    }
  368        *  }
  369        *  return (XXXContext)answer;
  370        * }
  371        * </pre></blockquote>
  372        * When providing implementations for the new methods in the subclass,
  373        * use this newly defined method to get the initial context.
  374        * <p><blockquote><pre>
  375        * public Object XXXMethod1(Name name, ...) {
  376        *  throws NamingException {
  377        *    return getURLOrDefaultInitXXXCtx(name).XXXMethod1(name, ...);
  378        * }
  379        * </pre></blockquote>
  380        *
  381        * @param name The non-null name for which to get the context.
  382        * @return A URL context for <code>name</code> or the cached
  383        *         initial context. The result cannot be null.
  384        * @exception NoInitialContextException If cannot find an initial context.
  385        * @exception NamingException In a naming exception is encountered.
  386        *
  387        * @see javax.naming.spi.NamingManager#getURLContext
  388        */
  389       protected Context getURLOrDefaultInitCtx(Name name)
  390           throws NamingException {
  391           if (NamingManager.hasInitialContextFactoryBuilder()) {
  392               return getDefaultInitCtx();
  393           }
  394           if (name.size() > 0) {
  395               String first = name.get(0);
  396               String scheme = getURLScheme(first);
  397               if (scheme != null) {
  398                   Context ctx = NamingManager.getURLContext(scheme, myProps);
  399                   if (ctx != null) {
  400                       return ctx;
  401                   }
  402               }
  403           }
  404           return getDefaultInitCtx();
  405       }
  406   
  407   // Context methods
  408   // Most Javadoc is deferred to the Context interface.
  409   
  410       public Object lookup(String name) throws NamingException {
  411           return getURLOrDefaultInitCtx(name).lookup(name);
  412       }
  413   
  414       public Object lookup(Name name) throws NamingException {
  415           return getURLOrDefaultInitCtx(name).lookup(name);
  416       }
  417   
  418       public void bind(String name, Object obj) throws NamingException {
  419           getURLOrDefaultInitCtx(name).bind(name, obj);
  420       }
  421   
  422       public void bind(Name name, Object obj) throws NamingException {
  423           getURLOrDefaultInitCtx(name).bind(name, obj);
  424       }
  425   
  426       public void rebind(String name, Object obj) throws NamingException {
  427           getURLOrDefaultInitCtx(name).rebind(name, obj);
  428       }
  429   
  430       public void rebind(Name name, Object obj) throws NamingException {
  431           getURLOrDefaultInitCtx(name).rebind(name, obj);
  432       }
  433   
  434       public void unbind(String name) throws NamingException  {
  435           getURLOrDefaultInitCtx(name).unbind(name);
  436       }
  437   
  438       public void unbind(Name name) throws NamingException  {
  439           getURLOrDefaultInitCtx(name).unbind(name);
  440       }
  441   
  442       public void rename(String oldName, String newName) throws NamingException {
  443           getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
  444       }
  445   
  446       public void rename(Name oldName, Name newName)
  447           throws NamingException
  448       {
  449           getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
  450       }
  451   
  452       public NamingEnumeration<NameClassPair> list(String name)
  453           throws NamingException
  454       {
  455           return (getURLOrDefaultInitCtx(name).list(name));
  456       }
  457   
  458       public NamingEnumeration<NameClassPair> list(Name name)
  459           throws NamingException
  460       {
  461           return (getURLOrDefaultInitCtx(name).list(name));
  462       }
  463   
  464       public NamingEnumeration<Binding> listBindings(String name)
  465               throws NamingException  {
  466           return getURLOrDefaultInitCtx(name).listBindings(name);
  467       }
  468   
  469       public NamingEnumeration<Binding> listBindings(Name name)
  470               throws NamingException  {
  471           return getURLOrDefaultInitCtx(name).listBindings(name);
  472       }
  473   
  474       public void destroySubcontext(String name) throws NamingException  {
  475           getURLOrDefaultInitCtx(name).destroySubcontext(name);
  476       }
  477   
  478       public void destroySubcontext(Name name) throws NamingException  {
  479           getURLOrDefaultInitCtx(name).destroySubcontext(name);
  480       }
  481   
  482       public Context createSubcontext(String name) throws NamingException  {
  483           return getURLOrDefaultInitCtx(name).createSubcontext(name);
  484       }
  485   
  486       public Context createSubcontext(Name name) throws NamingException  {
  487           return getURLOrDefaultInitCtx(name).createSubcontext(name);
  488       }
  489   
  490       public Object lookupLink(String name) throws NamingException  {
  491           return getURLOrDefaultInitCtx(name).lookupLink(name);
  492       }
  493   
  494       public Object lookupLink(Name name) throws NamingException {
  495           return getURLOrDefaultInitCtx(name).lookupLink(name);
  496       }
  497   
  498       public NameParser getNameParser(String name) throws NamingException {
  499           return getURLOrDefaultInitCtx(name).getNameParser(name);
  500       }
  501   
  502       public NameParser getNameParser(Name name) throws NamingException {
  503           return getURLOrDefaultInitCtx(name).getNameParser(name);
  504       }
  505   
  506       /**
  507        * Composes the name of this context with a name relative to
  508        * this context.
  509        * Since an initial context may never be named relative
  510        * to any context other than itself, the value of the
  511        * <tt>prefix</tt> parameter must be an empty name (<tt>""</tt>).
  512        */
  513       public String composeName(String name, String prefix)
  514               throws NamingException {
  515           return name;
  516       }
  517   
  518       /**
  519        * Composes the name of this context with a name relative to
  520        * this context.
  521        * Since an initial context may never be named relative
  522        * to any context other than itself, the value of the
  523        * <tt>prefix</tt> parameter must be an empty name.
  524        */
  525       public Name composeName(Name name, Name prefix)
  526           throws NamingException
  527       {
  528           return (Name)name.clone();
  529       }
  530   
  531       public Object addToEnvironment(String propName, Object propVal)
  532               throws NamingException {
  533           myProps.put(propName, propVal);
  534           return getDefaultInitCtx().addToEnvironment(propName, propVal);
  535       }
  536   
  537       public Object removeFromEnvironment(String propName)
  538               throws NamingException {
  539           myProps.remove(propName);
  540           return getDefaultInitCtx().removeFromEnvironment(propName);
  541       }
  542   
  543       public Hashtable<?,?> getEnvironment() throws NamingException {
  544           return getDefaultInitCtx().getEnvironment();
  545       }
  546   
  547       public void close() throws NamingException {
  548           myProps = null;
  549           if (defaultInitCtx != null) {
  550               defaultInitCtx.close();
  551               defaultInitCtx = null;
  552           }
  553           gotDefault = false;
  554       }
  555   
  556       public String getNameInNamespace() throws NamingException {
  557           return getDefaultInitCtx().getNameInNamespace();
  558       }
  559   };

Home » openjdk-7 » javax » naming » [javadoc | source]