Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/naming/InitialContext.java
38829 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.naming;2627import java.util.Hashtable;28import javax.naming.spi.NamingManager;29import com.sun.naming.internal.ResourceManager;3031/**32* This class is the starting context for performing naming operations.33*<p>34* All naming operations are relative to a context.35* The initial context implements the Context interface and36* provides the starting point for resolution of names.37*<p>38* <a name=ENVIRONMENT></a>39* When the initial context is constructed, its environment40* is initialized with properties defined in the environment parameter41* passed to the constructor, and in any42* <a href=Context.html#RESOURCEFILES>application resource files</a>.43* In addition, a small number of standard JNDI properties may44* be specified as system properties or as applet parameters45* (through the use of {@link Context#APPLET}).46* These special properties are listed in the field detail sections of the47* <a href=Context.html#field_detail><tt>Context</tt></a> and48* <a href=ldap/LdapContext.html#field_detail><tt>LdapContext</tt></a>49* interface documentation.50*<p>51* JNDI determines each property's value by merging52* the values from the following two sources, in order:53* <ol>54* <li>55* The first occurrence of the property from the constructor's56* environment parameter and (for appropriate properties) the applet57* parameters and system properties.58* <li>59* The application resource files (<tt>jndi.properties</tt>).60* </ol>61* For each property found in both of these two sources, or in62* more than one application resource file, the property's value63* is determined as follows. If the property is64* one of the standard JNDI properties that specify a list of JNDI65* factories (see <a href=Context.html#LISTPROPS><tt>Context</tt></a>),66* all of the values are67* concatenated into a single colon-separated list. For other68* properties, only the first value found is used.69*70*<p>71* The initial context implementation is determined at runtime.72* The default policy uses the environment property73* "{@link Context#INITIAL_CONTEXT_FACTORY java.naming.factory.initial}",74* which contains the class name of the initial context factory.75* An exception to this policy is made when resolving URL strings, as described76* below.77*<p>78* When a URL string (a <tt>String</tt> of the form79* <em>scheme_id:rest_of_name</em>) is passed as a name parameter to80* any method, a URL context factory for handling that scheme is81* located and used to resolve the URL. If no such factory is found,82* the initial context specified by83* <tt>"java.naming.factory.initial"</tt> is used. Similarly, when a84* <tt>CompositeName</tt> object whose first component is a URL string is85* passed as a name parameter to any method, a URL context factory is86* located and used to resolve the first name component.87* See {@link NamingManager#getURLContext88* <tt>NamingManager.getURLContext()</tt>} for a description of how URL89* context factories are located.90*<p>91* This default policy of locating the initial context and URL context92* factories may be overridden93* by calling94* <tt>NamingManager.setInitialContextFactoryBuilder()</tt>.95*<p>96* NoInitialContextException is thrown when an initial context cannot97* be instantiated. This exception can be thrown during any interaction98* with the InitialContext, not only when the InitialContext is constructed.99* For example, the implementation of the initial context might lazily100* retrieve the context only when actual methods are invoked on it.101* The application should not have any dependency on when the existence102* of an initial context is determined.103*<p>104* When the environment property "java.naming.factory.initial" is105* non-null, the InitialContext constructor will attempt to create the106* initial context specified therein. At that time, the initial context factory107* involved might throw an exception if a problem is encountered. However,108* it is provider implementation-dependent when it verifies and indicates109* to the users of the initial context any environment property- or110* connection- related problems. It can do so lazily--delaying until111* an operation is performed on the context, or eagerly, at the time112* the context is constructed.113*<p>114* An InitialContext instance is not synchronized against concurrent115* access by multiple threads. Multiple threads each manipulating a116* different InitialContext instance need not synchronize.117* Threads that need to access a single InitialContext instance118* concurrently should synchronize amongst themselves and provide the119* necessary locking.120*121* @author Rosanna Lee122* @author Scott Seligman123*124* @see Context125* @see NamingManager#setInitialContextFactoryBuilder126* NamingManager.setInitialContextFactoryBuilder127* @since JNDI 1.1 / Java 2 Platform, Standard Edition, v 1.3128*/129130public class InitialContext implements Context {131132/**133* The environment associated with this InitialContext.134* It is initialized to null and is updated by the constructor135* that accepts an environment or by the <tt>init()</tt> method.136* @see #addToEnvironment137* @see #removeFromEnvironment138* @see #getEnvironment139*/140protected Hashtable<Object,Object> myProps = null;141142/**143* Field holding the result of calling NamingManager.getInitialContext().144* It is set by getDefaultInitCtx() the first time getDefaultInitCtx()145* is called. Subsequent invocations of getDefaultInitCtx() return146* the value of defaultInitCtx.147* @see #getDefaultInitCtx148*/149protected Context defaultInitCtx = null;150151/**152* Field indicating whether the initial context has been obtained153* by calling NamingManager.getInitialContext().154* If true, its result is in <code>defaultInitCtx</code>.155*/156protected boolean gotDefault = false;157158/**159* Constructs an initial context with the option of not160* initializing it. This may be used by a constructor in161* a subclass when the value of the environment parameter162* is not yet known at the time the <tt>InitialContext</tt>163* constructor is called. The subclass's constructor will164* call this constructor, compute the value of the environment,165* and then call <tt>init()</tt> before returning.166*167* @param lazy168* true means do not initialize the initial context; false169* is equivalent to calling <tt>new InitialContext()</tt>170* @throws NamingException if a naming exception is encountered171*172* @see #init(Hashtable)173* @since 1.3174*/175protected InitialContext(boolean lazy) throws NamingException {176if (!lazy) {177init(null);178}179}180181/**182* Constructs an initial context.183* No environment properties are supplied.184* Equivalent to <tt>new InitialContext(null)</tt>.185*186* @throws NamingException if a naming exception is encountered187*188* @see #InitialContext(Hashtable)189*/190public InitialContext() throws NamingException {191init(null);192}193194/**195* Constructs an initial context using the supplied environment.196* Environment properties are discussed in the class description.197*198* <p> This constructor will not modify <tt>environment</tt>199* or save a reference to it, but may save a clone.200* Caller should not modify mutable keys and values in201* <tt>environment</tt> after it has been passed to the constructor.202*203* @param environment204* environment used to create the initial context.205* Null indicates an empty environment.206*207* @throws NamingException if a naming exception is encountered208*/209public InitialContext(Hashtable<?,?> environment)210throws NamingException211{212if (environment != null) {213environment = (Hashtable)environment.clone();214}215init(environment);216}217218/**219* Initializes the initial context using the supplied environment.220* Environment properties are discussed in the class description.221*222* <p> This method will modify <tt>environment</tt> and save223* a reference to it. The caller may no longer modify it.224*225* @param environment226* environment used to create the initial context.227* Null indicates an empty environment.228*229* @throws NamingException if a naming exception is encountered230*231* @see #InitialContext(boolean)232* @since 1.3233*/234@SuppressWarnings("unchecked")235protected void init(Hashtable<?,?> environment)236throws NamingException237{238myProps = (Hashtable<Object,Object>)239ResourceManager.getInitialEnvironment(environment);240241if (myProps.get(Context.INITIAL_CONTEXT_FACTORY) != null) {242// user has specified initial context factory; try to get it243getDefaultInitCtx();244}245}246247/**248* A static method to retrieve the named object.249* This is a shortcut method equivalent to invoking:250* <p>251* <code>252* InitialContext ic = new InitialContext();253* Object obj = ic.lookup();254* </code>255* <p> If <tt>name</tt> is empty, returns a new instance of this context256* (which represents the same naming context as this context, but its257* environment may be modified independently and it may be accessed258* concurrently).259*260* @param <T> the type of the returned object261* @param name262* the name of the object to look up263* @return the object bound to <tt>name</tt>264* @throws NamingException if a naming exception is encountered265*266* @see #doLookup(String)267* @see #lookup(Name)268* @since 1.6269*/270@SuppressWarnings("unchecked")271public static <T> T doLookup(Name name)272throws NamingException {273return (T) (new InitialContext()).lookup(name);274}275276/**277* A static method to retrieve the named object.278* See {@link #doLookup(Name)} for details.279* @param <T> the type of the returned object280* @param name281* the name of the object to look up282* @return the object bound to <tt>name</tt>283* @throws NamingException if a naming exception is encountered284* @since 1.6285*/286@SuppressWarnings("unchecked")287public static <T> T doLookup(String name)288throws NamingException {289return (T) (new InitialContext()).lookup(name);290}291292private static String getURLScheme(String str) {293int colon_posn = str.indexOf(':');294int slash_posn = str.indexOf('/');295296if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))297return str.substring(0, colon_posn);298return null;299}300301/**302* Retrieves the initial context by calling303* <code>NamingManager.getInitialContext()</code>304* and cache it in defaultInitCtx.305* Set <code>gotDefault</code> so that we know we've tried this before.306* @return The non-null cached initial context.307* @exception NoInitialContextException If cannot find an initial context.308* @exception NamingException If a naming exception was encountered.309*/310protected Context getDefaultInitCtx() throws NamingException{311if (!gotDefault) {312defaultInitCtx = NamingManager.getInitialContext(myProps);313gotDefault = true;314}315if (defaultInitCtx == null)316throw new NoInitialContextException();317318return defaultInitCtx;319}320321/**322* Retrieves a context for resolving the string name <code>name</code>.323* If <code>name</code> name is a URL string, then attempt324* to find a URL context for it. If none is found, or if325* <code>name</code> is not a URL string, then return326* <code>getDefaultInitCtx()</code>.327*<p>328* See getURLOrDefaultInitCtx(Name) for description329* of how a subclass should use this method.330* @param name The non-null name for which to get the context.331* @return A URL context for <code>name</code> or the cached332* initial context. The result cannot be null.333* @exception NoInitialContextException If cannot find an initial context.334* @exception NamingException In a naming exception is encountered.335* @see javax.naming.spi.NamingManager#getURLContext336*/337protected Context getURLOrDefaultInitCtx(String name)338throws NamingException {339if (NamingManager.hasInitialContextFactoryBuilder()) {340return getDefaultInitCtx();341}342String scheme = getURLScheme(name);343if (scheme != null) {344Context ctx = NamingManager.getURLContext(scheme, myProps);345if (ctx != null) {346return ctx;347}348}349return getDefaultInitCtx();350}351352/**353* Retrieves a context for resolving <code>name</code>.354* If the first component of <code>name</code> name is a URL string,355* then attempt to find a URL context for it. If none is found, or if356* the first component of <code>name</code> is not a URL string,357* then return <code>getDefaultInitCtx()</code>.358*<p>359* When creating a subclass of InitialContext, use this method as360* follows.361* Define a new method that uses this method to get an initial362* context of the desired subclass.363* <blockquote><pre>364* protected XXXContext getURLOrDefaultInitXXXCtx(Name name)365* throws NamingException {366* Context answer = getURLOrDefaultInitCtx(name);367* if (!(answer instanceof XXXContext)) {368* if (answer == null) {369* throw new NoInitialContextException();370* } else {371* throw new NotContextException("Not an XXXContext");372* }373* }374* return (XXXContext)answer;375* }376* </pre></blockquote>377* When providing implementations for the new methods in the subclass,378* use this newly defined method to get the initial context.379* <blockquote><pre>380* public Object XXXMethod1(Name name, ...) {381* throws NamingException {382* return getURLOrDefaultInitXXXCtx(name).XXXMethod1(name, ...);383* }384* </pre></blockquote>385*386* @param name The non-null name for which to get the context.387* @return A URL context for <code>name</code> or the cached388* initial context. The result cannot be null.389* @exception NoInitialContextException If cannot find an initial context.390* @exception NamingException In a naming exception is encountered.391*392* @see javax.naming.spi.NamingManager#getURLContext393*/394protected Context getURLOrDefaultInitCtx(Name name)395throws NamingException {396if (NamingManager.hasInitialContextFactoryBuilder()) {397return getDefaultInitCtx();398}399if (name.size() > 0) {400String first = name.get(0);401String scheme = getURLScheme(first);402if (scheme != null) {403Context ctx = NamingManager.getURLContext(scheme, myProps);404if (ctx != null) {405return ctx;406}407}408}409return getDefaultInitCtx();410}411412// Context methods413// Most Javadoc is deferred to the Context interface.414415public Object lookup(String name) throws NamingException {416return getURLOrDefaultInitCtx(name).lookup(name);417}418419public Object lookup(Name name) throws NamingException {420return getURLOrDefaultInitCtx(name).lookup(name);421}422423public void bind(String name, Object obj) throws NamingException {424getURLOrDefaultInitCtx(name).bind(name, obj);425}426427public void bind(Name name, Object obj) throws NamingException {428getURLOrDefaultInitCtx(name).bind(name, obj);429}430431public void rebind(String name, Object obj) throws NamingException {432getURLOrDefaultInitCtx(name).rebind(name, obj);433}434435public void rebind(Name name, Object obj) throws NamingException {436getURLOrDefaultInitCtx(name).rebind(name, obj);437}438439public void unbind(String name) throws NamingException {440getURLOrDefaultInitCtx(name).unbind(name);441}442443public void unbind(Name name) throws NamingException {444getURLOrDefaultInitCtx(name).unbind(name);445}446447public void rename(String oldName, String newName) throws NamingException {448getURLOrDefaultInitCtx(oldName).rename(oldName, newName);449}450451public void rename(Name oldName, Name newName)452throws NamingException453{454getURLOrDefaultInitCtx(oldName).rename(oldName, newName);455}456457public NamingEnumeration<NameClassPair> list(String name)458throws NamingException459{460return (getURLOrDefaultInitCtx(name).list(name));461}462463public NamingEnumeration<NameClassPair> list(Name name)464throws NamingException465{466return (getURLOrDefaultInitCtx(name).list(name));467}468469public NamingEnumeration<Binding> listBindings(String name)470throws NamingException {471return getURLOrDefaultInitCtx(name).listBindings(name);472}473474public NamingEnumeration<Binding> listBindings(Name name)475throws NamingException {476return getURLOrDefaultInitCtx(name).listBindings(name);477}478479public void destroySubcontext(String name) throws NamingException {480getURLOrDefaultInitCtx(name).destroySubcontext(name);481}482483public void destroySubcontext(Name name) throws NamingException {484getURLOrDefaultInitCtx(name).destroySubcontext(name);485}486487public Context createSubcontext(String name) throws NamingException {488return getURLOrDefaultInitCtx(name).createSubcontext(name);489}490491public Context createSubcontext(Name name) throws NamingException {492return getURLOrDefaultInitCtx(name).createSubcontext(name);493}494495public Object lookupLink(String name) throws NamingException {496return getURLOrDefaultInitCtx(name).lookupLink(name);497}498499public Object lookupLink(Name name) throws NamingException {500return getURLOrDefaultInitCtx(name).lookupLink(name);501}502503public NameParser getNameParser(String name) throws NamingException {504return getURLOrDefaultInitCtx(name).getNameParser(name);505}506507public NameParser getNameParser(Name name) throws NamingException {508return getURLOrDefaultInitCtx(name).getNameParser(name);509}510511/**512* Composes the name of this context with a name relative to513* this context.514* Since an initial context may never be named relative515* to any context other than itself, the value of the516* <tt>prefix</tt> parameter must be an empty name (<tt>""</tt>).517*/518public String composeName(String name, String prefix)519throws NamingException {520return name;521}522523/**524* Composes the name of this context with a name relative to525* this context.526* Since an initial context may never be named relative527* to any context other than itself, the value of the528* <tt>prefix</tt> parameter must be an empty name.529*/530public Name composeName(Name name, Name prefix)531throws NamingException532{533return (Name)name.clone();534}535536public Object addToEnvironment(String propName, Object propVal)537throws NamingException {538myProps.put(propName, propVal);539return getDefaultInitCtx().addToEnvironment(propName, propVal);540}541542public Object removeFromEnvironment(String propName)543throws NamingException {544myProps.remove(propName);545return getDefaultInitCtx().removeFromEnvironment(propName);546}547548public Hashtable<?,?> getEnvironment() throws NamingException {549return getDefaultInitCtx().getEnvironment();550}551552public void close() throws NamingException {553myProps = null;554if (defaultInitCtx != null) {555defaultInitCtx.close();556defaultInitCtx = null;557}558gotDefault = false;559}560561public String getNameInNamespace() throws NamingException {562return getDefaultInitCtx().getNameInNamespace();563}564};565566567