1 /* 2 * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.naming.ldap; 27 28 import javax.naming; 29 import javax.naming.directory; 30 31 import java.util.Hashtable; 32 33 /** 34 * This class is the starting context for performing 35 * LDAPv3-style extended operations and controls. 36 *<p> 37 * See <tt>javax.naming.InitialContext</tt> and 38 * <tt>javax.naming.InitialDirContext</tt> for details on synchronization, 39 * and the policy for how an initial context is created. 40 * 41 * <h4>Request Controls</h4> 42 * When you create an initial context (<tt>InitialLdapContext</tt>), 43 * you can specify a list of request controls. 44 * These controls will be used as the request controls for any 45 * implicit LDAP "bind" operation performed by the context or contexts 46 * derived from the context. These are called <em>connection request controls</em>. 47 * Use <tt>getConnectControls()</tt> to get a context's connection request 48 * controls. 49 *<p> 50 * The request controls supplied to the initial context constructor 51 * are <em>not</em> used as the context request controls 52 * for subsequent context operations such as searches and lookups. 53 * Context request controls are set and updated by using 54 * <tt>setRequestControls()</tt>. 55 *<p> 56 * As shown, there can be two different sets of request controls 57 * associated with a context: connection request controls and context 58 * request controls. 59 * This is required for those applications needing to send critical 60 * controls that might not be applicable to both the context operation and 61 * any implicit LDAP "bind" operation. 62 * A typical user program would do the following: 63 *<blockquote><pre> 64 * InitialLdapContext lctx = new InitialLdapContext(env, critConnCtls); 65 * lctx.setRequestControls(critModCtls); 66 * lctx.modifyAttributes(name, mods); 67 * Controls[] respCtls = lctx.getResponseControls(); 68 *</pre></blockquote> 69 * It specifies first the critical controls for creating the initial context 70 * (<tt>critConnCtls</tt>), and then sets the context's request controls 71 * (<tt>critModCtls</tt>) for the context operation. If for some reason 72 * <tt>lctx</tt> needs to reconnect to the server, it will use 73 * <tt>critConnCtls</tt>. See the <tt>LdapContext</tt> interface for 74 * more discussion about request controls. 75 *<p> 76 * Service provider implementors should read the "Service Provider" section 77 * in the <tt>LdapContext</tt> class description for implementation details. 78 * 79 * @author Rosanna Lee 80 * @author Scott Seligman 81 * @author Vincent Ryan 82 * 83 * @see LdapContext 84 * @see javax.naming.InitialContext 85 * @see javax.naming.directory.InitialDirContext 86 * @see javax.naming.spi.NamingManager#setInitialContextFactoryBuilder 87 * @since 1.3 88 */ 89 90 public class InitialLdapContext extends InitialDirContext implements LdapContext { 91 private static final String 92 BIND_CONTROLS_PROPERTY = "java.naming.ldap.control.connect"; 93 94 /** 95 * Constructs an initial context using no environment properties or 96 * connection request controls. 97 * Equivalent to <tt>new InitialLdapContext(null, null)</tt>. 98 * 99 * @throws NamingException if a naming exception is encountered 100 */ 101 public InitialLdapContext() throws NamingException { 102 super(null); 103 } 104 105 /** 106 * Constructs an initial context 107 * using environment properties and connection request controls. 108 * See <tt>javax.naming.InitialContext</tt> for a discussion of 109 * environment properties. 110 * 111 * <p> This constructor will not modify its parameters or 112 * save references to them, but may save a clone or copy. 113 * Caller should not modify mutable keys and values in 114 * <tt>environment</tt> after it has been passed to the constructor. 115 * 116 * <p> <tt>connCtls</tt> is used as the underlying context instance's 117 * connection request controls. See the class description 118 * for details. 119 * 120 * @param environment 121 * environment used to create the initial DirContext. 122 * Null indicates an empty environment. 123 * @param connCtls 124 * connection request controls for the initial context. 125 * If null, no connection request controls are used. 126 * 127 * @throws NamingException if a naming exception is encountered 128 * 129 * @see #reconnect 130 * @see LdapContext#reconnect 131 */ 132 public InitialLdapContext(Hashtable<?,?> environment, 133 Control[] connCtls) 134 throws NamingException { 135 super(true); // don't initialize yet 136 137 // Clone environment since caller owns it. 138 Hashtable env = (environment == null) 139 ? new Hashtable(11) 140 : (Hashtable)environment.clone(); 141 142 // Put connect controls into environment. Copy them first since 143 // caller owns the array. 144 if (connCtls != null) { 145 Control[] copy = new Control[connCtls.length]; 146 System.arraycopy(connCtls, 0, copy, 0, connCtls.length); 147 env.put(BIND_CONTROLS_PROPERTY, copy); 148 } 149 // set version to LDAPv3 150 env.put("java.naming.ldap.version", "3"); 151 152 // Initialize with updated environment 153 init(env); 154 } 155 156 /** 157 * Retrieves the initial LDAP context. 158 * 159 * @return The non-null cached initial context. 160 * @exception NotContextException If the initial context is not an 161 * instance of <tt>LdapContext</tt>. 162 * @exception NamingException If a naming exception was encountered. 163 */ 164 private LdapContext getDefaultLdapInitCtx() throws NamingException{ 165 Context answer = getDefaultInitCtx(); 166 167 if (!(answer instanceof LdapContext)) { 168 if (answer == null) { 169 throw new NoInitialContextException(); 170 } else { 171 throw new NotContextException( 172 "Not an instance of LdapContext"); 173 } 174 } 175 return (LdapContext)answer; 176 } 177 178 // LdapContext methods 179 // Most Javadoc is deferred to the LdapContext interface. 180 181 public ExtendedResponse extendedOperation(ExtendedRequest request) 182 throws NamingException { 183 return getDefaultLdapInitCtx().extendedOperation(request); 184 } 185 186 public LdapContext newInstance(Control[] reqCtls) 187 throws NamingException { 188 return getDefaultLdapInitCtx().newInstance(reqCtls); 189 } 190 191 public void reconnect(Control[] connCtls) throws NamingException { 192 getDefaultLdapInitCtx().reconnect(connCtls); 193 } 194 195 public Control[] getConnectControls() throws NamingException { 196 return getDefaultLdapInitCtx().getConnectControls(); 197 } 198 199 public void setRequestControls(Control[] requestControls) 200 throws NamingException { 201 getDefaultLdapInitCtx().setRequestControls(requestControls); 202 } 203 204 public Control[] getRequestControls() throws NamingException { 205 return getDefaultLdapInitCtx().getRequestControls(); 206 } 207 208 public Control[] getResponseControls() throws NamingException { 209 return getDefaultLdapInitCtx().getResponseControls(); 210 } 211 }