24 */ 25 26 package javax.naming.spi; 27 28 import java.util.Hashtable; 29 30 import javax.naming.Context; 31 import javax.naming.Name; 32 import javax.naming.Reference; 33 import javax.naming.Referenceable; 34 import javax.naming.NamingException; 35 import javax.naming.CannotProceedException; 36 import javax.naming.directory.DirContext; 37 import javax.naming.directory.Attributes; 38 39 import com.sun.naming.internal.ResourceManager; 40 import com.sun.naming.internal.FactoryEnumeration; 41 42 43 /** 44 * This class contains methods for supporting <tt>DirContext</tt> 45 * implementations. 46 *<p> 47 * This class is an extension of <tt>NamingManager</tt>. It contains methods 48 * for use by service providers for accessing object factories and 49 * state factories, and for getting continuation contexts for 50 * supporting federation. 51 *<p> 52 * <tt>DirectoryManager</tt> is safe for concurrent access by multiple threads. 53 *<p> 54 * Except as otherwise noted, 55 * a <tt>Name</tt>, <tt>Attributes</tt>, or environment parameter 56 * passed to any method is owned by the caller. 57 * The implementation will not modify the object or keep a reference 58 * to it, although it may keep a reference to a clone or copy. 59 * 60 * @author Rosanna Lee 61 * @author Scott Seligman 62 * 63 * @see DirObjectFactory 64 * @see DirStateFactory 65 * @since 1.3 66 */ 67 68 public class DirectoryManager extends NamingManager { 69 70 /* 71 * Disallow anyone from creating one of these. 72 */ 73 DirectoryManager() {} 74 75 /** 76 * Creates a context in which to continue a <tt>DirContext</tt> operation. 77 * Operates just like <tt>NamingManager.getContinuationContext()</tt>, 78 * only the continuation context returned is a <tt>DirContext</tt>. 79 * 80 * @param cpe 81 * The non-null exception that triggered this continuation. 82 * @return A non-null <tt>DirContext</tt> object for continuing the operation. 83 * @exception NamingException If a naming exception occurred. 84 * 85 * @see NamingManager#getContinuationContext(CannotProceedException) 86 */ 87 @SuppressWarnings("unchecked") 88 public static DirContext getContinuationDirContext( 89 CannotProceedException cpe) throws NamingException { 90 91 Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment(); 92 if (env == null) { 93 env = new Hashtable<>(7); 94 } else { 95 // Make a (shallow) copy of the environment. 96 env = (Hashtable<Object,Object>) env.clone(); 97 } 98 env.put(CPE, cpe); 99 100 return (new ContinuationDirContext(cpe, env)); 101 } 102 103 /** 104 * Creates an instance of an object for the specified object, 105 * attributes, and environment. 106 * <p> 107 * This method is the same as <tt>NamingManager.getObjectInstance</tt> 108 * except for the following differences: 109 *<ul> 110 *<li> 111 * It accepts an <tt>Attributes</tt> parameter that contains attributes 112 * associated with the object. The <tt>DirObjectFactory</tt> might use these 113 * attributes to save having to look them up from the directory. 114 *<li> 115 * The object factories tried must implement either 116 * <tt>ObjectFactory</tt> or <tt>DirObjectFactory</tt>. 117 * If it implements <tt>DirObjectFactory</tt>, 118 * <tt>DirObjectFactory.getObjectInstance()</tt> is used, otherwise, 119 * <tt>ObjectFactory.getObjectInstance()</tt> is used. 120 *</ul> 121 * Service providers that implement the <tt>DirContext</tt> interface 122 * should use this method, not <tt>NamingManager.getObjectInstance()</tt>. 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 is 127 * 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> is 130 * relative to the default initial context. 131 * @param environment The possibly null environment to 132 * 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>; or 137 * <code>refInfo</code> if an object cannot be created by 138 * a factory. 139 * @exception NamingException If a naming exception was encountered 140 * while attempting to get a URL context, or if one of the 141 * factories accessed throws a NamingException. 142 * @exception Exception If one of the factories accessed throws an 143 * exception, or if an error was encountered while loading 144 * and instantiating the factory and object classes. 145 * A factory should only throw an exception if it does not want 146 * other factories to be used in an attempt to create an object. 147 * See <tt>DirObjectFactory.getObjectInstance()</tt>. 148 * @see NamingManager#getURLContext 149 * @see DirObjectFactory 150 * @see DirObjectFactory#getObjectInstance 151 * @since 1.3 152 */ 153 public static Object 154 getObjectInstance(Object refInfo, Name name, Context nameCtx, 155 Hashtable<?,?> environment, Attributes attrs) 156 throws Exception { 157 158 ObjectFactory factory; 159 160 ObjectFactoryBuilder builder = getObjectFactoryBuilder(); 161 if (builder != null) { 162 // builder must return non-null factory 163 factory = builder.createObjectFactory(refInfo, environment); 164 if (factory instanceof DirObjectFactory) { 165 return ((DirObjectFactory)factory).getObjectInstance( 166 refInfo, name, nameCtx, environment, attrs); 167 } else { 229 ObjectFactory factory; 230 Object answer = null; 231 // Try each factory until one succeeds 232 while (answer == null && factories.hasMore()) { 233 factory = (ObjectFactory)factories.next(); 234 if (factory instanceof DirObjectFactory) { 235 answer = ((DirObjectFactory)factory). 236 getObjectInstance(obj, name, nameCtx, environment, attrs); 237 } else { 238 answer = 239 factory.getObjectInstance(obj, name, nameCtx, environment); 240 } 241 } 242 return answer; 243 } 244 245 /** 246 * Retrieves the state of an object for binding when given the original 247 * object and its attributes. 248 * <p> 249 * This method is like <tt>NamingManager.getStateToBind</tt> except 250 * for the following differences: 251 *<ul> 252 *<li>It accepts an <tt>Attributes</tt> parameter containing attributes 253 * that were passed to the <tt>DirContext.bind()</tt> method. 254 *<li>It returns a non-null <tt>DirStateFactory.Result</tt> instance 255 * containing the object to be bound, and the attributes to 256 * accompany the binding. Either the object or the attributes may be null. 257 *<li> 258 * The state factories tried must each implement either 259 * <tt>StateFactory</tt> or <tt>DirStateFactory</tt>. 260 * If it implements <tt>DirStateFactory</tt>, then 261 * <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> interface 266 * should use this method, not <tt>NamingManager.getStateToBind()</tt>. 267 *<p> 268 * See NamingManager.getStateToBind() for a description of how 269 * 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 is 274 * likewise owned by the caller, or a reference to the original 275 * <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> is 282 * relative to the default initial context. 283 * @param environment The possibly null environment to 284 * be used in the creation of the state factory and 285 * the object's state. 286 * @param attrs The possibly null Attributes that is to be bound with the 287 * object. 288 * @return A non-null DirStateFactory.Result containing 289 * the object and attributes to be bound. 290 * If no state factory returns a non-null answer, the result will contain 291 * the object (<tt>obj</tt>) itself with the original attributes. 292 * @exception NamingException If a naming exception was encountered 293 * while using the factories. 294 * A factory should only throw an exception if it does not want 295 * other factories to be used in an attempt to create an object. 296 * See <tt>DirStateFactory.getStateToBind()</tt>. 297 * @see DirStateFactory 298 * @see DirStateFactory#getStateToBind 299 * @see NamingManager#getStateToBind 300 * @since 1.3 301 */ 302 public static DirStateFactory.Result 303 getStateToBind(Object obj, Name name, Context nameCtx, 304 Hashtable<?,?> environment, Attributes attrs) 305 throws NamingException { 306 307 // Get list of state factories 308 FactoryEnumeration factories = ResourceManager.getFactories( 309 Context.STATE_FACTORIES, environment, nameCtx); 310 311 if (factories == null) { 312 // no factories to try; just return originals 313 return new DirStateFactory.Result(obj, attrs); 314 } 315 316 // Try each factory until one succeeds | 24 */ 25 26 package javax.naming.spi; 27 28 import java.util.Hashtable; 29 30 import javax.naming.Context; 31 import javax.naming.Name; 32 import javax.naming.Reference; 33 import javax.naming.Referenceable; 34 import javax.naming.NamingException; 35 import javax.naming.CannotProceedException; 36 import javax.naming.directory.DirContext; 37 import javax.naming.directory.Attributes; 38 39 import com.sun.naming.internal.ResourceManager; 40 import com.sun.naming.internal.FactoryEnumeration; 41 42 43 /** 44 * This class contains methods for supporting {@code DirContext} 45 * implementations. 46 *<p> 47 * This class is an extension of {@code NamingManager}. It contains methods 48 * for use by service providers for accessing object factories and 49 * state factories, and for getting continuation contexts for 50 * supporting federation. 51 *<p> 52 * {@code DirectoryManager} is safe for concurrent access by multiple threads. 53 *<p> 54 * Except as otherwise noted, 55 * a {@code Name}, {@code Attributes}, or environment parameter 56 * passed to any method is owned by the caller. 57 * The implementation will not modify the object or keep a reference 58 * to it, although it may keep a reference to a clone or copy. 59 * 60 * @author Rosanna Lee 61 * @author Scott Seligman 62 * 63 * @see DirObjectFactory 64 * @see DirStateFactory 65 * @since 1.3 66 */ 67 68 public class DirectoryManager extends NamingManager { 69 70 /* 71 * Disallow anyone from creating one of these. 72 */ 73 DirectoryManager() {} 74 75 /** 76 * Creates a context in which to continue a {@code DirContext} operation. 77 * Operates just like {@code NamingManager.getContinuationContext()}, 78 * only the continuation context returned is a {@code DirContext}. 79 * 80 * @param cpe 81 * The non-null exception that triggered this continuation. 82 * @return A non-null {@code DirContext} object for continuing the operation. 83 * @exception NamingException If a naming exception occurred. 84 * 85 * @see NamingManager#getContinuationContext(CannotProceedException) 86 */ 87 @SuppressWarnings("unchecked") 88 public static DirContext getContinuationDirContext( 89 CannotProceedException cpe) throws NamingException { 90 91 Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment(); 92 if (env == null) { 93 env = new Hashtable<>(7); 94 } else { 95 // Make a (shallow) copy of the environment. 96 env = (Hashtable<Object,Object>) env.clone(); 97 } 98 env.put(CPE, cpe); 99 100 return (new ContinuationDirContext(cpe, env)); 101 } 102 103 /** 104 * Creates an instance of an object for the specified object, 105 * attributes, and environment. 106 * <p> 107 * This method is the same as {@code NamingManager.getObjectInstance} 108 * except for the following differences: 109 *<ul> 110 *<li> 111 * It accepts an {@code Attributes} parameter that contains attributes 112 * associated with the object. The {@code DirObjectFactory} might use these 113 * attributes to save having to look them up from the directory. 114 *<li> 115 * The object factories tried must implement either 116 * {@code ObjectFactory} or {@code DirObjectFactory}. 117 * If it implements {@code DirObjectFactory}, 118 * {@code DirObjectFactory.getObjectInstance()} is used, otherwise, 119 * {@code ObjectFactory.getObjectInstance()} is used. 120 *</ul> 121 * Service providers that implement the {@code DirContext} interface 122 * should use this method, not {@code NamingManager.getObjectInstance()}. 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}. 126 * Specifying a name is optional; if it is 127 * omitted, {@code name} should be null. 128 * @param nameCtx The context relative to which the {@code name} 129 * parameter is specified. If null, {@code name} is 130 * relative to the default initial context. 131 * @param environment The possibly null environment to 132 * 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} and {@code attrs}; or 137 * {@code refInfo} if an object cannot be created by 138 * a factory. 139 * @exception NamingException If a naming exception was encountered 140 * while attempting to get a URL context, or if one of the 141 * factories accessed throws a NamingException. 142 * @exception Exception If one of the factories accessed throws an 143 * exception, or if an error was encountered while loading 144 * and instantiating the factory and object classes. 145 * A factory should only throw an exception if it does not want 146 * other factories to be used in an attempt to create an object. 147 * See {@code DirObjectFactory.getObjectInstance()}. 148 * @see NamingManager#getURLContext 149 * @see DirObjectFactory 150 * @see DirObjectFactory#getObjectInstance 151 * @since 1.3 152 */ 153 public static Object 154 getObjectInstance(Object refInfo, Name name, Context nameCtx, 155 Hashtable<?,?> environment, Attributes attrs) 156 throws Exception { 157 158 ObjectFactory factory; 159 160 ObjectFactoryBuilder builder = getObjectFactoryBuilder(); 161 if (builder != null) { 162 // builder must return non-null factory 163 factory = builder.createObjectFactory(refInfo, environment); 164 if (factory instanceof DirObjectFactory) { 165 return ((DirObjectFactory)factory).getObjectInstance( 166 refInfo, name, nameCtx, environment, attrs); 167 } else { 229 ObjectFactory factory; 230 Object answer = null; 231 // Try each factory until one succeeds 232 while (answer == null && factories.hasMore()) { 233 factory = (ObjectFactory)factories.next(); 234 if (factory instanceof DirObjectFactory) { 235 answer = ((DirObjectFactory)factory). 236 getObjectInstance(obj, name, nameCtx, environment, attrs); 237 } else { 238 answer = 239 factory.getObjectInstance(obj, name, nameCtx, environment); 240 } 241 } 242 return answer; 243 } 244 245 /** 246 * Retrieves the state of an object for binding when given the original 247 * object and its attributes. 248 * <p> 249 * This method is like {@code NamingManager.getStateToBind} except 250 * for the following differences: 251 *<ul> 252 *<li>It accepts an {@code Attributes} parameter containing attributes 253 * that were passed to the {@code DirContext.bind()} method. 254 *<li>It returns a non-null {@code DirStateFactory.Result} instance 255 * containing the object to be bound, and the attributes to 256 * accompany the binding. Either the object or the attributes may be null. 257 *<li> 258 * The state factories tried must each implement either 259 * {@code StateFactory} or {@code DirStateFactory}. 260 * If it implements {@code DirStateFactory}, then 261 * {@code DirStateFactory.getStateToBind()} is called; otherwise, 262 * {@code StateFactory.getStateToBind()} is called. 263 *</ul> 264 * 265 * Service providers that implement the {@code DirContext} interface 266 * should use this method, not {@code NamingManager.getStateToBind()}. 267 *<p> 268 * See NamingManager.getStateToBind() for a description of how 269 * 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 {@code Attributes} object that is 274 * likewise owned by the caller, or a reference to the original 275 * {@code attrs} 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}, 279 * or null if no name is specified. 280 * @param nameCtx The context relative to which the {@code name} 281 * parameter is specified, or null if {@code name} is 282 * relative to the default initial context. 283 * @param environment The possibly null environment to 284 * be used in the creation of the state factory and 285 * the object's state. 286 * @param attrs The possibly null Attributes that is to be bound with the 287 * object. 288 * @return A non-null DirStateFactory.Result containing 289 * the object and attributes to be bound. 290 * If no state factory returns a non-null answer, the result will contain 291 * the object ({@code obj}) itself with the original attributes. 292 * @exception NamingException If a naming exception was encountered 293 * while using the factories. 294 * A factory should only throw an exception if it does not want 295 * other factories to be used in an attempt to create an object. 296 * See {@code DirStateFactory.getStateToBind()}. 297 * @see DirStateFactory 298 * @see DirStateFactory#getStateToBind 299 * @see NamingManager#getStateToBind 300 * @since 1.3 301 */ 302 public static DirStateFactory.Result 303 getStateToBind(Object obj, Name name, Context nameCtx, 304 Hashtable<?,?> environment, Attributes attrs) 305 throws NamingException { 306 307 // Get list of state factories 308 FactoryEnumeration factories = ResourceManager.getFactories( 309 Context.STATE_FACTORIES, environment, nameCtx); 310 311 if (factories == null) { 312 // no factories to try; just return originals 313 return new DirStateFactory.Result(obj, attrs); 314 } 315 316 // Try each factory until one succeeds |