Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/naming/spi/DirectoryManager.java
38918 views
/*1* Copyright (c) 1999, 2011, 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.spi;2627import java.util.Hashtable;2829import javax.naming.Context;30import javax.naming.Name;31import javax.naming.Reference;32import javax.naming.Referenceable;33import javax.naming.NamingException;34import javax.naming.CannotProceedException;35import javax.naming.directory.DirContext;36import javax.naming.directory.Attributes;3738import com.sun.naming.internal.ResourceManager;39import com.sun.naming.internal.FactoryEnumeration;404142/**43* This class contains methods for supporting <tt>DirContext</tt>44* implementations.45*<p>46* This class is an extension of <tt>NamingManager</tt>. It contains methods47* for use by service providers for accessing object factories and48* state factories, and for getting continuation contexts for49* supporting federation.50*<p>51* <tt>DirectoryManager</tt> is safe for concurrent access by multiple threads.52*<p>53* Except as otherwise noted,54* a <tt>Name</tt>, <tt>Attributes</tt>, or environment parameter55* passed to any method is owned by the caller.56* The implementation will not modify the object or keep a reference57* to it, although it may keep a reference to a clone or copy.58*59* @author Rosanna Lee60* @author Scott Seligman61*62* @see DirObjectFactory63* @see DirStateFactory64* @since 1.365*/6667public class DirectoryManager extends NamingManager {6869/*70* Disallow anyone from creating one of these.71*/72DirectoryManager() {}7374/**75* Creates a context in which to continue a <tt>DirContext</tt> operation.76* Operates just like <tt>NamingManager.getContinuationContext()</tt>,77* only the continuation context returned is a <tt>DirContext</tt>.78*79* @param cpe80* The non-null exception that triggered this continuation.81* @return A non-null <tt>DirContext</tt> object for continuing the operation.82* @exception NamingException If a naming exception occurred.83*84* @see NamingManager#getContinuationContext(CannotProceedException)85*/86@SuppressWarnings("unchecked")87public static DirContext getContinuationDirContext(88CannotProceedException cpe) throws NamingException {8990Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment();91if (env == null) {92env = new Hashtable<>(7);93} else {94// Make a (shallow) copy of the environment.95env = (Hashtable<Object,Object>) env.clone();96}97env.put(CPE, cpe);9899return (new ContinuationDirContext(cpe, env));100}101102/**103* Creates an instance of an object for the specified object,104* attributes, and environment.105* <p>106* This method is the same as <tt>NamingManager.getObjectInstance</tt>107* except for the following differences:108*<ul>109*<li>110* It accepts an <tt>Attributes</tt> parameter that contains attributes111* associated with the object. The <tt>DirObjectFactory</tt> might use these112* attributes to save having to look them up from the directory.113*<li>114* The object factories tried must implement either115* <tt>ObjectFactory</tt> or <tt>DirObjectFactory</tt>.116* If it implements <tt>DirObjectFactory</tt>,117* <tt>DirObjectFactory.getObjectInstance()</tt> is used, otherwise,118* <tt>ObjectFactory.getObjectInstance()</tt> is used.119*</ul>120* Service providers that implement the <tt>DirContext</tt> interface121* should use this method, not <tt>NamingManager.getObjectInstance()</tt>.122*<p>123*124* @param refInfo The possibly null object for which to create an object.125* @param name The name of this object relative to <code>nameCtx</code>.126* Specifying a name is optional; if it is127* omitted, <code>name</code> should be null.128* @param nameCtx The context relative to which the <code>name</code>129* parameter is specified. If null, <code>name</code> is130* relative to the default initial context.131* @param environment The possibly null environment to132* be used in the creation of the object factory and the object.133* @param attrs The possibly null attributes associated with refInfo.134* This might not be the complete set of attributes for refInfo;135* you might be able to read more attributes from the directory.136* @return An object created using <code>refInfo</code> and <tt>attrs</tt>; or137* <code>refInfo</code> if an object cannot be created by138* a factory.139* @exception NamingException If a naming exception was encountered140* while attempting to get a URL context, or if one of the141* factories accessed throws a NamingException.142* @exception Exception If one of the factories accessed throws an143* exception, or if an error was encountered while loading144* and instantiating the factory and object classes.145* A factory should only throw an exception if it does not want146* other factories to be used in an attempt to create an object.147* See <tt>DirObjectFactory.getObjectInstance()</tt>.148* @see NamingManager#getURLContext149* @see DirObjectFactory150* @see DirObjectFactory#getObjectInstance151* @since 1.3152*/153public static Object154getObjectInstance(Object refInfo, Name name, Context nameCtx,155Hashtable<?,?> environment, Attributes attrs)156throws Exception {157158ObjectFactory factory;159160ObjectFactoryBuilder builder = getObjectFactoryBuilder();161if (builder != null) {162// builder must return non-null factory163factory = builder.createObjectFactory(refInfo, environment);164if (factory instanceof DirObjectFactory) {165return ((DirObjectFactory)factory).getObjectInstance(166refInfo, name, nameCtx, environment, attrs);167} else {168return factory.getObjectInstance(refInfo, name, nameCtx,169environment);170}171}172173// use reference if possible174Reference ref = null;175if (refInfo instanceof Reference) {176ref = (Reference) refInfo;177} else if (refInfo instanceof Referenceable) {178ref = ((Referenceable)(refInfo)).getReference();179}180181Object answer;182183if (ref != null) {184String f = ref.getFactoryClassName();185if (f != null) {186// if reference identifies a factory, use exclusively187188factory = getObjectFactoryFromReference(ref, f);189if (factory instanceof DirObjectFactory) {190return ((DirObjectFactory)factory).getObjectInstance(191ref, name, nameCtx, environment, attrs);192} else if (factory != null) {193return factory.getObjectInstance(ref, name, nameCtx,194environment);195}196// No factory found, so return original refInfo.197// Will reach this point if factory class is not in198// class path and reference does not contain a URL for it199return refInfo;200201} else {202// if reference has no factory, check for addresses203// containing URLs204// ignore name & attrs params; not used in URL factory205206answer = processURLAddrs(ref, name, nameCtx, environment);207if (answer != null) {208return answer;209}210}211}212213// try using any specified factories214answer = createObjectFromFactories(refInfo, name, nameCtx,215environment, attrs);216return (answer != null) ? answer : refInfo;217}218219private static Object createObjectFromFactories(Object obj, Name name,220Context nameCtx, Hashtable<?,?> environment, Attributes attrs)221throws Exception {222223FactoryEnumeration factories = ResourceManager.getFactories(224Context.OBJECT_FACTORIES, environment, nameCtx);225226if (factories == null)227return null;228229ObjectFactory factory;230Object answer = null;231// Try each factory until one succeeds232while (answer == null && factories.hasMore()) {233factory = (ObjectFactory)factories.next();234if (factory instanceof DirObjectFactory) {235answer = ((DirObjectFactory)factory).236getObjectInstance(obj, name, nameCtx, environment, attrs);237} else {238answer =239factory.getObjectInstance(obj, name, nameCtx, environment);240}241}242return answer;243}244245/**246* Retrieves the state of an object for binding when given the original247* object and its attributes.248* <p>249* This method is like <tt>NamingManager.getStateToBind</tt> except250* for the following differences:251*<ul>252*<li>It accepts an <tt>Attributes</tt> parameter containing attributes253* that were passed to the <tt>DirContext.bind()</tt> method.254*<li>It returns a non-null <tt>DirStateFactory.Result</tt> instance255* containing the object to be bound, and the attributes to256* accompany the binding. Either the object or the attributes may be null.257*<li>258* The state factories tried must each implement either259* <tt>StateFactory</tt> or <tt>DirStateFactory</tt>.260* If it implements <tt>DirStateFactory</tt>, then261* <tt>DirStateFactory.getStateToBind()</tt> is called; otherwise,262* <tt>StateFactory.getStateToBind()</tt> is called.263*</ul>264*265* Service providers that implement the <tt>DirContext</tt> interface266* should use this method, not <tt>NamingManager.getStateToBind()</tt>.267*<p>268* See NamingManager.getStateToBind() for a description of how269* the list of state factories to be tried is determined.270*<p>271* The object returned by this method is owned by the caller.272* The implementation will not subsequently modify it.273* It will contain either a new <tt>Attributes</tt> object that is274* likewise owned by the caller, or a reference to the original275* <tt>attrs</tt> parameter.276*277* @param obj The non-null object for which to get state to bind.278* @param name The name of this object relative to <code>nameCtx</code>,279* or null if no name is specified.280* @param nameCtx The context relative to which the <code>name</code>281* parameter is specified, or null if <code>name</code> is282* relative to the default initial context.283* @param environment The possibly null environment to284* be used in the creation of the state factory and285* the object's state.286* @param attrs The possibly null Attributes that is to be bound with the287* object.288* @return A non-null DirStateFactory.Result containing289* the object and attributes to be bound.290* If no state factory returns a non-null answer, the result will contain291* the object (<tt>obj</tt>) itself with the original attributes.292* @exception NamingException If a naming exception was encountered293* while using the factories.294* A factory should only throw an exception if it does not want295* other factories to be used in an attempt to create an object.296* See <tt>DirStateFactory.getStateToBind()</tt>.297* @see DirStateFactory298* @see DirStateFactory#getStateToBind299* @see NamingManager#getStateToBind300* @since 1.3301*/302public static DirStateFactory.Result303getStateToBind(Object obj, Name name, Context nameCtx,304Hashtable<?,?> environment, Attributes attrs)305throws NamingException {306307// Get list of state factories308FactoryEnumeration factories = ResourceManager.getFactories(309Context.STATE_FACTORIES, environment, nameCtx);310311if (factories == null) {312// no factories to try; just return originals313return new DirStateFactory.Result(obj, attrs);314}315316// Try each factory until one succeeds317StateFactory factory;318Object objanswer;319DirStateFactory.Result answer = null;320while (answer == null && factories.hasMore()) {321factory = (StateFactory)factories.next();322if (factory instanceof DirStateFactory) {323answer = ((DirStateFactory)factory).324getStateToBind(obj, name, nameCtx, environment, attrs);325} else {326objanswer =327factory.getStateToBind(obj, name, nameCtx, environment);328if (objanswer != null) {329answer = new DirStateFactory.Result(objanswer, attrs);330}331}332}333334return (answer != null) ? answer :335new DirStateFactory.Result(obj, attrs); // nothing new336}337}338339340