mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
15.17.2013 cab0b20204866c68b0cce38b4492f707187cc128
Refactoring on the LocalBackend*Operation classes:
- Extracted process*() methods from the processLocal*() methods for the LocalBackend*Operation classes.
- Transformed plain comments into javadocs.
- Used interfaces instead of concrete classes.
- Made all protected members be private.
3 files modified
646 ■■■■■ changed files
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java 131 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java 399 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java 116 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -68,22 +68,22 @@
  /**
   * The backend in which the comparison is to be performed.
   */
  protected Backend backend;
  private Backend backend;
  /**
   * The client connection for this operation.
   */
  protected ClientConnection clientConnection;
  private ClientConnection clientConnection;
  /**
   * The DN of the entry to compare.
   */
  protected DN entryDN;
  private DN entryDN;
  /**
   * The entry to be compared.
   */
  protected Entry entry = null;
  private Entry entry;
@@ -125,49 +125,58 @@
  public void processLocalCompare(LocalBackendWorkflowElement wfe)
      throws CanceledOperationException
  {
    boolean executePostOpPlugins = false;
    this.backend = wfe.getBackend();
    clientConnection  = getClientConnection();
    // Get the plugin config manager that will be used for invoking plugins.
    PluginConfigManager pluginConfigManager =
         DirectoryServer.getPluginConfigManager();
    // Get a reference to the client connection
    ClientConnection clientConnection = getClientConnection();
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Create a labeled block of code that we can break out of if a problem is
    // detected.
compareProcessing:
    BooleanHolder executePostOpPlugins = new BooleanHolder();
    processCompare(executePostOpPlugins);
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Invoke the post-operation compare plugins.
    if (executePostOpPlugins.value)
    {
      PluginResult.PostOperation postOpResult =
          DirectoryServer.getPluginConfigManager()
              .invokePostOperationComparePlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
      }
    }
  }
  private void processCompare(BooleanHolder executePostOpPlugins)
      throws CanceledOperationException
    {
      // Process the entry DN to convert it from the raw form to the form
      // required for the rest of the compare processing.
      entryDN = getEntryDN();
      if (entryDN == null)
      {
        break compareProcessing;
      return;
      }
      // If the target entry is in the server configuration, then make sure the
      // requester has the CONFIG_READ privilege.
      if (DirectoryServer.getConfigHandler().handlesEntry(entryDN) &&
          (! clientConnection.hasPrivilege(Privilege.CONFIG_READ, this)))
    if (DirectoryServer.getConfigHandler().handlesEntry(entryDN)
        && (!clientConnection.hasPrivilege(Privilege.CONFIG_READ, this)))
      {
        appendErrorMessage(ERR_COMPARE_CONFIG_INSUFFICIENT_PRIVILEGES.get());
        setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
        break compareProcessing;
      return;
      }
      // Check for a request to cancel this operation.
      checkIfCanceled(false);
@@ -177,9 +186,9 @@
      if (readLock == null)
      {
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(
                                String.valueOf(entryDN)));
        break compareProcessing;
      appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(String
          .valueOf(entryDN)));
      return;
      }
      try
@@ -192,8 +201,8 @@
          if (entry == null)
          {
            setResultCode(ResultCode.NO_SUCH_OBJECT);
            appendErrorMessage(
                    ERR_COMPARE_NO_SUCH_ENTRY.get(String.valueOf(entryDN)));
          appendErrorMessage(ERR_COMPARE_NO_SUCH_ENTRY.get(String
              .valueOf(entryDN)));
            // See if one of the entry's ancestors exists.
            DN parentDN = entryDN.getParentDNInSuffix();
@@ -219,7 +228,7 @@
              parentDN = parentDN.getParentDNInSuffix();
            }
            break compareProcessing;
          return;
          }
        }
        catch (DirectoryException de)
@@ -231,7 +240,7 @@
          setResultCode(de.getResultCode());
          appendErrorMessage(de.getMessageObject());
          break compareProcessing;
        return;
        }
        // Check to see if there are any controls in the request.  If so, then
@@ -248,7 +257,7 @@
          }
          setResponseData(de);
          break compareProcessing;
        return;
        }
@@ -263,20 +272,20 @@
        // have already exposed sensitive information to the client.
        try
        {
          if (!AccessControlConfigManager.getInstance()
              .getAccessControlHandler().isAllowed(this))
        if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
            .isAllowed(this))
          {
            setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
            appendErrorMessage(ERR_COMPARE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
                .get(String.valueOf(entryDN)));
            break compareProcessing;
          return;
          }
        }
        catch (DirectoryException e)
        {
          setResultCode(e.getResultCode());
          appendErrorMessage(e.getMessageObject());
          break compareProcessing;
        return;
        }
        // Check for a request to cancel this operation.
@@ -284,16 +293,17 @@
        // Invoke the pre-operation compare plugins.
        executePostOpPlugins = true;
      executePostOpPlugins.value = true;
        PluginResult.PreOperation preOpResult =
             pluginConfigManager.invokePreOperationComparePlugins(this);
          DirectoryServer.getPluginConfigManager()
              .invokePreOperationComparePlugins(this);
          if (!preOpResult.continueProcessing())
          {
            setResultCode(preOpResult.getResultCode());
            appendErrorMessage(preOpResult.getErrorMessage());
            setMatchedDN(preOpResult.getMatchedDN());
            setReferralURLs(preOpResult.getReferralURLs());
            break compareProcessing;
        return;
          }
@@ -309,21 +319,19 @@
          setResultCode(ResultCode.NO_SUCH_ATTRIBUTE);
          if (options == null)
          {
            appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR.get(
                                    String.valueOf(entryDN),
                                    getRawAttributeType()));
          appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR.get(String
              .valueOf(entryDN), getRawAttributeType()));
          }
          else
          {
            appendErrorMessage(WARN_COMPARE_OP_NO_SUCH_ATTR_WITH_OPTIONS.get(
                                    String.valueOf(entryDN),
                                    getRawAttributeType()));
              String.valueOf(entryDN), getRawAttributeType()));
          }
        }
        else
        {
          AttributeValue value = AttributeValues.create(attrType,
                                                    getAssertionValue());
        AttributeValue value =
            AttributeValues.create(attrType, getAssertionValue());
          boolean matchFound = false;
          for (Attribute a : attrList)
@@ -351,43 +359,19 @@
      }
    }
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Invoke the post-operation compare plugins.
    if (executePostOpPlugins)
    {
      PluginResult.PostOperation postOpResult =
           pluginConfigManager.invokePostOperationComparePlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
      }
    }
  }
  /**
   * Performs any processing required for the controls included in the request.
   *
   * @throws  DirectoryException  If a problem occurs that should prevent the
   *                              operation from succeeding.
   */
  protected void handleRequestControls()
          throws DirectoryException
  private void handleRequestControls() throws DirectoryException
  {
    List<Control> requestControls = getRequestControls();
    if ((requestControls != null) && (! requestControls.isEmpty()))
    {
      for (int i=0; i < requestControls.size(); i++)
      for (Control c : requestControls)
      {
        Control c   = requestControls.get(i);
        String  oid = c.getOID();
        if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c))
@@ -462,7 +446,7 @@
          addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
              "obsoleteProxiedAuthzV1Control"));
          // The requester must have the PROXIED_AUTH privilige in order to
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
          if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
          {
@@ -486,7 +470,7 @@
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        {
          // The requester must have the PROXIED_AUTH privilige in order to
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
          if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
          {
@@ -524,4 +508,3 @@
    }
  }
}
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -74,43 +74,43 @@
  /**
   * The backend in which the operation is to be processed.
   */
  protected Backend backend;
  private Backend backend;
  /**
   * Indicates whether the no-op control was included in the request.
   */
  protected boolean noOp;
  private boolean noOp;
  /**
   * The client connection on which this operation was requested.
   */
  protected ClientConnection clientConnection;
  private ClientConnection clientConnection;
  /**
   * The original DN of the entry.
   */
  protected DN entryDN;
  private DN entryDN;
  /**
   * The current entry, before it is renamed.
   */
  protected Entry currentEntry;
  private Entry currentEntry;
  /**
   * The new entry, as it will appear after it has been renamed.
   */
  protected Entry newEntry;
  private Entry newEntry;
  // The LDAP post-read request control, if present in the request.
  /** The LDAP post-read request control, if present in the request. */
  private LDAPPostReadRequestControl postReadRequest;
  // The LDAP pre-read request control, if present in the request.
  /** The LDAP pre-read request control, if present in the request. */
  private LDAPPreReadRequestControl preReadRequest;
  /**
   * The new RDN for the entry.
   */
  protected RDN newRDN;
  private RDN newRDN;
@@ -171,21 +171,86 @@
  public void processLocalModifyDN(final LocalBackendWorkflowElement wfe)
      throws CanceledOperationException
  {
    boolean executePostOpPlugins = false;
    this.backend = wfe.getBackend();
    clientConnection = getClientConnection();
    // Get the plugin config manager that will be used for invoking plugins.
    PluginConfigManager pluginConfigManager =
         DirectoryServer.getPluginConfigManager();
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Create a labeled block of code that we can break out of if a problem is
    // detected.
modifyDNProcessing:
    BooleanHolder executePostOpPlugins = new BooleanHolder();
    processModifyDN(executePostOpPlugins);
    // Invoke the post-operation or post-synchronization modify DN plugins.
    PluginConfigManager pluginConfigManager =
        DirectoryServer.getPluginConfigManager();
    if (isSynchronizationOperation())
    {
      if (getResultCode() == ResultCode.SUCCESS)
      {
        pluginConfigManager.invokePostSynchronizationModifyDNPlugins(this);
      }
    }
    else if (executePostOpPlugins.value)
    {
      PluginResult.PostOperation postOpResult =
          pluginConfigManager.invokePostOperationModifyDNPlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
        return;
      }
    }
    // Register a post-response call-back which will notify persistent
    // searches and change listeners.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      registerPostResponseCallback(new Runnable()
      {
        @Override
        public void run()
        {
          // Notify persistent searches.
          for (PersistentSearch psearch : wfe.getPersistentSearches())
          {
            psearch.processModifyDN(newEntry, getChangeNumber(), currentEntry
                .getDN());
          }
          // Notify change listeners.
          for (ChangeNotificationListener changeListener : DirectoryServer
              .getChangeNotificationListeners())
          {
            try
            {
              changeListener.handleModifyDNOperation(
                  LocalBackendModifyDNOperation.this, currentEntry, newEntry);
            }
            catch (Exception e)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              Message message =
                  ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
                      .get(getExceptionMessage(e));
              logError(message);
            }
          }
        }
      });
    }
  }
  private void processModifyDN(BooleanHolder executePostOpPlugins)
      throws CanceledOperationException
    {
      // Process the entry DN, newRDN, and newSuperior elements from their raw
      // forms as provided by the client to the forms required for the rest of
@@ -195,14 +260,13 @@
      newRDN = getNewRDN();
      if (newRDN == null)
      {
        break modifyDNProcessing;
      return;
      }
      DN newSuperior = getNewSuperior();
      if ((newSuperior == null) &&
          (getRawNewSuperior() != null))
    if (newSuperior == null && getRawNewSuperior() != null)
      {
        break modifyDNProcessing;
      return;
      }
      // Construct the new DN to use for the entry.
@@ -216,18 +280,18 @@
        if(newSuperior.isDescendantOf(entryDN))
        {
          setResultCode(ResultCode.UNWILLING_TO_PERFORM);
          appendErrorMessage(ERR_MODDN_NEW_SUPERIOR_IN_SUBTREE.get(
              String.valueOf(entryDN), String.valueOf(newSuperior)));
          break modifyDNProcessing;
        appendErrorMessage(ERR_MODDN_NEW_SUPERIOR_IN_SUBTREE.get(String
            .valueOf(entryDN), String.valueOf(newSuperior)));
        return;
        }
        parentDN = newSuperior;
      }
      if ((parentDN == null) || parentDN.isNullDN())
    if (parentDN == null || parentDN.isNullDN())
      {
        setResultCode(ResultCode.UNWILLING_TO_PERFORM);
        appendErrorMessage(ERR_MODDN_NO_PARENT.get(String.valueOf(entryDN)));
        break modifyDNProcessing;
      return;
      }
      DN newDN = parentDN.concat(newRDN);
@@ -238,42 +302,38 @@
      if (currentBackend == null)
      {
        setResultCode(ResultCode.NO_SUCH_OBJECT);
        appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_CURRENT_ENTRY.get(
                                String.valueOf(entryDN)));
        break modifyDNProcessing;
      appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_CURRENT_ENTRY.get(String
          .valueOf(entryDN)));
      return;
      }
      Backend newBackend = DirectoryServer.getBackend(newDN);
      if (newBackend == null)
      {
        setResultCode(ResultCode.NO_SUCH_OBJECT);
        appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_NEW_ENTRY.get(
                                String.valueOf(entryDN),
                                String.valueOf(newDN)));
        break modifyDNProcessing;
      appendErrorMessage(ERR_MODDN_NO_BACKEND_FOR_NEW_ENTRY.get(String
          .valueOf(entryDN), String.valueOf(newDN)));
      return;
      }
      else if (! currentBackend.equals(newBackend))
      {
        setResultCode(ResultCode.UNWILLING_TO_PERFORM);
        appendErrorMessage(ERR_MODDN_DIFFERENT_BACKENDS.get(
                                String.valueOf(entryDN),
                                String.valueOf(newDN)));
        break modifyDNProcessing;
      appendErrorMessage(ERR_MODDN_DIFFERENT_BACKENDS.get(String
          .valueOf(entryDN), String.valueOf(newDN)));
      return;
      }
      // Check for a request to cancel this operation.
      checkIfCanceled(false);
      // Acquire write locks for the current and new DN.
      final Lock currentLock = LockManager.lockWrite(entryDN);
      if (currentLock == null)
      {
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_MODDN_CANNOT_LOCK_CURRENT_DN.get(
                                String.valueOf(entryDN)));
        break modifyDNProcessing;
      appendErrorMessage(ERR_MODDN_CANNOT_LOCK_CURRENT_DN.get(String
          .valueOf(entryDN)));
      return;
      }
      Lock newLock = null;
@@ -296,10 +356,9 @@
        }
        setResultCode(DirectoryServer.getServerErrorResultCode());
        appendErrorMessage(ERR_MODDN_EXCEPTION_LOCKING_NEW_DN.get(
                                String.valueOf(entryDN), String.valueOf(newDN),
                                getExceptionMessage(e)));
        break modifyDNProcessing;
      appendErrorMessage(ERR_MODDN_EXCEPTION_LOCKING_NEW_DN.get(String
          .valueOf(entryDN), String.valueOf(newDN), getExceptionMessage(e)));
      return;
      }
      if (newLock == null)
@@ -307,10 +366,9 @@
        LockManager.unlock(entryDN, currentLock);
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_MODDN_CANNOT_LOCK_NEW_DN.get(
                                String.valueOf(entryDN),
                                String.valueOf(newDN)));
        break modifyDNProcessing;
      appendErrorMessage(ERR_MODDN_CANNOT_LOCK_NEW_DN.get(String
          .valueOf(entryDN), String.valueOf(newDN)));
      return;
      }
      try
@@ -318,23 +376,9 @@
        // Check for a request to cancel this operation.
        checkIfCanceled(false);
        // Get the current entry from the appropriate backend.  If it doesn't
        // exist, then fail.
        try
        {
          currentEntry = currentBackend.getEntry(entryDN);
        }
        catch (DirectoryException de)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, de);
          }
          setResponseData(de);
          break modifyDNProcessing;
        }
        if (getOriginalEntry() == null)
        {
@@ -363,29 +407,14 @@
          }
          setResultCode(ResultCode.NO_SUCH_OBJECT);
          appendErrorMessage(ERR_MODDN_NO_CURRENT_ENTRY.get(
                                  String.valueOf(entryDN)));
          break modifyDNProcessing;
        appendErrorMessage(ERR_MODDN_NO_CURRENT_ENTRY.get(String
            .valueOf(entryDN)));
        return;
        }
        // Check to see if there are any controls in the request.  If so, then
        // see if there is any special processing required.
        try
        {
          handleRequestControls();
        }
        catch (DirectoryException de)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, de);
          }
          setResponseData(de);
          break modifyDNProcessing;
        }
        // Check to see if the client has permission to perform the
        // modify DN.
@@ -399,20 +428,20 @@
        // to the client.
        try
        {
          if (!AccessControlConfigManager.getInstance()
              .getAccessControlHandler().isAllowed(this))
        if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
            .isAllowed(this))
          {
            setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
            appendErrorMessage(ERR_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
                .get(String.valueOf(entryDN)));
            break modifyDNProcessing;
          return;
          }
        }
        catch (DirectoryException e)
        {
          setResultCode(e.getResultCode());
          appendErrorMessage(e.getMessageObject());
          break modifyDNProcessing;
        return;
        }
        // Duplicate the entry and set its new DN.  Also, create an empty list
@@ -424,8 +453,9 @@
        addModification(null);
        List<Modification> modifications = this.getModifications();
        if(!handleConflictResolution()) {
            break modifyDNProcessing;
      if (!handleConflictResolution())
      {
        return;
        }
        // If the operation is not a synchronization operation,
@@ -438,91 +468,47 @@
        {
          // Apply any changes to the entry based on the change in its RDN.
          // Also perform schema checking on the updated entry.
          try
          {
            applyRDNChanges(modifications);
          }
          catch (DirectoryException de)
          {
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, de);
            }
            setResponseData(de);
            break modifyDNProcessing;
          }
          // Check for a request to cancel this operation.
          checkIfCanceled(false);
          // Get a count of the current number of modifications.  The
          // pre-operation plugins may alter this list, and we need to be able
          // to identify which changes were made after they're done.
          int modCount = modifications.size();
          executePostOpPlugins = true;
        executePostOpPlugins.value = true;
          PluginResult.PreOperation preOpResult =
            pluginConfigManager.invokePreOperationModifyDNPlugins(this);
            DirectoryServer.getPluginConfigManager()
                .invokePreOperationModifyDNPlugins(this);
          if (!preOpResult.continueProcessing())
          {
            setResultCode(preOpResult.getResultCode());
            appendErrorMessage(preOpResult.getErrorMessage());
            setMatchedDN(preOpResult.getMatchedDN());
            setReferralURLs(preOpResult.getReferralURLs());
            break modifyDNProcessing;
          return;
          }
          // Check to see if any of the pre-operation plugins made any changes
          // to the entry.  If so, then apply them.
          if (modifications.size() > modCount)
          {
            try
            {
              applyPreOpModifications(modifications, modCount, true);
            }
            catch (DirectoryException de)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, de);
              }
              setResponseData(de);
              break modifyDNProcessing;
            }
          }
        }
        else
        {
          // This is a synchronization operation
          // Apply the modifications as they were originally done.
          try
          {
            applyRDNChanges(modifications);
            applyPreOpModifications(modifications, 0, false);
          }
          catch (DirectoryException de)
          {
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, de);
            }
            setResponseData(de);
            break modifyDNProcessing;
          }
        }
        // Actually perform the modify DN operation.
        // This should include taking
        // care of any synchronization that might be needed.
        try
        {
          // If it is not a private backend, then check to see if the server or
          // backend is operating in read-only mode.
          if (! currentBackend.isPrivateBackend())
@@ -531,17 +517,17 @@
            {
              case DISABLED:
                setResultCode(ResultCode.UNWILLING_TO_PERFORM);
                appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(
                                        String.valueOf(entryDN)));
                break modifyDNProcessing;
          appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(String
              .valueOf(entryDN)));
          return;
              case INTERNAL_ONLY:
                if (! (isInternalOperation() || isSynchronizationOperation()))
                {
                  setResultCode(ResultCode.UNWILLING_TO_PERFORM);
                  appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(
                                          String.valueOf(entryDN)));
                  break modifyDNProcessing;
            appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(String
                .valueOf(entryDN)));
            return;
                }
            }
@@ -549,22 +535,21 @@
            {
              case DISABLED:
                setResultCode(ResultCode.UNWILLING_TO_PERFORM);
                appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(
                                        String.valueOf(entryDN)));
                break modifyDNProcessing;
          appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(String
              .valueOf(entryDN)));
          return;
              case INTERNAL_ONLY:
                if (! (isInternalOperation() || isSynchronizationOperation()))
                {
                  setResultCode(ResultCode.UNWILLING_TO_PERFORM);
                  appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(
                                          String.valueOf(entryDN)));
                  break modifyDNProcessing;
            appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(String
                .valueOf(entryDN)));
            return;
                }
            }
          }
          if (noOp)
          {
            appendErrorMessage(INFO_MODDN_NOOP.get());
@@ -572,20 +557,19 @@
          }
          else
          {
              if(!processPreOperation()) {
                  break modifyDNProcessing;
        if (!processPreOperation())
        {
          return;
              }
              currentBackend.renameEntry(entryDN, newEntry, this);
          }
          // Attach the pre-read and/or post-read controls to the response if
          // appropriate.
          LocalBackendWorkflowElement.addPreReadResponse(this,
              preReadRequest, currentEntry);
          LocalBackendWorkflowElement.addPostReadResponse(this,
              postReadRequest, newEntry);
      LocalBackendWorkflowElement.addPreReadResponse(this, preReadRequest,
          currentEntry);
      LocalBackendWorkflowElement.addPostReadResponse(this, postReadRequest,
          newEntry);
          if (! noOp)
          {
@@ -600,8 +584,7 @@
          }
          setResponseData(de);
          break modifyDNProcessing;
        }
      return;
      }
      finally
      {
@@ -611,81 +594,13 @@
      }
    }
    // Invoke the post-operation or post-synchronization modify DN plugins.
    if (isSynchronizationOperation())
    {
      if (getResultCode() == ResultCode.SUCCESS)
      {
        pluginConfigManager.invokePostSynchronizationModifyDNPlugins(this);
      }
    }
    else if (executePostOpPlugins)
    {
      PluginResult.PostOperation postOpResult =
           pluginConfigManager.invokePostOperationModifyDNPlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
        return;
      }
    }
    // Register a post-response call-back which will notify persistent
    // searches and change listeners.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      registerPostResponseCallback(new Runnable()
      {
        @Override
        public void run()
        {
          // Notify persistent searches.
          for (PersistentSearch psearch : wfe.getPersistentSearches())
          {
            psearch.processModifyDN(newEntry, getChangeNumber(),
                currentEntry.getDN());
          }
          // Notify change listeners.
          for (ChangeNotificationListener changeListener : DirectoryServer
              .getChangeNotificationListeners())
          {
            try
            {
              changeListener.handleModifyDNOperation(
                  LocalBackendModifyDNOperation.this, currentEntry, newEntry);
            }
            catch (Exception e)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              Message message = ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
                  .get(getExceptionMessage(e));
              logError(message);
            }
          }
        }
      });
    }
  }
  /**
   * Processes the set of controls included in the request.
   *
   * @throws  DirectoryException  If a problem occurs that should cause the
   *                              modify DN operation to fail.
   */
  protected void handleRequestControls()
          throws DirectoryException
  private void handleRequestControls() throws DirectoryException
  {
    List<Control> requestControls = getRequestControls();
    if ((requestControls != null) && (! requestControls.isEmpty()))
@@ -790,7 +705,7 @@
          addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
              "obsoleteProxiedAuthzV1Control"));
          // The requester must have the PROXIED_AUTH privilige in order to
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
          if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
          {
@@ -814,7 +729,7 @@
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        {
          // The requester must have the PROXIED_AUTH privilige in order to
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
          if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
          {
@@ -864,7 +779,7 @@
   * @throws  DirectoryException  If a problem occurs that should cause the
   *                              modify DN operation to fail.
   */
  protected void applyRDNChanges(List<Modification> modifications)
  private void applyRDNChanges(List<Modification> modifications)
          throws DirectoryException
  {
    // If we should delete the old RDN values from the entry, then do so.
@@ -891,8 +806,7 @@
          }
        }
        LinkedList<AttributeValue> missingValues =
             new LinkedList<AttributeValue>();
        List<AttributeValue> missingValues = new LinkedList<AttributeValue>();
        newEntry.removeAttribute(a, missingValues);
        if (missingValues.isEmpty())
@@ -912,8 +826,7 @@
          newRDN.getAttributeName(i),
          newRDN.getAttributeValue(i));
      LinkedList<AttributeValue> duplicateValues =
           new LinkedList<AttributeValue>();
      List<AttributeValue> duplicateValues = new LinkedList<AttributeValue>();
      newEntry.addAttribute(a, duplicateValues);
      if (duplicateValues.isEmpty())
@@ -981,7 +894,7 @@
   * @throws  DirectoryException  If a problem occurs that should cause the
   *                              modify DN operation to fail.
   */
  protected void applyPreOpModifications(List<Modification> modifications,
  private void applyPreOpModifications(List<Modification> modifications,
                                       int startPos, boolean checkSchema)
          throws DirectoryException
  {
@@ -993,14 +906,13 @@
      switch (m.getModificationType())
      {
        case ADD:
          LinkedList<AttributeValue> duplicateValues =
          List<AttributeValue> duplicateValues =
               new LinkedList<AttributeValue>();
          newEntry.addAttribute(a, duplicateValues);
          break;
        case DELETE:
          LinkedList<AttributeValue> missingValues =
               new LinkedList<AttributeValue>();
          List<AttributeValue> missingValues = new LinkedList<AttributeValue>();
          newEntry.removeAttribute(a, missingValues);
          break;
@@ -1038,7 +950,8 @@
   * @return  {@code true} if processing should continue for the operation, or
   *          {@code false} if not.
   */
  protected boolean handleConflictResolution() {
  private boolean handleConflictResolution()
  {
      boolean returnVal = true;
      for (SynchronizationProvider<?> provider :
@@ -1075,7 +988,8 @@
   * @return  {@code true} if processing should continue for the operation, or
   *          {@code false} if not.
   */
  protected boolean processPreOperation() {
  private boolean processPreOperation()
  {
      boolean returnVal = true;
      for (SynchronizationProvider<?> provider :
@@ -1108,7 +1022,8 @@
  /**
   * Invoke post operation synchronization providers.
   */
  protected void processSynchPostOperationPlugins() {
  private void processSynchPostOperationPlugins()
  {
      for (SynchronizationProvider<?> provider : DirectoryServer
              .getSynchronizationProviders()) {
          try {
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -27,8 +27,6 @@
 */
package org.opends.server.workflowelement.localbackend;
import java.util.List;
import org.opends.server.api.Backend;
@@ -43,7 +41,6 @@
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.core.SearchOperationWrapper;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
@@ -58,8 +55,6 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to search for entries in a local backend
 * of the Directory Server.
@@ -79,33 +74,33 @@
  /**
   * The backend in which the search is to be performed.
   */
  protected Backend backend;
  private Backend backend;
  /**
   * Indicates whether we should actually process the search.  This should
   * only be false if it's a persistent search with changesOnly=true.
   */
  protected boolean processSearch;
  private boolean processSearch;
  /**
   * The client connection for the search operation.
   */
  protected ClientConnection clientConnection;
  private ClientConnection clientConnection;
  /**
   * The base DN for the search.
   */
  protected DN baseDN;
  private DN baseDN;
  /**
   * The persistent search request, if applicable.
   */
  protected PersistentSearch persistentSearch;
  private PersistentSearch persistentSearch;
  /**
   * The filter for the search.
   */
  protected SearchFilter filter;
  private SearchFilter filter;
@@ -134,22 +129,39 @@
  public void processLocalSearch(LocalBackendWorkflowElement wfe)
      throws CanceledOperationException
  {
    boolean executePostOpPlugins = false;
    this.backend = wfe.getBackend();
    clientConnection = getClientConnection();
    // Get the plugin config manager that will be used for invoking plugins.
    PluginConfigManager pluginConfigManager =
      DirectoryServer.getPluginConfigManager();
    processSearch = true;
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Create a labeled block of code that we can break out of if a problem is
    // detected.
searchProcessing:
    BooleanHolder executePostOpPlugins = new BooleanHolder();
    processSearch(wfe, executePostOpPlugins);
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Invoke the post-operation search plugins.
    if (executePostOpPlugins.value)
    {
      PluginResult.PostOperation postOpResult =
          DirectoryServer.getPluginConfigManager()
              .invokePostOperationSearchPlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
      }
    }
  }
  private void processSearch(LocalBackendWorkflowElement wfe,
      BooleanHolder executePostOpPlugins) throws CanceledOperationException
    {
      // Process the search base and filter to convert them from their raw forms
      // as provided by the client to the forms required for the rest of the
@@ -157,8 +169,9 @@
      baseDN = getBaseDN();
      filter = getFilter();
      if ((baseDN == null) || (filter == null)){
        break searchProcessing;
    if ((baseDN == null) || (filter == null))
    {
      return;
      }
      // Check to see if there are any controls in the request.  If so, then
@@ -175,7 +188,7 @@
        }
        setResponseData(de);
        break searchProcessing;
      return;
      }
@@ -187,20 +200,20 @@
      // and any other controls specified.
      try
      {
        if (!AccessControlConfigManager.getInstance()
            .getAccessControlHandler().isAllowed(this))
      if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
          .isAllowed(this))
        {
          setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
          appendErrorMessage(ERR_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
              .get(String.valueOf(baseDN)));
          break searchProcessing;
        return;
        }
      }
      catch (DirectoryException e)
      {
        setResultCode(e.getResultCode());
        appendErrorMessage(e.getMessageObject());
        break searchProcessing;
      return;
      }
      // Check for a request to cancel this operation.
@@ -208,16 +221,17 @@
      // Invoke the pre-operation search plugins.
      executePostOpPlugins = true;
    executePostOpPlugins.value = true;
      PluginResult.PreOperation preOpResult =
          pluginConfigManager.invokePreOperationSearchPlugins(this);
        DirectoryServer.getPluginConfigManager()
            .invokePreOperationSearchPlugins(this);
      if (!preOpResult.continueProcessing())
      {
        setResultCode(preOpResult.getResultCode());
        appendErrorMessage(preOpResult.getErrorMessage());
        setMatchedDN(preOpResult.getMatchedDN());
        setReferralURLs(preOpResult.getReferralURLs());
        break searchProcessing;
      return;
      }
@@ -230,9 +244,9 @@
      if (backend == null)
      {
        setResultCode(ResultCode.NO_SUCH_OBJECT);
        appendErrorMessage(ERR_SEARCH_BASE_DOESNT_EXIST.get(
                                String.valueOf(baseDN)));
        break searchProcessing;
      appendErrorMessage(ERR_SEARCH_BASE_DOESNT_EXIST.get(String
          .valueOf(baseDN)));
      return;
      }
@@ -251,7 +265,7 @@
        {
          setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
          appendErrorMessage(ERR_MAX_PSEARCH_LIMIT_EXCEEDED.get());
          break searchProcessing;
        return;
        }
        wfe.registerPersistentSearch(persistentSearch);
        persistentSearch.enable();
@@ -281,7 +295,7 @@
          setSendResponse(true);
        }
        break searchProcessing;
      return;
      }
      catch (CanceledOperationException coe)
      {
@@ -301,35 +315,14 @@
        }
        setResultCode(DirectoryServer.getServerErrorResultCode());
        appendErrorMessage(ERR_SEARCH_BACKEND_EXCEPTION.get(
                                getExceptionMessage(e)));
      appendErrorMessage(ERR_SEARCH_BACKEND_EXCEPTION
          .get(getExceptionMessage(e)));
        if (persistentSearch != null)
        {
          persistentSearch.cancel();
          setSendResponse(true);
        }
        break searchProcessing;
      }
    }
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Invoke the post-operation search plugins.
    if (executePostOpPlugins)
    {
      PluginResult.PostOperation postOpResult =
           pluginConfigManager.invokePostOperationSearchPlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
      }
    }
  }
@@ -337,11 +330,10 @@
  /**
   * Handles any controls contained in the request.
   *
   * @throws  DirectoryException  If there is a problem with any of the request
   *                              controls.
   * @throws DirectoryException
   *           If there is a problem with any of the request controls.
   */
  protected void handleRequestControls()
          throws DirectoryException
  private void handleRequestControls() throws DirectoryException
  {
    List<Control> requestControls  = getRequestControls();
    if ((requestControls != null) && (! requestControls.isEmpty()))
@@ -443,7 +435,7 @@
          addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
              "obsoleteProxiedAuthzV1Control"));
          // The requester must have the PROXIED_AUTH privilige in order to be
          // The requester must have the PROXIED_AUTH privilege in order to be
          // able to use this control.
          if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
          {
@@ -467,7 +459,7 @@
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        {
          // The requester must have the PROXIED_AUTH privilige in order to be
          // The requester must have the PROXIED_AUTH privilege in order to be
          // able to use this control.
          if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
          {