1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/* * @(#)ControlFactory.java 1.13 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.naming.ldap; import javax.naming.NamingException; import javax.naming.Context; import java.util.Hashtable; import com.sun.naming.internal.FactoryEnumeration; import com.sun.naming.internal.ResourceManager; /** * This abstract class represents a factory for creating LDAPv3 controls. * LDAPv3 controls are defined in * <A HREF="ftp://ftp.isi.edu/in-notes/rfc2251.txt">RFC 2251</A>. *<p> * When a service provider receives a response control, it uses control * factories to return the specific/appropriate control class implementation. * * @author Rosanna Lee * @author Scott Seligman * @author Vincent Ryan * @version 1.13 05/11/17 * * @see Control * @since 1.3 */ public abstract class ControlFactory { /* * Creates a new instance of a control factory. */ protected ControlFactory() { } /** * Creates a control using this control factory. *<p> * The factory is used by the service provider to return controls * that it reads from the LDAP protocol as specialized control classes. * Without this mechanism, the provider would be returning * controls that only contained data in BER encoded format. *<p> * Typically, <tt>ctl</tt> is a "basic" control containing * BER encoded data. The factory is used to create a specialized * control implementation, usually by decoding the BER encoded data, * that provides methods to access that data in a type-safe and friendly * manner. * <p> * For example, a factory might use the BER encoded data in * basic control and return an instance of a VirtualListReplyControl. *<p> * If this factory cannot create a control using the argument supplied, * it should return null. * A factory should only throw an exception if it is sure that * it is the only intended factory and that no other control factories * should be tried. This might happen, for example, if the BER data * in the control does not match what is expected of a control with * the given OID. Since this method throws <tt>NamingException</tt>, * any other internally generated exception that should be propagated * must be wrapped inside a <tt>NamingException</tt>. * * @param ctl A non-null control. * * @return A possibly null Control. * @exception NamingException If <tt>ctl</tt> contains invalid data that prevents it * from being used to create a control. A factory should only throw * an exception if it knows how to produce the control (identified by the OID) * but is unable to because of, for example invalid BER data. */ public abstract Control getControlInstance(Control ctl) throws NamingException; /** * Creates a control using known control factories. * <p> * The following rule is used to create the control: *<ul> * <li> Use the control factories specified in * the <tt>LdapContext.CONTROL_FACTORIES</tt> property of the * environment, and of the provider resource file associated with * <tt>ctx</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 the control is the one used. * If none of the factories can be loaded, * return <code>ctl</code>. * If an exception is encountered while creating the control, the * exception is passed up to the caller. *</ul> * <p> * Note that a control factory * must be public and must have a public constructor that accepts no arguments. * <p> * @param ctl The non-null control object containing the OID and BER data. * @param ctx The possibly null context in which the control is being created. * If null, no such information is available. * @param env The possibly null environment of the context. This is used * to find the value of the <tt>LdapContext.CONTROL_FACTORIES</tt> property. * @return A control object created using <code>ctl</code>; or * <code>ctl</code> if a control object cannot be created using * the algorithm described above. * @exception NamingException if a naming exception was encountered * while attempting to create the control object. * If one of the factories accessed throws an * exception, it is propagated up to the caller. * If an error was encountered while loading * and instantiating the factory and object classes, the exception * is wrapped inside a <tt>NamingException</tt> and then rethrown. */ public static Control getControlInstance(Control ctl, Context ctx, Hashtable<?,?> env) throws NamingException { // Get object factories list from environment properties or // provider resource file. FactoryEnumeration factories = ResourceManager.getFactories( LdapContext.CONTROL_FACTORIES, env, ctx); if (factories == null) { return ctl; } // Try each factory until one succeeds Control answer = null; ControlFactory factory; while (answer == null && factories.hasMore()) { factory = (ControlFactory)factories.next(); answer = factory.getControlInstance(ctl); } return (answer != null)? answer : ctl; } }