48 * 49 * @see Control 50 * @since 1.3 51 */ 52 53 public abstract class ControlFactory { 54 /** 55 * Creates a new instance of a control factory. 56 */ 57 protected ControlFactory() { 58 } 59 60 /** 61 * Creates a control using this control factory. 62 *<p> 63 * The factory is used by the service provider to return controls 64 * that it reads from the LDAP protocol as specialized control classes. 65 * Without this mechanism, the provider would be returning 66 * controls that only contained data in BER encoded format. 67 *<p> 68 * Typically, <tt>ctl</tt> is a "basic" control containing 69 * BER encoded data. The factory is used to create a specialized 70 * control implementation, usually by decoding the BER encoded data, 71 * that provides methods to access that data in a type-safe and friendly 72 * manner. 73 * <p> 74 * For example, a factory might use the BER encoded data in 75 * basic control and return an instance of a VirtualListReplyControl. 76 *<p> 77 * If this factory cannot create a control using the argument supplied, 78 * it should return null. 79 * A factory should only throw an exception if it is sure that 80 * it is the only intended factory and that no other control factories 81 * should be tried. This might happen, for example, if the BER data 82 * in the control does not match what is expected of a control with 83 * the given OID. Since this method throws <tt>NamingException</tt>, 84 * any other internally generated exception that should be propagated 85 * must be wrapped inside a <tt>NamingException</tt>. 86 * 87 * @param ctl A non-null control. 88 * 89 * @return A possibly null Control. 90 * @exception NamingException If <tt>ctl</tt> contains invalid data that prevents it 91 * from being used to create a control. A factory should only throw 92 * an exception if it knows how to produce the control (identified by the OID) 93 * but is unable to because of, for example invalid BER data. 94 */ 95 public abstract Control getControlInstance(Control ctl) throws NamingException; 96 97 /** 98 * Creates a control using known control factories. 99 * <p> 100 * The following rule is used to create the control: 101 *<ul> 102 * <li> Use the control factories specified in 103 * the <tt>LdapContext.CONTROL_FACTORIES</tt> property of the 104 * environment, and of the provider resource file associated with 105 * <tt>ctx</tt>, in that order. 106 * The value of this property is a colon-separated list of factory 107 * class names that are tried in order, and the first one that succeeds 108 * in creating the control is the one used. 109 * If none of the factories can be loaded, 110 * return <code>ctl</code>. 111 * If an exception is encountered while creating the control, the 112 * exception is passed up to the caller. 113 *</ul> 114 * <p> 115 * Note that a control factory 116 * must be public and must have a public constructor that accepts no arguments. 117 * 118 * @param ctl The non-null control object containing the OID and BER data. 119 * @param ctx The possibly null context in which the control is being created. 120 * If null, no such information is available. 121 * @param env The possibly null environment of the context. This is used 122 * to find the value of the <tt>LdapContext.CONTROL_FACTORIES</tt> property. 123 * @return A control object created using <code>ctl</code>; or 124 * <code>ctl</code> if a control object cannot be created using 125 * the algorithm described above. 126 * @exception NamingException if a naming exception was encountered 127 * while attempting to create the control object. 128 * If one of the factories accessed throws an 129 * exception, it is propagated up to the caller. 130 * If an error was encountered while loading 131 * and instantiating the factory and object classes, the exception 132 * is wrapped inside a <tt>NamingException</tt> and then rethrown. 133 */ 134 public static Control getControlInstance(Control ctl, Context ctx, 135 Hashtable<?,?> env) 136 throws NamingException { 137 138 // Get object factories list from environment properties or 139 // provider resource file. 140 FactoryEnumeration factories = ResourceManager.getFactories( 141 LdapContext.CONTROL_FACTORIES, env, ctx); 142 143 if (factories == null) { 144 return ctl; 145 } 146 147 // Try each factory until one succeeds 148 Control answer = null; 149 ControlFactory factory; 150 while (answer == null && factories.hasMore()) { 151 factory = (ControlFactory)factories.next(); 152 answer = factory.getControlInstance(ctl); | 48 * 49 * @see Control 50 * @since 1.3 51 */ 52 53 public abstract class ControlFactory { 54 /** 55 * Creates a new instance of a control factory. 56 */ 57 protected ControlFactory() { 58 } 59 60 /** 61 * Creates a control using this control factory. 62 *<p> 63 * The factory is used by the service provider to return controls 64 * that it reads from the LDAP protocol as specialized control classes. 65 * Without this mechanism, the provider would be returning 66 * controls that only contained data in BER encoded format. 67 *<p> 68 * Typically, {@code ctl} is a "basic" control containing 69 * BER encoded data. The factory is used to create a specialized 70 * control implementation, usually by decoding the BER encoded data, 71 * that provides methods to access that data in a type-safe and friendly 72 * manner. 73 * <p> 74 * For example, a factory might use the BER encoded data in 75 * basic control and return an instance of a VirtualListReplyControl. 76 *<p> 77 * If this factory cannot create a control using the argument supplied, 78 * it should return null. 79 * A factory should only throw an exception if it is sure that 80 * it is the only intended factory and that no other control factories 81 * should be tried. This might happen, for example, if the BER data 82 * in the control does not match what is expected of a control with 83 * the given OID. Since this method throws {@code NamingException}, 84 * any other internally generated exception that should be propagated 85 * must be wrapped inside a {@code NamingException}. 86 * 87 * @param ctl A non-null control. 88 * 89 * @return A possibly null Control. 90 * @exception NamingException If {@code ctl} contains invalid data that prevents it 91 * from being used to create a control. A factory should only throw 92 * an exception if it knows how to produce the control (identified by the OID) 93 * but is unable to because of, for example invalid BER data. 94 */ 95 public abstract Control getControlInstance(Control ctl) throws NamingException; 96 97 /** 98 * Creates a control using known control factories. 99 * <p> 100 * The following rule is used to create the control: 101 *<ul> 102 * <li> Use the control factories specified in 103 * the {@code LdapContext.CONTROL_FACTORIES} property of the 104 * environment, and of the provider resource file associated with 105 * {@code ctx}, in that order. 106 * The value of this property is a colon-separated list of factory 107 * class names that are tried in order, and the first one that succeeds 108 * in creating the control is the one used. 109 * If none of the factories can be loaded, 110 * return {@code ctl}. 111 * If an exception is encountered while creating the control, the 112 * exception is passed up to the caller. 113 *</ul> 114 * <p> 115 * Note that a control factory 116 * must be public and must have a public constructor that accepts no arguments. 117 * 118 * @param ctl The non-null control object containing the OID and BER data. 119 * @param ctx The possibly null context in which the control is being created. 120 * If null, no such information is available. 121 * @param env The possibly null environment of the context. This is used 122 * to find the value of the {@code LdapContext.CONTROL_FACTORIES} property. 123 * @return A control object created using {@code ctl}; or 124 * {@code ctl} if a control object cannot be created using 125 * the algorithm described above. 126 * @exception NamingException if a naming exception was encountered 127 * while attempting to create the control object. 128 * If one of the factories accessed throws an 129 * exception, it is propagated up to the caller. 130 * If an error was encountered while loading 131 * and instantiating the factory and object classes, the exception 132 * is wrapped inside a {@code NamingException} and then rethrown. 133 */ 134 public static Control getControlInstance(Control ctl, Context ctx, 135 Hashtable<?,?> env) 136 throws NamingException { 137 138 // Get object factories list from environment properties or 139 // provider resource file. 140 FactoryEnumeration factories = ResourceManager.getFactories( 141 LdapContext.CONTROL_FACTORIES, env, ctx); 142 143 if (factories == null) { 144 return ctl; 145 } 146 147 // Try each factory until one succeeds 148 Control answer = null; 149 ControlFactory factory; 150 while (answer == null && factories.hasMore()) { 151 factory = (ControlFactory)factories.next(); 152 answer = factory.getControlInstance(ctl); |