122 */
123 static synchronized ObjectFactoryBuilder getObjectFactoryBuilder() {
124 return object_factory_builder;
125 }
126
127
128 /**
129 * Retrieves the ObjectFactory for the object identified by a reference,
130 * using the reference's factory class name and factory codebase
131 * to load in the factory's class.
132 * @param ref The non-null reference to use.
133 * @param factoryName The non-null class name of the factory.
134 * @return The object factory for the object identified by ref; null
135 * if unable to load the factory.
136 */
137 static ObjectFactory getObjectFactoryFromReference(
138 Reference ref, String factoryName)
139 throws IllegalAccessException,
140 InstantiationException,
141 MalformedURLException {
142 Class clas = null;
143
144 // Try to use current class loader
145 try {
146 clas = helper.loadClass(factoryName);
147 } catch (ClassNotFoundException e) {
148 // ignore and continue
149 // e.printStackTrace();
150 }
151 // All other exceptions are passed up.
152
153 // Not in class path; try to use codebase
154 String codebase;
155 if (clas == null &&
156 (codebase = ref.getFactoryClassLocation()) != null) {
157 try {
158 clas = helper.loadClass(factoryName, codebase);
159 } catch (ClassNotFoundException e) {
160 }
161 }
162
163 return (clas != null) ? (ObjectFactory) clas.newInstance() : null;
164 }
165
166
167 /**
168 * Creates an object using the factories specified in the
169 * <tt>Context.OBJECT_FACTORIES</tt> property of the environment
170 * or of the provider resource file associated with <tt>nameCtx</tt>.
171 *
172 * @return factory created; null if cannot create
173 */
174 private static Object createObjectFromFactories(Object obj, Name name,
175 Context nameCtx, Hashtable environment) throws Exception {
176
177 FactoryEnumeration factories = ResourceManager.getFactories(
178 Context.OBJECT_FACTORIES, environment, nameCtx);
179
180 if (factories == null)
181 return null;
182
183 // Try each factory until one succeeds
184 ObjectFactory factory;
185 Object answer = null;
186 while (answer == null && factories.hasMore()) {
187 factory = (ObjectFactory)factories.next();
188 answer = factory.getObjectInstance(obj, name, nameCtx, environment);
189 }
190 return answer;
191 }
192
193 private static String getURLScheme(String str) {
194 int colon_posn = str.indexOf(':');
195 int slash_posn = str.indexOf('/');
332
333 answer = processURLAddrs(ref, name, nameCtx, environment);
334 if (answer != null) {
335 return answer;
336 }
337 }
338 }
339
340 // try using any specified factories
341 answer =
342 createObjectFromFactories(refInfo, name, nameCtx, environment);
343 return (answer != null) ? answer : refInfo;
344 }
345
346 /*
347 * Ref has no factory. For each address of type "URL", try its URL
348 * context factory. Returns null if unsuccessful in creating and
349 * invoking a factory.
350 */
351 static Object processURLAddrs(Reference ref, Name name, Context nameCtx,
352 Hashtable environment)
353 throws NamingException {
354
355 for (int i = 0; i < ref.size(); i++) {
356 RefAddr addr = ref.get(i);
357 if (addr instanceof StringRefAddr &&
358 addr.getType().equalsIgnoreCase("URL")) {
359
360 String url = (String)addr.getContent();
361 Object answer = processURL(url, name, nameCtx, environment);
362 if (answer != null) {
363 return answer;
364 }
365 }
366 }
367 return null;
368 }
369
370 private static Object processURL(Object refInfo, Name name,
371 Context nameCtx, Hashtable environment)
372 throws NamingException {
373 Object answer;
374
375 // If refInfo is a URL string, try to use its URL context factory
376 // If no context found, continue to try object factories.
377 if (refInfo instanceof String) {
378 String url = (String)refInfo;
379 String scheme = getURLScheme(url);
380 if (scheme != null) {
381 answer = getURLObject(scheme, refInfo, name, nameCtx,
382 environment);
383 if (answer != null) {
384 return answer;
385 }
386 }
387 }
388
389 // If refInfo is an array of URL strings,
390 // try to find a context factory for any one of its URLs.
391 // If no context found, continue to try object factories.
410 * environment.
411 * Used by ContinuationContext.
412 *
413 * @param obj The object identifying the context.
414 * @param name The name of the context being returned, relative to
415 * <code>nameCtx</code>, or null if no name is being
416 * specified.
417 * See the <code>getObjectInstance</code> method for
418 * details.
419 * @param ctx The context relative to which <code>name</code> is
420 * specified, or null for the default initial context.
421 * See the <code>getObjectInstance</code> method for
422 * details.
423 * @param environment Environment specifying characteristics of the
424 * resulting context.
425 * @return A context identified by <code>obj</code>.
426 *
427 * @see #getObjectInstance
428 */
429 static Context getContext(Object obj, Name name, Context nameCtx,
430 Hashtable environment) throws NamingException {
431 Object answer;
432
433 if (obj instanceof Context) {
434 // %%% Ignore environment for now. OK since method not public.
435 return (Context)obj;
436 }
437
438 try {
439 answer = getObjectInstance(obj, name, nameCtx, environment);
440 } catch (NamingException e) {
441 throw e;
442 } catch (Exception e) {
443 NamingException ne = new NamingException();
444 ne.setRootCause(e);
445 throw ne;
446 }
447
448 return (answer instanceof Context)
449 ? (Context)answer
450 : null;
451 }
452
453 // Used by ContinuationContext
454 static Resolver getResolver(Object obj, Name name, Context nameCtx,
455 Hashtable environment) throws NamingException {
456 Object answer;
457
458 if (obj instanceof Resolver) {
459 // %%% Ignore environment for now. OK since method not public.
460 return (Resolver)obj;
461 }
462
463 try {
464 answer = getObjectInstance(obj, name, nameCtx, environment);
465 } catch (NamingException e) {
466 throw e;
467 } catch (Exception e) {
468 NamingException ne = new NamingException();
469 ne.setRootCause(e);
470 throw ne;
471 }
472
473 return (answer instanceof Resolver)
474 ? (Resolver)answer
475 : null;
568 * context (i.e. not a URL). For example, if urlInfo is
569 * "ldap://ldap.wiz.com/o=Wiz,c=us", the resulting context will
570 * be that pointed to by "o=Wiz,c=us" on the server 'ldap.wiz.com'.
571 * Subsequent names that can be passed to this context will be
572 * LDAP names relative to this context (e.g. cn="Barbs Jensen").
573 * If urlInfo is an array of URLs, the URLs are assumed
574 * to be equivalent in terms of the context to which they refer.
575 * The resulting context is like that of the single URL case.
576 * If urlInfo is of any other type, that is handled by the
577 * context factory for the URL scheme.
578 * @param scheme the URL scheme id for the context
579 * @param urlInfo information used to create the context
580 * @param name name of this object relative to <code>nameCtx</code>
581 * @param nameCtx Context whose provider resource file will be searched
582 * for package prefix values (or null if none)
583 * @param environment Environment properties for creating the context
584 * @see javax.naming.InitialContext
585 */
586 private static Object getURLObject(String scheme, Object urlInfo,
587 Name name, Context nameCtx,
588 Hashtable environment)
589 throws NamingException {
590
591 // e.g. "ftpURLContextFactory"
592 ObjectFactory factory = (ObjectFactory)ResourceManager.getFactory(
593 Context.URL_PKG_PREFIXES, environment, nameCtx,
594 "." + scheme + "." + scheme + "URLContextFactory", defaultPkgPrefix);
595
596 if (factory == null)
597 return null;
598
599 // Found object factory
600 try {
601 return factory.getObjectInstance(urlInfo, name, nameCtx, environment);
602 } catch (NamingException e) {
603 throw e;
604 } catch (Exception e) {
605 NamingException ne = new NamingException();
606 ne.setRootCause(e);
607 throw ne;
608 }
754 * <code>CannotProceedException</code> containing information
755 * pinpointing how far it has proceeded. It then obtains a
756 * continuation context from JNDI by calling
757 * <code>getContinuationContext</code>. The context
758 * implementation should then resume the context operation by
759 * invoking the same operation on the continuation context, using
760 * the remainder of the name that has not yet been resolved.
761 *<p>
762 * Before making use of the <tt>cpe</tt> parameter, this method
763 * updates the environment associated with that object by setting
764 * the value of the property <a href="#CPE"><tt>CPE</tt></a>
765 * to <tt>cpe</tt>. This property will be inherited by the
766 * continuation context, and may be used by that context's
767 * service provider to inspect the fields of this exception.
768 *
769 * @param cpe
770 * The non-null exception that triggered this continuation.
771 * @return A non-null Context object for continuing the operation.
772 * @exception NamingException If a naming exception occurred.
773 */
774 public static Context getContinuationContext(CannotProceedException cpe)
775 throws NamingException {
776
777 Hashtable env = cpe.getEnvironment();
778 if (env == null) {
779 env = new Hashtable(7);
780 } else {
781 // Make a (shallow) copy of the environment.
782 env = (Hashtable) env.clone();
783 }
784 env.put(CPE, cpe);
785
786 ContinuationContext cctx = new ContinuationContext(cpe, env);
787 return cctx.getTargetContext();
788 }
789
790 // ------------ State Factory Stuff
791
792 /**
793 * Retrieves the state of an object for binding.
794 * <p>
795 * Service providers that implement the <tt>DirContext</tt> interface
796 * should use <tt>DirectoryManager.getStateToBind()</tt>, not this method.
797 * Service providers that implement only the <tt>Context</tt> interface
798 * should use this method.
799 *<p>
800 * This method uses the specified state factories in
801 * the <tt>Context.STATE_FACTORIES</tt> property from the environment
802 * properties, and from the provider resource file associated with
|
122 */
123 static synchronized ObjectFactoryBuilder getObjectFactoryBuilder() {
124 return object_factory_builder;
125 }
126
127
128 /**
129 * Retrieves the ObjectFactory for the object identified by a reference,
130 * using the reference's factory class name and factory codebase
131 * to load in the factory's class.
132 * @param ref The non-null reference to use.
133 * @param factoryName The non-null class name of the factory.
134 * @return The object factory for the object identified by ref; null
135 * if unable to load the factory.
136 */
137 static ObjectFactory getObjectFactoryFromReference(
138 Reference ref, String factoryName)
139 throws IllegalAccessException,
140 InstantiationException,
141 MalformedURLException {
142 Class<?> clas = null;
143
144 // Try to use current class loader
145 try {
146 clas = helper.loadClass(factoryName);
147 } catch (ClassNotFoundException e) {
148 // ignore and continue
149 // e.printStackTrace();
150 }
151 // All other exceptions are passed up.
152
153 // Not in class path; try to use codebase
154 String codebase;
155 if (clas == null &&
156 (codebase = ref.getFactoryClassLocation()) != null) {
157 try {
158 clas = helper.loadClass(factoryName, codebase);
159 } catch (ClassNotFoundException e) {
160 }
161 }
162
163 return (clas != null) ? (ObjectFactory) clas.newInstance() : null;
164 }
165
166
167 /**
168 * Creates an object using the factories specified in the
169 * <tt>Context.OBJECT_FACTORIES</tt> property of the environment
170 * or of the provider resource file associated with <tt>nameCtx</tt>.
171 *
172 * @return factory created; null if cannot create
173 */
174 private static Object createObjectFromFactories(Object obj, Name name,
175 Context nameCtx, Hashtable<?,?> environment) throws Exception {
176
177 FactoryEnumeration factories = ResourceManager.getFactories(
178 Context.OBJECT_FACTORIES, environment, nameCtx);
179
180 if (factories == null)
181 return null;
182
183 // Try each factory until one succeeds
184 ObjectFactory factory;
185 Object answer = null;
186 while (answer == null && factories.hasMore()) {
187 factory = (ObjectFactory)factories.next();
188 answer = factory.getObjectInstance(obj, name, nameCtx, environment);
189 }
190 return answer;
191 }
192
193 private static String getURLScheme(String str) {
194 int colon_posn = str.indexOf(':');
195 int slash_posn = str.indexOf('/');
332
333 answer = processURLAddrs(ref, name, nameCtx, environment);
334 if (answer != null) {
335 return answer;
336 }
337 }
338 }
339
340 // try using any specified factories
341 answer =
342 createObjectFromFactories(refInfo, name, nameCtx, environment);
343 return (answer != null) ? answer : refInfo;
344 }
345
346 /*
347 * Ref has no factory. For each address of type "URL", try its URL
348 * context factory. Returns null if unsuccessful in creating and
349 * invoking a factory.
350 */
351 static Object processURLAddrs(Reference ref, Name name, Context nameCtx,
352 Hashtable<?,?> environment)
353 throws NamingException {
354
355 for (int i = 0; i < ref.size(); i++) {
356 RefAddr addr = ref.get(i);
357 if (addr instanceof StringRefAddr &&
358 addr.getType().equalsIgnoreCase("URL")) {
359
360 String url = (String)addr.getContent();
361 Object answer = processURL(url, name, nameCtx, environment);
362 if (answer != null) {
363 return answer;
364 }
365 }
366 }
367 return null;
368 }
369
370 private static Object processURL(Object refInfo, Name name,
371 Context nameCtx, Hashtable<?,?> environment)
372 throws NamingException {
373 Object answer;
374
375 // If refInfo is a URL string, try to use its URL context factory
376 // If no context found, continue to try object factories.
377 if (refInfo instanceof String) {
378 String url = (String)refInfo;
379 String scheme = getURLScheme(url);
380 if (scheme != null) {
381 answer = getURLObject(scheme, refInfo, name, nameCtx,
382 environment);
383 if (answer != null) {
384 return answer;
385 }
386 }
387 }
388
389 // If refInfo is an array of URL strings,
390 // try to find a context factory for any one of its URLs.
391 // If no context found, continue to try object factories.
410 * environment.
411 * Used by ContinuationContext.
412 *
413 * @param obj The object identifying the context.
414 * @param name The name of the context being returned, relative to
415 * <code>nameCtx</code>, or null if no name is being
416 * specified.
417 * See the <code>getObjectInstance</code> method for
418 * details.
419 * @param ctx The context relative to which <code>name</code> is
420 * specified, or null for the default initial context.
421 * See the <code>getObjectInstance</code> method for
422 * details.
423 * @param environment Environment specifying characteristics of the
424 * resulting context.
425 * @return A context identified by <code>obj</code>.
426 *
427 * @see #getObjectInstance
428 */
429 static Context getContext(Object obj, Name name, Context nameCtx,
430 Hashtable<?,?> environment) throws NamingException {
431 Object answer;
432
433 if (obj instanceof Context) {
434 // %%% Ignore environment for now. OK since method not public.
435 return (Context)obj;
436 }
437
438 try {
439 answer = getObjectInstance(obj, name, nameCtx, environment);
440 } catch (NamingException e) {
441 throw e;
442 } catch (Exception e) {
443 NamingException ne = new NamingException();
444 ne.setRootCause(e);
445 throw ne;
446 }
447
448 return (answer instanceof Context)
449 ? (Context)answer
450 : null;
451 }
452
453 // Used by ContinuationContext
454 static Resolver getResolver(Object obj, Name name, Context nameCtx,
455 Hashtable<?,?> environment) throws NamingException {
456 Object answer;
457
458 if (obj instanceof Resolver) {
459 // %%% Ignore environment for now. OK since method not public.
460 return (Resolver)obj;
461 }
462
463 try {
464 answer = getObjectInstance(obj, name, nameCtx, environment);
465 } catch (NamingException e) {
466 throw e;
467 } catch (Exception e) {
468 NamingException ne = new NamingException();
469 ne.setRootCause(e);
470 throw ne;
471 }
472
473 return (answer instanceof Resolver)
474 ? (Resolver)answer
475 : null;
568 * context (i.e. not a URL). For example, if urlInfo is
569 * "ldap://ldap.wiz.com/o=Wiz,c=us", the resulting context will
570 * be that pointed to by "o=Wiz,c=us" on the server 'ldap.wiz.com'.
571 * Subsequent names that can be passed to this context will be
572 * LDAP names relative to this context (e.g. cn="Barbs Jensen").
573 * If urlInfo is an array of URLs, the URLs are assumed
574 * to be equivalent in terms of the context to which they refer.
575 * The resulting context is like that of the single URL case.
576 * If urlInfo is of any other type, that is handled by the
577 * context factory for the URL scheme.
578 * @param scheme the URL scheme id for the context
579 * @param urlInfo information used to create the context
580 * @param name name of this object relative to <code>nameCtx</code>
581 * @param nameCtx Context whose provider resource file will be searched
582 * for package prefix values (or null if none)
583 * @param environment Environment properties for creating the context
584 * @see javax.naming.InitialContext
585 */
586 private static Object getURLObject(String scheme, Object urlInfo,
587 Name name, Context nameCtx,
588 Hashtable<?,?> environment)
589 throws NamingException {
590
591 // e.g. "ftpURLContextFactory"
592 ObjectFactory factory = (ObjectFactory)ResourceManager.getFactory(
593 Context.URL_PKG_PREFIXES, environment, nameCtx,
594 "." + scheme + "." + scheme + "URLContextFactory", defaultPkgPrefix);
595
596 if (factory == null)
597 return null;
598
599 // Found object factory
600 try {
601 return factory.getObjectInstance(urlInfo, name, nameCtx, environment);
602 } catch (NamingException e) {
603 throw e;
604 } catch (Exception e) {
605 NamingException ne = new NamingException();
606 ne.setRootCause(e);
607 throw ne;
608 }
754 * <code>CannotProceedException</code> containing information
755 * pinpointing how far it has proceeded. It then obtains a
756 * continuation context from JNDI by calling
757 * <code>getContinuationContext</code>. The context
758 * implementation should then resume the context operation by
759 * invoking the same operation on the continuation context, using
760 * the remainder of the name that has not yet been resolved.
761 *<p>
762 * Before making use of the <tt>cpe</tt> parameter, this method
763 * updates the environment associated with that object by setting
764 * the value of the property <a href="#CPE"><tt>CPE</tt></a>
765 * to <tt>cpe</tt>. This property will be inherited by the
766 * continuation context, and may be used by that context's
767 * service provider to inspect the fields of this exception.
768 *
769 * @param cpe
770 * The non-null exception that triggered this continuation.
771 * @return A non-null Context object for continuing the operation.
772 * @exception NamingException If a naming exception occurred.
773 */
774 @SuppressWarnings("unchecked")
775 public static Context getContinuationContext(CannotProceedException cpe)
776 throws NamingException {
777
778 Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment();
779 if (env == null) {
780 env = new Hashtable<>(7);
781 } else {
782 // Make a (shallow) copy of the environment.
783 env = (Hashtable<Object,Object>)env.clone();
784 }
785 env.put(CPE, cpe);
786
787 ContinuationContext cctx = new ContinuationContext(cpe, env);
788 return cctx.getTargetContext();
789 }
790
791 // ------------ State Factory Stuff
792
793 /**
794 * Retrieves the state of an object for binding.
795 * <p>
796 * Service providers that implement the <tt>DirContext</tt> interface
797 * should use <tt>DirectoryManager.getStateToBind()</tt>, not this method.
798 * Service providers that implement only the <tt>Context</tt> interface
799 * should use this method.
800 *<p>
801 * This method uses the specified state factories in
802 * the <tt>Context.STATE_FACTORIES</tt> property from the environment
803 * properties, and from the provider resource file associated with
|