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

Jean-Noel Rouvignac
26.11.2014 98a5df3565beaa1999020a16fcb5338d13d5b50f
Removed useless getChangeNumber() and setChangeNumber methods from *Operation interfaces.
These methods are useless because setChangeNumber() is never set inside production code, so changeNumber is always equal to -1 for all the update operations. In addition it is very unlikely the ChangeNumberIndexer could have computed the changeNumber before a results are sent to a persistent search.


AddOperation*.java, DeleteOperation*.java, ModifyDNOperation*.java, ModifyOperation*.java:
Removed changeNumber fields + getters and setters.
Code cleanup.

PersistentSearch.java:
In process*() public methods, removed the long changeNumber attributes.
Removed baseDN, scope and filter fields, and retrieve them directly from the SearchOperation.
Extracted methods isInScope(), isInScopeForModify(), isAnyInScopeForModify(), matchesFilter(), anyMatchesFilter(), sendEntry(), createControls().
to factorize duplicated code.

LocalBackend*Operation.java:
Consequence of the changes to PersistentSearch.process*() methods.
Code cleanup.

ECLServerWriter.java:
In publish(), consequence of the change to PersistentSearch.processAdd().
In doIt(), simplified code by extracting takeECLUpdate() method.
21 files modified
2734 ■■■■ changed files
opends/src/server/org/opends/server/core/AddOperation.java 50 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/AddOperationBasis.java 145 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/AddOperationWrapper.java 85 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DeleteOperation.java 29 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DeleteOperationBasis.java 73 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DeleteOperationWrapper.java 46 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyDNOperation.java 57 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java 159 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyDNOperationWrapper.java 90 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyOperation.java 41 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyOperationBasis.java 105 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyOperationWrapper.java 65 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/PersistentSearch.java 494 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/server/ECLServerWriter.java 51 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java 165 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java 99 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java 130 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java 360 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java 347 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java 56 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java 87 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/AddOperation.java
@@ -22,6 +22,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -44,7 +45,7 @@
   *
   * @return  The DN of the entry in a raw, unparsed form.
   */
  public abstract ByteString getRawEntryDN();
  ByteString getRawEntryDN();
  /**
   * Specifies the raw entry DN for the entry to add.  This should only be
@@ -55,7 +56,7 @@
   *
   * @param  rawEntryDN  The raw entry DN for the entry to add.
   */
  public abstract void setRawEntryDN(ByteString rawEntryDN);
  void setRawEntryDN(ByteString rawEntryDN);
  /**
   * Retrieves the DN of the entry to add.  This method should not be called
@@ -65,7 +66,7 @@
   * @return  The DN of the entry to add, or <CODE>null</CODE> if it has not yet
   *          been parsed from the raw DN.
   */
  public abstract DN getEntryDN();
  DN getEntryDN();
  /**
   * Retrieves the set of attributes in their raw, unparsed form as read from
@@ -76,7 +77,7 @@
   * @return  The set of attributes in their raw, unparsed form as read from the
   *          client request.
   */
  public abstract List<RawAttribute> getRawAttributes();
  List<RawAttribute> getRawAttributes();
  /**
   * Adds the provided attribute to the set of raw attributes for this add
@@ -85,7 +86,7 @@
   * @param  rawAttribute  The attribute to add to the set of raw attributes for
   *                       this add operation.
   */
  public abstract void addRawAttribute(RawAttribute rawAttribute);
  void addRawAttribute(RawAttribute rawAttribute);
  /**
   * Replaces the set of raw attributes for this add operation.  This should
@@ -93,7 +94,7 @@
   *
   * @param  rawAttributes  The set of raw attributes for this add operation.
   */
  public abstract void setRawAttributes(List<RawAttribute> rawAttributes);
  void setRawAttributes(List<RawAttribute> rawAttributes);
  /**
   * Retrieves the set of processed user attributes for the entry to add.  This
@@ -104,7 +105,7 @@
   * @return  The set of processed user attributes for the entry to add, or
   *          <CODE>null</CODE> if that information is not yet available.
   */
  public abstract Map<AttributeType, List<Attribute>> getUserAttributes();
  Map<AttributeType, List<Attribute>> getUserAttributes();
  /**
   * Sets the specified attribute in the entry to add, overwriting any existing
@@ -117,8 +118,7 @@
   * @param  attributeType  The attribute type for the attribute.
   * @param  attributeList  The attribute list for the provided attribute type.
   */
  public abstract void setAttribute(AttributeType attributeType,
      List<Attribute> attributeList);
  void setAttribute(AttributeType attributeType, List<Attribute> attributeList);
  /**
   * Removes the specified attribute from the entry to add. This should only be
@@ -129,25 +129,7 @@
   *
   * @param  attributeType  The attribute tyep for the attribute to remove.
   */
  public abstract void removeAttribute(AttributeType attributeType);
  /**
   * Retrieves the change number that has been assigned to this operation.
   *
   * @return  The change number that has been assigned to this operation, or -1
   *          if none has been assigned yet or if there is no applicable
   *          synchronization mechanism in place that uses change numbers.
   */
  public abstract long getChangeNumber();
  /**
   * Specifies the change number that has been assigned to this operation by the
   * synchronization mechanism.
   *
   * @param  changeNumber  The change number that has been assigned to this
   *                       operation by the synchronization mechanism.
   */
  public abstract void setChangeNumber(long changeNumber);
  void removeAttribute(AttributeType attributeType);
  /**
   * Retrieves the set of processed objectclasses for the entry to add.  This
@@ -158,7 +140,7 @@
   * @return  The set of processed objectclasses for the entry to add, or
   *          <CODE>null</CODE> if that information is not yet available.
   */
  public abstract Map<ObjectClass,String> getObjectClasses();
  Map<ObjectClass, String> getObjectClasses();
  /**
   * Adds the provided objectclass to the entry to add.  This should only be
@@ -170,7 +152,7 @@
   * @param  objectClass  The objectclass to add to the entry.
   * @param  name         The name to use for the objectclass.
   */
  public abstract void addObjectClass(ObjectClass objectClass, String name);
  void addObjectClass(ObjectClass objectClass, String name);
  /**
   * Removes the provided objectclass from the entry to add.  This should only
@@ -181,7 +163,7 @@
   *
   * @param  objectClass  The objectclass to remove from the entry.
   */
  public abstract void removeObjectClass(ObjectClass objectClass);
  void removeObjectClass(ObjectClass objectClass);
  /**
   * Retrieves the set of processed operational attributes for the entry to add.
@@ -192,7 +174,7 @@
   * @return  The set of processed operational attributes for the entry to add,
   *          or <CODE>null</CODE> if that information is not yet available.
   */
  public abstract Map<AttributeType,List<Attribute>> getOperationalAttributes();
  Map<AttributeType, List<Attribute>> getOperationalAttributes();
  /**
   * Retrieves the proxied authorization DN for this operation if proxied
@@ -202,7 +184,7 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public abstract DN getProxiedAuthorizationDN();
  DN getProxiedAuthorizationDN();
  /**
   * Set the proxied authorization DN for this operation if proxied
@@ -213,6 +195,6 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public abstract void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
  void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
}
opends/src/server/org/opends/server/core/AddOperationBasis.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2007-2010 Sun Microsystems, Inc.
 *      Portions copyright 2013 ForgeRock AS
 *      Portions copyright 2013-2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -94,9 +94,6 @@
  /** The set of objectclasses for the entry to add. */
  private Map<ObjectClass,String> objectClasses;
  /** The change number that has been assigned to this operation. */
  private long changeNumber;
  /** The flag indicates if an LDAP error was reported. */
  private boolean ldapError;
@@ -132,7 +129,6 @@
    operationalAttributes = null;
    objectClasses         = null;
    proxiedAuthorizationDN = null;
    changeNumber          = -1;
  }
@@ -198,22 +194,16 @@
    responseControls = new ArrayList<Control>();
    proxiedAuthorizationDN = null;
    cancelRequest    = null;
    changeNumber     = -1;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ByteString getRawEntryDN()
  {
    return rawEntryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawEntryDN(ByteString rawEntryDN)
  {
@@ -222,10 +212,7 @@
    entryDN = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final DN getEntryDN()
  {
@@ -251,20 +238,14 @@
    return entryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final List<RawAttribute> getRawAttributes()
  {
    return rawAttributes;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addRawAttribute(RawAttribute rawAttribute)
  {
@@ -275,10 +256,7 @@
    operationalAttributes = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawAttributes(List<RawAttribute> rawAttributes)
  {
@@ -289,11 +267,7 @@
    operationalAttributes = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final Map<ObjectClass,String> getObjectClasses()
  {
@@ -303,33 +277,21 @@
    return objectClasses;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addObjectClass(ObjectClass objectClass, String name)
  {
    objectClasses.put(objectClass, name);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void removeObjectClass(ObjectClass objectClass)
  {
    objectClasses.remove(objectClass);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final Map<AttributeType,List<Attribute>> getUserAttributes()
  {
@@ -339,10 +301,7 @@
    return userAttributes;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final Map<AttributeType,List<Attribute>> getOperationalAttributes()
  {
@@ -396,16 +355,11 @@
              attr = builder.toAttribute();
            }
          }
          else
          else if (attr.hasOption("binary"))
          {
            // binary option is not honored for non-BER-encodable attributes.
            if(attr.hasOption("binary"))
            {
              throw new LDAPException(LDAPResultCode.UNDEFINED_ATTRIBUTE_TYPE,
                      ERR_ADD_ATTR_IS_INVALID_OPTION.get(
                      String.valueOf(entryDN),
                      attr.getName()));
            }
                ERR_ADD_ATTR_IS_INVALID_OPTION.get(String.valueOf(entryDN), attr.getName()));
          }
          if (attrType.isObjectClassType())
@@ -486,9 +440,7 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setAttribute(AttributeType attributeType,
                                 List<Attribute> attributeList)
@@ -505,18 +457,14 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void removeAttribute(AttributeType attributeType)
  {
    getAttributes(attributeType.isOperational()).remove(attributeType);
  }
  private Map<AttributeType, List<Attribute>> getAttributes(
      boolean isOperational)
  private Map<AttributeType, List<Attribute>> getAttributes(boolean isOperational)
  {
    if (isOperational)
    {
@@ -525,29 +473,7 @@
    return userAttributes;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final long getChangeNumber()
  {
    return changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final void setChangeNumber(long changeNumber)
  {
    this.changeNumber = changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final OperationType getOperationType()
  {
@@ -557,52 +483,35 @@
    return OperationType.ADD;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ArrayList<Control> getResponseControls()
  {
    return responseControls;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addResponseControl(Control control)
  {
    responseControls.add(control);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void removeResponseControl(Control control)
  {
    responseControls.remove(control);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void toString(StringBuilder buffer)
  {
@@ -615,18 +524,14 @@
    buffer.append(")");
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
  {
    this.proxiedAuthorizationDN = proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void run()
  {
opends/src/server/org/opends/server/core/AddOperationWrapper.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS
 *      Portions Copyright 2013-2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -31,7 +31,6 @@
import org.opends.server.types.*;
/**
 * This abstract class wraps/decorates a given add operation.
 * This class will be extended by sub-classes to enhance the
@@ -51,108 +50,77 @@
    super(add);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void addObjectClass(ObjectClass objectClass, String name)
  {
    getOperation().addObjectClass(objectClass, name);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void addRawAttribute(RawAttribute rawAttribute)
  {
    getOperation().addRawAttribute(rawAttribute);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public long getChangeNumber()
  {
    return getOperation().getChangeNumber();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getEntryDN()
  {
    return getOperation().getEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public Map<ObjectClass, String> getObjectClasses()
  {
    return getOperation().getObjectClasses();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public Map<AttributeType, List<Attribute>> getOperationalAttributes()
  {
    return getOperation().getOperationalAttributes();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public List<RawAttribute> getRawAttributes()
  {
    return getOperation().getRawAttributes();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ByteString getRawEntryDN()
  {
    return getOperation().getRawEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public Map<AttributeType, List<Attribute>> getUserAttributes()
  {
    return getOperation().getUserAttributes();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void removeAttribute(AttributeType attributeType)
  {
    getOperation().removeAttribute(attributeType);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void removeObjectClass(ObjectClass objectClass)
  {
    getOperation().removeObjectClass(objectClass);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setAttribute(AttributeType attributeType,
      List<Attribute> attributeList)
@@ -160,54 +128,35 @@
    getOperation().setAttribute(attributeType, attributeList);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void setChangeNumber(long changeNumber)
  {
    getOperation().setChangeNumber(changeNumber);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawAttributes(List<RawAttribute> rawAttributes)
  {
    getOperation().setRawAttributes(rawAttributes);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawEntryDN(ByteString rawEntryDN)
  {
    getOperation().setRawEntryDN(rawEntryDN);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public String toString()
  {
    return getOperation().toString();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return getOperation().getProxiedAuthorizationDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
  {
opends/src/server/org/opends/server/core/DeleteOperation.java
@@ -22,6 +22,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -43,7 +44,7 @@
   *
   * @return  The raw, unprocessed entry DN as included in the client request.
   */
  public abstract ByteString getRawEntryDN();
  ByteString getRawEntryDN();
  /**
   * Specifies the raw, unprocessed entry DN as included in the client request.
@@ -53,7 +54,7 @@
   * @param  rawEntryDN  The raw, unprocessed entry DN as included in the client
   *                     request.
   */
  public abstract void setRawEntryDN(ByteString rawEntryDN);
  void setRawEntryDN(ByteString rawEntryDN);
  /**
   * Retrieves the DN of the entry to delete.  This should not be called by
@@ -63,25 +64,7 @@
   * @return  The DN of the entry to delete, or <CODE>null</CODE> if the raw
   *          entry DN has not yet been processed.
   */
  public abstract DN getEntryDN();
  /**
   * Retrieves the change number that has been assigned to this operation.
   *
   * @return  The change number that has been assigned to this operation, or -1
   *          if none has been assigned yet or if there is no applicable
   *          synchronization mechanism in place that uses change numbers.
   */
  public abstract long getChangeNumber();
  /**
   * Specifies the change number that has been assigned to this operation by the
   * synchronization mechanism.
   *
   * @param  changeNumber  The change number that has been assigned to this
   *                       operation by the synchronization mechanism.
   */
  public abstract void setChangeNumber(long changeNumber);
  DN getEntryDN();
  /**
   * Retrieves the proxied authorization DN for this operation if proxied
@@ -91,7 +74,7 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public abstract DN getProxiedAuthorizationDN();
  DN getProxiedAuthorizationDN();
  /**
   * Set the proxied authorization DN for this operation if proxied
@@ -102,7 +85,7 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public abstract void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
  void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
}
opends/src/server/org/opends/server/core/DeleteOperationBasis.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2007-2010 Sun Microsystems, Inc.
 *      Portions copyright 2013 ForgeRock AS
 *      Portions copyright 2013-2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -41,7 +41,7 @@
import org.opends.server.types.*;
import org.opends.server.types.operation.PostResponseDeleteOperation;
import org.opends.server.types.operation.PreParseDeleteOperation;
import org.opends.server.workflowelement.localbackend.*;
import org.opends.server.workflowelement.localbackend.LocalBackendDeleteOperation;
/**
 * This class defines an operation that may be used to remove an entry from the
@@ -70,10 +70,6 @@
  /** The set of response controls for this delete operation. */
  private List<Control> responseControls;
  /** The change number that has been assigned to this operation. */
  private long changeNumber;
  /**
   * Creates a new delete operation with the provided information.
   *
@@ -99,7 +95,6 @@
    entryDN          = null;
    responseControls = new ArrayList<Control>();
    cancelRequest    = null;
    changeNumber     = -1;
  }
@@ -128,21 +123,16 @@
    rawEntryDN       = ByteString.valueOf(entryDN.toString());
    responseControls = new ArrayList<Control>();
    cancelRequest    = null;
    changeNumber     = -1;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ByteString getRawEntryDN()
  {
    return rawEntryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawEntryDN(ByteString rawEntryDN)
  {
@@ -151,9 +141,7 @@
    entryDN = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final DN getEntryDN()
  {
@@ -180,27 +168,7 @@
    return entryDN;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final long getChangeNumber()
  {
    return changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final void setChangeNumber(long changeNumber)
  {
    this.changeNumber = changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  public final OperationType getOperationType()
  {
@@ -209,45 +177,35 @@
    return OperationType.DELETE;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  public final List<Control> getResponseControls()
  {
    return responseControls;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  public final void addResponseControl(Control control)
  {
    responseControls.add(control);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  public final void removeResponseControl(Control control)
  {
    responseControls.remove(control);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  public final void toString(StringBuilder buffer)
  {
@@ -259,18 +217,15 @@
    buffer.append(rawEntryDN);
    buffer.append(")");
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
  {
    this.proxiedAuthorizationDN = proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void run()
  {
opends/src/server/org/opends/server/core/DeleteOperationWrapper.java
@@ -22,15 +22,13 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS
 *      Portions Copyright 2013-2014 ForgeRock AS
 */
package org.opends.server.core;
import org.opends.server.types.ByteString;
import org.opends.server.types.DN;
/**
 * This abstract class wraps/decorates a given delete operation.
 * This class will be extended by sub-classes to enhance the
@@ -50,72 +48,42 @@
    super(delete);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getEntryDN()
  {
    return getOperation().getEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ByteString getRawEntryDN()
  {
    return getOperation().getRawEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawEntryDN(ByteString rawEntryDN)
  {
    getOperation().setRawEntryDN(rawEntryDN);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final long getChangeNumber()
  {
    return getOperation().getChangeNumber();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final void setChangeNumber(long changeNumber)
  {
    getOperation().setChangeNumber(changeNumber);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public String toString()
  {
    return getOperation().toString();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return getOperation().getProxiedAuthorizationDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
  {
opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -22,6 +22,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -45,7 +46,7 @@
   *
   * @return  The raw, unprocessed entry DN as included in the client request.
   */
  public ByteString getRawEntryDN();
  ByteString getRawEntryDN();
  /**
   * Specifies the raw, unprocessed entry DN as included in the client request.
@@ -54,7 +55,7 @@
   * @param  rawEntryDN  The raw, unprocessed entry DN as included in the client
   *                     request.
   */
  public void setRawEntryDN(ByteString rawEntryDN);
  void setRawEntryDN(ByteString rawEntryDN);
  /**
@@ -65,7 +66,7 @@
   * @return  The DN of the entry to rename, or <CODE>null</CODE> if the raw
   *          entry DN has not yet been processed.
   */
  public DN getEntryDN();
  DN getEntryDN();
  /**
   * Retrieves the raw, unprocessed newRDN as included in the request from the
@@ -75,7 +76,7 @@
   * @return  The raw, unprocessed newRDN as included in the request from the
   *          client.
   */
  public ByteString getRawNewRDN();
  ByteString getRawNewRDN();
  /**
   * Specifies the raw, unprocessed newRDN as included in the request from the
@@ -85,7 +86,7 @@
   * @param  rawNewRDN  The raw, unprocessed newRDN as included in the request
   *                    from the client.
   */
  public void setRawNewRDN(ByteString rawNewRDN);
  void setRawNewRDN(ByteString rawNewRDN);
  /**
   * Retrieves the new RDN to use for the entry.  This should not be called by
@@ -95,7 +96,7 @@
   * @return  The new RDN to use for the entry, or <CODE>null</CODE> if the raw
   *          newRDN has not yet been processed.
   */
  public RDN getNewRDN();
  RDN getNewRDN();
  /**
@@ -104,7 +105,7 @@
   * @return  <CODE>true</CODE> if the current RDN value should be removed from
   *          the entry, or <CODE>false</CODE> if not.
   */
  public boolean deleteOldRDN();
  boolean deleteOldRDN();
  /**
   * Specifies whether the current RDN value should be removed from the entry.
@@ -112,7 +113,7 @@
   * @param  deleteOldRDN  Specifies whether the current RDN value should be
   *                       removed from the entry.
   */
  public void setDeleteOldRDN(boolean deleteOldRDN);
  void setDeleteOldRDN(boolean deleteOldRDN);
  /**
   * Retrieves the raw, unprocessed newSuperior from the client request.  This
@@ -122,7 +123,7 @@
   * @return  The raw, unprocessed newSuperior from the client request, or
   *          <CODE>null</CODE> if there is none.
   */
  public ByteString getRawNewSuperior();
  ByteString getRawNewSuperior();
  /**
   * Specifies the raw, unprocessed newSuperior for this modify DN operation, as
@@ -132,7 +133,7 @@
   * @param  rawNewSuperior  The raw, unprocessed newSuperior as provided in the
   *                         request from the client.
   */
  public void setRawNewSuperior(ByteString rawNewSuperior);
  void setRawNewSuperior(ByteString rawNewSuperior);
  /**
   * Retrieves the newSuperior DN for the entry.  This should not be called by
@@ -144,7 +145,7 @@
   *          no newSuperior DN for this request or if the raw newSuperior has
   *          not yet been processed.
   */
  public DN getNewSuperior();
  DN getNewSuperior();
  /**
   * Retrieves the new DN for the entry.
@@ -152,7 +153,7 @@
   * @return The new DN for the entry, or <CODE>null</CODE> if there is
   *          neither newRDN, nor entryDN for this request.
   */
  public DN getNewDN();
  DN getNewDN();
  /**
   * Retrieves the set of modifications applied to attributes of the target
@@ -171,7 +172,7 @@
   *          of the modify DN processing, or <CODE>null</CODE> if that
   *          information is not yet available (e.g., during pre-parse plugins).
   */
  public List<Modification> getModifications();
  List<Modification> getModifications();
  /**
   * Adds the provided modification to the set of modifications to be applied
@@ -181,7 +182,7 @@
   * @param  modification  The modification to add to the set of modifications
   *                       to apply to the entry.
   */
  public void addModification(Modification modification);
  void addModification(Modification modification);
  /**
   * Retrieves the current entry, before it is renamed.  This will not be
@@ -191,7 +192,7 @@
   * @return  The current entry, or <CODE>null</CODE> if it is not yet
   *           available.
   */
  public Entry getOriginalEntry();
  Entry getOriginalEntry();
  /**
@@ -202,27 +203,7 @@
   * @return  The updated entry, or <CODE>null</CODE> if it is not yet
   *           available.
   */
  public Entry getUpdatedEntry();
  /**
   * Retrieves the change number that has been assigned to this operation.
   *
   * @return  The change number that has been assigned to this operation, or -1
   *          if none has been assigned yet or if there is no applicable
   *          synchronization mechanism in place that uses change numbers.
   */
  public long getChangeNumber();
  /**
   * Specifies the change number that has been assigned to this operation by the
   * synchronization mechanism.
   *
   * @param  changeNumber  The change number that has been assigned to this
   *                       operation by the synchronization mechanism.
   */
  public void setChangeNumber(long changeNumber);
  Entry getUpdatedEntry();
  /**
   * Retrieves the proxied authorization DN for this operation if proxied
@@ -232,7 +213,7 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public DN getProxiedAuthorizationDN();
  DN getProxiedAuthorizationDN();
  /**
@@ -243,6 +224,6 @@
   *            authorization has been requested, or {@code null} if proxied
   *            authorization has not been requested.
   */
  public void setProxiedAuthorizationDN(DN dn);
  void setProxiedAuthorizationDN(DN dn);
}
opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
@@ -22,14 +22,10 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011-2013 ForgeRock AS.
 *      Portions copyright 2011-2014 ForgeRock AS.
 */
package org.opends.server.core;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.AccessLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import java.util.ArrayList;
import java.util.List;
@@ -41,7 +37,11 @@
import org.opends.server.types.*;
import org.opends.server.types.operation.PostResponseModifyDNOperation;
import org.opends.server.types.operation.PreParseModifyDNOperation;
import org.opends.server.workflowelement.localbackend.*;
import org.opends.server.workflowelement.localbackend.LocalBackendModifyDNOperation;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.AccessLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
/**
 * This class defines an operation that may be used to alter the DN of an entry
@@ -95,14 +95,11 @@
   */
  private List<Modification> modifications;
  /** The change number that has been assigned to this operation. */
  private long changeNumber;
  /** The new RDN for the entry. */
  private RDN newRDN;
  /** The new entry DN. */
  private DN newDN = null;
  private DN newDN;
  /**
   * Creates a new modify DN operation with the provided information.
@@ -142,7 +139,6 @@
    responseControls = new ArrayList<Control>();
    cancelRequest    = null;
    modifications    = null;
    changeNumber     = -1;
  }
@@ -192,25 +188,16 @@
    responseControls = new ArrayList<Control>();
    cancelRequest    = null;
    modifications    = null;
    changeNumber     = -1;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ByteString getRawEntryDN()
  {
    return rawEntryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawEntryDN(ByteString rawEntryDN)
  {
@@ -219,11 +206,7 @@
    entryDN = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final DN getEntryDN()
  {
@@ -246,18 +229,14 @@
    return entryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ByteString getRawNewRDN()
  {
    return rawNewRDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawNewRDN(ByteString rawNewRDN)
  {
@@ -267,9 +246,7 @@
    newDN = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final RDN getNewRDN()
  {
@@ -293,37 +270,28 @@
    return newRDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final boolean deleteOldRDN()
  {
    return deleteOldRDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setDeleteOldRDN(boolean deleteOldRDN)
  {
    this.deleteOldRDN = deleteOldRDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ByteString getRawNewSuperior()
  {
    return rawNewSuperior;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawNewSuperior(ByteString rawNewSuperior)
  {
@@ -333,9 +301,7 @@
    newDN = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final DN getNewSuperior()
  {
@@ -366,20 +332,14 @@
    return newSuperior;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final List<Modification> getModifications()
  {
    return modifications;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addModification(Modification modification)
  {
@@ -393,50 +353,22 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final Entry getOriginalEntry()
  {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final Entry getUpdatedEntry()
  {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final long getChangeNumber()
  {
    return changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final void setChangeNumber(long changeNumber)
  {
    this.changeNumber = changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public final OperationType getOperationType()
  {
    // Note that no debugging will be done in this method because it is a likely
@@ -445,41 +377,29 @@
    return OperationType.MODIFY_DN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public final List<Control> getResponseControls()
  {
    return responseControls;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public final void addResponseControl(Control control)
  {
    responseControls.add(control);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public final void removeResponseControl(Control control)
  {
    responseControls.remove(control);
@@ -656,11 +576,8 @@
            String.valueOf(entryDN)));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public final void toString(StringBuilder buffer)
  {
    buffer.append("ModifyDNOperation(connID=");
@@ -682,20 +599,14 @@
    buffer.append(")");
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN dn)
  {
    proxiedAuthorizationDN = dn;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getNewDN()
  {
@@ -715,7 +626,7 @@
        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)));
opends/src/server/org/opends/server/core/ModifyDNOperationWrapper.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS
 *      Portions Copyright 2013-2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -49,162 +49,110 @@
    super(modifyDN);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void addModification(Modification modification) {
    getOperation().addModification(modification);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public boolean deleteOldRDN() {
    return getOperation().deleteOldRDN();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public long getChangeNumber() {
    return getOperation().getChangeNumber();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getEntryDN() {
    return getOperation().getEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public List<Modification> getModifications() {
    return getOperation().getModifications();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public RDN getNewRDN() {
    return getOperation().getNewRDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getNewSuperior() {
    return getOperation().getNewSuperior();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public Entry getOriginalEntry() {
    return getOperation().getOriginalEntry();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN() {
    return getOperation().getProxiedAuthorizationDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ByteString getRawEntryDN() {
    return getOperation().getRawEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ByteString getRawNewRDN() {
    return getOperation().getRawNewRDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ByteString getRawNewSuperior() {
    return getOperation().getRawNewSuperior();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public Entry getUpdatedEntry() {
    return getOperation().getUpdatedEntry();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void setChangeNumber(long changeNumber) {
    getOperation().setChangeNumber(changeNumber);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setDeleteOldRDN(boolean deleteOldRDN) {
    getOperation().setDeleteOldRDN(deleteOldRDN);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawEntryDN(ByteString rawEntryDN) {
    getOperation().setRawEntryDN(rawEntryDN);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawNewRDN(ByteString rawNewRDN) {
    getOperation().setRawNewRDN(rawNewRDN);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawNewSuperior(ByteString rawNewSuperior) {
    getOperation().setRawNewSuperior(rawNewSuperior);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN dn)
  {
    getOperation().setProxiedAuthorizationDN(dn);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getNewDN()
  {
opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -22,6 +22,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.opends.server.core;
@@ -42,7 +43,7 @@
   *
   * @return  The raw, unprocessed entry DN as included in the client request.
   */
  public abstract ByteString getRawEntryDN();
  ByteString getRawEntryDN();
  /**
   * Specifies the raw, unprocessed entry DN as included in the client request.
@@ -51,7 +52,7 @@
   * @param  rawEntryDN  The raw, unprocessed entry DN as included in the client
   *                     request.
   */
  public abstract void setRawEntryDN(ByteString rawEntryDN);
  void setRawEntryDN(ByteString rawEntryDN);
  /**
   * Retrieves the DN of the entry to modify.  This should not be called by
@@ -61,7 +62,7 @@
   * @return  The DN of the entry to modify, or <CODE>null</CODE> if the raw
   *          entry DN has not yet been processed.
   */
  public abstract DN getEntryDN();
  DN getEntryDN();
  /**
   * Retrieves the set of raw, unprocessed modifications as included in the
@@ -72,7 +73,7 @@
   * @return  The set of raw, unprocessed modifications as included in the
   *          client request.
   */
  public abstract List<RawModification> getRawModifications();
  List<RawModification> getRawModifications();
  /**
   * Adds the provided modification to the set of raw modifications for this
@@ -81,15 +82,14 @@
   * @param  rawModification  The modification to add to the set of raw
   *                          modifications for this modify operation.
   */
  public abstract void addRawModification(RawModification rawModification);
  void addRawModification(RawModification rawModification);
  /**
   * Specifies the raw modifications for this modify operation.
   *
   * @param  rawModifications  The raw modifications for this modify operation.
   */
  public abstract void setRawModifications(
      List<RawModification> rawModifications);
  void setRawModifications(List<RawModification> rawModifications);
  /**
   * Retrieves the set of modifications for this modify operation.  Its contents
@@ -99,7 +99,7 @@
   *          <CODE>null</CODE> if the modifications have not yet been
   *          processed.
   */
  public abstract List<Modification> getModifications();
  List<Modification> getModifications();
  /**
   * Adds the provided modification to the set of modifications to this modify
@@ -111,26 +111,7 @@
   * @throws  DirectoryException  If an unexpected problem occurs while applying
   *                              the modification to the entry.
   */
  public abstract void addModification(Modification modification)
      throws DirectoryException;
  /**
   * Retrieves the change number that has been assigned to this operation.
   *
   * @return  The change number that has been assigned to this operation, or -1
   *          if none has been assigned yet or if there is no applicable
   *          synchronization mechanism in place that uses change numbers.
   */
  public abstract long getChangeNumber();
  /**
   * Specifies the change number that has been assigned to this operation by the
   * synchronization mechanism.
   *
   * @param  changeNumber  The change number that has been assigned to this
   *                       operation by the synchronization mechanism.
   */
  public abstract void setChangeNumber(long changeNumber);
  void addModification(Modification modification) throws DirectoryException;
  /**
   * Retrieves the proxied authorization DN for this operation if proxied
@@ -140,7 +121,7 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public abstract DN getProxiedAuthorizationDN();
  DN getProxiedAuthorizationDN();
  /**
   * Set the proxied authorization DN for this operation if proxied
@@ -151,6 +132,6 @@
   *          authorization has been requested, or {@code null} if proxied
   *          authorization has not been requested.
   */
  public abstract void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
  void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
}
opends/src/server/org/opends/server/core/ModifyOperationBasis.java
@@ -22,14 +22,10 @@
 *
 *
 *      Copyright 2007-2010 Sun Microsystems, Inc.
 *      Portions copyright 2012-2013 ForgeRock AS.
 *      Portions copyright 2012-2014 ForgeRock AS.
 */
package org.opends.server.core;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.AccessLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import java.util.ArrayList;
import java.util.List;
@@ -44,7 +40,11 @@
import org.opends.server.types.*;
import org.opends.server.types.operation.PostResponseModifyOperation;
import org.opends.server.types.operation.PreParseModifyOperation;
import org.opends.server.workflowelement.localbackend.*;
import org.opends.server.workflowelement.localbackend.LocalBackendModifyOperation;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.AccessLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
/**
 * This class defines an operation that may be used to modify an entry in the
@@ -82,9 +82,6 @@
  /** The set of modifications for this modify operation. */
  private List<Modification> modifications;
  /** The change number that has been assigned to this operation. */
  private long changeNumber;
  /**
   * Creates a new modify operation with the provided information.
   *
@@ -155,18 +152,14 @@
    cancelRequest    = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final ByteString getRawEntryDN()
  {
    return rawEntryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawEntryDN(ByteString rawEntryDN)
  {
@@ -175,9 +168,7 @@
    entryDN = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final DN getEntryDN()
  {
@@ -198,18 +189,14 @@
    return entryDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final List<RawModification> getRawModifications()
  {
    return rawModifications;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addRawModification(RawModification rawModification)
  {
@@ -218,9 +205,7 @@
    modifications = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void setRawModifications(List<RawModification> rawModifications)
  {
@@ -229,9 +214,7 @@
    modifications = null;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final List<Modification> getModifications()
  {
@@ -256,16 +239,11 @@
               mod.setAttribute(attr);
             }
           }
           else
           else if (attr.hasOption("binary"))
           {
             // binary option is not honored for non-BER-encodable attributes.
             if(attr.hasOption("binary"))
             {
               throw new LDAPException(LDAPResultCode.UNDEFINED_ATTRIBUTE_TYPE,
                       ERR_ADD_ATTR_IS_INVALID_OPTION.get(
                       String.valueOf(entryDN),
                       attr.getName()));
             }
                 ERR_ADD_ATTR_IS_INVALID_OPTION.get(String.valueOf(entryDN), attr.getName()));
           }
           modifications.add(mod);
@@ -285,9 +263,7 @@
    return modifications;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addModification(Modification modification)
  throws DirectoryException
@@ -295,9 +271,7 @@
    modifications.add(modification);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final OperationType getOperationType()
  {
@@ -307,45 +281,35 @@
    return OperationType.MODIFY;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final List<Control> getResponseControls()
  {
    return responseControls;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void addResponseControl(Control control)
  {
    responseControls.add(control);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void removeResponseControl(Control control)
  {
    responseControls.remove(control);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void toString(StringBuilder buffer)
  {
@@ -358,35 +322,14 @@
    buffer.append(")");
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final long getChangeNumber(){
    return changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void setChangeNumber(long changeNumber)
  {
    this.changeNumber = changeNumber;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
  {
    this.proxiedAuthorizationDN = proxiedAuthorizationDN;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public final void run()
  {
opends/src/server/org/opends/server/core/ModifyOperationWrapper.java
@@ -22,16 +22,14 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.core;
import java.util.List;
import org.opends.server.types.*;
/**
 * This abstract class wraps/decorates a given modify operation.
 * This class will be extended by sub-classes to enhance the
@@ -51,9 +49,7 @@
    super(modify);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void addModification(Modification modification)
    throws DirectoryException
@@ -61,107 +57,70 @@
    getOperation().addModification(modification);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void addRawModification(RawModification rawModification)
  {
    getOperation().addRawModification(rawModification);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getEntryDN()
  {
    return getOperation().getEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public List<Modification> getModifications()
  {
    return getOperation().getModifications();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public ByteString getRawEntryDN()
  {
    return getOperation().getRawEntryDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public List<RawModification> getRawModifications()
  {
    return getOperation().getRawModifications();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawEntryDN(ByteString rawEntryDN)
  {
    getOperation().setRawEntryDN(rawEntryDN);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setRawModifications(List<RawModification> rawModifications)
  {
    getOperation().setRawModifications(rawModifications);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public String toString()
  {
    return getOperation().toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final long getChangeNumber(){
    return getOperation().getChangeNumber();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void setChangeNumber(long changeNumber)
  {
    getOperation().setChangeNumber(changeNumber);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public DN getProxiedAuthorizationDN()
  {
    return getOperation().getProxiedAuthorizationDN();
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN){
    getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN);
opends/src/server/org/opends/server/core/PersistentSearch.java
@@ -22,14 +22,11 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2014 ForgeRock AS
 */
package org.opends.server.core;
import static org.opends.server.loggers.debug.DebugLogger.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -44,10 +41,9 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import static org.opends.server.controls.PersistentSearchChangeType.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
/**
 * This class defines a data structure that will be used to hold the
@@ -109,7 +105,7 @@
  // Cancel a persistent search.
  /** Cancel a persistent search. */
  private static synchronized void cancel(PersistentSearch psearch)
  {
    if (!psearch.isCancelled)
@@ -141,32 +137,28 @@
    }
  }
  // The base DN for the search operation.
  private final DN baseDN;
  // Cancellation callbacks which should be run when this persistent
  // search is cancelled.
  /**
   * Cancellation callbacks which should be run when this persistent search is
   * cancelled.
   */
  private final List<CancellationCallback> cancellationCallbacks =
    new CopyOnWriteArrayList<CancellationCallback>();
  // The set of change types we want to see.
  /** The set of change types to send to the client. */
  private final Set<PersistentSearchChangeType> changeTypes;
  // The filter for the search operation.
  private final SearchFilter filter;
  /**
   * Indicates whether or not this persistent search has already been aborted.
   */
  private boolean isCancelled;
  // Indicates whether or not this persistent search has already been
  // aborted.
  private boolean isCancelled = false;
  // Indicates whether entries returned should include the entry
  // change notification control.
  /**
   * Indicates whether entries returned should include the entry change
   * notification control.
   */
  private final boolean returnECs;
  // The scope for the search operation.
  private final SearchScope scope;
  // The reference to the associated search operation.
  /** The reference to the associated search operation. */
  private final SearchOperation searchOperation;
@@ -189,10 +181,6 @@
    this.searchOperation = searchOperation;
    this.changeTypes = changeTypes;
    this.returnECs = returnECs;
    this.baseDN = searchOperation.getBaseDN();
    this.scope = searchOperation.getScope();
    this.filter = searchOperation.getFilter();
  }
@@ -257,60 +245,45 @@
   *
   * @param entry
   *          The entry that was added.
   * @param changeNumber
   *          The change number associated with the operation that
   *          added the entry, or {@code -1} if there is no change
   *          number.
   */
  public void processAdd(Entry entry, long changeNumber)
  public void processAdd(Entry entry)
  {
    // See if we care about add operations.
    if (!changeTypes.contains(PersistentSearchChangeType.ADD))
    if (changeTypes.contains(ADD)
        && isInScope(entry.getDN())
        && matchesFilter(entry))
    {
      return;
      sendEntry(entry, createControls(ADD, null));
    }
    }
    // Make sure that the entry is within our target scope.
    switch (scope)
  private boolean isInScope(final DN dn)
  {
    final DN baseDN = searchOperation.getBaseDN();
    switch (searchOperation.getScope())
    {
    case BASE_OBJECT:
      if (!baseDN.equals(entry.getDN()))
      {
        return;
      }
      break;
      return baseDN.equals(dn);
    case SINGLE_LEVEL:
      if (!baseDN.equals(entry.getDN().getParentDNInSuffix()))
      {
        return;
      }
      break;
      return baseDN.equals(dn.getParentDNInSuffix());
    case WHOLE_SUBTREE:
      if (!baseDN.isAncestorOf(entry.getDN()))
      {
        return;
      }
      break;
      return baseDN.isAncestorOf(dn);
    case SUBORDINATE_SUBTREE:
      if (baseDN.equals(entry.getDN()) || (!baseDN.isAncestorOf(entry.getDN())))
      {
        return;
      }
      break;
      return !baseDN.equals(dn) && baseDN.isAncestorOf(dn);
    default:
      return;
      return false;
    }
    }
    // Make sure that the entry matches the target filter.
  private boolean matchesFilter(Entry entry)
  {
    try
    {
      TRACER.debugInfo(this + " " + entry + " +filter="
          + filter.matchesEntry(entry));
      if (!filter.matchesEntry(entry))
      final boolean filterMatchesEntry = searchOperation.getFilter().matchesEntry(entry);
      if (debugEnabled())
      {
        return;
        TRACER.debugInfo(this + " " + entry + " filter=" + filterMatchesEntry);
      }
      return filterMatchesEntry;
    }
    catch (DirectoryException de)
    {
@@ -320,162 +293,23 @@
      }
      // FIXME -- Do we need to do anything here?
      return;
    }
    // The entry is one that should be sent to the client. See if we
    // also need to construct an entry change notification control.
    ArrayList<Control> entryControls = new ArrayList<Control>(1);
    if (returnECs)
    {
      entryControls.add(new EntryChangeNotificationControl(
          PersistentSearchChangeType.ADD, changeNumber));
    }
    // Send the entry and see if we should continue processing. If
    // not, then deregister this persistent search.
    try
    {
      if (!searchOperation.returnEntry(entry, entryControls))
      {
        cancel();
        searchOperation.sendSearchResultDone();
      return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      cancel();
      try
      {
        searchOperation.sendSearchResultDone();
      }
      catch (Exception e2)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e2);
        }
      }
    }
  }
  /**
   * Notifies the persistent searches that an entry has been deleted.
   *
   * @param entry
   *          The entry that was deleted.
   * @param changeNumber
   *          The change number associated with the operation that
   *          deleted the entry, or {@code -1} if there is no change
   *          number.
   */
  public void processDelete(Entry entry, long changeNumber)
  public void processDelete(Entry entry)
  {
    // See if we care about delete operations.
    if (!changeTypes.contains(PersistentSearchChangeType.DELETE))
    if (changeTypes.contains(DELETE)
        && isInScope(entry.getDN())
        && matchesFilter(entry))
    {
      return;
    }
    // Make sure that the entry is within our target scope.
    switch (scope)
    {
    case BASE_OBJECT:
      if (!baseDN.equals(entry.getDN()))
      {
        return;
      }
      break;
    case SINGLE_LEVEL:
      if (!baseDN.equals(entry.getDN().getParentDNInSuffix()))
      {
        return;
      }
      break;
    case WHOLE_SUBTREE:
      if (!baseDN.isAncestorOf(entry.getDN()))
      {
        return;
      }
      break;
    case SUBORDINATE_SUBTREE:
      if (baseDN.equals(entry.getDN()) || (!baseDN.isAncestorOf(entry.getDN())))
      {
        return;
      }
      break;
    default:
      return;
    }
    // Make sure that the entry matches the target filter.
    try
    {
      if (!filter.matchesEntry(entry))
      {
        return;
      }
    }
    catch (DirectoryException de)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, de);
      }
      // FIXME -- Do we need to do anything here?
      return;
    }
    // The entry is one that should be sent to the client. See if we
    // also need to construct an entry change notification control.
    ArrayList<Control> entryControls = new ArrayList<Control>(1);
    if (returnECs)
    {
      entryControls.add(new EntryChangeNotificationControl(
          PersistentSearchChangeType.DELETE, changeNumber));
    }
    // Send the entry and see if we should continue processing. If
    // not, then deregister this persistent search.
    try
    {
      if (!searchOperation.returnEntry(entry, entryControls))
      {
        cancel();
        searchOperation.sendSearchResultDone();
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      cancel();
      try
      {
        searchOperation.sendSearchResultDone();
      }
      catch (Exception e2)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e2);
        }
      }
      sendEntry(entry, createControls(DELETE, null));
    }
  }
@@ -486,14 +320,10 @@
   *
   * @param entry
   *          The entry after it was modified.
   * @param changeNumber
   *          The change number associated with the operation that
   *          modified the entry, or {@code -1} if there is no change
   *          number.
   */
  public void processModify(Entry entry, long changeNumber)
  public void processModify(Entry entry)
  {
    processModify(entry, changeNumber, entry);
    processModify(entry, entry);
  }
@@ -503,222 +333,84 @@
   *
   * @param entry
   *          The entry after it was modified.
   * @param changeNumber
   *          The change number associated with the operation that
   *          modified the entry, or {@code -1} if there is no change
   *          number.
   * @param oldEntry
   *          The entry before it was modified.
   */
  public void processModify(Entry entry, long changeNumber, Entry oldEntry)
  public void processModify(Entry entry, Entry oldEntry)
  {
    // See if we care about modify operations.
    if (!changeTypes.contains(PersistentSearchChangeType.MODIFY))
    if (changeTypes.contains(MODIFY)
        && isInScopeForModify(oldEntry.getDN())
        && anyMatchesFilter(entry, oldEntry))
    {
      return;
      sendEntry(entry, createControls(MODIFY, null));
    }
    }
    // Make sure that the entry is within our target scope.
    switch (scope)
  private boolean isInScopeForModify(final DN dn)
  {
    final DN baseDN = searchOperation.getBaseDN();
    switch (searchOperation.getScope())
    {
    case BASE_OBJECT:
      if (!baseDN.equals(oldEntry.getDN()))
      {
        return;
      }
      break;
      return baseDN.equals(dn);
    case SINGLE_LEVEL:
      if (!baseDN.equals(oldEntry.getDN().getParent()))
      {
        return;
      }
      break;
      return baseDN.equals(dn.getParent());
    case WHOLE_SUBTREE:
      if (!baseDN.isAncestorOf(oldEntry.getDN()))
      {
        return;
      }
      break;
      return baseDN.isAncestorOf(dn);
    case SUBORDINATE_SUBTREE:
      if (baseDN.equals(oldEntry.getDN())
          || (!baseDN.isAncestorOf(oldEntry.getDN())))
      {
        return;
      }
      break;
      return !baseDN.equals(dn) && baseDN.isAncestorOf(dn);
    default:
      return;
    }
    // Make sure that the entry matches the target filter.
    try
    {
      if ((!filter.matchesEntry(oldEntry)) && (!filter.matchesEntry(entry)))
      {
        return;
      }
    }
    catch (DirectoryException de)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, de);
      }
      // FIXME -- Do we need to do anything here?
      return;
    }
    // The entry is one that should be sent to the client. See if we
    // also need to construct an entry change notification control.
    ArrayList<Control> entryControls = new ArrayList<Control>(1);
    if (returnECs)
    {
      entryControls.add(new EntryChangeNotificationControl(
          PersistentSearchChangeType.MODIFY, changeNumber));
    }
    // Send the entry and see if we should continue processing. If
    // not, then deregister this persistent search.
    try
    {
      if (!searchOperation.returnEntry(entry, entryControls))
      {
        cancel();
        searchOperation.sendSearchResultDone();
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      cancel();
      try
      {
        searchOperation.sendSearchResultDone();
      }
      catch (Exception e2)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e2);
        }
      }
      return false;
    }
  }
  private boolean anyMatchesFilter(Entry entry, Entry oldEntry)
  {
    return matchesFilter(oldEntry) || matchesFilter(entry);
  }
  /**
   * Notifies the persistent searches that an entry has been renamed.
   *
   * @param entry
   *          The entry after it was modified.
   * @param changeNumber
   *          The change number associated with the operation that
   *          modified the entry, or {@code -1} if there is no change
   *          number.
   * @param oldDN
   *          The DN of the entry before it was renamed.
   */
  public void processModifyDN(Entry entry, long changeNumber, DN oldDN)
  public void processModifyDN(Entry entry, DN oldDN)
  {
    // See if we care about modify DN operations.
    if (!changeTypes.contains(PersistentSearchChangeType.MODIFY_DN))
    if (changeTypes.contains(MODIFY_DN)
        && isAnyInScopeForModify(entry, oldDN)
        && matchesFilter(entry))
    {
      return;
    }
    // Make sure that the old or new entry is within our target scope.
    // In this case, we need to check the DNs of both the old and new
    // entry so we know which one(s) should be compared against the
    // filter.
    boolean oldMatches = false;
    boolean newMatches = false;
    switch (scope)
    {
    case BASE_OBJECT:
      oldMatches = baseDN.equals(oldDN);
      newMatches = baseDN.equals(entry.getDN());
      if (!(oldMatches || newMatches))
      {
        return;
      }
      break;
    case SINGLE_LEVEL:
      oldMatches = baseDN.equals(oldDN.getParent());
      newMatches = baseDN.equals(entry.getDN().getParent());
      if (!(oldMatches || newMatches))
      {
        return;
      }
      break;
    case WHOLE_SUBTREE:
      oldMatches = baseDN.isAncestorOf(oldDN);
      newMatches = baseDN.isAncestorOf(entry.getDN());
      if (!(oldMatches || newMatches))
      {
        return;
      }
      break;
    case SUBORDINATE_SUBTREE:
      oldMatches = ((!baseDN.equals(oldDN)) && baseDN.isAncestorOf(oldDN));
      newMatches = ((!baseDN.equals(entry.getDN())) && baseDN
          .isAncestorOf(entry.getDN()));
      if (!(oldMatches || newMatches))
      {
        return;
      }
      break;
    default:
      return;
    }
    // Make sure that the entry matches the target filter.
    try
    {
      if (!oldMatches && !newMatches && !filter.matchesEntry(entry))
      {
        return;
      sendEntry(entry, createControls(MODIFY_DN, oldDN));
      }
    }
    catch (DirectoryException de)
  private boolean isAnyInScopeForModify(Entry entry, DN oldDN)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, de);
    return isInScopeForModify(oldDN) || isInScopeForModify(entry.getDN());
      }
      // FIXME -- Do we need to do anything here?
      return;
    }
    // The entry is one that should be sent to the client. See if we
    // also need to construct an entry change notification control.
    ArrayList<Control> entryControls = new ArrayList<Control>(1);
  /**
   * The entry is one that should be sent to the client. See if we also need to
   * construct an entry change notification control.
   */
  private List<Control> createControls(PersistentSearchChangeType changeType,
      DN previousDN)
  {
    if (returnECs)
    {
      entryControls.add(new EntryChangeNotificationControl(
          PersistentSearchChangeType.MODIFY_DN, oldDN, changeNumber));
      final Control c = previousDN != null
          ? new EntryChangeNotificationControl(changeType, previousDN, -1)
          : new EntryChangeNotificationControl(changeType, -1);
      return Collections.singletonList(c);
    }
    return Collections.emptyList();
    }
    // Send the entry and see if we should continue processing. If
    // not, then deregister this persistent search.
  private void sendEntry(Entry entry, List<Control> entryControls)
  {
    try
    {
      if (!searchOperation.returnEntry(entry, entryControls))
@@ -813,9 +505,9 @@
    buffer.append(",baseDN=\"");
    searchOperation.getBaseDN().toString(buffer);
    buffer.append("\",scope=");
    buffer.append(scope.toString());
    buffer.append(searchOperation.getScope());
    buffer.append(",filter=\"");
    filter.toString(buffer);
    searchOperation.getFilter().toString(buffer);
    buffer.append("\")");
  }
}
opends/src/server/org/opends/server/replication/server/ECLServerWriter.java
@@ -149,13 +149,17 @@
        }
        if (shutdown)
        {
          return;
        }
        // Not suspended
        doIt();
        if (shutdown)
        {
          return;
        }
        suspendWriter();
      }
@@ -183,9 +187,11 @@
        session.close();
      }
      if (replicationServerDomain != null)
      {
        replicationServerDomain.stopServer(handler, false);
    }
  }
  }
  /**
   * Loop getting changes from the domain and publishing them either to
@@ -195,24 +201,10 @@
   */
  private void doIt() throws IOException, InterruptedException
  {
    while (true)
    while (!shutdown && !suspended)
    {
      if (shutdown || suspended)
      {
        return;
      }
      ECLUpdateMsg update = null;
      try
      {
        update = handler.takeECLUpdate();
      }
      catch(DirectoryException de)
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, de);
      }
      if (update == null)
      final ECLUpdateMsg updateMsg = takeECLUpdate(handler);
      if (updateMsg == null)
      {
        if (session != null && handler.isInitPhaseDone())
        {
@@ -232,14 +224,25 @@
      }
      else
      {
        // Publish the update to the remote server using a protocol version it
        // supports
        publish(update);
        update = null;
        // Publish the update to the remote server using a protocol version it supports
        publish(updateMsg);
      }
    }
  }
  private ECLUpdateMsg takeECLUpdate(ECLServerHandler handler)
  {
    try
    {
      return handler.takeECLUpdate();
    }
    catch(DirectoryException de)
    {
      TRACER.debugCaught(DebugLogLevel.ERROR, de);
      return null;
    }
  }
  /**
   * Shutdown the writer.
   */
@@ -255,7 +258,9 @@
  private void publish(ECLUpdateMsg msg) throws IOException
  {
    if (debugEnabled())
    {
      TRACER.debugInfo(getName() + " publishes msg=[" + msg + "]");
    }
    if (session != null)
    {
@@ -265,8 +270,10 @@
    {
      try
      {
        // Using processAdd() because all ECLUpdateMsgs are adds to the external changelog
        // (even though the underlying changes can be adds, deletes, modifies or modDNs)
        Entry eclEntry = ECLSearchOperation.createEntryFromMsg(msg);
        mypsearch.processAdd(eclEntry, -1);
        mypsearch.processAdd(eclEntry);
      }
      catch (Exception e)
      {
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -22,17 +22,10 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -55,6 +48,13 @@
import org.opends.server.types.operation.PreOperationAddOperation;
import org.opends.server.util.TimeThread;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to add an entry in a local backend
 * of the Directory Server.
@@ -64,53 +64,33 @@
       implements PreOperationAddOperation, PostOperationAddOperation,
                  PostResponseAddOperation, PostSynchronizationAddOperation
{
  /**
   * The tracer object for the debug logger.
   */
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
  /**
   * The backend in which the entry is to be added.
   */
  private Backend backend;
  /** The backend in which the entry is to be added. */
  private Backend<?> backend;
  /**
   * Indicates whether the request includes the LDAP no-op control.
   */
  /** Indicates whether the request includes the LDAP no-op control. */
  private boolean noOp;
  /**
   * The DN of the entry to be added.
   */
  /** The DN of the entry to be added. */
  private DN entryDN;
  /**
   * The entry being added to the server.
   */
  /** The entry being added to the server. */
  private Entry entry;
  /**
   * The post-read request control included in the request, if applicable.
   */
  /** The post-read request control included in the request, if applicable. */
  private LDAPPostReadRequestControl postReadRequest;
  /**
   * The set of object classes for the entry to add.
   */
  /** The set of object classes for the entry to add. */
  private Map<ObjectClass, String> objectClasses;
  /**
   * The set of operational attributes for the entry to add.
   */
  /** The set of operational attributes for the entry to add. */
  private Map<AttributeType, List<Attribute>> operationalAttributes;
  /**
   * The set of user attributes for the entry to add.
   */
  /** The set of user attributes for the entry to add. */
  private Map<AttributeType, List<Attribute>> userAttributes;
  /**
   * Creates a new operation that may be used to add a new entry in a
   * local backend of the Directory Server.
@@ -207,7 +187,7 @@
          // Notify persistent searches.
          for (PersistentSearch psearch : wfe.getPersistentSearches())
          {
            psearch.processAdd(entry, getChangeNumber());
            psearch.processAdd(entry);
          }
          // Notify change listeners.
@@ -216,8 +196,7 @@
          {
            try
            {
              changeListener.handleAddOperation(LocalBackendAddOperation.this,
                  entry);
              changeListener.handleAddOperation(LocalBackendAddOperation.this, entry);
            }
            catch (Exception e)
            {
@@ -310,8 +289,9 @@
      userAttributes = getUserAttributes();
      operationalAttributes = getOperationalAttributes();
      if ((objectClasses == null) || (userAttributes == null)
          || (operationalAttributes == null))
      if (objectClasses == null
          || userAttributes == null
          || operationalAttributes == null)
      {
        return;
      }
@@ -423,8 +403,7 @@
      if (backend == null)
      {
        setResultCode(ResultCode.NO_SUCH_OBJECT);
        appendErrorMessage(Message.raw("No backend for entry "
            + entryDN.toString())); // TODO: i18n
        appendErrorMessage(Message.raw("No backend for entry " + entryDN)); // TODO: i18n
        return;
      }
@@ -600,9 +579,9 @@
  {
    for (AttributeType at : attributes.keySet())
    {
      if (at.isNoUserModification())
      {
        if (!(isInternalOperation() || isSynchronizationOperation()))
      if (at.isNoUserModification()
          && !isInternalOperation()
          && !isSynchronizationOperation())
        {
          setResultCodeAndMessageNoInfoDisclosure(entryDN,
              ResultCode.CONSTRAINT_VIOLATION,
@@ -611,7 +590,6 @@
          return true;
        }
      }
    }
    return false;
  }
@@ -821,7 +799,7 @@
    // See if a password was specified.
    AttributeType passwordAttribute = passwordPolicy.getPasswordAttribute();
    List<Attribute> attrList = entry.getAttribute(passwordAttribute);
    if ((attrList == null) || attrList.isEmpty())
    if (attrList == null || attrList.isEmpty())
    {
      // The entry doesn't have a password, so no action is required.
      return;
@@ -849,9 +827,9 @@
      return;
    }
    if ((!isInternalOperation())
        && (!passwordPolicy.isAllowMultiplePasswordValues())
        && (passwordAttr.size() > 1))
    if (!isInternalOperation()
        && !passwordPolicy.isAllowMultiplePasswordValues()
        && passwordAttr.size() > 1)
    {
      // FIXME -- What if they're pre-encoded and might all be the
      // same?
@@ -875,44 +853,35 @@
      {
        if (AuthPasswordSyntax.isEncoded(value))
        {
          if (isInternalOperation() ||
              passwordPolicy.isAllowPreEncodedPasswords())
          if (isInternalOperation()
              || passwordPolicy.isAllowPreEncodedPasswords())
          {
            builder.add(v);
            continue;
          }
          else
          {
            addPWPolicyControl(
                 PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY);
            addPWPolicyControl(PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY);
            Message message = ERR_PWPOLICY_PREENCODED_NOT_ALLOWED.get(
                passwordAttribute.getNameOrOID());
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         message);
                ERR_PWPOLICY_PREENCODED_NOT_ALLOWED.get(passwordAttribute.getNameOrOID()));
          }
        }
      }
      else
      else if (UserPasswordSyntax.isEncoded(value))
      {
        if (UserPasswordSyntax.isEncoded(value))
        {
          if (isInternalOperation() ||
              passwordPolicy.isAllowPreEncodedPasswords())
        if (isInternalOperation()
            || passwordPolicy.isAllowPreEncodedPasswords())
          {
            builder.add(v);
            continue;
          }
          else
          {
            addPWPolicyControl(
                 PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY);
          addPWPolicyControl(PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY);
            Message message = ERR_PWPOLICY_PREENCODED_NOT_ALLOWED.get(
                passwordAttribute.getNameOrOID());
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         message);
          }
              ERR_PWPOLICY_PREENCODED_NOT_ALLOWED.get(passwordAttribute.getNameOrOID()));
        }
      }
@@ -1005,10 +974,9 @@
  {
    for (Control c : getRequestControls())
    {
      if (c.getOID().equals(OID_PASSWORD_POLICY_CONTROL))
      if (OID_PASSWORD_POLICY_CONTROL.equals(c.getOID()))
      {
        addResponseControl(new PasswordPolicyResponseControl(null, 0,
                                                             errorType));
        addResponseControl(new PasswordPolicyResponseControl(null, 0, errorType));
      }
    }
  }
@@ -1137,12 +1105,11 @@
    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 (oid.equals(OID_LDAP_ASSERTION))
        if (OID_LDAP_ASSERTION.equals(oid))
        {
          // RFC 4528 mandates support for Add operation basically
          // suggesting an assertion on self. As daft as it may be
@@ -1205,16 +1172,16 @@
                    de.getMessageObject()));
          }
        }
        else if (oid.equals(OID_LDAP_NOOP_OPENLDAP_ASSIGNED))
        else if (OID_LDAP_NOOP_OPENLDAP_ASSIGNED.equals(oid))
        {
          noOp = true;
        }
        else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
        else if (OID_LDAP_READENTRY_POSTREAD.equals(oid))
        {
          postReadRequest =
                getRequestControl(LDAPPostReadRequestControl.DECODER);
        }
        else if (oid.equals(OID_PROXIED_AUTH_V1))
        else if (OID_PROXIED_AUTH_V1.equals(oid))
        {
          // Log usage of legacy proxy authz V1 control.
          addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
@@ -1233,16 +1200,9 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          setProxiedAuthorizationDN(getDN(authorizationEntry));
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        else if (OID_PROXIED_AUTH_V2.equals(oid))
        {
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
@@ -1258,34 +1218,27 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          setProxiedAuthorizationDN(getDN(authorizationEntry));
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
        }
        else if (oid.equals(OID_PASSWORD_POLICY_CONTROL))
        else if (OID_PASSWORD_POLICY_CONTROL.equals(oid))
        {
          // We don't need to do anything here because it's already handled
          // in LocalBackendAddOperation.handlePasswordPolicy().
        }
        // NYI -- Add support for additional controls.
        else if (c.isCritical())
        {
          if ((backend == null) || (! backend.supportsControl(oid)))
        else if (c.isCritical()
            && (backend == null || !backend.supportsControl(oid)))
          {
            throw newDirectoryException(entryDN,
                           ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
                           ERR_ADD_UNSUPPORTED_CRITICAL_CONTROL.get(
                                String.valueOf(entryDN), oid));
          }
        }
              ERR_ADD_UNSUPPORTED_CRITICAL_CONTROL.get(String.valueOf(entryDN), oid));
      }
    }
  }
}
  private DN getDN(Entry e)
  {
    return e != null ? e.getDN() : DN.nullDN();
  }
}
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -22,16 +22,10 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.List;
import java.util.concurrent.locks.Lock;
@@ -53,6 +47,12 @@
import org.opends.server.types.operation.PostSynchronizationDeleteOperation;
import org.opends.server.types.operation.PreOperationDeleteOperation;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to delete an entry in a local backend
 * of the Directory Server.
@@ -63,36 +63,22 @@
                  PostResponseDeleteOperation,
                  PostSynchronizationDeleteOperation
{
  /**
   * The tracer object for the debug logger.
   */
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
  /** The backend in which the operation is to be processed. */
  private Backend<?> backend;
  /**
   * The backend in which the operation is to be processed.
   */
  private Backend backend;
  /**
   * Indicates whether the LDAP no-op control has been requested.
   */
  /** Indicates whether the LDAP no-op control has been requested. */
  private boolean noOp;
  /**
   * The client connection on which this operation was requested.
   */
  /** The client connection on which this operation was requested. */
  private ClientConnection clientConnection;
  /**
   * The DN of the entry to be deleted.
   */
  /** The DN of the entry to be deleted. */
  private DN entryDN;
  /**
   * The entry to be deleted.
   */
  /** The entry to be deleted. */
  private Entry entry;
  /** The pre-read request control included in the request, if applicable. */
@@ -193,7 +179,7 @@
          // Notify persistent searches.
          for (PersistentSearch psearch : wfe.getPersistentSearches())
          {
            psearch.processDelete(entry, getChangeNumber());
            psearch.processDelete(entry);
          }
          // Notify change listeners.
@@ -202,8 +188,7 @@
          {
            try
            {
              changeListener.handleDeleteOperation(
                  LocalBackendDeleteOperation.this, entry);
              changeListener.handleDeleteOperation(LocalBackendDeleteOperation.this, entry);
            }
            catch (Exception e)
            {
@@ -212,10 +197,8 @@
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              Message message =
                  ERR_DELETE_ERROR_NOTIFYING_CHANGE_LISTENER
                      .get(getExceptionMessage(e));
              logError(message);
              logError(ERR_DELETE_ERROR_NOTIFYING_CHANGE_LISTENER
                  .get(getExceptionMessage(e)));
            }
          }
        }
@@ -334,8 +317,7 @@
      // handling a subtree delete). But we will need to check if there are
      // any subordinate backends that should stop us from attempting the
      // delete.
      Backend[] subBackends = backend.getSubordinateBackends();
      for (Backend b : subBackends)
      for (Backend<?> b : backend.getSubordinateBackends())
      {
        for (DN dn : b.getBaseDNs())
        {
@@ -450,7 +432,7 @@
      for (Control c : requestControls)
      {
        final String oid = c.getOID();
        if (oid.equals(OID_LDAP_ASSERTION))
        if (OID_LDAP_ASSERTION.equals(oid))
        {
          LDAPAssertionRequestControl assertControl =
                getRequestControl(LDAPAssertionRequestControl.DECODER);
@@ -509,16 +491,16 @@
                                de.getMessageObject()));
          }
        }
        else if (oid.equals(OID_LDAP_NOOP_OPENLDAP_ASSIGNED))
        else if (OID_LDAP_NOOP_OPENLDAP_ASSIGNED.equals(oid))
        {
          noOp = true;
        }
        else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
        else if (OID_LDAP_READENTRY_PREREAD.equals(oid))
        {
          preReadRequest =
                getRequestControl(LDAPPreReadRequestControl.DECODER);
        }
        else if (oid.equals(OID_PROXIED_AUTH_V1))
        else if (OID_PROXIED_AUTH_V1.equals(oid))
        {
          // Log usage of legacy proxy authz V1 control.
          addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
@@ -537,16 +519,9 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          setProxiedAuthorizationDN(getDN(authorizationEntry));
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        else if (OID_PROXIED_AUTH_V2.equals(oid))
        {
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
@@ -561,32 +536,24 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          setProxiedAuthorizationDN(getDN(authorizationEntry));
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
        }
        // NYI -- Add support for additional controls.
        else if (c.isCritical())
        {
          if ((backend == null) || (! backend.supportsControl(oid)))
        else if (c.isCritical()
            && (backend == null || !backend.supportsControl(oid)))
          {
            throw newDirectoryException(entry,
                           ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
                           ERR_DELETE_UNSUPPORTED_CRITICAL_CONTROL.get(
                                String.valueOf(entryDN), oid));
          }
              ERR_DELETE_UNSUPPORTED_CRITICAL_CONTROL.get(String.valueOf(entryDN), oid));
        }
      }
    }
  }
  private DN getDN(Entry e)
  {
    return e != null ? e.getDN() : DN.nullDN();
  }
  /**
   * Handle conflict resolution.
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -22,12 +22,13 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
@@ -63,41 +64,25 @@
             PostResponseModifyDNOperation,
             PostSynchronizationModifyDNOperation
{
  /**
   * The tracer object for the debug logger.
   */
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
  /** The backend in which the operation is to be processed. */
  private Backend<?> backend;
  /**
   * The backend in which the operation is to be processed.
   */
  private Backend backend;
  /**
   * Indicates whether the no-op control was included in the request.
   */
  /** Indicates whether the no-op control was included in the request. */
  private boolean noOp;
  /**
   * The client connection on which this operation was requested.
   */
  /** The client connection on which this operation was requested. */
  private ClientConnection clientConnection;
  /**
   * The original DN of the entry.
   */
  /** The original DN of the entry. */
  private DN entryDN;
  /**
   * The current entry, before it is renamed.
   */
  /** The current entry, before it is renamed. */
  private Entry currentEntry;
  /**
   * The new entry, as it will appear after it has been renamed.
   */
  /** The new entry, as it will appear after it has been renamed. */
  private Entry newEntry;
  /** The LDAP post-read request control, if present in the request. */
@@ -106,9 +91,7 @@
  /** The LDAP pre-read request control, if present in the request. */
  private LDAPPreReadRequestControl preReadRequest;
  /**
   * The new RDN for the entry.
   */
  /** The new RDN for the entry. */
  private RDN newRDN;
@@ -224,8 +207,7 @@
          // Notify persistent searches.
          for (PersistentSearch psearch : wfe.getPersistentSearches())
          {
            psearch.processModifyDN(newEntry, getChangeNumber(), currentEntry
                .getDN());
            psearch.processModifyDN(newEntry, currentEntry.getDN());
          }
          // Notify change listeners.
@@ -244,10 +226,8 @@
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              Message message =
                  ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
                      .get(getExceptionMessage(e));
              logError(message);
              logError(ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
                  .get(getExceptionMessage(e)));
            }
          }
        }
@@ -304,7 +284,7 @@
    // Get the backend for the current entry, and the backend for the new
    // entry. If either is null, or if they are different, then fail.
    Backend currentBackend = backend;
    Backend<?> currentBackend = backend;
    if (currentBackend == null)
    {
      setResultCode(ResultCode.NO_SUCH_OBJECT);
@@ -313,7 +293,7 @@
      return;
    }
    Backend newBackend = DirectoryServer.getBackend(newDN);
    Backend<?> newBackend = DirectoryServer.getBackend(newDN);
    if (newBackend == null)
    {
      setResultCode(ResultCode.NO_SUCH_OBJECT);
@@ -589,14 +569,14 @@
    LocalBackendWorkflowElement.removeAllDisallowedControls(entryDN, this);
    List<Control> requestControls = getRequestControls();
    if ((requestControls != null) && (! requestControls.isEmpty()))
    if (requestControls != null && !requestControls.isEmpty())
    {
      for (int i=0; i < requestControls.size(); i++)
      for (ListIterator<Control> iter = requestControls.listIterator(); iter.hasNext();)
      {
        Control c   = requestControls.get(i);
        Control c = iter.next();
        String  oid = c.getOID();
        if (oid.equals(OID_LDAP_ASSERTION))
        if (OID_LDAP_ASSERTION.equals(oid))
        {
          LDAPAssertionRequestControl assertControl =
                getRequestControl(LDAPAssertionRequestControl.DECODER);
@@ -657,17 +637,16 @@
                    de.getMessageObject()));
          }
        }
        else if (oid.equals(OID_LDAP_NOOP_OPENLDAP_ASSIGNED))
        else if (OID_LDAP_NOOP_OPENLDAP_ASSIGNED.equals(oid))
        {
          noOp = true;
        }
        else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
        else if (OID_LDAP_READENTRY_PREREAD.equals(oid))
        {
          preReadRequest =
                getRequestControl(LDAPPreReadRequestControl.DECODER);
          requestControls.set(i, preReadRequest);
          preReadRequest = getRequestControl(LDAPPreReadRequestControl.DECODER);
          iter.set(preReadRequest);
        }
        else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
        else if (OID_LDAP_READENTRY_POSTREAD.equals(oid))
        {
          if (c instanceof LDAPPostReadRequestControl)
          {
@@ -675,12 +654,11 @@
          }
          else
          {
            postReadRequest =
                  getRequestControl(LDAPPostReadRequestControl.DECODER);
            requestControls.set(i, postReadRequest);
            postReadRequest = getRequestControl(LDAPPostReadRequestControl.DECODER);
            iter.set(postReadRequest);
          }
        }
        else if (oid.equals(OID_PROXIED_AUTH_V1))
        else if (OID_PROXIED_AUTH_V1.equals(oid))
        {
          // Log usage of legacy proxy authz V1 control.
          addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
@@ -699,16 +677,9 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          setProxiedAuthorizationDN(getDN(authorizationEntry));
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        else if (OID_PROXIED_AUTH_V2.equals(oid))
        {
          // The requester must have the PROXIED_AUTH privilege in order to
          // be able to use this control.
@@ -723,33 +694,23 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          setProxiedAuthorizationDN(getDN(authorizationEntry));
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
        }
        // NYI -- Add support for additional controls.
        else if (c.isCritical())
        {
          if ((backend == null) || (! backend.supportsControl(oid)))
        else if (c.isCritical()
            && (backend == null || !backend.supportsControl(oid)))
          {
            throw new DirectoryException(
                           ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
                           ERR_MODDN_UNSUPPORTED_CRITICAL_CONTROL.get(
                                String.valueOf(entryDN), oid));
          }
              ERR_MODDN_UNSUPPORTED_CRITICAL_CONTROL.get(String.valueOf(entryDN), oid));
        }
      }
    }
  }
  private DN getDN(Entry e)
  {
    return e != null ? e.getDN() : DN.nullDN();
  }
  /**
   * Updates the entry so that its attributes are changed to reflect the changes
@@ -777,14 +738,12 @@
        // If the associated attribute type is marked NO-USER-MODIFICATION, then
        // refuse the update.
        if (a.getAttributeType().isNoUserModification())
        {
          if (! (isInternalOperation() || isSynchronizationOperation()))
        if (a.getAttributeType().isNoUserModification()
            && !isInternalOperation()
            && !isSynchronizationOperation())
          {
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                           ERR_MODDN_OLD_RDN_ATTR_IS_NO_USER_MOD.get(
                                String.valueOf(entryDN), a.getName()));
          }
              ERR_MODDN_OLD_RDN_ATTR_IS_NO_USER_MOD.get(String.valueOf(entryDN), a.getName()));
        }
        List<AttributeValue> missingValues = new LinkedList<AttributeValue>();
@@ -816,7 +775,7 @@
        // refuse the update.
        if (a.getAttributeType().isNoUserModification())
        {
          if (! (isInternalOperation() || isSynchronizationOperation()))
          if (!isInternalOperation() && !isSynchronizationOperation())
          {
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                           ERR_MODDN_NEW_RDN_ATTR_IS_NO_USER_MOD.get(
@@ -833,7 +792,7 @@
    // If the server is configured to check the schema and the operation is not
    // a synchronization operation, make sure that the resulting entry is valid
    // as per the server schema.
    if ((DirectoryServer.checkSchema()) && (! isSynchronizationOperation()))
    if (DirectoryServer.checkSchema() && !isSynchronizationOperation())
    {
      MessageBuilder invalidReason = new MessageBuilder();
      if (! newEntry.conformsToSchema(null, false, true, true,
@@ -1013,4 +972,3 @@
      }
  }
}
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -22,20 +22,14 @@
 *
 *
 *      Copyright 2008-2011 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.workflowelement.localbackend;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
@@ -54,6 +48,13 @@
import org.opends.server.types.operation.PreOperationModifyOperation;
import org.opends.server.util.Validator;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines an operation used to modify an entry in a local backend
 * of the Directory Server.
@@ -64,15 +65,11 @@
                  PostResponseModifyOperation,
                  PostSynchronizationModifyOperation
{
  /**
   * The tracer object for the debug logger.
   */
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
  /**
   * The backend in which the target entry exists.
   */
  protected Backend backend;
  /** The backend in which the target entry exists. */
  private Backend<?> backend;
  /** Indicates whether the request included the user's current password. */
  private boolean currentPasswordProvided;
@@ -81,60 +78,40 @@
   * Indicates whether the user's account has been enabled or disabled
   * by this modify operation.
   */
  protected boolean enabledStateChanged;
  private boolean enabledStateChanged;
  /** Indicates whether the user's account is currently enabled. */
  private boolean isEnabled;
  /**
   * Indicates whether the request included the LDAP no-op control.
   */
  protected boolean noOp;
  /** Indicates whether the request included the LDAP no-op control. */
  private boolean noOp;
  /**
   * Indicates whether the request included the Permissive Modify control.
   */
  protected boolean permissiveModify = false;
  /** Indicates whether the request included the Permissive Modify control. */
  private boolean permissiveModify;
  /**
   * Indicates whether this modify operation includes a password change.
   */
  protected boolean passwordChanged;
  /** Indicates whether this modify operation includes a password change. */
  private boolean passwordChanged;
  /**
   * Indicates whether the request included the password policy request control.
   */
  protected boolean pwPolicyControlRequested;
  /** Indicates whether the request included the password policy request control. */
  private boolean pwPolicyControlRequested;
  /**
   * Indicates whether the password change is a self-change.
   */
  protected boolean selfChange;
  /** Indicates whether the password change is a self-change. */
  private boolean selfChange;
  /**
   * Indicates whether the user's account was locked before this change.
   */
  protected boolean wasLocked = false;
  /** Indicates whether the user's account was locked before this change. */
  private boolean wasLocked;
  /**
   * The client connection associated with this operation.
   */
  protected ClientConnection clientConnection;
  /** The client connection associated with this operation. */
  private ClientConnection clientConnection;
  /**
   * The DN of the entry to modify.
   */
  protected DN entryDN;
  /** The DN of the entry to modify. */
  private DN entryDN;
  /**
   * The current entry, before any changes are applied.
   */
  protected Entry currentEntry = null;
  /** The current entry, before any changes are applied. */
  private Entry currentEntry;
  /**
   * The modified entry that will be stored in the backend.
   */
  protected Entry modifiedEntry = null;
  /** The modified entry that will be stored in the backend. */
  private Entry modifiedEntry;
  /** The number of passwords contained in the modify operation. */
  private int numPasswords;
@@ -146,25 +123,19 @@
  private LDAPPreReadRequestControl preReadRequest;
  /** The set of clear-text current passwords (if any were provided).*/
  private List<AttributeValue> currentPasswords = null;
  private List<AttributeValue> currentPasswords;
  /** The set of clear-text new passwords (if any were provided).*/
  private List<AttributeValue> newPasswords = null;
  private List<AttributeValue> newPasswords;
  /**
   * The set of modifications contained in this request.
   */
  protected List<Modification> modifications;
  /** The set of modifications contained in this request. */
  private List<Modification> modifications;
  /**
   * The password policy error type for this operation.
   */
  protected PasswordPolicyErrorType pwpErrorType;
  /** The password policy error type for this operation. */
  private PasswordPolicyErrorType pwpErrorType;
  /**
   * The password policy state for this modify operation.
   */
  protected PasswordPolicyState pwPolicyState;
  /** The password policy state for this modify operation. */
  private PasswordPolicyState pwPolicyState;
@@ -349,8 +320,7 @@
          // Notify persistent searches.
          for (PersistentSearch psearch : wfe.getPersistentSearches())
          {
            psearch.processModify(modifiedEntry, getChangeNumber(),
                currentEntry);
            psearch.processModify(modifiedEntry, currentEntry);
          }
          // Notify change listeners.
@@ -370,9 +340,8 @@
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
              }
              Message message = ERR_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER
                  .get(getExceptionMessage(e));
              logError(message);
              logError(ERR_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER
                  .get(getExceptionMessage(e)));
            }
          }
        }
@@ -401,8 +370,7 @@
    if (modifications.isEmpty())
    {
      setResultCode(ResultCode.CONSTRAINT_VIOLATION);
      appendErrorMessage(ERR_MODIFY_NO_MODIFICATIONS.get(String
          .valueOf(entryDN)));
      appendErrorMessage(ERR_MODIFY_NO_MODIFICATIONS.get(String.valueOf(entryDN)));
      return;
    }
@@ -417,8 +385,7 @@
      if (entryLock == null)
      {
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_MODIFY_CANNOT_LOCK_ENTRY.get(
            String.valueOf(entryDN)));
        appendErrorMessage(ERR_MODIFY_CANNOT_LOCK_ENTRY.get(String.valueOf(entryDN)));
        return;
      }
@@ -431,8 +398,7 @@
      if (currentEntry == null)
      {
        setResultCode(ResultCode.NO_SUCH_OBJECT);
        appendErrorMessage(ERR_MODIFY_NO_SUCH_ENTRY
            .get(String.valueOf(entryDN)));
        appendErrorMessage(ERR_MODIFY_NO_SUCH_ENTRY.get(String.valueOf(entryDN)));
        // See if one of the entry's ancestors exists.
        setMatchedDN(findMatchedDN(entryDN));
@@ -451,7 +417,8 @@
      // Check that the authorizing account isn't required to change its
      // password.
      if ((!isInternalOperation()) && !selfChange
      if (!isInternalOperation()
          && !selfChange
          && getAuthorizationEntry() != null)
      {
        AuthenticationPolicy authzPolicy =
@@ -524,7 +491,7 @@
      handleInitialPasswordPolicyProcessing();
      performAdditionalPasswordChangedProcessing();
      if ((!passwordChanged) && (!isInternalOperation()) && selfChange
      if (!passwordChanged && !isInternalOperation() && selfChange
          && pwPolicyState != null && pwPolicyState.mustChangePassword())
      {
        // The user did not attempt to change their password.
@@ -538,11 +505,10 @@
      // If the server is configured to check the schema and the
      // operation is not a synchronization operation,
      // make sure that the new entry is valid per the server schema.
      if ((DirectoryServer.checkSchema()) && (!isSynchronizationOperation()))
      if (DirectoryServer.checkSchema() && !isSynchronizationOperation())
      {
        MessageBuilder invalidReason = new MessageBuilder();
        if (!modifiedEntry.conformsToSchema(null, false, false, false,
            invalidReason))
        if (!modifiedEntry.conformsToSchema(null, false, false, false, invalidReason))
        {
          setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
          appendErrorMessage(ERR_MODIFY_VIOLATES_SCHEMA.get(String
@@ -682,16 +648,16 @@
   * @throws  DirectoryException  If a problem is encountered with any of the
   *                              controls.
   */
  protected void processRequestControls() throws DirectoryException
  private void processRequestControls() throws DirectoryException
  {
    LocalBackendWorkflowElement.removeAllDisallowedControls(entryDN, this);
    List<Control> requestControls = getRequestControls();
    if ((requestControls != null) && (! requestControls.isEmpty()))
    if (requestControls != null && !requestControls.isEmpty())
    {
      for (int i=0; i < requestControls.size(); i++)
      for (ListIterator<Control> iter = requestControls.listIterator(); iter.hasNext();)
      {
        Control c   = requestControls.get(i);
        Control c = iter.next();
        String  oid = c.getOID();
        if (oid.equals(OID_LDAP_ASSERTION))
@@ -764,8 +730,7 @@
        }
        else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
        {
          preReadRequest =
                getRequestControl(LDAPPreReadRequestControl.DECODER);
          preReadRequest = getRequestControl(LDAPPreReadRequestControl.DECODER);
        }
        else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
        {
@@ -775,9 +740,8 @@
          }
          else
          {
            postReadRequest =
                getRequestControl(LDAPPostReadRequestControl.DECODER);
            requestControls.set(i, postReadRequest);
            postReadRequest = getRequestControl(LDAPPostReadRequestControl.DECODER);
            iter.set(postReadRequest);
          }
        }
        else if (oid.equals(OID_PROXIED_AUTH_V1))
@@ -799,14 +763,7 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
          setProxiedAuthorizationDN(getDN(authorizationEntry));
        }
        else if (oid.equals(OID_PROXIED_AUTH_V2))
        {
@@ -823,33 +780,27 @@
          Entry authorizationEntry = proxyControl.getAuthorizationEntry();
          setAuthorizationEntry(authorizationEntry);
          if (authorizationEntry == null)
          {
            setProxiedAuthorizationDN(DN.nullDN());
          }
          else
          {
            setProxiedAuthorizationDN(authorizationEntry.getDN());
          }
          setProxiedAuthorizationDN(getDN(authorizationEntry));
        }
        else if (oid.equals(OID_PASSWORD_POLICY_CONTROL))
        {
          pwPolicyControlRequested = true;
        }
        // NYI -- Add support for additional controls.
        else if (c.isCritical())
        {
          if ((backend == null) || (! backend.supportsControl(oid)))
        else if (c.isCritical()
            && (backend == null || !backend.supportsControl(oid)))
          {
            throw newDirectoryException(currentEntry,
                           ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
                           ERR_MODIFY_UNSUPPORTED_CRITICAL_CONTROL.get(
                                String.valueOf(entryDN), oid));
              ERR_MODIFY_UNSUPPORTED_CRITICAL_CONTROL.get(String.valueOf(entryDN), oid));
          }
        }
      }
    }
  private DN getDN(Entry e)
  {
    return e != null ? e.getDN() : DN.nullDN();
  }
   /**
@@ -858,9 +809,8 @@
   * @throws  DirectoryException  If a problem is encountered that should cause
   *                              the modify operation to fail.
   */
  protected void handleSchemaProcessing() throws DirectoryException
  private void handleSchemaProcessing() throws DirectoryException
  {
    for (Modification m : modifications)
    {
      Attribute     a = m.getAttribute();
@@ -868,37 +818,30 @@
      // If the attribute type is marked "NO-USER-MODIFICATION" then fail unless
      // this is an internal operation or is related to synchronization in some
      // way.
      if (t.isNoUserModification())
      {
        if (! (isInternalOperation() || isSynchronizationOperation() ||
                m.isInternal()))
      // this is an internal operation or is related to synchronization in some way.
      if (t.isNoUserModification()
          && !isInternalOperation()
          && !isSynchronizationOperation()
          && !m.isInternal())
        {
          throw newDirectoryException(currentEntry,
              ResultCode.CONSTRAINT_VIOLATION,
              ERR_MODIFY_ATTR_IS_NO_USER_MOD.get(
                          String.valueOf(entryDN), a.getName()));
        }
            ResultCode.CONSTRAINT_VIOLATION, ERR_MODIFY_ATTR_IS_NO_USER_MOD
                .get(String.valueOf(entryDN), a.getName()));
      }
      // If the attribute type is marked "OBSOLETE" and the modification is
      // setting new values, then fail unless this is an internal operation or
      // is related to synchronization in some way.
      if (t.isObsolete())
      {
        if (!a.isEmpty() &&
                (m.getModificationType() != ModificationType.DELETE))
        {
          if (! (isInternalOperation() || isSynchronizationOperation() ||
                  m.isInternal()))
      if (t.isObsolete()
          && !a.isEmpty()
          && m.getModificationType() != ModificationType.DELETE
          && !isInternalOperation()
          && !isSynchronizationOperation()
          && !m.isInternal())
          {
            throw newDirectoryException(currentEntry,
                ResultCode.CONSTRAINT_VIOLATION,
                ERR_MODIFY_ATTR_IS_OBSOLETE.get(
                            String.valueOf(entryDN), a.getName()));
          }
        }
            ERR_MODIFY_ATTR_IS_OBSOLETE.get(String.valueOf(entryDN), a.getName()));
      }
@@ -916,9 +859,8 @@
      // If the modification is not updating the password attribute,
      // then perform any schema processing.
      boolean isPassword = (pwPolicyState != null)
          && t.equals(pwPolicyState.getAuthenticationPolicy()
              .getPasswordAttribute());
      boolean isPassword = pwPolicyState != null
          && t.equals(pwPolicyState.getAuthenticationPolicy().getPasswordAttribute());
      if (!isPassword )
      {
        switch (m.getModificationType())
@@ -949,8 +891,7 @@
   * @throws  DirectoryException  If a problem is encountered that should cause
   *                              the modify operation to fail.
   */
  protected void handleInitialPasswordPolicyProcessing()
          throws DirectoryException
  private void handleInitialPasswordPolicyProcessing() throws DirectoryException
  {
    // Declare variables used for password policy state processing.
    currentPasswordProvided = false;
@@ -963,8 +904,8 @@
      return;
    }
    if (currentEntry.hasAttribute(
            pwPolicyState.getAuthenticationPolicy().getPasswordAttribute()))
    final PasswordPolicy authPolicy = pwPolicyState.getAuthenticationPolicy();
    if (currentEntry.hasAttribute(authPolicy.getPasswordAttribute()))
    {
      // It may actually have more than one, but we can't tell the difference if
      // the values are encoded, and its enough for our purposes just to know
@@ -986,22 +927,17 @@
      for (Modification m : modifications)
      {
        AttributeType t = m.getAttribute().getAttributeType();
        boolean isPassword = t.equals(pwPolicyState.getAuthenticationPolicy()
            .getPasswordAttribute());
        boolean isPassword = t.equals(authPolicy.getPasswordAttribute());
        if (isPassword)
        {
          passwordChanged = true;
          if (! selfChange)
          {
            if (! clientConnection.hasPrivilege(Privilege.PASSWORD_RESET, this))
          if (!selfChange && !clientConnection.hasPrivilege(Privilege.PASSWORD_RESET, this))
            {
              pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
              throw new DirectoryException(
                      ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
                      ERR_MODIFY_PWRESET_INSUFFICIENT_PRIVILEGES.get());
            }
          }
          break;
        }
      }
@@ -1017,8 +953,7 @@
      // If the modification is updating the password attribute, then perform
      // any necessary password policy processing.  This processing should be
      // skipped for synchronization operations.
      boolean isPassword = t.equals(pwPolicyState.getAuthenticationPolicy()
          .getPasswordAttribute());
      boolean isPassword = t.equals(authPolicy.getPasswordAttribute());
      if (isPassword)
      {
        if (!isSynchronizationOperation())
@@ -1050,9 +985,7 @@
            }
            // If it's a self change, then see if that's allowed.
            if (selfChange
                && (!pwPolicyState.getAuthenticationPolicy()
                    .isAllowUserPasswordChanges()))
            if (selfChange && !authPolicy.isAllowUserPasswordChanges())
            {
              pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
              throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
@@ -1062,9 +995,8 @@
            // If we require secure password changes, then makes sure it's a
            // secure communication channel.
            if (pwPolicyState.getAuthenticationPolicy()
                .isRequireSecurePasswordChanges()
                && (!clientConnection.isSecure()))
            if (authPolicy.isRequireSecurePasswordChanges()
                && !clientConnection.isSecure())
            {
              pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
              throw new DirectoryException(ResultCode.CONFIDENTIALITY_REQUIRED,
@@ -1211,8 +1143,7 @@
        for (ByteString s : pwPolicyState.encodePassword(v.getValue()))
        {
          builder.add(AttributeValues.create(
              pwAttr.getAttributeType(), s));
          builder.add(AttributeValues.create(pwAttr.getAttributeType(), s));
        }
      }
    }
@@ -1251,7 +1182,7 @@
    {
      if (pwPolicyState.passwordIsPreEncoded(v.getValue()))
      {
        if ((!isInternalOperation()) && selfChange)
        if (!isInternalOperation() && selfChange)
        {
          pwpErrorType = PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY;
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
@@ -1261,9 +1192,8 @@
        {
          // We still need to check if the pre-encoded password matches
          // an existing value, to decrease the number of passwords.
          List<Attribute> attrList = currentEntry.getAttribute(pwAttr
              .getAttributeType());
          if ((attrList == null) || (attrList.isEmpty()))
          List<Attribute> attrList = currentEntry.getAttribute(pwAttr.getAttributeType());
          if (attrList == null || attrList.isEmpty())
          {
            throw new DirectoryException(ResultCode.NO_SUCH_ATTRIBUTE,
                ERR_MODIFY_NO_EXISTING_VALUES.get());
@@ -1288,8 +1218,7 @@
      }
      else
      {
        List<Attribute> attrList = currentEntry.getAttribute(pwAttr
            .getAttributeType());
        List<Attribute> attrList = currentEntry.getAttribute(pwAttr.getAttributeType());
        if ((attrList == null) || (attrList.isEmpty()))
        {
          throw new DirectoryException(ResultCode.NO_SUCH_ATTRIBUTE,
@@ -1406,10 +1335,9 @@
    // If the server is configured to check schema and the operation
    // is not a synchronization operation, make sure that all the new
    // values are valid according to the associated syntax.
    if ((DirectoryServer.checkSchema()) && (!isSynchronizationOperation()))
    if (DirectoryServer.checkSchema() && !isSynchronizationOperation())
    {
      AcceptRejectWarn syntaxPolicy = DirectoryServer
          .getSyntaxEnforcementPolicy();
      AcceptRejectWarn syntaxPolicy = DirectoryServer.getSyntaxEnforcementPolicy();
      AttributeSyntax<?> syntax = attr.getAttributeType().getSyntax();
      if (syntaxPolicy == AcceptRejectWarn.REJECT)
@@ -1568,9 +1496,9 @@
        AttributeType t = attr.getAttributeType();
        RDN rdn = modifiedEntry.getDN().getRDN();
        if ((rdn !=  null) && rdn.hasAttributeType(t) &&
            (! modifiedEntry.hasValue(t, attr.getOptions(),
                                      rdn.getAttributeValue(t))))
        if (rdn != null
            && rdn.hasAttributeType(t)
            && !modifiedEntry.hasValue(t, attr.getOptions(), rdn.getAttributeValue(t)))
        {
          throw newDirectoryException(currentEntry,
              ResultCode.NOT_ALLOWED_ON_RDN,
@@ -1578,9 +1506,7 @@
                  String.valueOf(entryDN), attr.getName()));
        }
      }
      else
      {
        if (! permissiveModify)
      else if (!permissiveModify)
        {
          String missingValuesStr = collectionToString(missingValues, ", ");
@@ -1590,15 +1516,10 @@
                  String.valueOf(entryDN), attr.getName(), missingValuesStr));
        }
      }
    }
    else
    {
      if (! permissiveModify)
    else if (!permissiveModify)
      {
        throw newDirectoryException(currentEntry, ResultCode.NO_SUCH_ATTRIBUTE,
                     ERR_MODIFY_DELETE_NO_SUCH_ATTR.get(
                          String.valueOf(entryDN), attr.getName()));
      }
          ERR_MODIFY_DELETE_NO_SUCH_ATTR.get(String.valueOf(entryDN), attr.getName()));
    }
  }
@@ -1620,7 +1541,7 @@
    // If the server is configured to check schema and the operation
    // is not a synchronization operation, make sure that all the
    // new values are valid according to the associated syntax.
    if ((DirectoryServer.checkSchema()) && (!isSynchronizationOperation()))
    if (DirectoryServer.checkSchema() && !isSynchronizationOperation())
    {
      AcceptRejectWarn syntaxPolicy = DirectoryServer
          .getSyntaxEnforcementPolicy();
@@ -1691,14 +1612,12 @@
    // Make sure that the RDN attribute value(s) has not been removed.
    AttributeType t = attr.getAttributeType();
    RDN rdn = modifiedEntry.getDN().getRDN();
    if ((rdn != null)
    if (rdn != null
        && rdn.hasAttributeType(t)
        && (!modifiedEntry.hasValue(t, attr.getOptions(), rdn
            .getAttributeValue(t))))
        && !modifiedEntry.hasValue(t, attr.getOptions(), rdn.getAttributeValue(t)))
    {
      throw newDirectoryException(modifiedEntry, ResultCode.NOT_ALLOWED_ON_RDN,
          ERR_MODIFY_DELETE_RDN_ATTR.get(String.valueOf(entryDN), attr
              .getName()));
          ERR_MODIFY_DELETE_RDN_ATTR.get(String.valueOf(entryDN), attr.getName()));
    }
  }
@@ -1720,20 +1639,17 @@
    // The specified attribute type must not be an RDN attribute.
    AttributeType t = attr.getAttributeType();
    RDN rdn = modifiedEntry.getDN().getRDN();
    if ((rdn != null) && rdn.hasAttributeType(t))
    if (rdn != null && rdn.hasAttributeType(t))
    {
      throw newDirectoryException(modifiedEntry, ResultCode.NOT_ALLOWED_ON_RDN,
          ERR_MODIFY_INCREMENT_RDN.get(String.valueOf(entryDN),
              attr.getName()));
          ERR_MODIFY_INCREMENT_RDN.get(String.valueOf(entryDN), attr.getName()));
    }
    // The provided attribute must have a single value, and it must be
    // an integer.
    // The provided attribute must have a single value, and it must be an integer
    if (attr.isEmpty())
    {
      throw newDirectoryException(modifiedEntry, ResultCode.PROTOCOL_ERROR,
          ERR_MODIFY_INCREMENT_REQUIRES_VALUE.get(String.valueOf(entryDN), attr
              .getName()));
          ERR_MODIFY_INCREMENT_REQUIRES_VALUE.get(String.valueOf(entryDN), attr.getName()));
    }
    if (attr.size() > 1)
@@ -1832,10 +1748,10 @@
    // If it was a self change, then see if the current password was provided
    // and handle accordingly.
    final PasswordPolicy authPolicy = pwPolicyState.getAuthenticationPolicy();
    if (selfChange
        && pwPolicyState.getAuthenticationPolicy()
            .isPasswordChangeRequiresCurrentPassword()
        && (!currentPasswordProvided))
        && authPolicy.isPasswordChangeRequiresCurrentPassword()
        && !currentPasswordProvided)
    {
      pwpErrorType = PasswordPolicyErrorType.MUST_SUPPLY_OLD_PASSWORD;
@@ -1846,9 +1762,7 @@
    // If this change would result in multiple password values, then see if
    // that's OK.
    if ((numPasswords > 1)
        && (!pwPolicyState.getAuthenticationPolicy()
            .isAllowMultiplePasswordValues()))
    if (numPasswords > 1 && !authPolicy.isAllowMultiplePasswordValues())
    {
      pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED;
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
@@ -1857,9 +1771,7 @@
    // If any of the password values should be validated, then do so now.
    if (selfChange
        || (!pwPolicyState.getAuthenticationPolicy()
            .isSkipValidationForAdministrators()))
    if (selfChange || !authPolicy.isSkipValidationForAdministrators())
    {
      if (newPasswords != null)
      {
@@ -1911,11 +1823,9 @@
          if (! pwPolicyState.passwordIsAcceptable(this, modifiedEntry,
                                   v.getValue(), clearPasswords, invalidReason))
          {
            pwpErrorType =
                 PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY;
            pwpErrorType = PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY;
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                         ERR_MODIFY_PW_VALIDATION_FAILED.get(
                                              invalidReason));
                ERR_MODIFY_PW_VALIDATION_FAILED.get(invalidReason));
          }
        }
      }
@@ -1929,17 +1839,14 @@
      {
        for (AttributeValue v : newPasswords)
        {
          if (pwPolicyState.isPasswordInHistory(v.getValue()))
          {
            if (selfChange || (! pwPolicyState.getAuthenticationPolicy().
                                      isSkipValidationForAdministrators()))
          if (pwPolicyState.isPasswordInHistory(v.getValue())
              && (selfChange || !authPolicy.isSkipValidationForAdministrators()))
            {
              pwpErrorType = PasswordPolicyErrorType.PASSWORD_IN_HISTORY;
              throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                                           ERR_MODIFY_PW_IN_HISTORY.get());
            }
          }
        }
        pwPolicyState.updatePasswordHistory();
      }
@@ -1958,8 +1865,7 @@
    pwPolicyState.clearGraceLoginTimes();
    pwPolicyState.clearWarnedTime();
    if (pwPolicyState.getAuthenticationPolicy().isForceChangeOnAdd() ||
        pwPolicyState.getAuthenticationPolicy().isForceChangeOnReset())
    if (authPolicy.isForceChangeOnAdd() || authPolicy.isForceChangeOnReset())
    {
      if (selfChange)
      {
@@ -1967,18 +1873,16 @@
      }
      else
      {
        if ((pwpErrorType == null) &&
            pwPolicyState.getAuthenticationPolicy().isForceChangeOnReset())
        if (pwpErrorType == null && authPolicy.isForceChangeOnReset())
        {
          pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET;
        }
        pwPolicyState.setMustChangePassword(
             pwPolicyState.getAuthenticationPolicy().isForceChangeOnReset());
        pwPolicyState.setMustChangePassword(authPolicy.isForceChangeOnReset());
      }
    }
    if (pwPolicyState.getAuthenticationPolicy().getRequireChangeByTime() > 0)
    if (authPolicy.getRequireChangeByTime() > 0)
    {
      pwPolicyState.setRequiredChangeTime();
    }
@@ -1993,7 +1897,7 @@
   * Handles any account status notifications that may be needed as a result of
   * modify processing.
   */
  protected void handleAccountStatusNotifications()
  private void handleAccountStatusNotifications()
  {
    if (pwPolicyState == null)
    {
@@ -2075,7 +1979,7 @@
   * @return  {@code true} if processing should continue for the operation, or
   *          {@code false} if not.
   */
  protected boolean handleConflictResolution() {
  private boolean handleConflictResolution() {
      for (SynchronizationProvider<?> provider :
          DirectoryServer.getSynchronizationProviders()) {
          try {
@@ -2107,7 +2011,7 @@
   * @return  {@code true} if processing should continue for the operation, or
   *          {@code false} if not.
   */
  protected boolean processPreOperation() {
  private boolean processPreOperation() {
      for (SynchronizationProvider<?> provider :
          DirectoryServer.getSynchronizationProviders()) {
          try {
@@ -2136,7 +2040,7 @@
  /**
   * Invoke post operation synchronization providers.
   */
  protected void processSynchPostOperationPlugins() {
  private void processSynchPostOperationPlugins() {
      for (SynchronizationProvider<?> provider :
          DirectoryServer.getSynchronizationProviders()) {
          try {
opends/tests/unit-tests-testng/src/server/org/opends/server/core/AddOperationTestCase.java
@@ -22,13 +22,10 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011-2013 ForgeRock AS.
 *      Portions copyright 2011-2014 ForgeRock AS.
 */
package org.opends.server.core;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.testng.Assert.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
@@ -52,9 +49,14 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.opends.server.protocols.internal.InternalClientConnection.*;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.testng.Assert.*;
/**
 * A set of test cases for add operations
 * A set of test cases for add operations.
 */
@SuppressWarnings("javadoc")
public class AddOperationTestCase
       extends OperationTestCase
{
@@ -62,7 +64,7 @@
  /** Some of the tests disable the backends, so we reenable them here. */
  @AfterMethod(alwaysRun=true)
  public void reenableBackend() throws DirectoryException {
    Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> b = DirectoryServer.getBackend(DN.decode("o=test"));
    b.setWritabilityMode(WritabilityMode.ENABLED);
  }
@@ -77,9 +79,6 @@
  public Object[][] getAddOperations()
         throws Exception
  {
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    ArrayList<Control> noControls = new ArrayList<Control>();
    ArrayList<RawAttribute> ldapAttrList = new ArrayList<RawAttribute>();
@@ -101,17 +100,17 @@
    Operation[] opArray = new Operation[]
    {
      new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
      new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                       null, ByteString.valueOf("ou=People,o=test"),
                       ldapAttrList),
      new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
      new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                       noControls, ByteString.valueOf("ou=People,o=test"),
                       ldapAttrList),
      new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
      new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                       null, entry.getDN(), entry.getObjectClasses(),
                       entry.getUserAttributes(),
                       entry.getOperationalAttributes()),
      new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
      new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                       noControls, entry.getDN(), entry.getObjectClasses(),
                       entry.getUserAttributes(),
                       entry.getOperationalAttributes()),
@@ -129,9 +128,7 @@
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  protected Operation[] createTestOperations()
         throws Exception
@@ -179,9 +176,6 @@
  @Test()
  public void testGetEntryDNInitiallyNull()
  {
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    ArrayList<RawAttribute> ldapAttrList = new ArrayList<RawAttribute>();
    ArrayList<ByteString> values = new ArrayList<ByteString>();
@@ -194,7 +188,7 @@
    ldapAttrList.add(new LDAPAttribute("ou", values));
    AddOperationBasis addOperation =
         new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
         new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                          null, ByteString.valueOf("ou=People,o=test"),
                          ldapAttrList);
    assertNotNull(addOperation.getEntryDN());
@@ -212,9 +206,6 @@
  public void testGetEntryDNInitiallyNonNull()
         throws Exception
  {
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    Entry entry = TestCaseUtils.makeEntry(
         "dn: ou=People,o=test",
         "objectClass: top",
@@ -222,7 +213,7 @@
         "ou: People");
    AddOperationBasis addOperation =
         new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
         new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                          null, entry.getDN(), entry.getObjectClasses(),
                          entry.getUserAttributes(),
                          entry.getOperationalAttributes());
@@ -242,9 +233,6 @@
  public void testGetEntryDNNonNullChangedToNull()
         throws Exception
  {
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    Entry entry = TestCaseUtils.makeEntry(
         "dn: ou=People,o=test",
         "objectClass: top",
@@ -252,7 +240,7 @@
         "ou: People");
    AddOperationBasis addOperation =
         new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
         new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                          null, entry.getDN(), entry.getObjectClasses(),
                          entry.getUserAttributes(),
                          entry.getOperationalAttributes());
@@ -285,29 +273,24 @@
    values.add(ByteString.valueOf("foo"));
    addOperation.addRawAttribute(new LDAPAttribute("description", values));
    boolean found = false;
    for (RawAttribute a : addOperation.getRawAttributes())
    {
      if (a.getAttributeType().equalsIgnoreCase("description"))
      {
        found = true;
        break;
      }
    }
    assertTrue(found);
    assertTrue(find(addOperation));
    addOperation.setRawAttributes(rawAttrs);
    found = false;
    assertFalse(find(addOperation));
  }
  private boolean find(AddOperation addOperation)
  {
    boolean found = false;
    for (RawAttribute a : addOperation.getRawAttributes())
    {
      if (a.getAttributeType().equalsIgnoreCase("description"))
      if ("description".equalsIgnoreCase(a.getAttributeType()))
      {
        found = true;
        break;
        return true;
      }
    }
    assertFalse(found);
    return found;
  }
@@ -329,18 +312,12 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    UpdatePreOpPlugin.reset();
    ObjectClass oc = DirectoryServer.getObjectClass("extensibleobject", true);
    UpdatePreOpPlugin.addObjectClassToAdd(oc);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -370,18 +347,12 @@
         "objectClass: extensibleObject",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    UpdatePreOpPlugin.reset();
    ObjectClass oc = DirectoryServer.getObjectClass("extensibleobject", true);
    UpdatePreOpPlugin.addObjectClassToRemove(oc);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -412,18 +383,12 @@
         "ou: People",
         "description: foo");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    UpdatePreOpPlugin.reset();
    Attribute a = Attributes.create("description", "bar");
    UpdatePreOpPlugin.addAttributeToSet(a);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -475,18 +440,12 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    UpdatePreOpPlugin.reset();
    Attribute a = Attributes.create("description", "foo");
    UpdatePreOpPlugin.addAttributeToSet(a);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -518,19 +477,13 @@
         "ou: People",
         "description: foo");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    UpdatePreOpPlugin.reset();
    AttributeType attrType = DirectoryServer.getAttributeType("description",
                                                              true);
    UpdatePreOpPlugin.addAttributeToRemove(attrType);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -556,9 +509,6 @@
    assertTrue(addOperation.getProcessingStopTime() >=
               addOperation.getProcessingStartTime());
    assertTrue(addOperation.getProcessingTime() >= 0);
    long changeNumber = addOperation.getChangeNumber();
    addOperation.setChangeNumber(changeNumber);
  }
@@ -586,11 +536,8 @@
    values.add(ByteString.valueOf("People"));
    attrs.add(new LDAPAttribute("ou", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=test"), attrs);
         getRootConnection().processAdd(ByteString.valueOf("ou=People,o=test"), attrs);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
  }
@@ -615,13 +562,7 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
  }
@@ -651,11 +592,8 @@
    values.add(ByteString.valueOf("People"));
    attrs.add(new LDAPAttribute("ou", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("invalid"), attrs);
         getRootConnection().processAdd(ByteString.valueOf("invalid"), attrs);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -684,11 +622,8 @@
    values.add(ByteString.valueOf("test"));
    attrs.add(new LDAPAttribute("o", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("o=test"), attrs);
         getRootConnection().processAdd(ByteString.valueOf("o=test"), attrs);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -717,11 +652,8 @@
    values.add(ByteString.valueOf("undefined"));
    attrs.add(new LDAPAttribute("o", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("o=undefined"), attrs);
         getRootConnection().processAdd(ByteString.valueOf("o=undefined"), attrs);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -750,8 +682,7 @@
    values.add(ByteString.valueOf("People"));
    attrs.add(new LDAPAttribute("ou", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=undefined"), attrs);
@@ -783,8 +714,7 @@
    values.add(ByteString.valueOf("People"));
    attrs.add(new LDAPAttribute("ou", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=missing,o=test"),
@@ -886,8 +816,7 @@
    values.add(ByteString.valueOf("People"));
    attrs.add(new LDAPAttribute("ou", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=test"),
@@ -923,13 +852,7 @@
         "ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
              "cn=Password Policies,cn=config");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
  }
@@ -967,8 +890,7 @@
    values.add(ByteString.valueOf("bar"));
    attrs.add(new LDAPAttribute("description", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=test"),
@@ -1009,8 +931,7 @@
    values.add(ByteString.valueOf("foo"));
    attrs.add(new LDAPAttribute("description;lang-en-us", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=test"),
@@ -1047,8 +968,7 @@
    values.add(ByteString.valueOf("foo"));
    attrs.add(new LDAPAttribute("description;lang-en-us", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.valueOf("ou=People,o=test"),
@@ -1086,13 +1006,7 @@
         "cn;lang-en-us: Test User",
         "userPassword: password");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
  }
@@ -1123,8 +1037,7 @@
    values.add(ByteString.valueOf("Root DSE"));
    attrs.add(new LDAPAttribute("cn", values));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(ByteString.empty(), attrs);
@@ -1149,13 +1062,7 @@
         "objectClass: top",
         "objectClass: organizationalUnit");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -1184,13 +1091,7 @@
         "objectClass: top",
         "objectClass: organizationalUnit");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
    DirectoryServer.setAddMissingRDNAttributes(true);
@@ -1219,13 +1120,7 @@
         "cn: Test User",
         "userPassword: password");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -1239,7 +1134,7 @@
    {
      for (AttributeValue v : a)
      {
        if (v.getValue().toString().equalsIgnoreCase("top"))
        if ("top".equalsIgnoreCase(v.getValue().toString()))
        {
          found = true;
          break;
@@ -1266,13 +1161,7 @@
         "dn: ou=People,o=test",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1295,13 +1184,7 @@
         "objectClass: top",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1325,13 +1208,7 @@
         "objectClass: extensibleObject",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1358,13 +1235,7 @@
         "cn: Test User",
         "sn: User");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1392,13 +1263,7 @@
         "sn: User",
         "userPassword: password"); // Missing cn
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1428,13 +1293,7 @@
         "sn: User",
         "userPassword: password"); // Missing cn
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1465,13 +1324,7 @@
         "userPassword: password",
         "dc: Not allowed by inetOrgPerson");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
  }
@@ -1504,13 +1357,7 @@
         "userPassword: password",
         "dc: Not allowed by inetOrgPerson but allowed by extensibleObject");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
  }
@@ -1543,8 +1390,7 @@
    userAttrs.put(attrType, attrList);
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(), userAttrs,
@@ -1578,15 +1424,9 @@
         "cn: Test User",
         "userPassword: password");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    DirectoryServer.setWritabilityMode(WritabilityMode.DISABLED);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
    DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
@@ -1618,15 +1458,9 @@
         "cn: Test User",
         "userPassword: password");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -1724,16 +1558,10 @@
         "cn: Test User",
         "userPassword: password");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> b = DirectoryServer.getBackend(DN.decode("o=test"));
    b.setWritabilityMode(WritabilityMode.DISABLED);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
    b.setWritabilityMode(WritabilityMode.ENABLED);
@@ -1765,16 +1593,10 @@
         "cn: Test User",
         "userPassword: password");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> b = DirectoryServer.getBackend(DN.decode("o=test"));
    b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -1822,7 +1644,7 @@
    values.add(ByteString.valueOf("People"));
    attrs.add(new LDAPAttribute("ou", values));
    Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> b = DirectoryServer.getBackend(DN.decode("o=test"));
    b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
    long addRequests  = ldapStatistics.getAddRequests();
@@ -1872,13 +1694,7 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(addOperation);
@@ -1911,13 +1727,7 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperation addOperation =
         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                         entry.getUserAttributes(),
                         entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertFalse(addOperation.getResultCode() == ResultCode.SUCCESS);
    assertEquals(changeListener.getAddCount(), 0);
@@ -1943,11 +1753,8 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperationBasis addOperation =
         new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
         new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                          null, entry.getDN(), entry.getObjectClasses(),
                          entry.getUserAttributes(),
                          entry.getOperationalAttributes());
@@ -1976,11 +1783,8 @@
         "objectClass: organizationalUnit",
         "ou: People");
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    AddOperationBasis addOperation =
         new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
         new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                          null, entry.getDN(), entry.getObjectClasses(),
                          entry.getUserAttributes(),
                          entry.getOperationalAttributes());
@@ -2019,13 +1823,7 @@
           "objectClass: organizationalUnit",
           "ou: People");
      InternalClientConnection conn =
           InternalClientConnection.getRootConnection();
      AddOperation addOperation =
           conn.processAdd(entry.getDN(), entry.getObjectClasses(),
                           entry.getUserAttributes(),
                           entry.getOperationalAttributes());
      AddOperation addOperation = getRootConnection().processAdd(entry);
      assertEquals(addOperation.getResultCode(), ResultCode.BUSY);
    }
    finally
@@ -2483,9 +2281,6 @@
  {
    TestCaseUtils.initializeTestBackend(false);
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    List<Control> controls =
         ShortCircuitPlugin.createShortCircuitControlList(0, "PreParse");
@@ -2498,7 +2293,7 @@
    rawAttrs.add(RawAttribute.create("o", "test"));
    AddOperationBasis addOperation =
         new AddOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
         new AddOperationBasis(getRootConnection(), nextOperationID(), nextMessageID(),
                          controls, ByteString.valueOf("o=test"), rawAttrs);
    addOperation.run();
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
opends/tests/unit-tests-testng/src/server/org/opends/server/core/DeleteOperationTestCase.java
@@ -22,13 +22,10 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011-2013 ForgeRock AS.
 *      Portions copyright 2011-2014 ForgeRock AS.
 */
package org.opends.server.core;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.testng.Assert.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
@@ -52,8 +49,12 @@
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import static org.opends.server.protocols.internal.InternalClientConnection.*;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.testng.Assert.*;
/**
 * A set of test cases for delete operations
 * A set of test cases for delete operations.
 */
@SuppressWarnings("javadoc")
public class DeleteOperationTestCase extends OperationTestCase
@@ -62,13 +63,11 @@
  /** Some of the tests disable the backends, so we reenable them here. */
  @AfterMethod(alwaysRun=true)
  public void reenableBackend() throws DirectoryException {
    Backend b = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> b = DirectoryServer.getBackend(DN.decode("o=test"));
    b.setWritabilityMode(WritabilityMode.ENABLED);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  protected Operation[] createTestOperations()
         throws Exception
@@ -91,9 +90,7 @@
      List<Control> requestControls, ByteString rawEntryDn)
  {
    return new DeleteOperationBasis(
        InternalClientConnection.getRootConnection(),
        InternalClientConnection.nextOperationID(),
        InternalClientConnection.nextMessageID(),
        getRootConnection(), nextOperationID(), nextMessageID(),
        requestControls, rawEntryDn);
  }
@@ -101,9 +98,7 @@
      List<Control> requestControls, DN entryDn)
  {
    return new DeleteOperationBasis(
        InternalClientConnection.getRootConnection(),
        InternalClientConnection.nextOperationID(),
        InternalClientConnection.nextMessageID(),
        getRootConnection(), nextOperationID(), nextMessageID(),
        requestControls, entryDn);
  }
@@ -196,10 +191,6 @@
    assertTrue(deleteOperation.getProcessingStopTime() >=
               deleteOperation.getProcessingStartTime());
    assertTrue(deleteOperation.getProcessingTime() >= 0);
    long changeNumber = deleteOperation.getChangeNumber();
    deleteOperation.setChangeNumber(changeNumber);
  }
@@ -220,7 +211,7 @@
    assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveCompletedOperationElements(deleteOperation);
    List<LocalBackendDeleteOperation> localOps =
      (List) (deleteOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS));
      (List) deleteOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS);
    assertNotNull(localOps);
    for (LocalBackendDeleteOperation curOp : localOps)
    {
@@ -230,26 +221,20 @@
  private DeleteOperation processDeleteRaw(String entryDN)
  {
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    InternalClientConnection conn =getRootConnection();
    return conn.processDelete(ByteString.valueOf(entryDN));
  }
  private DeleteOperation processDelete(String entryDN) throws DirectoryException
  {
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    InternalClientConnection conn =getRootConnection();
    return conn.processDelete(DN.decode(entryDN));
  }
  private void processAdd(String... entryLines) throws Exception
  {
    Entry e = TestCaseUtils.makeEntry(entryLines);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    AddOperation addOperation =
        conn.processAdd(e.getDN(), e.getObjectClasses(), e.getUserAttributes(),
            e.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(e);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
  }
@@ -268,7 +253,7 @@
    DeleteOperation deleteOperation = processDeleteRaw("ou=People,o=test");
    assertFalse(deleteOperation.getResultCode() == ResultCode.SUCCESS);
    List<LocalBackendDeleteOperation> localOps =
      (List) (deleteOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS));
      (List) deleteOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS);
    assertNotNull(localOps);
    for (LocalBackendDeleteOperation curOp : localOps)
    {
@@ -623,7 +608,7 @@
  {
    TestCaseUtils.initializeTestBackend(true);
    Backend backend = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> backend = DirectoryServer.getBackend(DN.decode("o=test"));
    backend.setWritabilityMode(WritabilityMode.DISABLED);
    DeleteOperation deleteOperation = processDeleteRaw("o=test");
@@ -646,7 +631,7 @@
  {
    TestCaseUtils.initializeTestBackend(true);
    Backend backend = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> backend = DirectoryServer.getBackend(DN.decode("o=test"));
    backend.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
    DeleteOperation deleteOperation = processDeleteRaw("o=test");
@@ -669,7 +654,7 @@
  {
    TestCaseUtils.initializeTestBackend(true);
    Backend backend = DirectoryServer.getBackend(DN.decode("o=test"));
    Backend<?> backend = DirectoryServer.getBackend(DN.decode("o=test"));
    backend.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
    String[] args = getArgs("o=test");
@@ -966,10 +951,7 @@
          break responseLoop;
        default:
          // This is a problem.  It's an unexpected response.
          try
          {
            s.close();
          } catch (Exception e) {}
          StaticUtils.close(s);
          throw new Exception("Unexpected response message " + message +
                              " encountered in " +
opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -22,14 +22,10 @@
 *
 *
 *      Copyright 2006-2011 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2013 ForgeRock AS
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.core;
import static org.opends.server.TestCaseUtils.*;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.testng.Assert.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
@@ -54,8 +50,13 @@
import org.opends.server.workflowelement.localbackend.LocalBackendModifyOperation;
import org.testng.annotations.*;
import static org.opends.server.TestCaseUtils.*;
import static org.opends.server.protocols.internal.InternalClientConnection.*;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import static org.testng.Assert.*;
/**
 * A set of test cases for modify operations
 * A set of test cases for modify operations.
 */
@SuppressWarnings("javadoc")
public class ModifyOperationTestCase
@@ -67,14 +68,13 @@
    TestCaseUtils.restartServer();
  }
  // Some of the tests disable the backends, so we reenable them here.
  /** Some of the tests disable the backends, so we reenable them here. */
  @AfterMethod(alwaysRun=true)
  public void reenableBackend() throws DirectoryException {
    Object[][] backendBaseDNs = getBaseDNs();
    for (Object[] backendBaseDN2 : backendBaseDNs)
    for (Object[] backendBaseDN2 : getBaseDNs())
    {
      String backendBaseDN = backendBaseDN2[0].toString();
      Backend b = DirectoryServer.getBackend(DN.decode(backendBaseDN));
      final DN baseDN = DN.decode(backendBaseDN2[0].toString());
      Backend<?> b = DirectoryServer.getBackend(baseDN);
      b.setWritabilityMode(WritabilityMode.ENABLED);
    }
  }
@@ -208,9 +208,7 @@
      DN entryDn, List<Modification> modifications)
  {
    return new ModifyOperationBasis(
        InternalClientConnection.getRootConnection(),
        InternalClientConnection.nextOperationID(),
        InternalClientConnection.nextMessageID(),
        getRootConnection(), nextOperationID(), nextMessageID(),
        requestControls, entryDn, modifications);
  }
@@ -218,9 +216,7 @@
      ByteString rawEntryDn, List<RawModification> rawModifications)
  {
    return new ModifyOperationBasis(
        InternalClientConnection.getRootConnection(),
        InternalClientConnection.nextOperationID(),
        InternalClientConnection.nextMessageID(),
        getRootConnection(), nextOperationID(), nextMessageID(),
        requestControls, rawEntryDn, rawModifications);
  }
@@ -239,9 +235,7 @@
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override()
  protected Operation[] createTestOperations()
         throws Exception
@@ -373,8 +367,7 @@
    modifyOperation.addRawModification(replace(attr));
    assertEquals(modifyOperation.getRawModifications().size(),
                 (rawMods.size() + 1));
    assertEquals(modifyOperation.getRawModifications().size(), rawMods.size() + 1);
    modifyOperation.setRawModifications(rawMods);
    assertEquals(modifyOperation.getRawModifications().size(), rawMods.size());
@@ -398,7 +391,7 @@
    assertTrue(modifyOperation.getProcessingTime() >= 0);
    List<LocalBackendModifyOperation> localOps =
      (List) (modifyOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS));
      (List) modifyOperation.getAttachment(Operation.LOCALBACKENDOPERATIONS);
    assertNotNull(localOps);
    for (LocalBackendModifyOperation curOp : localOps)
    {
@@ -407,9 +400,6 @@
      assertNotNull(curOp.getCurrentEntry());
      assertNotNull(curOp.getModifiedEntry());
    }
    long changeNumber = modifyOperation.getChangeNumber();
    modifyOperation.setChangeNumber(changeNumber);
  }
@@ -428,9 +418,6 @@
    assertTrue(modifyOperation.getProcessingStopTime() >=
               modifyOperation.getProcessingStartTime());
    assertTrue(modifyOperation.getProcessingTime() >= 0);
    long changeNumber = modifyOperation.getChangeNumber();
    modifyOperation.setChangeNumber(changeNumber);
  }
@@ -454,15 +441,12 @@
             Attributes.create("description", "foo")));
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    List<Modification> mods = new ArrayList<Modification>();
    mods.add(new Modification(ModificationType.REPLACE,
        Attributes.create("l", "Austin")));
    ModifyOperation modifyOperation =
         conn.processModify(DN.decode("o=test"), mods);
        getRootConnection().processModify(DN.decode("o=test"), mods);
    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
    retrieveSuccessfulOperationElements(modifyOperation);
@@ -793,34 +777,27 @@
  private ModifyOperation processModify(String entryDN,
      List<RawModification> mods)
  {
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    return conn.processModify(ByteString.valueOf(entryDN), mods);
  }
  private ModifyOperation processModify(String entryDN, RawModification... mods)
  {
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    return conn.processModify(ByteString.valueOf(entryDN), Arrays.asList(mods));
  }
  private ModifyOperation processModify(String entryDN,
      List<RawModification> mods, List<Control> requestControls)
  {
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    InternalClientConnection conn = getRootConnection();
    return conn.processModify(ByteString.valueOf(entryDN), mods, requestControls);
  }
  private void processAdd(String... entryLines) throws Exception
  {
    Entry entry = TestCaseUtils.makeEntry(entryLines);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    AddOperation addOperation =
        conn.processAdd(entry.getDN(), entry.getObjectClasses(), entry
            .getUserAttributes(), entry.getOperationalAttributes());
    AddOperation addOperation = getRootConnection().processAdd(entry);
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
  }
@@ -1425,9 +1402,7 @@
    InternalSearchOperation searchOperation =
         new InternalSearchOperation(
              InternalClientConnection.getRootConnection(),
              InternalClientConnection.nextOperationID(),
              InternalClientConnection.nextMessageID(),
              getRootConnection(), nextOperationID(), nextMessageID(),
              new ArrayList<Control>(),
              ByteString.valueOf("uid=test.user," + baseDN),
              SearchScope.WHOLE_SUBTREE,
@@ -1477,9 +1452,7 @@
    InternalSearchOperation searchOperation =
         new InternalSearchOperation(
              InternalClientConnection.getRootConnection(),
              InternalClientConnection.nextOperationID(),
              InternalClientConnection.nextMessageID(),
              getRootConnection(), nextOperationID(), nextMessageID(),
              new ArrayList<Control>(),
              ByteString.valueOf(baseDN),
              SearchScope.WHOLE_SUBTREE,
@@ -1532,9 +1505,7 @@
    InternalSearchOperation searchOperation =
         new InternalSearchOperation(
              InternalClientConnection.getRootConnection(),
              InternalClientConnection.nextOperationID(),
              InternalClientConnection.nextMessageID(),
              getRootConnection(), nextOperationID(), nextMessageID(),
              new ArrayList<Control>(),
              ByteString.valueOf(baseDN),
              SearchScope.WHOLE_SUBTREE,
@@ -2617,7 +2588,7 @@
         "mail: foo",
         "employeeNumber: 1");
    Backend b = DirectoryServer.getBackend(DN.decode(baseDN));
    Backend<?> b = DirectoryServer.getBackend(DN.decode(baseDN));
    b.setWritabilityMode(WritabilityMode.DISABLED);
    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
@@ -2655,7 +2626,7 @@
         "mail: foo",
         "employeeNumber: 1");
    Backend b = DirectoryServer.getBackend(DN.decode(baseDN));
    Backend<?> b = DirectoryServer.getBackend(DN.decode(baseDN));
    b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
    LDAPAttribute attr = newLDAPAttribute("objectClass", "extensibleObject");
@@ -2693,7 +2664,7 @@
         "mail: foo",
         "employeeNumber: 1");
    Backend b = DirectoryServer.getBackend(DN.decode(baseDN));
    Backend<?> b = DirectoryServer.getBackend(DN.decode(baseDN));
    b.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
@@ -3559,7 +3530,7 @@
        "cn: Test User",
        "userPassword: password",
        "userPassword;deleted: oldpassword");
    Backend backend = DirectoryServer.getBackend(TEST_BACKEND_ID);
    Backend<?> backend = DirectoryServer.getBackend(TEST_BACKEND_ID);
    backend.addEntry(e, null); // Don't use add operation.
    // Constraint violation.
@@ -3601,7 +3572,7 @@
        "cn: Test User",
        "userPassword: password",
        "userPassword;deleted: oldpassword");
    Backend backend = DirectoryServer.getBackend(TEST_BACKEND_ID);
    Backend<?> backend = DirectoryServer.getBackend(TEST_BACKEND_ID);
    backend.addEntry(e, null); // Don't use add operation.
    // Constraint violation.