1. /*
  2. * @(#)InitialLdapContext.java 1.9 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.naming.ldap;
  8. import javax.naming.*;
  9. import javax.naming.directory.*;
  10. import java.util.Hashtable;
  11. /**
  12. * This class is the starting context for performing
  13. * LDAPv3-style extended operations and controls.
  14. *<p>
  15. * See <tt>javax.naming.InitialContext</tt> and
  16. * <tt>javax.naming.InitialDirContext</tt> for details on synchronization,
  17. * and the policy for how an initial context is created.
  18. *
  19. * <h4>Request Controls</h4>
  20. * When you create an initial context (<tt>InitialLdapContext</tt>),
  21. * you can specify a list of request controls.
  22. * These controls will be used as the request controls for any
  23. * implicit LDAP "bind" operation performed by the context or contexts
  24. * derived from the context. These are called <em>connection request controls</em>.
  25. * Use <tt>getConnectControls()</tt> to get a context's connection request
  26. * controls.
  27. *<p>
  28. * The request controls supplied to the initial context constructor
  29. * are <em>not</em> used as the context request controls
  30. * for subsequent context operations such as searches and lookups.
  31. * Context request controls are set and updated by using
  32. * <tt>setRequestControls()</tt>.
  33. *<p>
  34. * As shown, there can be two different sets of request controls
  35. * associated with a context: connection request controls and context
  36. * request controls.
  37. * This is required for those applications needing to send critical
  38. * controls that might not be applicable to both the context operation and
  39. * any implicit LDAP "bind" operation.
  40. * A typical user program would do the following:
  41. *<blockquote><pre>
  42. * InitialLdapContext lctx = new InitialLdapContext(env, critConnCtls);
  43. * lctx.setRequestControls(critModCtls);
  44. * lctx.modifyAttributes(name, mods);
  45. * Controls[] respCtls = lctx.getResponseControls();
  46. *</pre></blockquote>
  47. * It specifies first the critical controls for creating the initial context
  48. * (<tt>critConnCtls</tt>), and then sets the context's request controls
  49. * (<tt>critModCtls</tt>) for the context operation. If for some reason
  50. * <tt>lctx</tt> needs to reconnect to the server, it will use
  51. * <tt>critConnCtls</tt>. See the <tt>LdapContext</tt> interface for
  52. * more discussion about request controls.
  53. *<p>
  54. * Service provider implementors should read the "Service Provider" section
  55. * in the <tt>LdapContext</tt> class description for implementation details.
  56. *
  57. * @author Rosanna Lee
  58. * @author Scott Seligman
  59. * @author Vincent Ryan
  60. * @version 1.9 03/01/23
  61. *
  62. * @see LdapContext
  63. * @see javax.naming.InitialContext
  64. * @see javax.naming.directory.InitialDirContext
  65. * @see javax.naming.spi.NamingManager#setInitialContextFactoryBuilder
  66. * @since 1.3
  67. */
  68. public class InitialLdapContext extends InitialDirContext implements LdapContext {
  69. private static final String
  70. BIND_CONTROLS_PROPERTY = "java.naming.ldap.control.connect";
  71. /**
  72. * Constructs an initial context using no environment properties or
  73. * connection request controls.
  74. * Equivalent to <tt>new InitialLdapContext(null, null)</tt>.
  75. *
  76. * @throws NamingException if a naming exception is encountered
  77. */
  78. public InitialLdapContext() throws NamingException {
  79. super(null);
  80. }
  81. /**
  82. * Constructs an initial context
  83. * using environment properties and connection request controls.
  84. * See <tt>javax.naming.InitialContext</tt> for a discussion of
  85. * environment properties.
  86. *
  87. * <p> This constructor will not modify its parameters or
  88. * save references to them, but may save a clone or copy.
  89. *
  90. * <p> <tt>connCtls</tt> is used as the underlying context instance's
  91. * connection request controls. See the class description
  92. * for details.
  93. *
  94. * @param environment
  95. * environment used to create the initial DirContext.
  96. * Null indicates an empty environment.
  97. * @param connCtls
  98. * connection request controls for the initial context.
  99. * If null, no connection request controls are used.
  100. *
  101. * @throws NamingException if a naming exception is encountered
  102. *
  103. * @see #reconnect
  104. * @see LdapContext#reconnect
  105. */
  106. public InitialLdapContext(Hashtable environment, Control[] connCtls)
  107. throws NamingException {
  108. super(true); // don't initialize yet
  109. // Clone environment since caller owns it.
  110. Hashtable env = (environment == null)
  111. ? new Hashtable(11)
  112. : (Hashtable)environment.clone();
  113. // Put connect controls into environment. Copy them first since
  114. // caller owns the array.
  115. if (connCtls != null) {
  116. Control[] copy = new Control[connCtls.length];
  117. System.arraycopy(connCtls, 0, copy, 0, connCtls.length);
  118. env.put(BIND_CONTROLS_PROPERTY, copy);
  119. }
  120. // set version to LDAPv3
  121. env.put("java.naming.ldap.version", "3");
  122. // Initialize with updated environment
  123. init(env);
  124. }
  125. /**
  126. * Retrieves the initial LDAP context.
  127. *
  128. * @return The non-null cached initial context.
  129. * @exception NotContextException If the initial context is not an
  130. * instance of <tt>LdapContext</tt>.
  131. * @exception NamingException If a naming exception was encountered.
  132. */
  133. private LdapContext getDefaultLdapInitCtx() throws NamingException{
  134. Context answer = getDefaultInitCtx();
  135. if (!(answer instanceof LdapContext)) {
  136. if (answer == null) {
  137. throw new NoInitialContextException();
  138. } else {
  139. throw new NotContextException(
  140. "Not an instance of LdapContext");
  141. }
  142. }
  143. return (LdapContext)answer;
  144. }
  145. // LdapContext methods
  146. // Most Javadoc is deferred to the LdapContext interface.
  147. public ExtendedResponse extendedOperation(ExtendedRequest request)
  148. throws NamingException {
  149. return getDefaultLdapInitCtx().extendedOperation(request);
  150. }
  151. public LdapContext newInstance(Control[] reqCtls)
  152. throws NamingException {
  153. return getDefaultLdapInitCtx().newInstance(reqCtls);
  154. }
  155. public void reconnect(Control[] connCtls) throws NamingException {
  156. getDefaultLdapInitCtx().reconnect(connCtls);
  157. }
  158. public Control[] getConnectControls() throws NamingException {
  159. return getDefaultLdapInitCtx().getConnectControls();
  160. }
  161. public void setRequestControls(Control[] requestControls)
  162. throws NamingException {
  163. getDefaultLdapInitCtx().setRequestControls(requestControls);
  164. }
  165. public Control[] getRequestControls() throws NamingException {
  166. return getDefaultLdapInitCtx().getRequestControls();
  167. }
  168. public Control[] getResponseControls() throws NamingException {
  169. return getDefaultLdapInitCtx().getResponseControls();
  170. }
  171. }