You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
5.6 KiB
158 lines
5.6 KiB
/*
|
|
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE 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="http://www.ietf.org/rfc/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
|
|
*
|
|
* @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;
|
|
}
|
|
}
|