337 lines · 14.3 KB · Java
RawDownload
/* * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.naming.spi; import java.util.Hashtable; import javax.naming.Context;import javax.naming.Name;import javax.naming.Reference;import javax.naming.Referenceable;import javax.naming.NamingException;import javax.naming.CannotProceedException;import javax.naming.directory.DirContext;import javax.naming.directory.Attributes; import com.sun.naming.internal.ResourceManager;import com.sun.naming.internal.FactoryEnumeration;  /**  * This class contains methods for supporting <tt>DirContext</tt>  * implementations.  *<p>  * This class is an extension of <tt>NamingManager</tt>.  It contains methods  * for use by service providers for accessing object factories and  * state factories, and for getting continuation contexts for  * supporting federation.  *<p>  * <tt>DirectoryManager</tt> is safe for concurrent access by multiple threads.  *<p>  * Except as otherwise noted,  * a <tt>Name</tt>, <tt>Attributes</tt>, or environment parameter  * passed to any method is owned by the caller.  * The implementation will not modify the object or keep a reference  * to it, although it may keep a reference to a clone or copy.  *  * @author Rosanna Lee  * @author Scott Seligman  *  * @see DirObjectFactory  * @see DirStateFactory  * @since 1.3  */ public class DirectoryManager extends NamingManager {     /*     * Disallow anyone from creating one of these.     */    DirectoryManager() {}     /**      * Creates a context in which to continue a <tt>DirContext</tt> operation.      * Operates just like <tt>NamingManager.getContinuationContext()</tt>,      * only the continuation context returned is a <tt>DirContext</tt>.      *      * @param cpe      *         The non-null exception that triggered this continuation.      * @return A non-null <tt>DirContext</tt> object for continuing the operation.      * @exception NamingException If a naming exception occurred.      *      * @see NamingManager#getContinuationContext(CannotProceedException)      */    public static DirContext getContinuationDirContext(            CannotProceedException cpe) throws NamingException {         Hashtable env = cpe.getEnvironment();        if (env == null) {            env = new Hashtable(7);        } else {            // Make a (shallow) copy of the environment.            env = (Hashtable) env.clone();        }        env.put(CPE, cpe);         return (new ContinuationDirContext(cpe, env));    }     /**      * Creates an instance of an object for the specified object,      * attributes, and environment.      * <p>      * This method is the same as <tt>NamingManager.getObjectInstance</tt>      * except for the following differences:      *<ul>      *<li>      * It accepts an <tt>Attributes</tt> parameter that contains attributes      * associated with the object. The <tt>DirObjectFactory</tt> might use these      * attributes to save having to look them up from the directory.      *<li>      * The object factories tried must implement either      * <tt>ObjectFactory</tt> or <tt>DirObjectFactory</tt>.      * If it implements <tt>DirObjectFactory</tt>,      * <tt>DirObjectFactory.getObjectInstance()</tt> is used, otherwise,      * <tt>ObjectFactory.getObjectInstance()</tt> is used.      *</ul>      * Service providers that implement the <tt>DirContext</tt> interface      * should use this method, not <tt>NamingManager.getObjectInstance()</tt>.      *<p>      *      * @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.      * @param attrs The possibly null attributes associated with refInfo.      *         This might not be the complete set of attributes for refInfo;      *         you might be able to read more attributes from the directory.      * @return An object created using <code>refInfo</code> and <tt>attrs</tt>; or      *         <code>refInfo</code> if an object cannot be created by      *         a factory.      * @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 <tt>DirObjectFactory.getObjectInstance()</tt>.      * @see NamingManager#getURLContext      * @see DirObjectFactory      * @see DirObjectFactory#getObjectInstance      * @since 1.3      */    public static Object        getObjectInstance(Object refInfo, Name name, Context nameCtx,                          Hashtable<?,?> environment, Attributes attrs)        throws Exception {             ObjectFactory factory;             ObjectFactoryBuilder builder = getObjectFactoryBuilder();            if (builder != null) {                // builder must return non-null factory                factory = builder.createObjectFactory(refInfo, environment);                if (factory instanceof DirObjectFactory) {                    return ((DirObjectFactory)factory).getObjectInstance(                        refInfo, name, nameCtx, environment, attrs);                } else {                    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 instanceof DirObjectFactory) {                        return ((DirObjectFactory)factory).getObjectInstance(                            ref, name, nameCtx, environment, attrs);                    } else 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                    // ignore name & attrs params; not used in URL factory                     answer = processURLAddrs(ref, name, nameCtx, environment);                    if (answer != null) {                        return answer;                    }                }            }             // try using any specified factories            answer = createObjectFromFactories(refInfo, name, nameCtx,                                               environment, attrs);            return (answer != null) ? answer : refInfo;    }     private static Object createObjectFromFactories(Object obj, Name name,            Context nameCtx, Hashtable environment, Attributes attrs)        throws Exception {         FactoryEnumeration factories = ResourceManager.getFactories(            Context.OBJECT_FACTORIES, environment, nameCtx);         if (factories == null)            return null;         ObjectFactory factory;        Object answer = null;        // Try each factory until one succeeds        while (answer == null && factories.hasMore()) {            factory = (ObjectFactory)factories.next();            if (factory instanceof DirObjectFactory) {                answer = ((DirObjectFactory)factory).                    getObjectInstance(obj, name, nameCtx, environment, attrs);            } else {                answer =                    factory.getObjectInstance(obj, name, nameCtx, environment);            }        }        return answer;    }     /**      * Retrieves the state of an object for binding when given the original      * object and its attributes.      * <p>      * This method is like <tt>NamingManager.getStateToBind</tt> except      * for the following differences:      *<ul>      *<li>It accepts an <tt>Attributes</tt> parameter containing attributes      *    that were passed to the <tt>DirContext.bind()</tt> method.      *<li>It returns a non-null <tt>DirStateFactory.Result</tt> instance      *    containing the object to be bound, and the attributes to      *    accompany the binding. Either the object or the attributes may be null.      *<li>      * The state factories tried must each implement either      * <tt>StateFactory</tt> or <tt>DirStateFactory</tt>.      * If it implements <tt>DirStateFactory</tt>, then      * <tt>DirStateFactory.getStateToBind()</tt> is called; otherwise,      * <tt>StateFactory.getStateToBind()</tt> is called.      *</ul>      *      * Service providers that implement the <tt>DirContext</tt> interface      * should use this method, not <tt>NamingManager.getStateToBind()</tt>.      *<p>      * See NamingManager.getStateToBind() for a description of how      * the list of state factories to be tried is determined.      *<p>      * The object returned by this method is owned by the caller.      * The implementation will not subsequently modify it.      * It will contain either a new <tt>Attributes</tt> object that is      * likewise owned by the caller, or a reference to the original      * <tt>attrs</tt> parameter.      *      * @param obj The non-null object for which to get state to bind.      * @param name The name of this object relative to <code>nameCtx</code>,      *         or null if no name is specified.      * @param nameCtx The context relative to which the <code>name</code>      *         parameter is specified, or null if <code>name</code> is      *         relative to the default initial context.      * @param environment The possibly null environment to      *         be used in the creation of the state factory and      *         the object's state.      * @param attrs The possibly null Attributes that is to be bound with the      *         object.      * @return A non-null DirStateFactory.Result containing      *  the object and attributes to be bound.      *  If no state factory returns a non-null answer, the result will contain      *  the object (<tt>obj</tt>) itself with the original attributes.      * @exception NamingException If a naming exception was encountered      *         while using the factories.      *         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 <tt>DirStateFactory.getStateToBind()</tt>.      * @see DirStateFactory      * @see DirStateFactory#getStateToBind      * @see NamingManager#getStateToBind      * @since 1.3      */    public static DirStateFactory.Result        getStateToBind(Object obj, Name name, Context nameCtx,                       Hashtable<?,?> environment, Attributes attrs)        throws NamingException {         // Get list of state factories        FactoryEnumeration factories = ResourceManager.getFactories(            Context.STATE_FACTORIES, environment, nameCtx);         if (factories == null) {            // no factories to try; just return originals            return new DirStateFactory.Result(obj, attrs);        }         // Try each factory until one succeeds        StateFactory factory;        Object objanswer;        DirStateFactory.Result answer = null;        while (answer == null && factories.hasMore()) {            factory = (StateFactory)factories.next();            if (factory instanceof DirStateFactory) {                answer = ((DirStateFactory)factory).                    getStateToBind(obj, name, nameCtx, environment, attrs);            } else {                objanswer =                    factory.getStateToBind(obj, name, nameCtx, environment);                if (objanswer != null) {                    answer = new DirStateFactory.Result(objanswer, attrs);                }            }        }         return (answer != null) ? answer :            new DirStateFactory.Result(obj, attrs); // nothing new    }}