001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.protocols.internal;
028    
029    
030    
031    import java.net.InetAddress;
032    import java.nio.ByteBuffer;
033    import java.util.ArrayList;
034    import java.util.Collection;
035    import java.util.LinkedHashMap;
036    import java.util.LinkedHashSet;
037    import java.util.LinkedList;
038    import java.util.List;
039    import java.util.Map;
040    import java.util.concurrent.atomic.AtomicInteger;
041    import java.util.concurrent.atomic.AtomicLong;
042    
043    import org.opends.messages.Message;
044    import org.opends.server.api.ClientConnection;
045    import org.opends.server.api.ConnectionHandler;
046    import org.opends.server.api.ConnectionSecurityProvider;
047    import org.opends.server.core.*;
048    import org.opends.server.extensions.*;
049    import org.opends.server.loggers.debug.DebugTracer;
050    import org.opends.server.protocols.asn1.ASN1OctetString;
051    import org.opends.server.types.AbstractOperation;
052    import org.opends.server.types.Attribute;
053    import org.opends.server.types.AttributeType;
054    import org.opends.server.types.AttributeValue;
055    import org.opends.server.types.AuthenticationInfo;
056    import org.opends.server.types.ByteString;
057    import org.opends.server.types.CancelRequest;
058    import org.opends.server.types.CancelResult;
059    import org.opends.server.types.Control;
060    import org.opends.server.types.DN;
061    import org.opends.server.types.DebugLogLevel;
062    import org.opends.server.types.DereferencePolicy;
063    import org.opends.server.types.DirectoryException;
064    import org.opends.server.types.DisconnectReason;
065    import org.opends.server.types.Entry;
066    import org.opends.server.types.IntermediateResponse;
067    import org.opends.server.types.LDAPException;
068    import org.opends.server.types.Modification;
069    import org.opends.server.types.ObjectClass;
070    import org.opends.server.types.Operation;
071    import org.opends.server.types.Privilege;
072    import org.opends.server.types.RDN;
073    import org.opends.server.types.RawAttribute;
074    import org.opends.server.types.RawFilter;
075    import org.opends.server.types.RawModification;
076    import org.opends.server.types.ResultCode;
077    import org.opends.server.types.SearchFilter;
078    import org.opends.server.types.SearchResultEntry;
079    import org.opends.server.types.SearchResultReference;
080    import org.opends.server.types.SearchScope;
081    import org.opends.server.util.AddChangeRecordEntry;
082    import org.opends.server.util.DeleteChangeRecordEntry;
083    import org.opends.server.util.ModifyChangeRecordEntry;
084    import org.opends.server.util.ModifyDNChangeRecordEntry;
085    
086    import static org.opends.messages.ProtocolMessages.*;
087    import static org.opends.server.config.ConfigConstants.*;
088    import static org.opends.server.loggers.ErrorLogger.logError;
089    import static org.opends.server.loggers.debug.DebugLogger.*;
090    import static org.opends.server.util.ServerConstants.*;
091    import static org.opends.server.util.StaticUtils.*;
092    
093    
094    
095    /**
096     * This class defines a pseudo-connection object that can be used for
097     * performing internal operations.
098     */
099    @org.opends.server.types.PublicAPI(
100         stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
101         mayInstantiate=true,
102         mayExtend=false,
103         mayInvoke=true)
104    public final class InternalClientConnection
105           extends ClientConnection
106    {
107      /**
108       * The tracer object for the debug logger.
109       */
110      private static final DebugTracer TRACER = getTracer();
111    
112      /**
113       * The protocol verison string that will be used for internal bind
114       * operations.  Since this is modeled after LDAPv3 binds, it will
115       * use a version number string of "3".
116       */
117      public static final String PROTOCOL_VERSION = "3";
118    
119    
120    
121      // The message ID counter to use for internal connections.
122      private static AtomicInteger nextMessageID;
123    
124      // The connection ID counter to use for internal connections.
125      private static AtomicLong nextConnectionID;
126    
127      // The operation ID counter to use for operations on this
128      // connection.
129      private static AtomicLong nextOperationID;
130    
131      // The connection security provider for this client connection.
132      private ConnectionSecurityProvider securityProvider;
133    
134      // The static connection for root-based connections.
135      private static InternalClientConnection rootConnection;
136    
137      // The authentication info for this connection.
138      private AuthenticationInfo authenticationInfo;
139    
140      // The empty operation list for this connection.
141      private LinkedList<AbstractOperation> operationList;
142    
143      // The connection ID for this client connection.
144      private long connectionID;
145    
146    
147    
148      static
149      {
150        nextMessageID    = new AtomicInteger(1);
151        nextConnectionID = new AtomicLong(-1);
152        nextOperationID  = new AtomicLong(0);
153      }
154    
155    
156    
157      /**
158       * Creates a new internal client connection that will be
159       * authenticated as a root user for which access control will not be
160       * enforced.
161       */
162      private InternalClientConnection()
163      {
164        super();
165    
166    
167        // This connection will be authenticated as a root user so that no
168        // access control will be enforced.
169        String commonName    = "Internal Client";
170        String shortDNString = "cn=" + commonName;
171        String fullDNString  = shortDNString + ",cn=Root DNs,cn=config";
172        try
173        {
174          LinkedHashMap<ObjectClass,String> objectClasses =
175               new LinkedHashMap<ObjectClass,String>();
176          ObjectClass topOC = DirectoryServer.getTopObjectClass();
177          ObjectClass personOC = DirectoryServer.getObjectClass(OC_PERSON,
178                                                                true);
179          ObjectClass rootOC = DirectoryServer.getObjectClass(OC_ROOT_DN,
180                                                              true);
181    
182          objectClasses.put(topOC, topOC.getPrimaryName());
183          objectClasses.put(personOC, personOC.getPrimaryName());
184          objectClasses.put(rootOC, rootOC.getPrimaryName());
185    
186    
187          LinkedHashMap<AttributeType,List<Attribute>> userAttrs =
188               new LinkedHashMap<AttributeType,List<Attribute>>();
189          AttributeType cnAT =
190               DirectoryServer.getAttributeType(ATTR_COMMON_NAME, true);
191          AttributeType snAT = DirectoryServer.getAttributeType(ATTR_SN,
192                                                                true);
193          AttributeType altDNAT =
194               DirectoryServer.getAttributeType(
195                    ATTR_ROOTDN_ALTERNATE_BIND_DN, true);
196    
197          LinkedList<Attribute> attrList = new LinkedList<Attribute>();
198          attrList.add(new Attribute(ATTR_COMMON_NAME, commonName));
199          userAttrs.put(cnAT, attrList);
200    
201          attrList = new LinkedList<Attribute>();
202          attrList.add(new Attribute(ATTR_SN, commonName));
203          userAttrs.put(snAT, attrList);
204    
205          attrList = new LinkedList<Attribute>();
206          attrList.add(new Attribute(ATTR_ROOTDN_ALTERNATE_BIND_DN,
207                                     shortDNString));
208          userAttrs.put(altDNAT, attrList);
209    
210    
211          LinkedHashMap<AttributeType,List<Attribute>> operationalAttrs =
212               new LinkedHashMap<AttributeType,List<Attribute>>();
213    
214          AttributeType privType =
215               DirectoryServer.getAttributeType(OP_ATTR_PRIVILEGE_NAME,
216                                                true);
217    
218          LinkedHashSet<AttributeValue> values =
219               new LinkedHashSet<AttributeValue>();
220          for (Privilege p : Privilege.getDefaultRootPrivileges())
221          {
222            values.add(new AttributeValue(privType, p.getName()));
223          }
224          Attribute privAttr =
225               new Attribute(privType, OP_ATTR_PRIVILEGE_NAME, values);
226          attrList = new LinkedList<Attribute>();
227          attrList.add(privAttr);
228    
229          operationalAttrs.put(privType, attrList);
230    
231    
232          DN internalUserDN = DN.decode(fullDNString);
233          Entry internalUserEntry =
234                     new Entry(internalUserDN, objectClasses, userAttrs,
235                               operationalAttrs);
236    
237          this.authenticationInfo =
238               new AuthenticationInfo(internalUserEntry, true);
239          super.setAuthenticationInfo(authenticationInfo);
240          super.setSizeLimit(0);
241          super.setTimeLimit(0);
242          super.setIdleTimeLimit(0);
243          super.setLookthroughLimit(0);
244        }
245        catch (DirectoryException de)
246        {
247          if (debugEnabled())
248          {
249            TRACER.debugCaught(DebugLogLevel.ERROR, de);
250          }
251    
252          logError(ERR_INTERNAL_CANNOT_DECODE_DN.get(
253              fullDNString, getExceptionMessage(de)));
254        }
255    
256        connectionID  = nextConnectionID.getAndDecrement();
257        operationList = new LinkedList<AbstractOperation>();
258    
259        try
260        {
261          securityProvider = new InternalConnectionSecurityProvider();
262          securityProvider.initializeConnectionSecurityProvider(null);
263        }
264        catch (Exception e)
265        {
266          if (debugEnabled())
267          {
268            TRACER.debugCaught(DebugLogLevel.ERROR, e);
269          }
270        }
271      }
272    
273    
274    
275      /**
276       * Creates a new internal client connection that will be
277       * authenticated as the specified user.
278       *
279       * @param  authInfo  The authentication information to use for the
280       *                   connection.
281       */
282      public InternalClientConnection(AuthenticationInfo authInfo)
283      {
284        super();
285    
286    
287        this.authenticationInfo = authInfo;
288        super.setAuthenticationInfo(authInfo);
289        super.setSizeLimit(0);
290        super.setTimeLimit(0);
291        super.setIdleTimeLimit(0);
292        super.setLookthroughLimit(0);
293    
294        connectionID  = nextConnectionID.getAndDecrement();
295        operationList = new LinkedList<AbstractOperation>();
296    
297        try
298        {
299          securityProvider = new InternalConnectionSecurityProvider();
300          securityProvider.initializeConnectionSecurityProvider(null);
301        }
302        catch (Exception e)
303        {
304          if (debugEnabled())
305          {
306            TRACER.debugCaught(DebugLogLevel.ERROR, e);
307          }
308        }
309      }
310    
311    
312    
313      /**
314       * Creates a new internal client connection that will be
315       * authenticated as the specified user.
316       *
317       * @param  userDN  The DN of the entry to use as the
318       *                 authentication and authorization identity.
319       *
320       * @throws  DirectoryException  If a problem occurs while trying to
321       *                              get the entry for the provided user
322       *                              DN.
323       */
324      public InternalClientConnection(DN userDN)
325             throws DirectoryException
326      {
327        this(getAuthInfoForDN(userDN));
328      }
329    
330    
331    
332      /**
333       * Creates an authentication information object for the user with
334       * the specified DN.
335       *
336       * @param  userDN  The DN of the user for whom to create an
337       *                 authentication information object.
338       *
339       * @return  The appropriate authentication information object.
340       *
341       * @throws  DirectoryException  If a problem occurs while trying to
342       *                              create the authentication
343       *                              information object, or there is no
344       *                              such user in the directory.
345       */
346      private static AuthenticationInfo getAuthInfoForDN(DN userDN)
347              throws DirectoryException
348      {
349        if ((userDN == null) || userDN.isNullDN())
350        {
351          return new AuthenticationInfo();
352        }
353    
354        DN rootUserDN = DirectoryServer.getActualRootBindDN(userDN);
355        if (rootUserDN != null)
356        {
357          userDN = rootUserDN;
358        }
359    
360        Entry userEntry = DirectoryServer.getEntry(userDN);
361        if (userEntry == null)
362        {
363          Message m =
364               ERR_INTERNALCONN_NO_SUCH_USER.get(String.valueOf(userDN));
365          throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, m);
366        }
367    
368        boolean isRoot = DirectoryServer.isRootDN(userDN);
369        return new AuthenticationInfo(userEntry, isRoot);
370      }
371    
372    
373    
374      /**
375       * Retrieves a shared internal client connection that is
376       * authenticated as a root user.
377       *
378       * @return  A shared internal client connection that is
379       *          authenticated as a root user.
380       */
381      public static InternalClientConnection getRootConnection()
382      {
383        if (rootConnection == null)
384        {
385          rootConnection = new InternalClientConnection();
386        }
387    
388        return rootConnection;
389      }
390    
391    
392    
393      /**
394       * Retrieves the operation ID that should be used for the next
395       * internal operation.
396       *
397       * @return  The operation ID that should be used for the next
398       *          internal operation.
399       */
400      public static long nextOperationID()
401      {
402        long opID = nextOperationID.getAndIncrement();
403        if (opID < 0)
404        {
405          synchronized (nextOperationID)
406          {
407            if (nextOperationID.get() < 0)
408            {
409              nextOperationID.set(1);
410              return 0;
411            }
412            else
413            {
414              return nextOperationID.getAndIncrement();
415            }
416          }
417        }
418    
419        return opID;
420      }
421    
422    
423    
424      /**
425       * Retrieves the message ID that should be used for the next
426       * internal operation.
427       *
428       * @return  The message ID that should be used for the next internal
429       *          operation.
430       */
431      public static int nextMessageID()
432      {
433        int msgID = nextMessageID.getAndIncrement();
434        if (msgID < 0)
435        {
436          synchronized (nextMessageID)
437          {
438            if (nextMessageID.get() < 0)
439            {
440              nextMessageID.set(2);
441              return 1;
442            }
443            else
444            {
445              return nextMessageID.getAndIncrement();
446            }
447          }
448        }
449    
450        return msgID;
451      }
452    
453    
454    
455      /**
456       * Retrieves the unique identifier that has been assigned to this
457       * connection.
458       *
459       * @return  The unique identifier that has been assigned to this
460       *          connection.
461       */
462      @Override()
463      public long getConnectionID()
464      {
465        return connectionID;
466      }
467    
468    
469    
470      /**
471       * Retrieves the connection handler that accepted this client
472       * connection.
473       *
474       * @return  The connection handler that accepted this client
475       *          connection.
476       */
477      @org.opends.server.types.PublicAPI(
478           stability=org.opends.server.types.StabilityLevel.PRIVATE,
479           mayInstantiate=false,
480           mayExtend=false,
481           mayInvoke=false)
482      @Override()
483      public ConnectionHandler getConnectionHandler()
484      {
485        return InternalConnectionHandler.getInstance();
486      }
487    
488    
489    
490      /**
491       * Retrieves the protocol that the client is using to communicate
492       * with the Directory Server.
493       *
494       * @return  The protocol that the client is using to communicate
495       *          with the Directory Server.
496       */
497      @Override()
498      public String getProtocol()
499      {
500        return "internal";
501      }
502    
503    
504    
505      /**
506       * Retrieves a string representation of the address of the client.
507       *
508       * @return  A string representation of the address of the client.
509       */
510      @Override()
511      public String getClientAddress()
512      {
513        return "internal";
514      }
515    
516    
517    
518      /**
519       * Retrieves a string representation of the address on the server to
520       * which the client connected.
521       *
522       * @return  A string representation of the address on the server to
523       *          which the client connected.
524       */
525      @Override()
526      public String getServerAddress()
527      {
528        return "internal";
529      }
530    
531    
532    
533      /**
534       * Retrieves the <CODE>java.net.InetAddress</CODE> associated with
535       * the remote client system.
536       *
537       * @return  The <CODE>java.net.InetAddress</CODE> associated with
538       *          the remote client system.  It may be <CODE>null</CODE>
539       *          if the client is not connected over an IP-based
540       *          connection.
541       */
542      @Override()
543      public InetAddress getRemoteAddress()
544      {
545        return null;
546      }
547    
548    
549    
550      /**
551       * Retrieves the <CODE>java.net.InetAddress</CODE> for the Directory
552       * Server system to which the client has established the connection.
553       *
554       * @return  The <CODE>java.net.InetAddress</CODE> for the Directory
555       *          Server system to which the client has established the
556       *          connection.  It may be <CODE>null</CODE> if the client
557       *          is not connected over an IP-based connection.
558       */
559      @Override()
560      public InetAddress getLocalAddress()
561      {
562        return null;
563      }
564    
565    
566    
567      /**
568       * Specifies the size limit that will be enforced for searches
569       * performed using this client connection.  This method does nothing
570       * because connection-level size limits will never be enforced for
571       * internal client connections.
572       *
573       * @param  sizeLimit  The size limit that will be enforced for
574       *                    searches performed using this client
575       *                    connection.
576       */
577      @Override()
578      public void setSizeLimit(int sizeLimit)
579      {
580        // No implementation required.  We never want to set a nonzero
581        // size limit for internal client connections.
582      }
583    
584    
585    
586      /**
587       * Specifies the default maximum number of entries that should
588       * be checked for matches during a search.  This method does nothing
589       * because connection-level lookthrough limits will never be
590       * enforced for internal client connections
591       *
592       * @param  lookthroughLimit  The default maximum number of
593       *                           entries that should be check for
594       *                           matches during a search.
595       */
596      @Override()
597      public void setLookthroughLimit(int lookthroughLimit)
598      {
599        // No implementation required.  We never want to set a nonzero
600        // lookthrough limit for internal client connections.
601      }
602    
603    
604    
605      /**
606       * Specifies the maximum length of time in milliseconds that this
607       * client connection will be allowed to remain idle before it should
608       * be disconnected.  This method does nothing because internal
609       * client connections will not be terminated due to an idle time
610       * limit.
611       *
612       * @param  idleTimeLimit  The maximum length of time in milliseconds
613       *                        that this client connection will be
614       *                        allowed to remain idle before it should be
615       *                        disconnected.
616       */
617      @Override()
618      public void setIdleTimeLimit(long idleTimeLimit)
619      {
620        // No implementation rqeuired.  We never want to set a nonzero
621        // idle time limit for internal client connections.
622      }
623    
624    
625    
626      /**
627       * Specifies the time limit that will be enforced for searches
628       * performed using this client connection.  This method does nothing
629       * because connection-level tim elimits will never be enforced for
630       * internal client connections.
631       *
632       * @param  timeLimit  The time limit that will be enforced for
633       *                    searches performed using this client
634       *                    connection.
635       */
636      @Override()
637      public void setTimeLimit(int timeLimit)
638      {
639        // No implementation required.  We never want to set a nonzero
640        // time limit for internal client connections.
641      }
642    
643    
644    
645      /**
646       * Indicates whether this client connection is currently using a
647       * secure mechanism to communicate with the server.  Note that this
648       * may change over time based on operations performed by the client
649       * or server (e.g., it may go from <CODE>false</CODE> to
650       * <CODE>true</CODE> if the client uses the StartTLS extended
651       * operation).
652       *
653       * @return  <CODE>true</CODE> if the client connection is currently
654       *          using a secure mechanism to communicate with the server,
655       *          or <CODE>false</CODE> if not.
656       */
657      @Override()
658      public boolean isSecure()
659      {
660        // Internal connections will generally be considered secure, but
661        // they may be declared insecure if they are accessed through some
662        // external mechanism (e.g., a DSML handler that runs the server
663        // in a Servlet engine and using internal operations for
664        // processing requests).
665        return securityProvider.isSecure();
666      }
667    
668    
669    
670      /**
671       * Retrieves the connection security provider for this client
672       * connection.
673       *
674       * @return  The connection security provider for this client
675       *          connection.
676       */
677      @Override()
678      public ConnectionSecurityProvider getConnectionSecurityProvider()
679      {
680        return securityProvider;
681      }
682    
683    
684    
685      /**
686       * Specifies the connection security provider for this client
687       * connection.
688       *
689       * @param  securityProvider  The connection security provider to use
690       *                           for communication on this client
691       *                           connection.
692       */
693      @org.opends.server.types.PublicAPI(
694           stability=org.opends.server.types.StabilityLevel.PRIVATE,
695           mayInstantiate=false,
696           mayExtend=false,
697           mayInvoke=false)
698      @Override()
699      public void setConnectionSecurityProvider(ConnectionSecurityProvider
700                                                     securityProvider)
701      {
702        this.securityProvider = securityProvider;
703      }
704    
705    
706    
707      /**
708       * Retrieves the human-readable name of the security mechanism that
709       * is used to protect communication with this client.
710       *
711       * @return  The human-readable name of the security mechanism that
712       *          is used to protect communication with this client, or
713       *          <CODE>null</CODE> if no security is in place.
714       */
715      @Override()
716      public String getSecurityMechanism()
717      {
718        return securityProvider.getSecurityMechanismName();
719      }
720    
721    
722    
723      /**
724       * Indicates that the data in the provided buffer has been read from
725       * the client and should be processed.  The contents of the provided
726       * buffer will be in clear-text (the data may have been passed
727       * through a connection security provider to obtain the clear-text
728       * version), and may contain part or all of one or more client
729       * requests.
730       *
731       * @param  buffer  The byte buffer containing the data available for
732       *                 reading.
733       *
734       * @return  <CODE>true</CODE> if all the data in the provided buffer
735       *          was processed and the client connection can remain
736       *          established, or <CODE>false</CODE> if a decoding error
737       *          occurred and requests from this client should no longer
738       *          be processed.  Note that if this method does return
739       *          <CODE>false</CODE>, then it must have already
740       *          disconnected the client.
741       */
742      @org.opends.server.types.PublicAPI(
743           stability=org.opends.server.types.StabilityLevel.PRIVATE,
744           mayInstantiate=false,
745           mayExtend=false,
746           mayInvoke=false)
747      @Override()
748      public boolean processDataRead(ByteBuffer buffer)
749      {
750        // This method will not do anything with the data because there is
751        // no actual "connection" from which information can be read, nor
752        // any protocol to use to read it.
753        return false;
754      }
755    
756    
757    
758      /**
759       * Sends a response to the client based on the information in the
760       * provided operation.
761       *
762       * @param  operation  The operation for which to send the response.
763       */
764      @org.opends.server.types.PublicAPI(
765           stability=org.opends.server.types.StabilityLevel.PRIVATE,
766           mayInstantiate=false,
767           mayExtend=false,
768           mayInvoke=false)
769      @Override()
770      public void sendResponse(Operation operation)
771      {
772        // There will not be any response sent by this method, since there
773        // is not an actual connection.
774      }
775    
776    
777    
778      /**
779       * Retrieves information about the authentication that has been
780       * performed for this connection.
781       *
782       * @return  Information about the user that is currently
783       *          authenticated on this connection.
784       */
785      @Override()
786      public AuthenticationInfo getAuthenticationInfo()
787      {
788        return authenticationInfo;
789      }
790    
791    
792    
793      /**
794       * This method has no effect, as the authentication info for
795       * internal client connections is set when the connection is created
796       * and cannot be changed after the fact.
797       *
798       * @param  authenticationInfo  Information about the authentication
799       *                             that has been performed for this
800       *                             connection.  It should not be
801       *                             <CODE>null</CODE>.
802       */
803      @org.opends.server.types.PublicAPI(
804           stability=org.opends.server.types.StabilityLevel.PRIVATE,
805           mayInstantiate=false,
806           mayExtend=false,
807           mayInvoke=false)
808      @Override()
809      public void setAuthenticationInfo(AuthenticationInfo
810                                             authenticationInfo)
811      {
812        // No implementation required.
813      }
814    
815    
816    
817      /**
818       * This method has no effect, as the authentication info for
819       * internal client connections is set when the connection is created
820       * and cannot be changed after the fact.
821       */
822      @org.opends.server.types.PublicAPI(
823           stability=org.opends.server.types.StabilityLevel.PRIVATE,
824           mayInstantiate=false,
825           mayExtend=false,
826           mayInvoke=false)
827      @Override()
828      public void setUnauthenticated()
829      {
830        // No implementation required.
831      }
832    
833    
834    
835      /**
836       * Processes an internal add operation with the provided
837       * information.
838       *
839       * @param  rawEntryDN     The DN to use for the entry to add.
840       * @param  rawAttributes  The set of attributes to include in the
841       *                        entry to add.
842       *
843       * @return  A reference to the add operation that was processed and
844       *          contains information about the result of the processing.
845       */
846      public AddOperation processAdd(String rawEntryDN,
847                                     List<RawAttribute> rawAttributes)
848      {
849        return processAdd(new ASN1OctetString(rawEntryDN), rawAttributes,
850                          null);
851      }
852    
853    
854    
855      /**
856       * Processes an internal add operation with the provided
857       * information.
858       *
859       * @param  rawEntryDN     The DN to use for the entry to add.
860       * @param  rawAttributes  The set of attributes to include in the
861       *                        entry to add.
862       *
863       * @return  A reference to the add operation that was processed and
864       *          contains information about the result of the processing.
865       */
866      public AddOperation processAdd(ByteString rawEntryDN,
867                                     List<RawAttribute> rawAttributes)
868      {
869        return processAdd(rawEntryDN, rawAttributes, null);
870      }
871    
872    
873    
874      /**
875       * Processes an internal add operation with the provided
876       * information.
877       *
878       * @param  rawEntryDN     The DN to use for the entry to add.
879       * @param  rawAttributes  The set of attributes to include in the
880       *                        entry to add.
881       * @param  controls       The set of controls to include in the
882       *                        request.
883       *
884       * @return  A reference to the add operation that was processed and
885       *          contains information about the result of the processing.
886       */
887      public AddOperation processAdd(ByteString rawEntryDN,
888                                     List<RawAttribute> rawAttributes,
889                                     List<Control> controls)
890      {
891        if (controls == null)
892        {
893          controls = new ArrayList<Control>(0);
894        }
895    
896        AddOperationBasis addOperation =
897             new AddOperationBasis(this, nextOperationID(),
898                              nextMessageID(), controls, rawEntryDN,
899                              rawAttributes);
900        addOperation.setInternalOperation(true);
901    
902        addOperation.run();
903        return addOperation;
904      }
905    
906    
907    
908      /**
909       * Processes an internal add operation with the provided
910       * information.
911       *
912       * @param  entryDN                The entry DN for the add
913       *                                operation.
914       * @param  objectClasses          The set of objectclasses for the
915       *                                add operation.
916       * @param  userAttributes         The set of user attributes for the
917       *                                add operation.
918       * @param  operationalAttributes  The set of operational attributes
919       *                                for the add operation.
920       *
921       * @return  A reference to the add operation that was processed and
922       *          contains information about the result of the processing.
923       */
924      public AddOperation processAdd(DN entryDN,
925                               Map<ObjectClass,String> objectClasses,
926                               Map<AttributeType,List<Attribute>>
927                                    userAttributes,
928                               Map<AttributeType,List<Attribute>>
929                                    operationalAttributes)
930      {
931        return processAdd(entryDN, objectClasses, userAttributes,
932                          operationalAttributes, null);
933      }
934    
935    
936    
937      /**
938       * Processes an internal add operation with the provided
939       * information.
940       *
941       * @param  entryDN                The entry DN for the add
942       *                                operation.
943       * @param  objectClasses          The set of objectclasses for the
944       *                                add operation.
945       * @param  userAttributes         The set of user attributes for the
946       *                                add operation.
947       * @param  operationalAttributes  The set of operational attributes
948       *                                for the add operation.
949       * @param  controls               The set of controls to include in
950       *                                the request.
951       *
952       * @return  A reference to the add operation that was processed and
953       *          contains information about the result of the processing.
954       */
955      public AddOperation processAdd(DN entryDN,
956                               Map<ObjectClass,String> objectClasses,
957                               Map<AttributeType,List<Attribute>>
958                                    userAttributes,
959                               Map<AttributeType,List<Attribute>>
960                                    operationalAttributes,
961                               List<Control> controls)
962      {
963        if (controls == null)
964        {
965          controls = new ArrayList<Control>(0);
966        }
967    
968        AddOperationBasis addOperation =
969             new AddOperationBasis(this, nextOperationID(),
970                              nextMessageID(), controls, entryDN,
971                              objectClasses, userAttributes,
972                              operationalAttributes);
973        addOperation.setInternalOperation(true);
974    
975        addOperation.run();
976        return addOperation;
977      }
978    
979    
980    
981      /**
982       * Processes an internal add operation with the provided
983       * information.
984       *
985       * @param  entry  The entry to be added.
986       *
987       * @return  A reference to the add operation that was processed and
988       *          contains information about the result of the processing.
989       */
990      public AddOperation processAdd(Entry entry)
991      {
992        return processAdd(entry, null);
993      }
994    
995    
996    
997      /**
998       * Processes an internal add operation with the provided
999       * information.
1000       *
1001       * @param  entry     The entry to be added.
1002       * @param  controls  The set of controls to include in the request.
1003       *
1004       * @return  A reference to the add operation that was processed and
1005       *          contains information about the result of the processing.
1006       */
1007      public AddOperation processAdd(Entry entry, List<Control> controls)
1008      {
1009        if (controls == null)
1010        {
1011          controls = new ArrayList<Control>(0);
1012        }
1013    
1014        return processAdd(entry.getDN(), entry.getObjectClasses(),
1015                          entry.getUserAttributes(),
1016                          entry.getOperationalAttributes());
1017      }
1018    
1019    
1020    
1021      /**
1022       * Processes an internal add operation based on the provided add
1023       * change record entry.
1024       *
1025       * @param  addRecord  The add change record entry to be processed.
1026       *
1027       * @return  A reference to the add operation that was processed and
1028       *          contains information about the result of the processing.
1029       */
1030      public AddOperation processAdd(AddChangeRecordEntry addRecord)
1031      {
1032        LinkedHashMap<ObjectClass,String> objectClasses =
1033             new LinkedHashMap<ObjectClass,String>();
1034        LinkedHashMap<AttributeType,List<Attribute>> userAttrs =
1035             new LinkedHashMap<AttributeType,List<Attribute>>();
1036        LinkedHashMap<AttributeType,List<Attribute>> opAttrs =
1037             new LinkedHashMap<AttributeType,List<Attribute>>();
1038    
1039        Entry e = new Entry(addRecord.getDN(), objectClasses, userAttrs,
1040                            opAttrs);
1041    
1042        ArrayList<AttributeValue> duplicateValues =
1043             new ArrayList<AttributeValue>();
1044        for (Attribute a : addRecord.getAttributes())
1045        {
1046          if (a.getAttributeType().isObjectClassType())
1047          {
1048            for (AttributeValue v : a.getValues())
1049            {
1050              String ocName = v.getStringValue();
1051              String lowerName = toLowerCase(ocName);
1052              ObjectClass oc = DirectoryServer.getObjectClass(lowerName,
1053                                                              true);
1054              objectClasses.put(oc, ocName);
1055            }
1056          }
1057          else
1058          {
1059            e.addAttribute(a, duplicateValues);
1060          }
1061        }
1062    
1063        return processAdd(addRecord.getDN(), objectClasses, userAttrs,
1064                          opAttrs);
1065      }
1066    
1067    
1068    
1069      /**
1070       * Processes an internal bind operation with the provided
1071       * information.  Note that regardless of whether the bind is
1072       * successful, the authentication state for this internal connection
1073       * will not be altered in any way.
1074       *
1075       * @param  rawBindDN  The bind DN for the operation.
1076       * @param  password   The bind password for the operation.
1077       *
1078       * @return  A reference to the bind operation that was processed and
1079       *          contains information about the result of the processing.
1080       */
1081      public BindOperation processSimpleBind(String rawBindDN,
1082                                             String password)
1083      {
1084        return processSimpleBind(new ASN1OctetString(rawBindDN),
1085                                 new ASN1OctetString(password),
1086                                 null);
1087      }
1088    
1089    
1090    
1091      /**
1092       * Processes an internal bind operation with the provided
1093       * information.  Note that regardless of whether the bind is
1094       * successful, the authentication state for this internal connection
1095       * will not be altered in any way.
1096       *
1097       * @param  rawBindDN  The bind DN for the operation.
1098       * @param  password   The bind password for the operation.
1099       * @param  controls   The set of controls to include in the
1100       *                    request.
1101       *
1102       * @return  A reference to the bind operation that was processed and
1103       *          contains information about the result of the processing.
1104       */
1105      public BindOperation processSimpleBind(String rawBindDN,
1106                                             String password,
1107                                             List<Control> controls)
1108      {
1109        return processSimpleBind(new ASN1OctetString(rawBindDN),
1110                                 new ASN1OctetString(password), controls);
1111      }
1112    
1113    
1114    
1115      /**
1116       * Processes an internal bind operation with the provided
1117       * information.  Note that regardless of whether the bind is
1118       * successful, the authentication state for this internal connection
1119       * will not be altered in any way.
1120       *
1121       * @param  rawBindDN  The bind DN for the operation.
1122       * @param  password   The bind password for the operation.
1123       *
1124       * @return  A reference to the bind operation that was processed and
1125       *          contains information about the result of the processing.
1126       */
1127      public BindOperation processSimpleBind(ByteString rawBindDN,
1128                                             ByteString password)
1129      {
1130        return processSimpleBind(rawBindDN, password, null);
1131      }
1132    
1133    
1134    
1135      /**
1136       * Processes an internal bind operation with the provided
1137       * information.  Note that regardless of whether the bind is
1138       * successful, the authentication state for this internal connection
1139       * will not be altered in any way.
1140       *
1141       * @param  rawBindDN  The bind DN for the operation.
1142       * @param  password   The bind password for the operation.
1143       * @param  controls   The set of controls to include in the request.
1144       *
1145       * @return  A reference to the bind operation that was processed and
1146       *          contains information about the result of the processing.
1147       */
1148      public BindOperation processSimpleBind(ByteString rawBindDN,
1149                                             ByteString password,
1150                                             List<Control> controls)
1151      {
1152        if (controls == null)
1153        {
1154          controls = new ArrayList<Control>(0);
1155        }
1156    
1157        BindOperationBasis bindOperation =
1158             new BindOperationBasis(this, nextOperationID(),
1159                               nextMessageID(), controls,
1160                               PROTOCOL_VERSION, rawBindDN, password);
1161        bindOperation.setInternalOperation(true);
1162    
1163        bindOperation.run();
1164        return bindOperation;
1165      }
1166    
1167    
1168    
1169      /**
1170       * Processes an internal bind operation with the provided
1171       * information.  Note that regardless of whether the bind is
1172       * successful, the authentication state for this internal connection
1173       * will not be altered in any way.
1174       *
1175       * @param  bindDN    The bind DN for the operation.
1176       * @param  password  The bind password for the operation.
1177       *
1178       * @return  A reference to the bind operation that was processed and
1179       *          contains information about the result of the processing.
1180       */
1181      public BindOperation processSimpleBind(DN bindDN,
1182                                             ByteString password)
1183      {
1184        return processSimpleBind(bindDN, password, null);
1185      }
1186    
1187    
1188    
1189      /**
1190       * Processes an internal bind operation with the provided
1191       * information.  Note that regardless of whether the bind is
1192       * successful, the authentication state for this internal connection
1193       * will not be altered in any way.
1194       *
1195       * @param  bindDN    The bind DN for the operation.
1196       * @param  password  The bind password for the operation.
1197       * @param  controls  The set of controls to include in the request.
1198       *
1199       * @return  A reference to the bind operation that was processed and
1200       *          contains information about the result of the processing.
1201       */
1202      public BindOperation processSimpleBind(DN bindDN,
1203                                             ByteString password,
1204                                             List<Control> controls)
1205      {
1206        if (controls == null)
1207        {
1208          controls = new ArrayList<Control>(0);
1209        }
1210    
1211        BindOperationBasis bindOperation =
1212             new BindOperationBasis(this, nextOperationID(),
1213                               nextMessageID(), controls,
1214                               PROTOCOL_VERSION, bindDN, password);
1215        bindOperation.setInternalOperation(true);
1216    
1217        bindOperation.run();
1218        return bindOperation;
1219      }
1220    
1221    
1222    
1223      /**
1224       * Processes an internal bind operation with the provided
1225       * information.  Note that regardless of whether the bind is
1226       * successful, the authentication state for this internal connection
1227       * will not be altered in any way.
1228       *
1229       * @param  rawBindDN        The bind DN for the operation.
1230       * @param  saslMechanism    The SASL mechanism for the operation.
1231       * @param  saslCredentials  The SASL credentials for the operation.
1232       *
1233       * @return  A reference to the bind operation that was processed and
1234       *          contains information about the result of the processing.
1235       */
1236      public BindOperation processSASLBind(ByteString rawBindDN,
1237                                String saslMechanism,
1238                                ASN1OctetString saslCredentials)
1239      {
1240        return processSASLBind(rawBindDN, saslMechanism, saslCredentials,
1241                               null);
1242      }
1243    
1244    
1245    
1246      /**
1247       * Processes an internal bind operation with the provided
1248       * information.  Note that regardless of whether the bind is
1249       * successful, the authentication state for this internal connection
1250       * will not be altered in any way.
1251       *
1252       * @param  rawBindDN        The bind DN for the operation.
1253       * @param  saslMechanism    The SASL mechanism for the operation.
1254       * @param  saslCredentials  The SASL credentials for the operation.
1255       * @param  controls         The set of controls to include in the
1256       *                          request.
1257       *
1258       * @return  A reference to the bind operation that was processed and
1259       *          contains information about the result of the processing.
1260       */
1261      public BindOperation processSASLBind(ByteString rawBindDN,
1262                                String saslMechanism,
1263                                ASN1OctetString saslCredentials,
1264                                List<Control> controls)
1265      {
1266        if (controls == null)
1267        {
1268          controls = new ArrayList<Control>(0);
1269        }
1270    
1271        BindOperationBasis bindOperation =
1272             new BindOperationBasis(this, nextOperationID(),
1273                               nextMessageID(), controls,
1274                               PROTOCOL_VERSION, rawBindDN, saslMechanism,
1275                               saslCredentials);
1276        bindOperation.setInternalOperation(true);
1277    
1278        bindOperation.run();
1279        return bindOperation;
1280      }
1281    
1282    
1283    
1284      /**
1285       * Processes an internal bind operation with the provided
1286       * information.  Note that regardless of whether the bind is
1287       * successful, the authentication state for this internal connection
1288       * will not be altered in any way.
1289       *
1290       * @param  bindDN           The bind DN for the operation.
1291       * @param  saslMechanism    The SASL mechanism for the operation.
1292       * @param  saslCredentials  The SASL credentials for the operation.
1293       *
1294       * @return  A reference to the bind operation that was processed and
1295       *          contains information about the result of the processing.
1296       */
1297      public BindOperation processSASLBind(DN bindDN,
1298                                String saslMechanism,
1299                                ASN1OctetString saslCredentials)
1300      {
1301        return processSASLBind(bindDN, saslMechanism, saslCredentials,
1302                               null);
1303      }
1304    
1305    
1306    
1307      /**
1308       * Processes an internal bind operation with the provided
1309       * information.  Note that regardless of whether the bind is
1310       * successful, the authentication state for this internal connection
1311       * will not be altered in any way.
1312       *
1313       * @param  bindDN           The bind DN for the operation.
1314       * @param  saslMechanism    The SASL mechanism for the operation.
1315       * @param  saslCredentials  The SASL credentials for the operation.
1316       * @param  controls         The set of controls to include in the
1317       *                          request.
1318       *
1319       * @return  A reference to the bind operation that was processed and
1320       *          contains information about the result of the processing.
1321       */
1322      public BindOperation processSASLBind(DN bindDN,
1323                                String saslMechanism,
1324                                ASN1OctetString saslCredentials,
1325                                List<Control> controls)
1326      {
1327        if (controls == null)
1328        {
1329          controls = new ArrayList<Control>(0);
1330        }
1331    
1332        BindOperationBasis bindOperation =
1333             new BindOperationBasis(this, nextOperationID(),
1334                               nextMessageID(), controls,
1335                               PROTOCOL_VERSION, bindDN, saslMechanism,
1336                               saslCredentials);
1337        bindOperation.setInternalOperation(true);
1338    
1339        bindOperation.run();
1340        return bindOperation;
1341      }
1342    
1343    
1344    
1345      /**
1346       * Processes an internal compare operation with the provided
1347       * information.
1348       *
1349       * @param  rawEntryDN      The entry DN for the compare operation.
1350       * @param  attributeType   The attribute type for the compare
1351       *                         operation.
1352       * @param  assertionValue  The assertion value for the compare
1353       *                         operation.
1354       *
1355       * @return  A reference to the compare operation that was processed
1356       *          and contains information about the result of the
1357       *          processing.
1358       */
1359      public CompareOperation processCompare(String rawEntryDN,
1360                                             String attributeType,
1361                                             String assertionValue)
1362      {
1363        return processCompare(new ASN1OctetString(rawEntryDN),
1364                              attributeType,
1365                              new ASN1OctetString(assertionValue), null);
1366      }
1367    
1368    
1369    
1370      /**
1371       * Processes an internal compare operation with the provided
1372       * information.
1373       *
1374       * @param  rawEntryDN      The entry DN for the compare operation.
1375       * @param  attributeType   The attribute type for the compare
1376       *                         operation.
1377       * @param  assertionValue  The assertion value for the compare
1378       *                         operation.
1379       * @param  controls        The set of controls to include in the
1380       *                         request.
1381       *
1382       * @return  A reference to the compare operation that was processed
1383       *          and contains information about the result of the
1384       *          processing.
1385       */
1386      public CompareOperation processCompare(String rawEntryDN,
1387                                             String attributeType,
1388                                             String assertionValue,
1389                                             List<Control> controls)
1390      {
1391        return processCompare(new ASN1OctetString(rawEntryDN),
1392                              attributeType,
1393                              new ASN1OctetString(assertionValue),
1394                              controls);
1395      }
1396    
1397    
1398    
1399      /**
1400       * Processes an internal compare operation with the provided
1401       * information.
1402       *
1403       * @param  rawEntryDN      The entry DN for the compare operation.
1404       * @param  attributeType   The attribute type for the compare
1405       *                         operation.
1406       * @param  assertionValue  The assertion value for the compare
1407       *                         operation.
1408       *
1409       * @return  A reference to the compare operation that was processed
1410       *          and contains information about the result of the
1411       *          processing.
1412       */
1413      public CompareOperation processCompare(ByteString rawEntryDN,
1414                                             String attributeType,
1415                                             ByteString assertionValue)
1416      {
1417        return processCompare(rawEntryDN, attributeType, assertionValue,
1418                              null);
1419      }
1420    
1421    
1422    
1423      /**
1424       * Processes an internal compare operation with the provided
1425       * information.
1426       *
1427       * @param  rawEntryDN      The entry DN for the compare operation.
1428       * @param  attributeType   The attribute type for the compare
1429       *                         operation.
1430       * @param  assertionValue  The assertion value for the compare
1431       *                         operation.
1432       * @param  controls        The set of controls to include in the
1433       *                         request.
1434       *
1435       * @return  A reference to the compare operation that was processed
1436       *          and contains information about the result of the
1437       *          processing.
1438       */
1439      public CompareOperation processCompare(ByteString rawEntryDN,
1440                                             String attributeType,
1441                                             ByteString assertionValue,
1442                                             List<Control> controls)
1443      {
1444        if (controls == null)
1445        {
1446          controls = new ArrayList<Control>(0);
1447        }
1448    
1449        CompareOperationBasis compareOperation =
1450             new CompareOperationBasis(this, nextOperationID(),
1451                                  nextMessageID(), controls, rawEntryDN,
1452                                  attributeType, assertionValue);
1453        compareOperation.setInternalOperation(true);
1454    
1455        compareOperation.run();
1456        return compareOperation;
1457      }
1458    
1459    
1460    
1461      /**
1462       * Processes an internal compare operation with the provided
1463       * information.
1464       *
1465       * @param  entryDN         The entry DN for the compare operation.
1466       * @param  attributeType   The attribute type for the compare
1467       *                         operation.
1468       * @param  assertionValue  The assertion value for the compare
1469       *                         operation.
1470       *
1471       * @return  A reference to the compare operation that was processed
1472       *          and contains information about the result of the
1473       *          processing.
1474       */
1475      public CompareOperation processCompare(DN entryDN,
1476                                             AttributeType attributeType,
1477                                             ByteString assertionValue)
1478      {
1479        return processCompare(entryDN, attributeType, assertionValue,
1480                              null);
1481      }
1482    
1483    
1484    
1485      /**
1486       * Processes an internal compare operation with the provided
1487       * information.
1488       *
1489       * @param  entryDN         The entry DN for the compare operation.
1490       * @param  attributeType   The attribute type for the compare
1491       *                         operation.
1492       * @param  assertionValue  The assertion value for the compare
1493       *                         operation.
1494       * @param  controls        The set of controls to include in the
1495       *                         request.
1496       *
1497       * @return  A reference to the compare operation that was processed
1498       *          and contains information about the result of the
1499       *          processing.
1500       */
1501      public CompareOperation processCompare(DN entryDN,
1502                                             AttributeType attributeType,
1503                                             ByteString assertionValue,
1504                                             List<Control> controls)
1505      {
1506        if (controls == null)
1507        {
1508          controls = new ArrayList<Control>(0);
1509        }
1510    
1511        CompareOperationBasis compareOperation =
1512             new CompareOperationBasis(this, nextOperationID(),
1513                                  nextMessageID(), controls, entryDN,
1514                                  attributeType, assertionValue);
1515        compareOperation.setInternalOperation(true);
1516    
1517        compareOperation.run();
1518        return compareOperation;
1519      }
1520    
1521    
1522    
1523      /**
1524       * Processes an internal delete operation with the provided
1525       * information.
1526       *
1527       * @param  rawEntryDN  The entry DN for the delete operation.
1528       *
1529       * @return  A reference to the delete operation that was processed
1530       *          and contains information about the result of the
1531       *          processing.
1532       */
1533      public DeleteOperation processDelete(String rawEntryDN)
1534      {
1535        return processDelete(new ASN1OctetString(rawEntryDN), null);
1536      }
1537    
1538    
1539    
1540      /**
1541       * Processes an internal delete operation with the provided
1542       * information.
1543       *
1544       * @param  rawEntryDN  The entry DN for the delete operation.
1545       * @param  controls    The set of controls to include in the
1546       *                     request.
1547       *
1548       * @return  A reference to the delete operation that was processed
1549       *          and contains information about the result of the
1550       *          processing.
1551       */
1552      public DeleteOperation processDelete(String rawEntryDN,
1553                                           List<Control> controls)
1554      {
1555        return processDelete(new ASN1OctetString(rawEntryDN), controls);
1556      }
1557    
1558    
1559    
1560      /**
1561       * Processes an internal delete operation with the provided
1562       * information.
1563       *
1564       * @param  rawEntryDN  The entry DN for the delete operation.
1565       *
1566       * @return  A reference to the delete operation that was processed
1567       *          and contains information about the result of the
1568       *          processing.
1569       */
1570      public DeleteOperation processDelete(ByteString rawEntryDN)
1571      {
1572        return processDelete(rawEntryDN, null);
1573      }
1574    
1575    
1576    
1577      /**
1578       * Processes an internal delete operation with the provided
1579       * information.
1580       *
1581       * @param  rawEntryDN  The entry DN for the delete operation.
1582       * @param  controls    The set of controls to include in the
1583       *                     request.
1584       *
1585       * @return  A reference to the delete operation that was processed
1586       *          and contains information about the result of the
1587       *          processing.
1588       */
1589      public DeleteOperation processDelete(ByteString rawEntryDN,
1590                                           List<Control> controls)
1591      {
1592        if (controls == null)
1593        {
1594          controls = new ArrayList<Control>(0);
1595        }
1596    
1597        DeleteOperationBasis deleteOperation =
1598             new DeleteOperationBasis(this, nextOperationID(),
1599                                 nextMessageID(), controls, rawEntryDN);
1600        deleteOperation.setInternalOperation(true);
1601    
1602        deleteOperation.run();
1603        return deleteOperation;
1604      }
1605    
1606    
1607    
1608      /**
1609       * Processes an internal delete operation with the provided
1610       * information.
1611       *
1612       * @param  entryDN  The entry DN for the delete operation.
1613       *
1614       * @return  A reference to the delete operation that was processed
1615       *          and contains information about the result of the
1616       *          processing.
1617       */
1618      public DeleteOperation processDelete(DN entryDN)
1619      {
1620        return processDelete(entryDN, null);
1621      }
1622    
1623    
1624    
1625      /**
1626       * Processes an internal delete operation with the provided
1627       * information.
1628       *
1629       * @param  entryDN   The entry DN for the delete operation.
1630       * @param  controls  The set of controls to include in the request.
1631       *
1632       * @return  A reference to the delete operation that was processed
1633       *          and contains information about the result of the
1634       *          processing.
1635       */
1636      public DeleteOperation processDelete(DN entryDN,
1637                                           List<Control> controls)
1638      {
1639        if (controls == null)
1640        {
1641          controls = new ArrayList<Control>(0);
1642        }
1643    
1644        DeleteOperationBasis deleteOperation =
1645             new DeleteOperationBasis(this, nextOperationID(),
1646                                 nextMessageID(), controls, entryDN);
1647        deleteOperation.setInternalOperation(true);
1648    
1649        deleteOperation.run();
1650        return deleteOperation;
1651      }
1652    
1653    
1654    
1655      /**
1656       * Processes an internal delete operation with the provided
1657       * information.
1658       *
1659       * @param  deleteRecord  The delete change record entry to be
1660       *                       processed.
1661       *
1662       * @return  A reference to the delete operation that was processed
1663       *          and contains information about the result of the
1664       *          processing.
1665       */
1666      public DeleteOperation processDelete(
1667                                  DeleteChangeRecordEntry deleteRecord)
1668      {
1669        return processDelete(deleteRecord.getDN());
1670      }
1671    
1672    
1673    
1674      /**
1675       * Processes an internal extended operation with the provided
1676       * information.
1677       *
1678       * @param  requestOID    The OID for the extended request.
1679       * @param  requestValue  The encoded value for the extended
1680       *                       operation, or <CODE>null</CODE> if there is
1681       *                       no value.
1682       *
1683       * @return  A reference to the extended operation that was processed
1684       *          and contains information about the result of the
1685       *          processing.
1686       */
1687      public ExtendedOperation processExtendedOperation(
1688                                    String requestOID,
1689                                    ASN1OctetString requestValue)
1690      {
1691        return processExtendedOperation(requestOID, requestValue, null);
1692      }
1693    
1694    
1695    
1696      /**
1697       * Processes an internal extended operation with the provided
1698       * information.
1699       *
1700       * @param  requestOID    The OID for the extended request.
1701       * @param  requestValue  The encoded value for the extended
1702       *                       operation, or <CODE>null</CODE> if there is
1703       *                       no value.
1704       * @param  controls      The set of controls to include in the
1705       *                       request.
1706       *
1707       * @return  A reference to the extended operation that was processed
1708       *          and contains information about the result of the
1709       *          processing.
1710       */
1711      public ExtendedOperation processExtendedOperation(
1712                                    String requestOID,
1713                                    ASN1OctetString requestValue,
1714                                    List<Control> controls)
1715      {
1716        if (controls == null)
1717        {
1718          controls = new ArrayList<Control>(0);
1719        }
1720    
1721        ExtendedOperationBasis extendedOperation =
1722             new ExtendedOperationBasis(this, nextOperationID(),
1723                                   nextMessageID(), controls, requestOID,
1724                                   requestValue);
1725        extendedOperation.setInternalOperation(true);
1726        extendedOperation.run();
1727        return extendedOperation;
1728      }
1729    
1730    
1731    
1732      /**
1733       * Processes an internal modify operation with the provided
1734       * information.
1735       *
1736       * @param  rawEntryDN        The raw entry DN for this modify
1737       *                           operation.
1738       * @param  rawModifications  The set of modifications for this
1739       *                           modify operation.
1740       *
1741       * @return  A reference to the modify operation that was processed
1742       *          and contains information about the result of the
1743       *          processing.
1744       */
1745      public ModifyOperation processModify(String rawEntryDN,
1746                                  List<RawModification> rawModifications)
1747      {
1748        return processModify(new ASN1OctetString(rawEntryDN),
1749                             rawModifications, null);
1750      }
1751    
1752    
1753    
1754      /**
1755       * Processes an internal modify operation with the provided
1756       * information.
1757       *
1758       * @param  rawEntryDN        The raw entry DN for this modify
1759       *                           operation.
1760       * @param  rawModifications  The set of modifications for this
1761       *                           modify operation.
1762       * @param  controls          The set of controls to include in the
1763       *                           request.
1764       *
1765       * @return  A reference to the modify operation that was processed
1766       *          and contains information about the result of the
1767       *          processing.
1768       */
1769      public ModifyOperation processModify(String rawEntryDN,
1770                                  List<RawModification> rawModifications,
1771                                  List<Control> controls)
1772      {
1773        return processModify(new ASN1OctetString(rawEntryDN),
1774                             rawModifications, controls);
1775      }
1776    
1777    
1778    
1779      /**
1780       * Processes an internal modify operation with the provided
1781       * information.
1782       *
1783       * @param  rawEntryDN        The raw entry DN for this modify
1784       *                           operation.
1785       * @param  rawModifications  The set of modifications for this
1786       *                           modify operation.
1787       *
1788       * @return  A reference to the modify operation that was processed
1789       *          and contains information about the result of the
1790       *          processing.
1791       */
1792      public ModifyOperation processModify(ByteString rawEntryDN,
1793                                  List<RawModification> rawModifications)
1794      {
1795        return processModify(rawEntryDN, rawModifications, null);
1796      }
1797    
1798    
1799    
1800      /**
1801       * Processes an internal modify operation with the provided
1802       * information.
1803       *
1804       * @param  rawEntryDN        The raw entry DN for this modify
1805       *                           operation.
1806       * @param  rawModifications  The set of modifications for this
1807       *                           modify operation.
1808       * @param  controls          The set of controls to include in the
1809       *                           request.
1810       *
1811       * @return  A reference to the modify operation that was processed
1812       *          and contains information about the result of the
1813       *          processing.
1814       */
1815      public ModifyOperation processModify(ByteString rawEntryDN,
1816                                  List<RawModification> rawModifications,
1817                                  List<Control> controls)
1818      {
1819        if (controls == null)
1820        {
1821          controls = new ArrayList<Control>(0);
1822        }
1823    
1824        ModifyOperationBasis modifyOperation =
1825             new ModifyOperationBasis(this, nextOperationID(),
1826                                 nextMessageID(), controls, rawEntryDN,
1827                                 rawModifications);
1828        modifyOperation.setInternalOperation(true);
1829        modifyOperation.run();
1830    
1831        return modifyOperation;
1832      }
1833    
1834    
1835    
1836      /**
1837       * Processes an internal modify operation with the provided
1838       * information.
1839       *
1840       * @param  entryDN        The entry DN for this modify operation.
1841       * @param  modifications  The set of modifications for this modify
1842       *                        operation.
1843       *
1844       * @return  A reference to the modify operation that was processed
1845       *          and contains information about the result of the
1846       *          processing.
1847       */
1848      public ModifyOperation processModify(DN entryDN,
1849                                  List<Modification> modifications)
1850      {
1851        return processModify(entryDN, modifications, null);
1852      }
1853    
1854    
1855    
1856      /**
1857       * Processes an internal modify operation with the provided
1858       * information.
1859       *
1860       * @param  entryDN        The entry DN for this modify operation.
1861       * @param  modifications  The set of modifications for this modify
1862       *                        operation.
1863       * @param  controls       The set of controls to include in the
1864       *                        request.
1865       *
1866       * @return  A reference to the modify operation that was processed
1867       *          and contains information about the result of the
1868       *          processing.
1869       */
1870      public ModifyOperation processModify(DN entryDN,
1871                                  List<Modification> modifications,
1872                                  List<Control> controls)
1873      {
1874        if (controls == null)
1875        {
1876          controls = new ArrayList<Control>(0);
1877        }
1878    
1879        ModifyOperationBasis modifyOperation =
1880             new ModifyOperationBasis(this, nextOperationID(),
1881                                 nextMessageID(), controls, entryDN,
1882                                 modifications);
1883        modifyOperation.setInternalOperation(true);
1884        modifyOperation.run();
1885    
1886        return modifyOperation;
1887      }
1888    
1889    
1890    
1891      /**
1892       * Processes an internal modify operation with the provided
1893       * information.
1894       *
1895       * @param  modifyRecord  The modify change record entry with
1896       *                       information about the changes to perform.
1897       *
1898       * @return  A reference to the modify operation that was processed
1899       *          and contains information about the result of the
1900       *          processing.
1901       */
1902      public ModifyOperation processModify(
1903                                  ModifyChangeRecordEntry modifyRecord)
1904      {
1905        return processModify(modifyRecord.getDN().toString(),
1906                             modifyRecord.getModifications());
1907      }
1908    
1909    
1910    
1911      /**
1912       * Processes an internal modify DN operation with the provided
1913       * information.
1914       *
1915       * @param  rawEntryDN    The current DN of the entry to rename.
1916       * @param  rawNewRDN     The new RDN to use for the entry.
1917       * @param  deleteOldRDN  The flag indicating whether the old RDN
1918       *                       value is to be removed from the entry.
1919       *
1920       * @return  A reference to the modify DN operation that was
1921       *          processed and contains information about the result of
1922       *          the processing.
1923       */
1924      public ModifyDNOperation processModifyDN(String rawEntryDN,
1925                                               String rawNewRDN,
1926                                               boolean deleteOldRDN)
1927      {
1928        return processModifyDN(new ASN1OctetString(rawEntryDN),
1929                               new ASN1OctetString(rawNewRDN),
1930                               deleteOldRDN, null, null);
1931      }
1932    
1933    
1934    
1935      /**
1936       * Processes an internal modify DN operation with the provided
1937       * information.
1938       *
1939       * @param  rawEntryDN    The current DN of the entry to rename.
1940       * @param  rawNewRDN     The new RDN to use for the entry.
1941       * @param  deleteOldRDN  The flag indicating whether the old RDN
1942       *                       value is to be removed from the entry.
1943       * @param  controls      The set of controls to include in the
1944       *                       request.
1945       *
1946       * @return  A reference to the modify DN operation that was
1947       *          processed and contains information about the result of
1948       *          the processing.
1949       */
1950      public ModifyDNOperation processModifyDN(String rawEntryDN,
1951                                               String rawNewRDN,
1952                                               boolean deleteOldRDN,
1953                                               List<Control> controls)
1954      {
1955        return processModifyDN(new ASN1OctetString(rawEntryDN),
1956                               new ASN1OctetString(rawNewRDN),
1957                               deleteOldRDN, null, controls);
1958      }
1959    
1960    
1961    
1962      /**
1963       * Processes an internal modify DN operation with the provided
1964       * information.
1965       *
1966       * @param  rawEntryDN    The current DN of the entry to rename.
1967       * @param  rawNewRDN     The new RDN to use for the entry.
1968       * @param  deleteOldRDN  The flag indicating whether the old RDN
1969       *                       value is to be removed from the entry.
1970       *
1971       * @return  A reference to the modify DN operation that was
1972       *          processed and contains information about the result of
1973       *          the processing.
1974       */
1975      public ModifyDNOperation processModifyDN(ByteString rawEntryDN,
1976                                               ByteString rawNewRDN,
1977                                               boolean deleteOldRDN)
1978      {
1979        return processModifyDN(rawEntryDN, rawNewRDN, deleteOldRDN, null,
1980                               null);
1981      }
1982    
1983    
1984    
1985      /**
1986       * Processes an internal modify DN operation with the provided
1987       * information.
1988       *
1989       * @param  rawEntryDN      The current DN of the entry to rename.
1990       * @param  rawNewRDN       The new RDN to use for the entry.
1991       * @param  deleteOldRDN    The flag indicating whether the old RDN
1992       *                         value is to be removed from the entry.
1993       * @param  rawNewSuperior  The new superior for the modify DN
1994       *                         operation, or <CODE>null</CODE> if the
1995       *                         entry will remain below the same parent.
1996       *
1997       * @return  A reference to the modify DN operation that was
1998       *          processed and contains information about the result of
1999       *          the processing.
2000       */
2001      public ModifyDNOperation processModifyDN(String rawEntryDN,
2002                                               String rawNewRDN,
2003                                               boolean deleteOldRDN,
2004                                               String rawNewSuperior)
2005      {
2006        return processModifyDN(new ASN1OctetString(rawEntryDN),
2007                               new ASN1OctetString(rawNewRDN),
2008                               deleteOldRDN,
2009                               new ASN1OctetString(rawNewSuperior), null);
2010      }
2011    
2012    
2013    
2014      /**
2015       * Processes an internal modify DN operation with the provided
2016       * information.
2017       *
2018       * @param  rawEntryDN      The current DN of the entry to rename.
2019       * @param  rawNewRDN       The new RDN to use for the entry.
2020       * @param  deleteOldRDN    The flag indicating whether the old RDN
2021       *                         value is to be removed from the entry.
2022       * @param  rawNewSuperior  The new superior for the modify DN
2023       *                         operation, or <CODE>null</CODE> if the
2024       *                         entry will remain below the same parent.
2025       * @param  controls        The set of controls to include in the
2026       *                         request.
2027       *
2028       * @return  A reference to the modify DN operation that was
2029       *          processed and contains information about the result of
2030       *          the processing.
2031       */
2032      public ModifyDNOperation processModifyDN(String rawEntryDN,
2033                                               String rawNewRDN,
2034                                               boolean deleteOldRDN,
2035                                               String rawNewSuperior,
2036                                               List<Control> controls)
2037      {
2038        return processModifyDN(new ASN1OctetString(rawEntryDN),
2039                               new ASN1OctetString(rawNewRDN),
2040                               deleteOldRDN,
2041                               new ASN1OctetString(rawNewSuperior),
2042                               controls);
2043      }
2044    
2045    
2046    
2047      /**
2048       * Processes an internal modify DN operation with the provided
2049       * information.
2050       *
2051       * @param  rawEntryDN      The current DN of the entry to rename.
2052       * @param  rawNewRDN       The new RDN to use for the entry.
2053       * @param  deleteOldRDN    The flag indicating whether the old RDN
2054       *                         value is to be removed from the entry.
2055       * @param  rawNewSuperior  The new superior for the modify DN
2056       *                         operation, or <CODE>null</CODE> if the
2057       *                         entry will remain below the same parent.
2058       *
2059       * @return  A reference to the modify DN operation that was
2060       *          processed and contains information about the result of
2061       *          the processing.
2062       */
2063      public ModifyDNOperation processModifyDN(ByteString rawEntryDN,
2064                                               ByteString rawNewRDN,
2065                                               boolean deleteOldRDN,
2066                                               ByteString rawNewSuperior)
2067      {
2068        return processModifyDN(rawEntryDN, rawNewRDN, deleteOldRDN,
2069                               rawNewSuperior, null);
2070      }
2071    
2072    
2073    
2074      /**
2075       * Processes an internal modify DN operation with the provided
2076       * information.
2077       *
2078       * @param  rawEntryDN      The current DN of the entry to rename.
2079       * @param  rawNewRDN       The new RDN to use for the entry.
2080       * @param  deleteOldRDN    The flag indicating whether the old RDN
2081       *                         value is to be removed from the entry.
2082       * @param  rawNewSuperior  The new superior for the modify DN
2083       *                         operation, or <CODE>null</CODE> if the
2084       *                         entry will remain below the same parent.
2085       * @param  controls        The set of controls to include in the
2086       *                         request.
2087       *
2088       * @return  A reference to the modify DN operation that was
2089       *          processed and contains information about the result of
2090       *          the processing.
2091       */
2092      public ModifyDNOperation processModifyDN(ByteString rawEntryDN,
2093                                               ByteString rawNewRDN,
2094                                               boolean deleteOldRDN,
2095                                               ByteString rawNewSuperior,
2096                                               List<Control> controls)
2097      {
2098        if (controls == null)
2099        {
2100          controls = new ArrayList<Control>(0);
2101        }
2102    
2103        ModifyDNOperationBasis modifyDNOperation =
2104             new ModifyDNOperationBasis(this, nextOperationID(),
2105                                   nextMessageID(), controls, rawEntryDN,
2106                                   rawNewRDN, deleteOldRDN,
2107                                   rawNewSuperior);
2108        modifyDNOperation.setInternalOperation(true);
2109    
2110        modifyDNOperation.run();
2111        return modifyDNOperation;
2112      }
2113    
2114    
2115    
2116      /**
2117       * Processes an internal modify DN operation with the provided
2118       * information.
2119       *
2120       * @param  entryDN       The current DN of the entry to rename.
2121       * @param  newRDN        The new RDN to use for the entry.
2122       * @param  deleteOldRDN  The flag indicating whether the old RDN
2123       *                       value is to be removed from the entry.
2124       *
2125       * @return  A reference to the modify DN operation that was
2126       *          processed and contains information about the result of
2127       *          the processing.
2128       */
2129      public ModifyDNOperation processModifyDN(DN entryDN,
2130                                               RDN newRDN,
2131                                               boolean deleteOldRDN)
2132      {
2133        return processModifyDN(entryDN, newRDN, deleteOldRDN, null, null);
2134      }
2135    
2136    
2137    
2138      /**
2139       * Processes an internal modify DN operation with the provided
2140       * information.
2141       *
2142       * @param  entryDN       The current DN of the entry to rename.
2143       * @param  newRDN        The new RDN to use for the entry.
2144       * @param  deleteOldRDN  The flag indicating whether the old RDN
2145       *                       value is to be removed from the entry.
2146       * @param  newSuperior   The new superior for the modify DN
2147       *                       operation, or <CODE>null</CODE> if the
2148       *                       entry will remain below the same parent.
2149       *
2150       * @return  A reference to the modify DN operation that was
2151       *          processed and contains information about the result of
2152       *          the processing.
2153       */
2154      public ModifyDNOperation processModifyDN(DN entryDN,
2155                                               RDN newRDN,
2156                                               boolean deleteOldRDN,
2157                                               DN newSuperior)
2158      {
2159        return processModifyDN(entryDN, newRDN, deleteOldRDN, newSuperior,
2160                               null);
2161      }
2162    
2163    
2164    
2165      /**
2166       * Processes an internal modify DN operation with the provided
2167       * information.
2168       *
2169       * @param  entryDN       The current DN of the entry to rename.
2170       * @param  newRDN        The new RDN to use for the entry.
2171       * @param  deleteOldRDN  The flag indicating whether the old RDN
2172       *                       value is to be removed from the entry.
2173       * @param  newSuperior   The new superior for the modify DN
2174       *                       operation, or <CODE>null</CODE> if the
2175       *                       entry will remain below the same parent.
2176       * @param  controls      The set of controls to include in the
2177       *                       request.
2178       *
2179       * @return  A reference to the modify DN operation that was
2180       *          processed and contains information about the result of
2181       *          the processing.
2182       */
2183      public ModifyDNOperation processModifyDN(DN entryDN,
2184                                               RDN newRDN,
2185                                               boolean deleteOldRDN,
2186                                               DN newSuperior,
2187                                               List<Control> controls)
2188      {
2189        if (controls == null)
2190        {
2191          controls = new ArrayList<Control>(0);
2192        }
2193    
2194        ModifyDNOperationBasis modifyDNOperation =
2195             new ModifyDNOperationBasis(this, nextOperationID(),
2196                                   nextMessageID(), controls, entryDN,
2197                                   newRDN, deleteOldRDN, newSuperior);
2198        modifyDNOperation.setInternalOperation(true);
2199    
2200        modifyDNOperation.run();
2201        return modifyDNOperation;
2202      }
2203    
2204    
2205    
2206      /**
2207       * Processes an internal modify DN operation with the provided
2208       * information.
2209       *
2210       * @param  modifyDNRecord  The modify DN change record entry with
2211       *                         information about the processing to
2212       *                         perform.
2213       *
2214       * @return  A reference to the modify DN operation that was
2215       *          processed and contains information about the result of
2216       *          the processing.
2217       */
2218      public ModifyDNOperation processModifyDN(
2219                  ModifyDNChangeRecordEntry modifyDNRecord)
2220      {
2221        return processModifyDN(modifyDNRecord.getDN(),
2222                               modifyDNRecord.getNewRDN(),
2223                               modifyDNRecord.deleteOldRDN(),
2224                               modifyDNRecord.getNewSuperiorDN());
2225      }
2226    
2227    
2228    
2229      /**
2230       * Processes an internal search operation with the provided
2231       * information.  It will not dereference any aliases, will not
2232       * request a size or time limit, and will retrieve all user
2233       * attributes.
2234       *
2235       * @param  rawBaseDN     The base DN for the search.
2236       * @param  scope         The scope for the search.
2237       * @param  filterString  The string representation of the filter for
2238       *                       the search.
2239       *
2240       * @return  A reference to the internal search operation that was
2241       *          processed and contains information about the result of
2242       *          the processing as well as lists of the matching entries
2243       *          and search references.
2244       *
2245       * @throws  DirectoryException  If the provided filter string cannot
2246       *                              be decoded as a search filter.
2247       */
2248      public InternalSearchOperation processSearch(String rawBaseDN,
2249                                          SearchScope scope,
2250                                          String filterString)
2251             throws DirectoryException
2252      {
2253        RawFilter rawFilter;
2254        try
2255        {
2256          rawFilter = RawFilter.create(filterString);
2257        }
2258        catch (LDAPException le)
2259        {
2260          throw new DirectoryException(
2261                         ResultCode.valueOf(le.getResultCode()),
2262                         le.getErrorMessage(), le);
2263        }
2264    
2265        return processSearch(new ASN1OctetString(rawBaseDN), scope,
2266                             rawFilter);
2267      }
2268    
2269    
2270    
2271      /**
2272       * Processes an internal search operation with the provided
2273       * information.
2274       *
2275       * @param  rawBaseDN     The base DN for the search.
2276       * @param  scope         The scope for the search.
2277       * @param  derefPolicy   The alias dereferencing policy for the
2278       *                       search.
2279       * @param  sizeLimit     The size limit for the search.
2280       * @param  timeLimit     The time limit for the search.
2281       * @param  typesOnly     The typesOnly flag for the search.
2282       * @param  filterString  The string representation of the filter for
2283       *                       the search.
2284       * @param  attributes    The set of requested attributes for the
2285       *                       search.
2286       *
2287       * @return  A reference to the internal search operation that was
2288       *          processed and contains information about the result of
2289       *          the processing as well as lists of the matching entries
2290       *          and search references.
2291       *
2292       * @throws  DirectoryException  If the provided filter string cannot
2293       *                              be decoded as a search filter.
2294       */
2295      public InternalSearchOperation
2296                  processSearch(String rawBaseDN, SearchScope scope,
2297                                DereferencePolicy derefPolicy,
2298                                int sizeLimit, int timeLimit,
2299                                boolean typesOnly, String filterString,
2300                                LinkedHashSet<String> attributes)
2301             throws DirectoryException
2302      {
2303        return processSearch(rawBaseDN, scope, derefPolicy, sizeLimit,
2304                             timeLimit, typesOnly, filterString,
2305                             attributes, null, null);
2306      }
2307    
2308    
2309    
2310      /**
2311       * Processes an internal search operation with the provided
2312       * information.
2313       *
2314       * @param  rawBaseDN       The base DN for the search.
2315       * @param  scope           The scope for the search.
2316       * @param  derefPolicy     The alias dereferencing policy for the
2317       *                         search.
2318       * @param  sizeLimit       The size limit for the search.
2319       * @param  timeLimit       The time limit for the search.
2320       * @param  typesOnly       The typesOnly flag for the search.
2321       * @param  filterString    The string representation of the filter
2322       *                         for the search.
2323       * @param  attributes      The set of requested attributes for the
2324       *                         search.
2325       * @param  searchListener  The internal search listener that should
2326       *                         be used to handle the matching entries
2327       *                         and references.
2328       *
2329       * @return  A reference to the internal search operation that was
2330       *          processed and contains information about the result of
2331       *          the processing as well as lists of the matching entries
2332       *          and search references.
2333       *
2334       * @throws  DirectoryException  If the provided filter string cannot
2335       *                              be decoded as a search filter.
2336       */
2337      public InternalSearchOperation
2338                  processSearch(String rawBaseDN, SearchScope scope,
2339                                DereferencePolicy derefPolicy,
2340                                int sizeLimit, int timeLimit,
2341                                boolean typesOnly, String filterString,
2342                                LinkedHashSet<String> attributes,
2343                                InternalSearchListener searchListener)
2344             throws DirectoryException
2345      {
2346        return processSearch(rawBaseDN, scope, derefPolicy, sizeLimit,
2347                             timeLimit, typesOnly, filterString,
2348                             attributes, null, searchListener);
2349      }
2350    
2351    
2352    
2353      /**
2354       * Processes an internal search operation with the provided
2355       * information.
2356       *
2357       * @param  rawBaseDN       The base DN for the search.
2358       * @param  scope           The scope for the search.
2359       * @param  derefPolicy     The alias dereferencing policy for the
2360       *                         search.
2361       * @param  sizeLimit       The size limit for the search.
2362       * @param  timeLimit       The time limit for the search.
2363       * @param  typesOnly       The typesOnly flag for the search.
2364       * @param  filterString    The string representation of the filter
2365       *                         for the search.
2366       * @param  attributes      The set of requested attributes for the
2367       *                         search.
2368       * @param  controls        The set of controls to include in the
2369       *                         request.
2370       * @param  searchListener  The internal search listener that should
2371       *                         be used to handle the matching entries
2372       *                         and references.
2373       *
2374       * @return  A reference to the internal search operation that was
2375       *          processed and contains information about the result of
2376       *          the processing as well as lists of the matching entries
2377       *          and search references.
2378       *
2379       * @throws  DirectoryException  If the provided filter string cannot
2380       *                              be decoded as a search filter.
2381       */
2382      public InternalSearchOperation
2383                  processSearch(String rawBaseDN, SearchScope scope,
2384                                DereferencePolicy derefPolicy,
2385                                int sizeLimit, int timeLimit,
2386                                boolean typesOnly, String filterString,
2387                                LinkedHashSet<String> attributes,
2388                                List<Control> controls,
2389                                InternalSearchListener searchListener)
2390             throws DirectoryException
2391      {
2392        RawFilter rawFilter;
2393        try
2394        {
2395          rawFilter = RawFilter.create(filterString);
2396        }
2397        catch (LDAPException le)
2398        {
2399          throw new DirectoryException(
2400                         ResultCode.valueOf(le.getResultCode()),
2401                         le.getErrorMessage(), le);
2402        }
2403    
2404        return processSearch(new ASN1OctetString(rawBaseDN), scope,
2405                             derefPolicy, sizeLimit, timeLimit, typesOnly,
2406                             rawFilter, attributes, controls,
2407                             searchListener);
2408      }
2409    
2410    
2411    
2412      /**
2413       * Processes an internal search operation with the provided
2414       * information.  It will not dereference any aliases, will not
2415       * request a size or time limit, and will retrieve all user
2416       * attributes.
2417       *
2418       * @param  rawBaseDN  The base DN for the search.
2419       * @param  scope      The scope for the search.
2420       * @param  filter     The filter for the search.
2421       *
2422       * @return  A reference to the internal search operation that was
2423       *          processed and contains information about the result of
2424       *          the processing as well as lists of the matching entries
2425       *          and search references.
2426       */
2427      public InternalSearchOperation processSearch(ByteString rawBaseDN,
2428                                          SearchScope scope,
2429                                          RawFilter filter)
2430      {
2431        return processSearch(rawBaseDN, scope,
2432                             DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0,
2433                             false, filter, new LinkedHashSet<String>(0));
2434      }
2435    
2436    
2437    
2438      /**
2439       * Processes an internal search operation with the provided
2440       * information.
2441       *
2442       * @param  rawBaseDN    The base DN for the search.
2443       * @param  scope        The scope for the search.
2444       * @param  derefPolicy  The alias dereferencing policy for the
2445       *                      search.
2446       * @param  sizeLimit    The size limit for the search.
2447       * @param  timeLimit    The time limit for the search.
2448       * @param  typesOnly    The typesOnly flag for the search.
2449       * @param  filter       The filter for the search.
2450       * @param  attributes   The set of requested attributes for the
2451       *                      search.
2452       *
2453       * @return  A reference to the internal search operation that was
2454       *          processed and contains information about the result of
2455       *          the processing as well as lists of the matching entries
2456       *          and search references.
2457       */
2458      public InternalSearchOperation
2459                  processSearch(ByteString rawBaseDN,
2460                                SearchScope scope,
2461                                DereferencePolicy derefPolicy,
2462                                int sizeLimit, int timeLimit,
2463                                boolean typesOnly, RawFilter filter,
2464                                LinkedHashSet<String> attributes)
2465      {
2466        return processSearch(rawBaseDN, scope, derefPolicy, sizeLimit,
2467                             timeLimit, typesOnly, filter, attributes,
2468                             null, null);
2469      }
2470    
2471    
2472    
2473      /**
2474       * Processes an internal search operation with the provided
2475       * information.
2476       *
2477       * @param  rawBaseDN       The base DN for the search.
2478       * @param  scope           The scope for the search.
2479       * @param  derefPolicy     The alias dereferencing policy for the
2480       *                         search.
2481       * @param  sizeLimit       The size limit for the search.
2482       * @param  timeLimit       The time limit for the search.
2483       * @param  typesOnly       The typesOnly flag for the search.
2484       * @param  filter          The filter for the search.
2485       * @param  attributes      The set of requested attributes for the
2486       *                         search.
2487       * @param  searchListener  The internal search listener that should
2488       *                         be used to handle the matching entries
2489       *                         and references.
2490       *
2491       * @return  A reference to the internal search operation that was
2492       *          processed and contains information about the result of
2493       *          the processing.
2494       */
2495      public InternalSearchOperation
2496                  processSearch(ByteString rawBaseDN,
2497                                SearchScope scope,
2498                                DereferencePolicy derefPolicy,
2499                                int sizeLimit, int timeLimit,
2500                                boolean typesOnly, RawFilter filter,
2501                                LinkedHashSet<String> attributes,
2502                                InternalSearchListener searchListener)
2503      {
2504        return processSearch(rawBaseDN, scope, derefPolicy, sizeLimit,
2505                             timeLimit, typesOnly, filter, attributes,
2506                             null, searchListener);
2507      }
2508    
2509    
2510    
2511      /**
2512       * Processes an internal search operation with the provided
2513       * information.
2514       *
2515       * @param  rawBaseDN       The base DN for the search.
2516       * @param  scope           The scope for the search.
2517       * @param  derefPolicy     The alias dereferencing policy for the
2518       *                         search.
2519       * @param  sizeLimit       The size limit for the search.
2520       * @param  timeLimit       The time limit for the search.
2521       * @param  typesOnly       The typesOnly flag for the search.
2522       * @param  filter          The filter for the search.
2523       * @param  attributes      The set of requested attributes for the
2524       *                         search.
2525       * @param  controls        The set of controls to include in the
2526       *                         request.
2527       * @param  searchListener  The internal search listener that should
2528       *                         be used to handle the matching entries
2529       *                         and references.
2530       *
2531       * @return  A reference to the internal search operation that was
2532       *          processed and contains information about the result of
2533       *          the processing.
2534       */
2535      public InternalSearchOperation
2536                  processSearch(ByteString rawBaseDN,
2537                                SearchScope scope,
2538                                DereferencePolicy derefPolicy,
2539                                int sizeLimit, int timeLimit,
2540                                boolean typesOnly, RawFilter filter,
2541                                LinkedHashSet<String> attributes,
2542                                List<Control> controls,
2543                                InternalSearchListener searchListener)
2544      {
2545        if (controls == null)
2546        {
2547          controls = new ArrayList<Control>(0);
2548        }
2549    
2550        InternalSearchOperation searchOperation =
2551             new InternalSearchOperation(this, nextOperationID(),
2552                                         nextMessageID(), controls,
2553                                         rawBaseDN, scope, derefPolicy,
2554                                         sizeLimit, timeLimit,
2555                                         typesOnly, filter, attributes,
2556                                         searchListener);
2557    
2558        searchOperation.run();
2559        return searchOperation;
2560      }
2561    
2562    
2563    
2564      /**
2565       * Processes an internal search operation with the provided
2566       * information.  It will not dereference any aliases, will not
2567       * request a size or time limit, and will retrieve all user
2568       * attributes.
2569       *
2570       * @param  baseDN  The base DN for the search.
2571       * @param  scope   The scope for the search.
2572       * @param  filter  The filter for the search.
2573       *
2574       * @return  A reference to the internal search operation that was
2575       *          processed and contains information about the result of
2576       *          the processing as well as lists of the matching entries
2577       *          and search references.
2578       */
2579      public InternalSearchOperation processSearch(DN baseDN,
2580                                          SearchScope scope,
2581                                          SearchFilter filter)
2582      {
2583        return processSearch(baseDN, scope,
2584                             DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0,
2585                             false, filter, new LinkedHashSet<String>(0));
2586      }
2587    
2588    
2589    
2590      /**
2591       * Processes an internal search operation with the provided
2592       * information.
2593       *
2594       * @param  baseDN       The base DN for the search.
2595       * @param  scope        The scope for the search.
2596       * @param  derefPolicy  The alias dereferencing policy for the
2597       *                      search.
2598       * @param  sizeLimit    The size limit for the search.
2599       * @param  timeLimit    The time limit for the search.
2600       * @param  typesOnly    The typesOnly flag for the search.
2601       * @param  filter       The filter for the search.
2602       * @param  attributes   The set of requested attributes for the
2603       *                      search.
2604       *
2605       * @return  A reference to the internal search operation that was
2606       *          processed and contains information about the result of
2607       *          the processing as well as lists of the matching entries
2608       *          and search references.
2609       */
2610      public InternalSearchOperation
2611                  processSearch(DN baseDN, SearchScope scope,
2612                                DereferencePolicy derefPolicy,
2613                                int sizeLimit, int timeLimit,
2614                                boolean typesOnly, SearchFilter filter,
2615                                LinkedHashSet<String> attributes)
2616      {
2617        return processSearch(baseDN, scope, derefPolicy, sizeLimit,
2618                             timeLimit, typesOnly, filter, attributes,
2619                             null, null);
2620      }
2621    
2622    
2623    
2624      /**
2625       * Processes an internal search operation with the provided
2626       * information.
2627       *
2628       * @param  baseDN          The base DN for the search.
2629       * @param  scope           The scope for the search.
2630       * @param  derefPolicy     The alias dereferencing policy for the
2631       *                         search.
2632       * @param  sizeLimit       The size limit for the search.
2633       * @param  timeLimit       The time limit for the search.
2634       * @param  typesOnly       The typesOnly flag for the search.
2635       * @param  filter          The filter for the search.
2636       * @param  attributes      The set of requested attributes for the
2637       *                         search.
2638       * @param  searchListener  The internal search listener that should
2639       *                         be used to handle the matching entries
2640       *                         and references.
2641       *
2642       * @return  A reference to the internal search operation that was
2643       *          processed and contains information about the result of
2644       *          the processing.
2645       */
2646      public InternalSearchOperation
2647                  processSearch(DN baseDN, SearchScope scope,
2648                                DereferencePolicy derefPolicy,
2649                                int sizeLimit, int timeLimit,
2650                                boolean typesOnly, SearchFilter filter,
2651                                LinkedHashSet<String> attributes,
2652                                InternalSearchListener searchListener)
2653      {
2654        return processSearch(baseDN, scope, derefPolicy, sizeLimit,
2655                             timeLimit, typesOnly, filter, attributes,
2656                             null, searchListener);
2657      }
2658    
2659    
2660    
2661      /**
2662       * Processes an internal search operation with the provided
2663       * information.
2664       *
2665       * @param  baseDN          The base DN for the search.
2666       * @param  scope           The scope for the search.
2667       * @param  derefPolicy     The alias dereferencing policy for the
2668       *                         search.
2669       * @param  sizeLimit       The size limit for the search.
2670       * @param  timeLimit       The time limit for the search.
2671       * @param  typesOnly       The typesOnly flag for the search.
2672       * @param  filter          The filter for the search.
2673       * @param  attributes      The set of requested attributes for the
2674       *                         search.
2675       * @param  controls        The set of controls to include in the
2676       *                         request.
2677       * @param  searchListener  The internal search listener that should
2678       *                         be used to handle the matching entries
2679       *                         and references.
2680       *
2681       * @return  A reference to the internal search operation that was
2682       *          processed and contains information about the result of
2683       *          the processing.
2684       */
2685      public InternalSearchOperation
2686                  processSearch(DN baseDN, SearchScope scope,
2687                                DereferencePolicy derefPolicy,
2688                                int sizeLimit, int timeLimit,
2689                                boolean typesOnly, SearchFilter filter,
2690                                LinkedHashSet<String> attributes,
2691                                List<Control> controls,
2692                                InternalSearchListener searchListener)
2693      {
2694        if (controls == null)
2695        {
2696          controls = new ArrayList<Control>(0);
2697        }
2698    
2699        InternalSearchOperation searchOperation =
2700             new InternalSearchOperation(this, nextOperationID(),
2701                                         nextMessageID(), controls,
2702                                         baseDN, scope, derefPolicy,
2703                                         sizeLimit, timeLimit,
2704                                         typesOnly, filter, attributes,
2705                                         searchListener);
2706    
2707        searchOperation.run();
2708        return searchOperation;
2709      }
2710    
2711    
2712    
2713      /**
2714       * Sends the provided search result entry to the client.
2715       *
2716       * @param  searchOperation  The search operation with which the
2717       *                          entry is associated.
2718       * @param  searchEntry      The search result entry to be sent to
2719       *                          the client.
2720       *
2721       * @throws  DirectoryException  If a problem occurs while processing
2722       *                              the entry and the search should be
2723       *                              terminated.
2724       */
2725      @org.opends.server.types.PublicAPI(
2726           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2727           mayInstantiate=false,
2728           mayExtend=false,
2729           mayInvoke=false)
2730      @Override()
2731      public void sendSearchEntry(SearchOperation searchOperation,
2732                                  SearchResultEntry searchEntry)
2733             throws DirectoryException
2734      {
2735        ((InternalSearchOperation) searchOperation).
2736             addSearchEntry(searchEntry);
2737      }
2738    
2739    
2740    
2741      /**
2742       * Sends the provided search result reference to the client.
2743       *
2744       * @param  searchOperation  The search operation with which the
2745       *                          reference is associated.
2746       * @param  searchReference  The search result reference to be sent
2747       *                          to the client.
2748       *
2749       * @return  <CODE>true</CODE> if the client is able to accept
2750       *          referrals, or <CODE>false</CODE> if the client cannot
2751       *          handle referrals and no more attempts should be made to
2752       *          send them for the associated search operation.
2753       *
2754       * @throws  DirectoryException  If a problem occurs while processing
2755       *                              the entry and the search should be
2756       *                              terminated.
2757       */
2758      @org.opends.server.types.PublicAPI(
2759           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2760           mayInstantiate=false,
2761           mayExtend=false,
2762           mayInvoke=false)
2763      @Override()
2764      public boolean sendSearchReference(SearchOperation searchOperation,
2765                          SearchResultReference searchReference)
2766             throws DirectoryException
2767      {
2768        ((InternalSearchOperation)
2769         searchOperation).addSearchReference(searchReference);
2770        return true;
2771      }
2772    
2773    
2774    
2775    
2776      /**
2777       * Sends the provided intermediate response message to the client.
2778       *
2779       * @param  intermediateResponse  The intermediate response message
2780       *                               to be sent.
2781       *
2782       * @return  <CODE>true</CODE> if processing on the associated
2783       *          operation should continue, or <CODE>false</CODE> if not.
2784       */
2785      @org.opends.server.types.PublicAPI(
2786           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2787           mayInstantiate=false,
2788           mayExtend=false,
2789           mayInvoke=false)
2790      @Override()
2791      protected boolean sendIntermediateResponseMessage(
2792                             IntermediateResponse intermediateResponse)
2793      {
2794        // FIXME -- Do we need to support internal intermediate responses?
2795        //          If so, then implement this.
2796        return false;
2797      }
2798    
2799    
2800    
2801    
2802      /**
2803       * Closes the connection to the client, optionally sending it a
2804       * message indicating the reason for the closure.  Note that the
2805       * ability to send a notice of disconnection may not be available
2806       * for all protocols or under all circumstances.
2807       *
2808       * @param  disconnectReason  The disconnect reason that provides the
2809       *                           generic cause for the disconnect.
2810       * @param  sendNotification  Indicates whether to try to provide
2811       *                           notification to the client that the
2812       *                           connection will be closed.
2813       * @param  message           The message to send to the client.  It
2814       *                           may be <CODE>null</CODE> if no
2815       *                           notification is to be sent.
2816       */
2817      @org.opends.server.types.PublicAPI(
2818           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2819           mayInstantiate=false,
2820           mayExtend=false,
2821           mayInvoke=false)
2822      @Override()
2823      public void disconnect(DisconnectReason disconnectReason,
2824                             boolean sendNotification,
2825                             Message message)
2826      {
2827        // No implementation is required since there is nothing to
2828        // disconnect.  Further, since there is no real disconnect, we can
2829        // wait to have the garbage collector call
2830        // finalizeConnectionInternal whenever this internal connection is
2831        // garbage collected.
2832      }
2833    
2834    
2835    
2836      /**
2837       * Indicates whether a bind operation is in progress on this client
2838       * connection.  If so, then no new operations should be allowed
2839       * until the bind has completed.
2840       *
2841       * @return  <CODE>true</CODE> if a bind operation is in progress on
2842       *          this connection, or <CODE>false</CODE> if not.
2843       */
2844      @Override()
2845      public boolean bindInProgress()
2846      {
2847        // For internal operations, we don't care if there are any binds
2848        // in progress.
2849        return false;
2850      }
2851    
2852    
2853    
2854      /**
2855       * Specifies whether a bind operation is in progress on this client
2856       * connection.  If so, then no new operations should be allowed
2857       * until the bind has completed.
2858       *
2859       * @param  bindInProgress  Specifies whether a bind operation is in
2860       *                         progress on this client connection.
2861       */
2862      @org.opends.server.types.PublicAPI(
2863           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2864           mayInstantiate=false,
2865           mayExtend=false,
2866           mayInvoke=false)
2867      @Override()
2868      public void setBindInProgress(boolean bindInProgress)
2869      {
2870        // No implementation is required.
2871      }
2872    
2873    
2874    
2875      /**
2876       * Retrieves the set of operations in progress for this client
2877       * connection.  This list must not be altered by any caller.
2878       *
2879       * @return  The set of operations in progress for this client
2880       *          connection.
2881       */
2882      @org.opends.server.types.PublicAPI(
2883           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2884           mayInstantiate=false,
2885           mayExtend=false,
2886           mayInvoke=false)
2887      @Override()
2888      public Collection<AbstractOperation> getOperationsInProgress()
2889      {
2890        return operationList;
2891      }
2892    
2893    
2894    
2895      /**
2896       * Retrieves the operation in progress with the specified message
2897       * ID.
2898       *
2899       * @param  messageID  The message ID of the operation to retrieve.
2900       *
2901       * @return  The operation in progress with the specified message ID,
2902       *          or <CODE>null</CODE> if no such operation could be
2903       *          found.
2904       */
2905      @org.opends.server.types.PublicAPI(
2906           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2907           mayInstantiate=false,
2908           mayExtend=false,
2909           mayInvoke=false)
2910      @Override()
2911      public AbstractOperation getOperationInProgress(int messageID)
2912      {
2913        // Internal operations will not be tracked.
2914        return null;
2915      }
2916    
2917    
2918    
2919      /**
2920       * Removes the provided operation from the set of operations in
2921       * progress for this client connection.  Note that this does not
2922       * make any attempt to cancel any processing that may already be in
2923       * progress for the operation.
2924       *
2925       * @param  messageID  The message ID of the operation to remove from
2926       *                    the set of operations in progress.
2927       *
2928       * @return  <CODE>true</CODE> if the operation was found and removed
2929       *          from the set of operations in progress, or
2930       *          <CODE>false</CODE> if not.
2931       */
2932      @org.opends.server.types.PublicAPI(
2933           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2934           mayInstantiate=false,
2935           mayExtend=false,
2936           mayInvoke=false)
2937      @Override()
2938      public boolean removeOperationInProgress(int messageID)
2939      {
2940        // No implementation is required, since internal operations will
2941        // not be tracked.
2942        return false;
2943      }
2944    
2945    
2946    
2947      /**
2948       * Attempts to cancel the specified operation.
2949       *
2950       * @param  messageID      The message ID of the operation to cancel.
2951       * @param  cancelRequest  An object providing additional information
2952       *                        about how the cancel should be processed.
2953       *
2954       * @return  A cancel result that either indicates that the cancel
2955       *          was successful or provides a reason that it was not.
2956       */
2957      @org.opends.server.types.PublicAPI(
2958           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2959           mayInstantiate=false,
2960           mayExtend=false,
2961           mayInvoke=false)
2962      @Override()
2963      public CancelResult cancelOperation(int messageID,
2964                                          CancelRequest cancelRequest)
2965      {
2966        // Internal operations cannot be cancelled.
2967        // TODO: i18n
2968        return new CancelResult(ResultCode.CANNOT_CANCEL,
2969            Message.raw("Internal operations cannot be cancelled"));
2970      }
2971    
2972    
2973    
2974      /**
2975       * Attempts to cancel all operations in progress on this connection.
2976       *
2977       * @param  cancelRequest  An object providing additional information
2978       *                        about how the cancel should be processed.
2979       */
2980      @org.opends.server.types.PublicAPI(
2981           stability=org.opends.server.types.StabilityLevel.PRIVATE,
2982           mayInstantiate=false,
2983           mayExtend=false,
2984           mayInvoke=false)
2985      @Override()
2986      public void cancelAllOperations(CancelRequest cancelRequest)
2987      {
2988        // No implementation is required since internal operations cannot
2989        // be cancelled.
2990      }
2991    
2992    
2993    
2994      /**
2995       * Attempts to cancel all operations in progress on this connection
2996       * except the operation with the specified message ID.
2997       *
2998       * @param  cancelRequest  An object providing additional information
2999       *                        about how the cancel should be processed.
3000       * @param  messageID      The message ID of the operation that
3001       *                        should not be canceled.
3002       */
3003      @org.opends.server.types.PublicAPI(
3004           stability=org.opends.server.types.StabilityLevel.PRIVATE,
3005           mayInstantiate=false,
3006           mayExtend=false,
3007           mayInvoke=false)
3008      @Override()
3009      public void cancelAllOperationsExcept(CancelRequest cancelRequest,
3010                                            int messageID)
3011      {
3012        // No implementation is required since internal operations cannot
3013        // be cancelled.
3014      }
3015    
3016    
3017    
3018      /**
3019       * Retrieves a one-line summary of this client connection in a form
3020       * that is suitable for including in the monitor entry for the
3021       * associated connection handler.  It should be in a format that is
3022       * both humand readable and machine parseable (e.g., a
3023       * space-delimited name-value list, with quotes around the values).
3024       *
3025       * @return  A one-line summary of this client connection in a form
3026       *          that is suitable for including in the monitor entry for
3027       *          the associated connection handler.
3028       */
3029      @Override()
3030      public String getMonitorSummary()
3031      {
3032        StringBuilder buffer = new StringBuilder();
3033        buffer.append("connID=\"");
3034        buffer.append(connectionID);
3035        buffer.append("\" authDN=\"");
3036        buffer.append(getAuthenticationInfo().getAuthenticationDN());
3037        buffer.append("\"");
3038    
3039        return buffer.toString();
3040      }
3041    
3042    
3043    
3044      /**
3045       * Appends a string representation of this client connection to the
3046       * provided buffer.
3047       *
3048       * @param  buffer  The buffer to which the information should be
3049       *                 appended.
3050       */
3051      @Override()
3052      public void toString(StringBuilder buffer)
3053      {
3054        buffer.append("InternalClientConnection(connID=");
3055        buffer.append(connectionID);
3056        buffer.append(", authDN=\"");
3057    
3058        if (getAuthenticationInfo() != null)
3059        {
3060          buffer.append(getAuthenticationInfo().getAuthenticationDN());
3061        }
3062    
3063        buffer.append("\")");
3064      }
3065    
3066      /**
3067       * Called near the end of server shutdown.  This ensures that a new
3068       * InternalClientConnection is created if the server is immediately
3069       * restarted as part of an in-core restart.
3070       */
3071      static void clearRootClientConnectionAtShutdown()
3072      {
3073        rootConnection = null;
3074      }
3075    }
3076