0N/A/*
3261N/A * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.naming.ldap;
0N/A
0N/Aimport javax.naming.NamingException;
0N/Aimport javax.naming.Context;
0N/A
0N/Aimport java.util.Hashtable;
0N/A
0N/Aimport com.sun.naming.internal.FactoryEnumeration;
0N/Aimport com.sun.naming.internal.ResourceManager;
0N/A
0N/A
0N/A/**
0N/A * This abstract class represents a factory for creating LDAPv3 controls.
0N/A * LDAPv3 controls are defined in
2395N/A * <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
0N/A *<p>
0N/A * When a service provider receives a response control, it uses control
0N/A * factories to return the specific/appropriate control class implementation.
0N/A *
0N/A * @author Rosanna Lee
0N/A * @author Scott Seligman
0N/A * @author Vincent Ryan
0N/A *
0N/A * @see Control
0N/A * @since 1.3
0N/A */
0N/A
0N/Apublic abstract class ControlFactory {
0N/A /*
0N/A * Creates a new instance of a control factory.
0N/A */
0N/A protected ControlFactory() {
0N/A }
0N/A
0N/A /**
0N/A * Creates a control using this control factory.
0N/A *<p>
0N/A * The factory is used by the service provider to return controls
0N/A * that it reads from the LDAP protocol as specialized control classes.
0N/A * Without this mechanism, the provider would be returning
0N/A * controls that only contained data in BER encoded format.
0N/A *<p>
0N/A * Typically, <tt>ctl</tt> is a "basic" control containing
0N/A * BER encoded data. The factory is used to create a specialized
0N/A * control implementation, usually by decoding the BER encoded data,
0N/A * that provides methods to access that data in a type-safe and friendly
0N/A * manner.
0N/A * <p>
0N/A * For example, a factory might use the BER encoded data in
0N/A * basic control and return an instance of a VirtualListReplyControl.
0N/A *<p>
0N/A * If this factory cannot create a control using the argument supplied,
0N/A * it should return null.
0N/A * A factory should only throw an exception if it is sure that
0N/A * it is the only intended factory and that no other control factories
0N/A * should be tried. This might happen, for example, if the BER data
0N/A * in the control does not match what is expected of a control with
0N/A * the given OID. Since this method throws <tt>NamingException</tt>,
0N/A * any other internally generated exception that should be propagated
0N/A * must be wrapped inside a <tt>NamingException</tt>.
0N/A *
0N/A * @param ctl A non-null control.
0N/A *
0N/A * @return A possibly null Control.
0N/A * @exception NamingException If <tt>ctl</tt> contains invalid data that prevents it
0N/A * from being used to create a control. A factory should only throw
0N/A * an exception if it knows how to produce the control (identified by the OID)
0N/A * but is unable to because of, for example invalid BER data.
0N/A */
0N/A public abstract Control getControlInstance(Control ctl) throws NamingException;
0N/A
0N/A /**
0N/A * Creates a control using known control factories.
0N/A * <p>
0N/A * The following rule is used to create the control:
0N/A *<ul>
0N/A * <li> Use the control factories specified in
0N/A * the <tt>LdapContext.CONTROL_FACTORIES</tt> property of the
0N/A * environment, and of the provider resource file associated with
0N/A * <tt>ctx</tt>, in that order.
0N/A * The value of this property is a colon-separated list of factory
0N/A * class names that are tried in order, and the first one that succeeds
0N/A * in creating the control is the one used.
0N/A * If none of the factories can be loaded,
0N/A * return <code>ctl</code>.
0N/A * If an exception is encountered while creating the control, the
0N/A * exception is passed up to the caller.
0N/A *</ul>
0N/A * <p>
0N/A * Note that a control factory
0N/A * must be public and must have a public constructor that accepts no arguments.
0N/A * <p>
0N/A * @param ctl The non-null control object containing the OID and BER data.
0N/A * @param ctx The possibly null context in which the control is being created.
0N/A * If null, no such information is available.
0N/A * @param env The possibly null environment of the context. This is used
0N/A * to find the value of the <tt>LdapContext.CONTROL_FACTORIES</tt> property.
0N/A * @return A control object created using <code>ctl</code>; or
0N/A * <code>ctl</code> if a control object cannot be created using
0N/A * the algorithm described above.
0N/A * @exception NamingException if a naming exception was encountered
0N/A * while attempting to create the control object.
0N/A * If one of the factories accessed throws an
0N/A * exception, it is propagated up to the caller.
0N/A * If an error was encountered while loading
0N/A * and instantiating the factory and object classes, the exception
0N/A * is wrapped inside a <tt>NamingException</tt> and then rethrown.
0N/A */
0N/A public static Control getControlInstance(Control ctl, Context ctx,
0N/A Hashtable<?,?> env)
0N/A throws NamingException {
0N/A
0N/A // Get object factories list from environment properties or
0N/A // provider resource file.
0N/A FactoryEnumeration factories = ResourceManager.getFactories(
0N/A LdapContext.CONTROL_FACTORIES, env, ctx);
0N/A
0N/A if (factories == null) {
0N/A return ctl;
0N/A }
0N/A
0N/A // Try each factory until one succeeds
0N/A Control answer = null;
0N/A ControlFactory factory;
0N/A while (answer == null && factories.hasMore()) {
0N/A factory = (ControlFactory)factories.next();
0N/A answer = factory.getControlInstance(ctl);
0N/A }
0N/A
0N/A return (answer != null)? answer : ctl;
0N/A }
0N/A}