/** * Creates an instance of an object for the specified object and environment. * * <p>If an object factory builder has been installed, it is used to create a factory for creating * the object. Otherwise, the following rules are used to create the object: * * <ol> * <li>If <code>refInfo</code> is a <code>Reference</code> or <code>Referenceable</code> * containing a factory class name, use the named factory to create the object. Return * <code>refInfo</code> if the factory cannot be created. Under JDK 1.1, if the factory * class must be loaded from a location specified in the reference, a * <tt>SecurityManager</tt> must have been installed or the factory creation will fail. If * an exception is encountered while creating the factory, it is passed up to the caller. * <li>If <tt>refInfo</tt> is a <tt>Reference</tt> or <tt>Referenceable</tt> with no factory * class name, and the address or addresses are <tt>StringRefAddr</tt>s with address type * "URL", try the URL context factory corresponding to each URL's scheme id to create the * object (see <tt>getURLContext()</tt>). If that fails, continue to the next step. * <li>Use the object factories specified in the <tt>Context.OBJECT_FACTORIES</tt> property of * the environment, and of the provider resource file associated with <tt>nameCtx</tt>, in * that order. The value of this property is a colon-separated list of factory class names * that are tried in order, and the first one that succeeds in creating an object is the one * used. If none of the factories can be loaded, return <code>refInfo</code>. If an * exception is encountered while creating the object, the exception is passed up to the * caller. * </ol> * * <p>Service providers that implement the <tt>DirContext</tt> interface should use * <tt>DirectoryManager.getObjectInstance()</tt>, not this method. Service providers that * implement only the <tt>Context</tt> interface should use this method. * * <p>Note that an object factory (an object that implements the ObjectFactory interface) must be * public and must have a public constructor that accepts no arguments. * * <p>The <code>name</code> and <code>nameCtx</code> parameters may optionally be used to specify * the name of the object being created. <code>name</code> is the name of the object, relative to * context <code>nameCtx</code>. This information could be useful to the object factory or to the * object implementation. If there are several possible contexts from which the object could be * named -- as will often be the case -- it is up to the caller to select one. A good rule of * thumb is to select the "deepest" context available. If <code>nameCtx</code> is null, <code>name * </code> is relative to the default initial context. If no name is being specified, the <code> * name</code> parameter should be null. * * @param refInfo The possibly null object for which to create an object. * @param name The name of this object relative to <code>nameCtx</code>. Specifying a name is * optional; if it is omitted, <code>name</code> should be null. * @param nameCtx The context relative to which the <code>name</code> parameter is specified. If * null, <code>name</code> is relative to the default initial context. * @param environment The possibly null environment to be used in the creation of the object * factory and the object. * @return An object created using <code>refInfo</code>; or <code>refInfo</code> if an object * cannot be created using the algorithm described above. * @exception NamingException if a naming exception was encountered while attempting to get a URL * context, or if one of the factories accessed throws a NamingException. * @exception Exception if one of the factories accessed throws an exception, or if an error was * encountered while loading and instantiating the factory and object classes. A factory * should only throw an exception if it does not want other factories to be used in an attempt * to create an object. See ObjectFactory.getObjectInstance(). * @see #getURLContext * @see ObjectFactory * @see ObjectFactory#getObjectInstance */ public static Object getObjectInstance( Object refInfo, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { ObjectFactory factory; // Use builder if installed ObjectFactoryBuilder builder = getObjectFactoryBuilder(); if (builder != null) { // builder must return non-null factory factory = builder.createObjectFactory(refInfo, environment); return factory.getObjectInstance(refInfo, name, nameCtx, environment); } // Use reference if possible Reference ref = null; if (refInfo instanceof Reference) { ref = (Reference) refInfo; } else if (refInfo instanceof Referenceable) { ref = ((Referenceable) (refInfo)).getReference(); } Object answer; if (ref != null) { String f = ref.getFactoryClassName(); if (f != null) { // if reference identifies a factory, use exclusively factory = getObjectFactoryFromReference(ref, f); if (factory != null) { return factory.getObjectInstance(ref, name, nameCtx, environment); } // No factory found, so return original refInfo. // Will reach this point if factory class is not in // class path and reference does not contain a URL for it return refInfo; } else { // if reference has no factory, check for addresses // containing URLs answer = processURLAddrs(ref, name, nameCtx, environment); if (answer != null) { return answer; } } } // try using any specified factories answer = createObjectFromFactories(refInfo, name, nameCtx, environment); return (answer != null) ? answer : refInfo; }
/** * Creates an object for the given URL scheme id using the supplied urlInfo. * * <p>If urlInfo is null, the result is a context for resolving URLs with the scheme id 'scheme'. * If urlInfo is a URL, the result is a context named by the URL. Names passed to this context is * assumed to be relative to this context (i.e. not a URL). For example, if urlInfo is * "ldap://ldap.wiz.com/o=Wiz,c=us", the resulting context will be that pointed to by "o=Wiz,c=us" * on the server 'ldap.wiz.com'. Subsequent names that can be passed to this context will be LDAP * names relative to this context (e.g. cn="Barbs Jensen"). If urlInfo is an array of URLs, the * URLs are assumed to be equivalent in terms of the context to which they refer. The resulting * context is like that of the single URL case. If urlInfo is of any other type, that is handled * by the context factory for the URL scheme. * * @param scheme the URL scheme id for the context * @param urlInfo information used to create the context * @param name name of this object relative to <code>nameCtx</code> * @param nameCtx Context whose provider resource file will be searched for package prefix values * (or null if none) * @param environment Environment properties for creating the context * @see javax.naming.InitialContext */ private static Object getURLObject( String scheme, Object urlInfo, Name name, Context nameCtx, Hashtable<?, ?> environment) throws NamingException { // e.g. "ftpURLContextFactory" ObjectFactory factory = (ObjectFactory) ResourceManager.getFactory( Context.URL_PKG_PREFIXES, environment, nameCtx, "." + scheme + "." + scheme + "URLContextFactory", defaultPkgPrefix); if (factory == null) return null; // Found object factory try { return factory.getObjectInstance(urlInfo, name, nameCtx, environment); } catch (NamingException e) { throw e; } catch (Exception e) { NamingException ne = new NamingException(); ne.setRootCause(e); throw ne; } }
/** * Creates an object using the factories specified in the <tt>Context.OBJECT_FACTORIES</tt> * property of the environment or of the provider resource file associated with <tt>nameCtx</tt>. * * @return factory created; null if cannot create */ private static Object createObjectFromFactories( Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { FactoryEnumeration factories = ResourceManager.getFactories(Context.OBJECT_FACTORIES, environment, nameCtx); if (factories == null) return null; // Try each factory until one succeeds ObjectFactory factory; Object answer = null; while (answer == null && factories.hasMore()) { factory = (ObjectFactory) factories.next(); answer = factory.getObjectInstance(obj, name, nameCtx, environment); } return answer; }