blob: 896cae8ccaf264c0da388288b7d59eb778fdfe4e [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2004 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.naming.ldap;
27
28import javax.naming.*;
29import javax.naming.directory.*;
30
31import 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
90public 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 *
114 * <p> <tt>connCtls</tt> is used as the underlying context instance's
115 * connection request controls. See the class description
116 * for details.
117 *
118 * @param environment
119 * environment used to create the initial DirContext.
120 * Null indicates an empty environment.
121 * @param connCtls
122 * connection request controls for the initial context.
123 * If null, no connection request controls are used.
124 *
125 * @throws NamingException if a naming exception is encountered
126 *
127 * @see #reconnect
128 * @see LdapContext#reconnect
129 */
130 public InitialLdapContext(Hashtable<?,?> environment,
131 Control[] connCtls)
132 throws NamingException {
133 super(true); // don't initialize yet
134
135 // Clone environment since caller owns it.
136 Hashtable env = (environment == null)
137 ? new Hashtable(11)
138 : (Hashtable)environment.clone();
139
140 // Put connect controls into environment. Copy them first since
141 // caller owns the array.
142 if (connCtls != null) {
143 Control[] copy = new Control[connCtls.length];
144 System.arraycopy(connCtls, 0, copy, 0, connCtls.length);
145 env.put(BIND_CONTROLS_PROPERTY, copy);
146 }
147 // set version to LDAPv3
148 env.put("java.naming.ldap.version", "3");
149
150 // Initialize with updated environment
151 init(env);
152 }
153
154 /**
155 * Retrieves the initial LDAP context.
156 *
157 * @return The non-null cached initial context.
158 * @exception NotContextException If the initial context is not an
159 * instance of <tt>LdapContext</tt>.
160 * @exception NamingException If a naming exception was encountered.
161 */
162 private LdapContext getDefaultLdapInitCtx() throws NamingException{
163 Context answer = getDefaultInitCtx();
164
165 if (!(answer instanceof LdapContext)) {
166 if (answer == null) {
167 throw new NoInitialContextException();
168 } else {
169 throw new NotContextException(
170 "Not an instance of LdapContext");
171 }
172 }
173 return (LdapContext)answer;
174 }
175
176// LdapContext methods
177// Most Javadoc is deferred to the LdapContext interface.
178
179 public ExtendedResponse extendedOperation(ExtendedRequest request)
180 throws NamingException {
181 return getDefaultLdapInitCtx().extendedOperation(request);
182 }
183
184 public LdapContext newInstance(Control[] reqCtls)
185 throws NamingException {
186 return getDefaultLdapInitCtx().newInstance(reqCtls);
187 }
188
189 public void reconnect(Control[] connCtls) throws NamingException {
190 getDefaultLdapInitCtx().reconnect(connCtls);
191 }
192
193 public Control[] getConnectControls() throws NamingException {
194 return getDefaultLdapInitCtx().getConnectControls();
195 }
196
197 public void setRequestControls(Control[] requestControls)
198 throws NamingException {
199 getDefaultLdapInitCtx().setRequestControls(requestControls);
200 }
201
202 public Control[] getRequestControls() throws NamingException {
203 return getDefaultLdapInitCtx().getRequestControls();
204 }
205
206 public Control[] getResponseControls() throws NamingException {
207 return getDefaultLdapInitCtx().getResponseControls();
208 }
209}