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 @SuppressWarnings("unchecked") 133 public InitialLdapContext(Hashtable<?,?> environment, 134 Control[] connCtls) 135 throws NamingException { 136 super(true); // don't initialize yet 137 138 // Clone environment since caller owns it. 139 Hashtable<Object,Object> env = (environment == null) 140 ? new Hashtable<>(11) 141 : (Hashtable<Object,Object>)environment.clone(); 142 143 // Put connect controls into environment. Copy them first since 144 // caller owns the array. 145 if (connCtls != null) { 146 Control[] copy = new Control[connCtls.length]; 147 System.arraycopy(connCtls, 0, copy, 0, connCtls.length); 148 env.put(BIND_CONTROLS_PROPERTY, copy); 149 } 150 // set version to LDAPv3 151 env.put("java.naming.ldap.version", "3"); 152 153 // Initialize with updated environment 154 init(env); 155 } 156 157 /** 158 * Retrieves the initial LDAP context. 159 * 160 * @return The non-null cached initial context. 161 * @exception NotContextException If the initial context is not an 162 * instance of <tt>LdapContext</tt>. 163 * @exception NamingException If a naming exception was encountered. 164 */ 165 private LdapContext getDefaultLdapInitCtx() throws NamingException{ 166 Context answer = getDefaultInitCtx(); 167 168 if (!(answer instanceof LdapContext)) { 169 if (answer == null) { 170 throw new NoInitialContextException(); 171 } else { 172 throw new NotContextException( 173 "Not an instance of LdapContext"); 174 } 175 } 176 return (LdapContext)answer; 177 } 178 179 // LdapContext methods 180 // Most Javadoc is deferred to the LdapContext interface. 181 182 public ExtendedResponse extendedOperation(ExtendedRequest request) 183 throws NamingException { 184 return getDefaultLdapInitCtx().extendedOperation(request); 185 } 186 187 public LdapContext newInstance(Control[] reqCtls) 188 throws NamingException { 189 return getDefaultLdapInitCtx().newInstance(reqCtls); 190 } 191 192 public void reconnect(Control[] connCtls) throws NamingException { 193 getDefaultLdapInitCtx().reconnect(connCtls); 194 } 195 196 public Control[] getConnectControls() throws NamingException { 197 return getDefaultLdapInitCtx().getConnectControls(); 198 } 199 200 public void setRequestControls(Control[] requestControls) 201 throws NamingException { 202 getDefaultLdapInitCtx().setRequestControls(requestControls); 203 } 204 205 public Control[] getRequestControls() throws NamingException { 206 return getDefaultLdapInitCtx().getRequestControls(); 207 } 208 209 public Control[] getResponseControls() throws NamingException { 210 return getDefaultLdapInitCtx().getResponseControls(); 211 } 212 }