KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > naming > spi > NamingManager


1 /*
2  * @(#)NamingManager.java 1.21 04/07/16
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.naming.spi;
9
10 import java.util.Enumeration JavaDoc;
11 import java.util.Hashtable JavaDoc;
12 import java.util.StringTokenizer JavaDoc;
13 import java.net.MalformedURLException JavaDoc;
14
15 import javax.naming.*;
16 import com.sun.naming.internal.VersionHelper;
17 import com.sun.naming.internal.ResourceManager;
18 import com.sun.naming.internal.FactoryEnumeration;
19
20 /**
21  * This class contains methods for creating context objects
22  * and objects referred to by location information in the naming
23  * or directory service.
24  *<p>
25  * This class cannot be instantiated. It has only static methods.
26  *<p>
27  * The mention of URL in the documentation for this class refers to
28  * a URL string as defined by RFC 1738 and its related RFCs. It is
29  * any string that conforms to the syntax described therein, and
30  * may not always have corresponding support in the java.net.URL
31  * class or Web browsers.
32  *<p>
33  * NamingManager is safe for concurrent access by multiple threads.
34  *<p>
35  * Except as otherwise noted,
36  * a <tt>Name</tt> or environment parameter
37  * passed to any method is owned by the caller.
38  * The implementation will not modify the object or keep a reference
39  * to it, although it may keep a reference to a clone or copy.
40  *
41  * @author Rosanna Lee
42  * @author Scott Seligman
43  * @version 1.21 04/07/16
44  * @since 1.3
45  */

46
47 public class NamingManager {
48
49     /*
50      * Disallow anyone from creating one of these.
51      * Made package private so that DirectoryManager can subclass.
52      */

53
54     NamingManager() {}
55
56     // should be protected and package private
57
static final VersionHelper helper = VersionHelper.getVersionHelper();
58
59 // --------- object factory stuff
60

61     /**
62      * Package-private; used by DirectoryManager and NamingManager.
63      */

64     private static ObjectFactoryBuilder JavaDoc object_factory_builder = null;
65
66     /**
67      * The ObjectFactoryBuilder determines the policy used when
68      * trying to load object factories.
69      * See getObjectInstance() and class ObjectFactory for a description
70      * of the default policy.
71      * setObjectFactoryBuilder() overrides this default policy by installing
72      * an ObjectFactoryBuilder. Subsequent object factories will
73      * be loaded and created using the installed builder.
74      *<p>
75      * The builder can only be installed if the executing thread is allowed
76      * (by the security manager's checkSetFactory() method) to do so.
77      * Once installed, the builder cannot be replaced.
78      *<p>
79      * @param builder The factory builder to install. If null, no builder
80      * is installed.
81      * @exception SecurityException builder cannot be installed
82      * for security reasons.
83      * @exception NamingException builder cannot be installed for
84      * a non-security-related reason.
85      * @exception IllegalStateException If a factory has already been installed.
86      * @see #getObjectInstance
87      * @see ObjectFactory
88      * @see ObjectFactoryBuilder
89      * @see java.lang.SecurityManager#checkSetFactory
90      */

91     public static synchronized void setObjectFactoryBuilder(
92         ObjectFactoryBuilder JavaDoc builder) throws NamingException {
93     if (object_factory_builder != null)
94         throw new IllegalStateException JavaDoc("ObjectFactoryBuilder already set");
95
96     SecurityManager JavaDoc security = System.getSecurityManager();
97     if (security != null) {
98         security.checkSetFactory();
99     }
100     object_factory_builder = builder;
101     }
102
103     /**
104      * Used for accessing object factory builder.
105      */

106     static synchronized ObjectFactoryBuilder JavaDoc getObjectFactoryBuilder() {
107     return object_factory_builder;
108     }
109
110
111     /**
112      * Retrieves the ObjectFactory for the object identified by a reference,
113      * using the reference's factory class name and factory codebase
114      * to load in the factory's class.
115      * @param ref The non-null reference to use.
116      * @param factoryName The non-null class name of the factory.
117      * @return The object factory for the object identified by ref; null
118      * if unable to load the factory.
119      */

120     static ObjectFactory JavaDoc getObjectFactoryFromReference(
121     Reference ref, String JavaDoc factoryName)
122     throws IllegalAccessException JavaDoc,
123     InstantiationException JavaDoc,
124     MalformedURLException JavaDoc {
125     Class JavaDoc clas = null;
126
127     // Try to use current class loader
128
try {
129          clas = helper.loadClass(factoryName);
130     } catch (ClassNotFoundException JavaDoc e) {
131         // ignore and continue
132
// e.printStackTrace();
133
}
134     // All other exceptions are passed up.
135

136     // Not in class path; try to use codebase
137
String JavaDoc codebase;
138     if (clas == null &&
139         (codebase = ref.getFactoryClassLocation()) != null) {
140         try {
141         clas = helper.loadClass(factoryName, codebase);
142         } catch (ClassNotFoundException JavaDoc e) {
143         }
144     }
145
146     return (clas != null) ? (ObjectFactory JavaDoc) clas.newInstance() : null;
147     }
148
149
150     /**
151      * Creates an object using the factories specified in the
152      * <tt>Context.OBJECT_FACTORIES</tt> property of the environment
153      * or of the provider resource file associated with <tt>nameCtx</tt>.
154      *
155      * @return factory created; null if cannot create
156      */

157     private static Object JavaDoc createObjectFromFactories(Object JavaDoc obj, Name name,
158         Context nameCtx, Hashtable JavaDoc environment) throws Exception JavaDoc {
159
160         FactoryEnumeration factories = ResourceManager.getFactories(
161         Context.OBJECT_FACTORIES, environment, nameCtx);
162
163     if (factories == null)
164         return null;
165
166     // Try each factory until one succeeds
167
ObjectFactory JavaDoc factory;
168     Object JavaDoc answer = null;
169     while (answer == null && factories.hasMore()) {
170         factory = (ObjectFactory JavaDoc)factories.next();
171         answer = factory.getObjectInstance(obj, name, nameCtx, environment);
172     }
173     return answer;
174     }
175
176     private static String JavaDoc getURLScheme(String JavaDoc str) {
177     int colon_posn = str.indexOf(':');
178     int slash_posn = str.indexOf('/');
179
180     if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))
181         return str.substring(0, colon_posn);
182     return null;
183     }
184
185     /**
186      * Creates an instance of an object for the specified object
187      * and environment.
188      * <p>
189      * If an object factory builder has been installed, it is used to
190      * create a factory for creating the object.
191      * Otherwise, the following rules are used to create the object:
192      *<ol>
193      * <li>If <code>refInfo</code> is a <code>Reference</code>
194      * or <code>Referenceable</code> containing a factory class name,
195      * use the named factory to create the object.
196      * Return <code>refInfo</code> if the factory cannot be created.
197      * Under JDK 1.1, if the factory class must be loaded from a location
198      * specified in the reference, a <tt>SecurityManager</tt> must have
199      * been installed or the factory creation will fail.
200      * If an exception is encountered while creating the factory,
201      * it is passed up to the caller.
202      * <li>If <tt>refInfo</tt> is a <tt>Reference</tt> or
203      * <tt>Referenceable</tt> with no factory class name,
204      * and the address or addresses are <tt>StringRefAddr</tt>s with
205      * address type "URL",
206      * try the URL context factory corresponding to each URL's scheme id
207      * to create the object (see <tt>getURLContext()</tt>).
208      * If that fails, continue to the next step.
209      * <li> Use the object factories specified in
210      * the <tt>Context.OBJECT_FACTORIES</tt> property of the environment,
211      * and of the provider resource file associated with
212      * <tt>nameCtx</tt>, in that order.
213      * The value of this property is a colon-separated list of factory
214      * class names that are tried in order, and the first one that succeeds
215      * in creating an object is the one used.
216      * If none of the factories can be loaded,
217      * return <code>refInfo</code>.
218      * If an exception is encountered while creating the object, the
219      * exception is passed up to the caller.
220      *</ol>
221      *<p>
222      * Service providers that implement the <tt>DirContext</tt>
223      * interface should use
224      * <tt>DirectoryManager.getObjectInstance()</tt>, not this method.
225      * Service providers that implement only the <tt>Context</tt>
226      * interface should use this method.
227      * <p>
228      * Note that an object factory (an object that implements the ObjectFactory
229      * interface) must be public and must have a public constructor that
230      * accepts no arguments.
231      * <p>
232      * The <code>name</code> and <code>nameCtx</code> parameters may
233      * optionally be used to specify the name of the object being created.
234      * <code>name</code> is the name of the object, relative to context
235      * <code>nameCtx</code>. This information could be useful to the object
236      * factory or to the object implementation.
237      * If there are several possible contexts from which the object
238      * could be named -- as will often be the case -- it is up to
239      * the caller to select one. A good rule of thumb is to select the
240      * "deepest" context available.
241      * If <code>nameCtx</code> is null, <code>name</code> is relative
242      * to the default initial context. If no name is being specified, the
243      * <code>name</code> parameter should be null.
244      *
245      * @param refInfo The possibly null object for which to create an object.
246      * @param name The name of this object relative to <code>nameCtx</code>.
247      * Specifying a name is optional; if it is
248      * omitted, <code>name</code> should be null.
249      * @param nameCtx The context relative to which the <code>name</code>
250      * parameter is specified. If null, <code>name</code> is
251      * relative to the default initial context.
252      * @param environment The possibly null environment to
253      * be used in the creation of the object factory and the object.
254      * @return An object created using <code>refInfo</code>; or
255      * <code>refInfo</code> if an object cannot be created using
256      * the algorithm described above.
257      * @exception NamingException if a naming exception was encountered
258      * while attempting to get a URL context, or if one of the
259      * factories accessed throws a NamingException.
260      * @exception Exception if one of the factories accessed throws an
261      * exception, or if an error was encountered while loading
262      * and instantiating the factory and object classes.
263      * A factory should only throw an exception if it does not want
264      * other factories to be used in an attempt to create an object.
265      * See ObjectFactory.getObjectInstance().
266      * @see #getURLContext
267      * @see ObjectFactory
268      * @see ObjectFactory#getObjectInstance
269      */

270     public static Object JavaDoc
271     getObjectInstance(Object JavaDoc refInfo, Name name, Context nameCtx,
272               Hashtable JavaDoc<?,?> environment)
273     throws Exception JavaDoc
274     {
275
276     ObjectFactory JavaDoc factory;
277
278     // Use builder if installed
279
ObjectFactoryBuilder JavaDoc builder = getObjectFactoryBuilder();
280     if (builder != null) {
281         // builder must return non-null factory
282
factory = builder.createObjectFactory(refInfo, environment);
283         return factory.getObjectInstance(refInfo, name, nameCtx,
284         environment);
285     }
286
287     // Use reference if possible
288
Reference ref = null;
289     if (refInfo instanceof Reference) {
290         ref = (Reference) refInfo;
291     } else if (refInfo instanceof Referenceable) {
292         ref = ((Referenceable)(refInfo)).getReference();
293     }
294
295     Object JavaDoc answer;
296
297     if (ref != null) {
298         String JavaDoc f = ref.getFactoryClassName();
299         if (f != null) {
300         // if reference identifies a factory, use exclusively
301

302         factory = getObjectFactoryFromReference(ref, f);
303         if (factory != null) {
304             return factory.getObjectInstance(ref, name, nameCtx,
305                              environment);
306         }
307         // No factory found, so return original refInfo.
308
// Will reach this point if factory class is not in
309
// class path and reference does not contain a URL for it
310
return refInfo;
311
312         } else {
313         // if reference has no factory, check for addresses
314
// containing URLs
315

316         answer = processURLAddrs(ref, name, nameCtx, environment);
317         if (answer != null) {
318             return answer;
319         }
320         }
321     }
322
323     // try using any specified factories
324
answer =
325         createObjectFromFactories(refInfo, name, nameCtx, environment);
326     return (answer != null) ? answer : refInfo;
327     }
328
329     /*
330      * Ref has no factory. For each address of type "URL", try its URL
331      * context factory. Returns null if unsuccessful in creating and
332      * invoking a factory.
333      */

334     static Object JavaDoc processURLAddrs(Reference ref, Name name, Context nameCtx,
335                   Hashtable JavaDoc environment)
336         throws NamingException {
337
338     for (int i = 0; i < ref.size(); i++) {
339         RefAddr addr = ref.get(i);
340         if (addr instanceof StringRefAddr &&
341         addr.getType().equalsIgnoreCase("URL")) {
342
343         String JavaDoc url = (String JavaDoc)addr.getContent();
344         Object JavaDoc answer = processURL(url, name, nameCtx, environment);
345         if (answer != null) {
346             return answer;
347         }
348         }
349     }
350     return null;
351     }
352
353     private static Object JavaDoc processURL(Object JavaDoc refInfo, Name name,
354                      Context nameCtx, Hashtable JavaDoc environment)
355         throws NamingException {
356     Object JavaDoc answer;
357
358     // If refInfo is a URL string, try to use its URL context factory
359
// If no context found, continue to try object factories.
360
if (refInfo instanceof String JavaDoc) {
361         String JavaDoc url = (String JavaDoc)refInfo;
362         String JavaDoc scheme = getURLScheme(url);
363         if (scheme != null) {
364         answer = getURLObject(scheme, refInfo, name, nameCtx,
365                       environment);
366         if (answer != null) {
367             return answer;
368         }
369         }
370     }
371
372     // If refInfo is an array of URL strings,
373
// try to find a context factory for any one of its URLs.
374
// If no context found, continue to try object factories.
375
if (refInfo instanceof String JavaDoc[]) {
376         String JavaDoc[] urls = (String JavaDoc[])refInfo;
377         for (int i = 0; i <urls.length; i++) {
378         String JavaDoc scheme = getURLScheme(urls[i]);
379         if (scheme != null) {
380             answer = getURLObject(scheme, refInfo, name, nameCtx,
381                       environment);
382             if (answer != null)
383             return answer;
384         }
385         }
386     }
387     return null;
388     }
389
390
391     /**
392      * Retrieves a context identified by <code>obj</code>, using the specified
393      * environment.
394      * Used by ContinuationContext.
395      *
396      * @param obj The object identifying the context.
397      * @param name The name of the context being returned, relative to
398      * <code>nameCtx</code>, or null if no name is being
399      * specified.
400      * See the <code>getObjectInstance</code> method for
401      * details.
402      * @param ctx The context relative to which <code>name</code> is
403      * specified, or null for the default initial context.
404      * See the <code>getObjectInstance</code> method for
405      * details.
406      * @param environment Environment specifying characteristics of the
407      * resulting context.
408      * @return A context identified by <code>obj</code>.
409      *
410      * @see #getObjectInstance
411      */

412     static Context getContext(Object JavaDoc obj, Name name, Context nameCtx,
413                   Hashtable JavaDoc environment) throws NamingException {
414     Object JavaDoc answer;
415
416     if (obj instanceof Context) {
417         // %%% Ignore environment for now. OK since method not public.
418
return (Context)obj;
419     }
420
421     try {
422         answer = getObjectInstance(obj, name, nameCtx, environment);
423     } catch (NamingException e) {
424         throw e;
425     } catch (Exception JavaDoc e) {
426         NamingException ne = new NamingException();
427         ne.setRootCause(e);
428         throw ne;
429     }
430
431     return (answer instanceof Context)
432         ? (Context)answer
433         : null;
434     }
435
436     // Used by ContinuationContext
437
static Resolver JavaDoc getResolver(Object JavaDoc obj, Name name, Context nameCtx,
438                 Hashtable JavaDoc environment) throws NamingException {
439     Object JavaDoc answer;
440
441     if (obj instanceof Resolver JavaDoc) {
442         // %%% Ignore environment for now. OK since method not public.
443
return (Resolver JavaDoc)obj;
444     }
445
446     try {
447         answer = getObjectInstance(obj, name, nameCtx, environment);
448     } catch (NamingException e) {
449         throw e;
450     } catch (Exception JavaDoc e) {
451         NamingException ne = new NamingException();
452         ne.setRootCause(e);
453         throw ne;
454     }
455
456     return (answer instanceof Resolver JavaDoc)
457         ? (Resolver JavaDoc)answer
458         : null;
459     }
460
461
462     /***************** URL Context implementations ***************/
463
464     /**
465      * Creates a context for the given URL scheme id.
466      * <p>
467      * The resulting context is for resolving URLs of the
468      * scheme <code>scheme</code>. The resulting context is not tied
469      * to a specific URL. It is able to handle arbitrary URLs with
470      * the specified scheme.
471      *<p>
472      * The class name of the factory that creates the resulting context
473      * has the naming convention <i>scheme-id</i>URLContextFactory
474      * (e.g. "ftpURLContextFactory" for the "ftp" scheme-id),
475      * in the package specified as follows.
476      * The <tt>Context.URL_PKG_PREFIXES</tt> environment property (which
477      * may contain values taken from applet parameters, system properties,
478      * or application resource files)
479      * contains a colon-separated list of package prefixes.
480      * Each package prefix in
481      * the property is tried in the order specified to load the factory class.
482      * The default package prefix is "com.sun.jndi.url" (if none of the
483      * specified packages work, this default is tried).
484      * The complete package name is constructed using the package prefix,
485      * concatenated with the scheme id.
486      *<p>
487      * For example, if the scheme id is "ldap", and the
488      * <tt>Context.URL_PKG_PREFIXES</tt> property
489      * contains "com.widget:com.wiz.jndi",
490      * the naming manager would attempt to load the following classes
491      * until one is successfully instantiated:
492      *<ul>
493      * <li>com.widget.ldap.ldapURLContextFactory
494      * <li>com.wiz.jndi.ldap.ldapURLContextFactory
495      * <li>com.sun.jndi.url.ldap.ldapURLContextFactory
496      *</ul>
497      * If none of the package prefixes work, null is returned.
498      *<p>
499      * If a factory is instantiated, it is invoked with the following
500      * parameters to produce the resulting context.
501      * <p>
502      * <code>factory.getObjectInstance(null, environment);</code>
503      * <p>
504      * For example, invoking getObjectInstance() as shown above
505      * on a LDAP URL context factory would return a
506      * context that can resolve LDAP urls
507      * (e.g. "ldap://ldap.wiz.com/o=wiz,c=us",
508      * "ldap://ldap.umich.edu/o=umich,c=us", ...).
509      *<p>
510      * Note that an object factory (an object that implements the ObjectFactory
511      * interface) must be public and must have a public constructor that
512      * accepts no arguments.
513      *
514      * @param scheme The non-null scheme-id of the URLs supported by the context.
515      * @param environment The possibly null environment properties to be
516      * used in the creation of the object factory and the context.
517      * @return A context for resolving URLs with the
518      * scheme id <code>scheme</code>;
519      * <code>null</code> if the factory for creating the
520      * context is not found.
521      * @exception NamingException If a naming exception occurs while creating
522      * the context.
523      * @see #getObjectInstance
524      * @see ObjectFactory#getObjectInstance
525      */

526     public static Context getURLContext(String JavaDoc scheme,
527                     Hashtable JavaDoc<?,?> environment)
528     throws NamingException
529     {
530     // pass in 'null' to indicate creation of generic context for scheme
531
// (i.e. not specific to a URL).
532

533         Object JavaDoc answer = getURLObject(scheme, null, null, null, environment);
534         if (answer instanceof Context) {
535         return (Context)answer;
536         } else {
537         return null;
538         }
539     }
540
541     private static final String JavaDoc defaultPkgPrefix = "com.sun.jndi.url";
542
543     /**
544      * Creates an object for the given URL scheme id using
545      * the supplied urlInfo.
546      * <p>
547      * If urlInfo is null, the result is a context for resolving URLs
548      * with the scheme id 'scheme'.
549      * If urlInfo is a URL, the result is a context named by the URL.
550      * Names passed to this context is assumed to be relative to this
551      * context (i.e. not a URL). For example, if urlInfo is
552      * "ldap://ldap.wiz.com/o=Wiz,c=us", the resulting context will
553      * be that pointed to by "o=Wiz,c=us" on the server 'ldap.wiz.com'.
554      * Subsequent names that can be passed to this context will be
555      * LDAP names relative to this context (e.g. cn="Barbs Jensen").
556      * If urlInfo is an array of URLs, the URLs are assumed
557      * to be equivalent in terms of the context to which they refer.
558      * The resulting context is like that of the single URL case.
559      * If urlInfo is of any other type, that is handled by the
560      * context factory for the URL scheme.
561      * @param scheme the URL scheme id for the context
562      * @param urlInfo information used to create the context
563      * @param name name of this object relative to <code>nameCtx</code>
564      * @param nameCtx Context whose provider resource file will be searched
565      * for package prefix values (or null if none)
566      * @param environment Environment properties for creating the context
567      * @see javax.naming.InitialContext
568      */

569     private static Object JavaDoc getURLObject(String JavaDoc scheme, Object JavaDoc urlInfo,
570                        Name name, Context nameCtx,
571                        Hashtable JavaDoc environment)
572         throws NamingException {
573
574     // e.g. "ftpURLContextFactory"
575
ObjectFactory JavaDoc factory = (ObjectFactory JavaDoc)ResourceManager.getFactory(
576         Context.URL_PKG_PREFIXES, environment, nameCtx,
577         "." + scheme + "." + scheme + "URLContextFactory", defaultPkgPrefix);
578     
579     if (factory == null)
580       return null;
581
582     // Found object factory
583
try {
584         return factory.getObjectInstance(urlInfo, name, nameCtx, environment);
585     } catch (NamingException e) {
586         throw e;
587     } catch (Exception JavaDoc e) {
588         NamingException ne = new NamingException();
589         ne.setRootCause(e);
590         throw ne;
591     }
592
593     }
594
595
596 // ------------ Initial Context Factory Stuff
597
private static InitialContextFactoryBuilder JavaDoc initctx_factory_builder = null;
598
599     /**
600      * Use this method for accessing initctx_factory_builder while
601      * inside an unsynchronized method.
602      */

603     private static synchronized InitialContextFactoryBuilder JavaDoc
604     getInitialContextFactoryBuilder() {
605     return initctx_factory_builder;
606     }
607
608     /**
609      * Creates an initial context using the specified environment
610      * properties.
611      *<p>
612      * If an InitialContextFactoryBuilder has been installed,
613      * it is used to create the factory for creating the initial context.
614      * Otherwise, the class specified in the
615      * <tt>Context.INITIAL_CONTEXT_FACTORY</tt> environment property is used.
616      * Note that an initial context factory (an object that implements the
617      * InitialContextFactory interface) must be public and must have a
618      * public constructor that accepts no arguments.
619      *
620      * @param env The possibly null environment properties used when
621      * creating the context.
622      * @return A non-null initial context.
623      * @exception NoInitialContextException If the
624      * <tt>Context.INITIAL_CONTEXT_FACTORY</tt> property
625      * is not found or names a nonexistent
626      * class or a class that cannot be instantiated,
627      * or if the initial context could not be created for some other
628      * reason.
629      * @exception NamingException If some other naming exception was encountered.
630      * @see javax.naming.InitialContext
631      * @see javax.naming.directory.InitialDirContext
632      */

633     public static Context getInitialContext(Hashtable JavaDoc<?,?> env)
634     throws NamingException {
635     InitialContextFactory JavaDoc factory;
636
637     InitialContextFactoryBuilder JavaDoc builder = getInitialContextFactoryBuilder();
638     if (builder == null) {
639         // No factory installed, use property
640
// Get initial context factory class name
641

642         String JavaDoc className = env != null ?
643             (String JavaDoc)env.get(Context.INITIAL_CONTEXT_FACTORY) : null;
644         if (className == null) {
645         NoInitialContextException ne = new NoInitialContextException(
646             "Need to specify class name in environment or system " +
647             "property, or as an applet parameter, or in an " +
648             "application resource file: " +
649             Context.INITIAL_CONTEXT_FACTORY);
650         throw ne;
651         }
652
653         try {
654         factory = (InitialContextFactory JavaDoc)
655             helper.loadClass(className).newInstance();
656         } catch(Exception JavaDoc e) {
657         NoInitialContextException ne =
658             new NoInitialContextException(
659             "Cannot instantiate class: " + className);
660         ne.setRootCause(e);
661         throw ne;
662         }
663     } else {
664         factory = builder.createInitialContextFactory(env);
665     }
666
667     return factory.getInitialContext(env);
668     }
669
670
671     /**
672      * Sets the InitialContextFactory builder to be builder.
673      *
674      *<p>
675      * The builder can only be installed if the executing thread is allowed by
676      * the security manager to do so. Once installed, the builder cannot
677      * be replaced.
678      * @param builder The initial context factory builder to install. If null,
679      * no builder is set.
680      * @exception SecurityException builder cannot be installed for security
681      * reasons.
682      * @exception NamingException builder cannot be installed for
683      * a non-security-related reason.
684      * @exception IllegalStateException If a builder was previous installed.
685      * @see #hasInitialContextFactoryBuilder
686      * @see java.lang.SecurityManager#checkSetFactory
687      */

688     public static synchronized void setInitialContextFactoryBuilder(
689     InitialContextFactoryBuilder JavaDoc builder)
690     throws NamingException {
691         if (initctx_factory_builder != null)
692         throw new IllegalStateException JavaDoc(
693             "InitialContextFactoryBuilder already set");
694
695         SecurityManager JavaDoc security = System.getSecurityManager();
696         if (security != null) {
697         security.checkSetFactory();
698         }
699         initctx_factory_builder = builder;
700     }
701
702     /**
703      * Determines whether an initial context factory builder has
704      * been set.
705      * @return true if an initial context factory builder has
706      * been set; false otherwise.
707      * @see #setInitialContextFactoryBuilder
708      */

709     public static boolean hasInitialContextFactoryBuilder() {
710     return (getInitialContextFactoryBuilder() != null);
711     }
712
713 // ----- Continuation Context Stuff
714

715     /**
716      * Constant that holds the name of the environment property into
717      * which <tt>getContinuationContext()</tt> stores the value of its
718      * <tt>CannotProceedException</tt> parameter.
719      * This property is inherited by the continuation context, and may
720      * be used by that context's service provider to inspect the
721      * fields of the exception.
722      *<p>
723      * The value of this constant is "java.naming.spi.CannotProceedException".
724      *
725      * @see #getContinuationContext
726      * @since 1.3
727      */

728     public static final String JavaDoc CPE = "java.naming.spi.CannotProceedException";
729
730     /**
731      * Creates a context in which to continue a context operation.
732      *<p>
733      * In performing an operation on a name that spans multiple
734      * namespaces, a context from one naming system may need to pass
735      * the operation on to the next naming system. The context
736      * implementation does this by first constructing a
737      * <code>CannotProceedException</code> containing information
738      * pinpointing how far it has proceeded. It then obtains a
739      * continuation context from JNDI by calling
740      * <code>getContinuationContext</code>. The context
741      * implementation should then resume the context operation by
742      * invoking the same operation on the continuation context, using
743      * the remainder of the name that has not yet been resolved.
744      *<p>
745      * Before making use of the <tt>cpe</tt> parameter, this method
746      * updates the environment associated with that object by setting
747      * the value of the property <a HREF="#CPE"><tt>CPE</tt></a>
748      * to <tt>cpe</tt>. This property will be inherited by the
749      * continuation context, and may be used by that context's
750      * service provider to inspect the fields of this exception.
751      *
752      * @param cpe
753      * The non-null exception that triggered this continuation.
754      * @return A non-null Context object for continuing the operation.
755      * @exception NamingException If a naming exception occurred.
756      */

757     public static Context getContinuationContext(CannotProceedException cpe)
758         throws NamingException {
759
760     Hashtable JavaDoc env = cpe.getEnvironment();
761         if (env == null) {
762             env = new Hashtable JavaDoc(7);
763         } else {
764             // Make a (shallow) copy of the environment.
765
env = (Hashtable JavaDoc) env.clone();
766         }
767     env.put(CPE, cpe);
768
769     ContinuationContext JavaDoc cctx = new ContinuationContext JavaDoc(cpe, env);
770     return cctx.getTargetContext();
771     }
772
773 // ------------ State Factory Stuff
774

775     /**
776      * Retrieves the state of an object for binding.
777      * <p>
778      * Service providers that implement the <tt>DirContext</tt> interface
779      * should use <tt>DirectoryManager.getStateToBind()</tt>, not this method.
780      * Service providers that implement only the <tt>Context</tt> interface
781      * should use this method.
782      *<p>
783      * This method uses the specified state factories in
784      * the <tt>Context.STATE_FACTORIES</tt> property from the environment
785      * properties, and from the provider resource file associated with
786      * <tt>nameCtx</tt>, in that order.
787      * The value of this property is a colon-separated list of factory
788      * class names that are tried in order, and the first one that succeeds
789      * in returning the object's state is the one used.
790      * If no object's state can be retrieved in this way, return the
791      * object itself.
792      * If an exception is encountered while retrieving the state, the
793      * exception is passed up to the caller.
794      * <p>
795      * Note that a state factory
796      * (an object that implements the StateFactory
797      * interface) must be public and must have a public constructor that
798      * accepts no arguments.
799      * <p>
800      * The <code>name</code> and <code>nameCtx</code> parameters may
801      * optionally be used to specify the name of the object being created.
802      * See the description of "Name and Context Parameters" in
803      * {@link ObjectFactory#getObjectInstance
804      * ObjectFactory.getObjectInstance()}
805      * for details.
806      * <p>
807      * This method may return a <tt>Referenceable</tt> object. The
808      * service provider obtaining this object may choose to store it
809      * directly, or to extract its reference (using
810      * <tt>Referenceable.getReference()</tt>) and store that instead.
811      *
812      * @param obj The non-null object for which to get state to bind.
813      * @param name The name of this object relative to <code>nameCtx</code>,
814      * or null if no name is specified.
815      * @param nameCtx The context relative to which the <code>name</code>
816      * parameter is specified, or null if <code>name</code> is
817      * relative to the default initial context.
818      * @param environment The possibly null environment to
819      * be used in the creation of the state factory and
820      * the object's state.
821      * @return The non-null object representing <tt>obj</tt>'s state for
822      * binding. It could be the object (<tt>obj</tt>) itself.
823      * @exception NamingException If one of the factories accessed throws an
824      * exception, or if an error was encountered while loading
825      * and instantiating the factory and object classes.
826      * A factory should only throw an exception if it does not want
827      * other factories to be used in an attempt to create an object.
828      * See <tt>StateFactory.getStateToBind()</tt>.
829      * @see StateFactory
830      * @see StateFactory#getStateToBind
831      * @see DirectoryManager#getStateToBind
832      * @since 1.3
833      */

834     public static Object JavaDoc
835     getStateToBind(Object JavaDoc obj, Name name, Context nameCtx,
836                Hashtable JavaDoc<?,?> environment)
837     throws NamingException
838     {
839
840     FactoryEnumeration factories = ResourceManager.getFactories(
841         Context.STATE_FACTORIES, environment, nameCtx);
842
843     if (factories == null) {
844         return obj;
845     }
846
847     // Try each factory until one succeeds
848
StateFactory JavaDoc factory;
849     Object JavaDoc answer = null;
850     while (answer == null && factories.hasMore()) {
851         factory = (StateFactory JavaDoc)factories.next();
852         answer = factory.getStateToBind(obj, name, nameCtx, environment);
853     }
854
855     return (answer != null) ? answer : obj;
856     }
857 }
858
Popular Tags