Path: blob/master/src/java.naming/share/classes/javax/naming/ldap/ControlFactory.java
41159 views
/*1* Copyright (c) 1999, 2020, 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.ldap;2627import javax.naming.NamingException;28import javax.naming.Context;2930import java.util.Hashtable;3132import com.sun.naming.internal.FactoryEnumeration;33import com.sun.naming.internal.ResourceManager;343536/**37* This abstract class represents a factory for creating LDAPv3 controls.38* LDAPv3 controls are defined in39* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.40*<p>41* When a service provider receives a response control, it uses control42* factories to return the specific/appropriate control class implementation.43*44* @author Rosanna Lee45* @author Scott Seligman46* @author Vincent Ryan47*48* @see Control49* @since 1.350*/5152public abstract class ControlFactory {53/**54* Creates a new instance of a control factory.55*/56protected ControlFactory() {57}5859/**60* Creates a control using this control factory.61*<p>62* The factory is used by the service provider to return controls63* that it reads from the LDAP protocol as specialized control classes.64* Without this mechanism, the provider would be returning65* controls that only contained data in BER encoded format.66*<p>67* Typically, {@code ctl} is a "basic" control containing68* BER encoded data. The factory is used to create a specialized69* control implementation, usually by decoding the BER encoded data,70* that provides methods to access that data in a type-safe and friendly71* manner.72* <p>73* For example, a factory might use the BER encoded data in74* basic control and return an instance of a VirtualListReplyControl.75*<p>76* If this factory cannot create a control using the argument supplied,77* it should return null.78* A factory should only throw an exception if it is sure that79* it is the only intended factory and that no other control factories80* should be tried. This might happen, for example, if the BER data81* in the control does not match what is expected of a control with82* the given OID. Since this method throws {@code NamingException},83* any other internally generated exception that should be propagated84* must be wrapped inside a {@code NamingException}.85*86* @param ctl A non-null control.87*88* @return A possibly null Control.89* @throws NamingException If {@code ctl} contains invalid data that prevents it90* from being used to create a control. A factory should only throw91* an exception if it knows how to produce the control (identified by the OID)92* but is unable to because of, for example invalid BER data.93*/94public abstract Control getControlInstance(Control ctl) throws NamingException;9596/**97* Creates a control using known control factories.98* <p>99* The following rule is used to create the control:100*<ul>101* <li> Use the control factories specified in102* the {@code LdapContext.CONTROL_FACTORIES} property of the103* environment, and of the provider resource file associated with104* {@code ctx}, in that order.105* The value of this property is a colon-separated list of factory106* class names that are tried in order, and the first one that succeeds107* in creating the control is the one used.108* If none of the factories can be loaded,109* return {@code ctl}.110* If an exception is encountered while creating the control, the111* exception is passed up to the caller.112*</ul>113* <p>114* Note that a control factory must be public and must have a public115* constructor that accepts no arguments.116* In cases where the factory is in a named module then it must be in a117* package which is exported by that module to the {@code java.naming}118* module.119*120* @param ctl The non-null control object containing the OID and BER data.121* @param ctx The possibly null context in which the control is being created.122* If null, no such information is available.123* @param env The possibly null environment of the context. This is used124* to find the value of the {@code LdapContext.CONTROL_FACTORIES} property.125* @return A control object created using {@code ctl}; or126* {@code ctl} if a control object cannot be created using127* the algorithm described above.128* @throws NamingException if a naming exception was encountered129* while attempting to create the control object.130* If one of the factories accessed throws an131* exception, it is propagated up to the caller.132* If an error was encountered while loading133* and instantiating the factory and object classes, the exception134* is wrapped inside a {@code NamingException} and then rethrown.135*/136public static Control getControlInstance(Control ctl, Context ctx,137Hashtable<?,?> env)138throws NamingException {139140// Get object factories list from environment properties or141// provider resource file.142FactoryEnumeration factories = ResourceManager.getFactories(143LdapContext.CONTROL_FACTORIES, env, ctx);144145if (factories == null) {146return ctl;147}148149// Try each factory until one succeeds150Control answer = null;151ControlFactory factory;152while (answer == null && factories.hasMore()) {153factory = (ControlFactory)factories.next();154answer = factory.getControlInstance(ctl);155}156157return (answer != null)? answer : ctl;158}159}160161162