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