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

neil_a_wilson
26.49.2007 33e1efa657583fb8d4676f45a537b2ff9dbda4dd
opendj-sdk/opends/resource/config/config.ldif
@@ -366,6 +366,7 @@
ds-cfg-backend-writability-mode: enabled
ds-cfg-backend-base-dn: cn=admin data
ds-cfg-ldif-file: config/admin-backend.ldif
ds-cfg-is-private-backend: true
dn: cn=Certificate Mappers,cn=config
objectClass: top
opendj-sdk/opends/resource/schema/02-config.ldif
@@ -1681,6 +1681,9 @@
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.496 NAME 'ds-cfg-ldif-file'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.497 NAME 'ds-cfg-is-private-backend'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler' SUP top STRUCTURAL
  MUST ( cn $ ds-cfg-acl-handler-class $ ds-cfg-acl-handler-enabled )
@@ -2517,5 +2520,5 @@
  STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.175 NAME 'ds-cfg-ldif-backend'
  SUP ds-cfg-backend STRUCTURAL MUST ds-cfg-ldif-file
  X-ORIGIN 'OpenDS Directory Server' )
  MAY ds-cfg-is-private-backend X-ORIGIN 'OpenDS Directory Server' )
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDIFBackendConfiguration.xml
@@ -59,9 +59,7 @@
    </adm:default-behavior>
  </adm:property-override>
  <adm:property name="ldif-file"
  mandatory="true"
  multi-valued="false">
  <adm:property name="ldif-file" mandatory="true" multi-valued="false">
    <adm:synopsis>
      This specifies the path to the LDIF file containing the data for this
      backend.
@@ -80,5 +78,31 @@
    </adm:profile>
  </adm:property>
  <adm:property name="is-private-backend" mandatory="false"
    multi-valued="false">
    <adm:synopsis>
      This indicates whether the backend should be considered a private backend,
      which indicates that it is used for storing operational data rather than
      user-defined information.
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:component-restart />
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:defined>
        <adm:value>false</adm:value>
      </adm:defined>
    </adm:default-behavior>
    <adm:syntax>
      <adm:boolean />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.497</ldap:oid>
        <ldap:name>ds-cfg-is-private-backend</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opendj-sdk/opends/src/messages/messages/access_control.properties
@@ -361,3 +361,6 @@
 Control Instruction (ACI) extop expression value "%s" is invalid. A valid \
 extop keyword expression value requires one or more valid extended operation \
 request OID strings in the following format: oid [|| oid1] ... [|| oidN]
SEVERE_WARN_ACI_ATTRIBUTE_NOT_INDEXED_96=Backend %s does not have a \
 presence index defined for attribute type %s.  Access control initialization \
 may take a very long time to complete in this backend
opendj-sdk/opends/src/messages/messages/backend.properties
@@ -1032,3 +1032,7 @@
 does not exist
SEVERE_ERR_TRUSTSTORE_ERROR_READING_KEY_367=Error reading key %s from key \
 store %s: %s
MILD_ERR_HAS_SUBORDINATES_NOT_SUPPORTED_368=This backend does not provide \
 support for the hasSubordinates operational attribute
MILD_ERR_NUM_SUBORDINATES_NOT_SUPPORTED_369=This backend does not provide \
 support for the numSubordinates operational attribute
opendj-sdk/opends/src/messages/messages/core.properties
@@ -1672,3 +1672,6 @@
SEVERE_ERR_PWPOLICY_DEPRECATED_SCHEME_NOT_AUTH_659=Password policy \
 configuration entry %s references deprecated password storage scheme DN %s \
 which does not support the auth password syntax
SEVERE_WARN_GROUP_FILTER_NOT_INDEXED_660=The search filter "%s" used by group \
 implementation %s is not indexed in backend %s.  Backend initialization \
 for this group implementation may take a very long time to complete
opendj-sdk/opends/src/messages/messages/plugin.properties
@@ -315,7 +315,7 @@
SEVERE_ERR_PLUGIN_UNIQUEATTR_MODDN_NOT_UNIQUE_80=An error occurred while \
 attempting to perform a modify DN operation on entry %s because the proposed \
 changes failed the attribute value uniqueness check
SEVERE_ERR_PLUGIN_REFERINT_INVALID_PLUGIN_TYPE_81=An attempt was made to \
SEVERE_ERR_PLUGIN_REFERENT_INVALID_PLUGIN_TYPE_81=An attempt was made to \
 register the Referential Integrity plugin to be invoked as a %s plugin.  This \
 plugin type is not allowed for this plugin
SEVERE_ERR_PLUGIN_REFERENT_CREATE_LOGFILE_82=An error occurred during \
@@ -395,3 +395,11 @@
 occurred while attempting to determine whether the synchronization operation \
 (connID=%d, opID=%d) for entry %s would have resulted in a unique attribute \
 conflict (result %s, message %s)
SEVERE_ERR_PLUGIN_REFERENT_ATTR_UNINDEXED_110=The referential integrity \
 plugin defined in configuration entry %s is configured to operate on \
 attribute %s but there is no equality index defined for this attribute \
 in backend %s
SEVERE_ERR_PLUGIN_UNIQUEATTR_ATTR_UNINDEXED_111=The unique attribute \
 plugin defined in configuration entry %s is configured to operate on \
 attribute %s but there is no equality index defined for this attribute \
 in backend %s
opendj-sdk/opends/src/server/org/opends/server/api/Backend.java
@@ -44,18 +44,21 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.monitors.BackendMonitor;
import org.opends.server.types.AttributeType;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.CancelledOperationException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.LockManager;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.WritabilityMode;
import org.opends.server.types.ConditionResult;
@@ -222,6 +225,175 @@
  /**
   * Indicates whether search operations which target the specified
   * attribute in the indicated manner would be considered indexed
   * in this backend.  The operation should be considered indexed only
   * if the specified operation can be completed efficiently within
   * the backend.
   * <BR><BR>
   * Note that this method should return a general result that covers
   * all values of the specified attribute.  If a the specified
   * attribute is indexed in the indicated manner but some particular
   * values may still be treated as unindexed (e.g., if the number of
   * entries with that attribute value exceeds some threshold), then
   * this method should still return {@code true} for the specified
   * attribute and index type.
   *
   * @param  attributeType  The attribute type for which to make the
   *                        determination.
   * @param  indexType      The index type for which to make the
   *                        determination.
   *
   * @return  {@code true} if search operations targeting the
   *          specified attribute in the indicated manner should be
   *          considered indexed, or {@code false} if not.
   */
  public abstract boolean isIndexed(AttributeType attributeType,
                                    IndexType indexType);
  /**
   * Indicates whether extensible match search operations that target
   * the specified attribute with the given matching rule should be
   * considered indexed in this backend.
   *
   * @param  attributeType  The attribute type for which to make the
   *                        determination.
   * @param  matchingRule   The matching rule for which to make the
   *                        determination.
   *
   * @return  {@code true} if extensible match search operations
   *          targeting the specified attribute with the given
   *          matching rule should be considered indexed, or
   *          {@code false} if not.
   */
  public boolean isIndexed(AttributeType attributeType,
                           MatchingRule matchingRule)
  {
    return false;
  }
  /**
   * Indicates whether a subtree search using the provided filter
   * would be indexed in this backend.  This default implementation
   * uses a rough set of logic that makes a best-effort determination.
   * Subclasses that provide a more complete indexing mechanism may
   * wish to override this method and provide a more accurate result.
   *
   * @param  filter  The search filter for which to make the
   *                 determination.
   *
   * @return  {@code true} if it is believed that the provided filter
   *          would be indexed in this backend, or {@code false} if
   *          not.
   */
  public boolean isIndexed(SearchFilter filter)
  {
    switch (filter.getFilterType())
    {
      case AND:
        // At least one of the subordinate filter components must be
        // indexed.
        for (SearchFilter f : filter.getFilterComponents())
        {
          if (isIndexed(f))
          {
            return true;
          }
        }
        return false;
      case OR:
        for (SearchFilter f : filter.getFilterComponents())
        {
          if (! isIndexed(f))
          {
            return false;
          }
        }
        return (! filter.getFilterComponents().isEmpty());
      case NOT:
        // NOT filters are not considered indexed by default.
        return false;
      case EQUALITY:
        return isIndexed(filter.getAttributeType(),
                         IndexType.EQUALITY);
      case SUBSTRING:
        return isIndexed(filter.getAttributeType(),
                         IndexType.SUBSTRING);
      case GREATER_OR_EQUAL:
        return isIndexed(filter.getAttributeType(),
                         IndexType.GREATER_OR_EQUAL);
      case LESS_OR_EQUAL:
        return isIndexed(filter.getAttributeType(),
                         IndexType.LESS_OR_EQUAL);
      case PRESENT:
        return isIndexed(filter.getAttributeType(),
                         IndexType.PRESENCE);
      case APPROXIMATE_MATCH:
        return isIndexed(filter.getAttributeType(),
                         IndexType.APPROXIMATE);
      case EXTENSIBLE_MATCH:
        // The attribute type must be provided for us to make the
        // determination.  If a matching rule ID is provided, then
        // we'll use it as well, but if not then we'll use the
        // default equality matching rule for the attribute type.
        AttributeType attrType = filter.getAttributeType();
        if (attrType == null)
        {
          return false;
        }
        MatchingRule matchingRule;
        String matchingRuleID = filter.getMatchingRuleID();
        if (matchingRuleID == null)
        {
          matchingRule = DirectoryServer.getMatchingRule(
                              matchingRuleID.toLowerCase());
        }
        else
        {
          matchingRule = attrType.getEqualityMatchingRule();
        }
        if (matchingRule == null)
        {
          return false;
        }
        else
        {
          return isIndexed(attrType, matchingRule);
        }
      default:
        return false;
    }
  }
  /**
   * Retrieves the requested entry from this backend.  Note that the
   * caller must hold a read or write lock on the specified DN.
   *
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -211,6 +211,17 @@
     * ACI list.
     */
    public void performBackendInitializationProcessing(Backend backend) {
      // Check to make sure that the backend has a presence index defined for
      // the ACI attribute.  If it does not, then log a warning message because
      // this processing could be very expensive.
      AttributeType aciType = DirectoryServer.getAttributeType("aci", true);
      if (! backend.isIndexed(aciType, IndexType.PRESENCE))
      {
        logError(WARN_ACI_ATTRIBUTE_NOT_INDEXED.get(backend.getBackendID(),
                                                    "aci"));
      }
      InternalClientConnection conn =
           InternalClientConnection.getRootConnection();
      LinkedList<Message>failedACIMsgs=new LinkedList<Message>();
opendj-sdk/opends/src/server/org/opends/server/backends/BackupBackend.java
@@ -25,13 +25,16 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.backends;
import org.opends.messages.Message;
import java.io.File;
import java.util.*;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.BackupBackendCfg;
import org.opends.server.api.Backend;
import org.opends.server.config.ConfigException;
import org.opends.server.core.AddOperation;
@@ -40,22 +43,40 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.BackupInfo;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.RDN;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.schema.BooleanSyntax;
import org.opends.server.schema.GeneralizedTimeSyntax;
import org.opends.server.util.Validator;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.util.Validator;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.BackupBackendCfg;
import org.opends.server.admin.Configuration;
/**
@@ -75,6 +96,8 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The current configuration state.
  private BackupBackendCfg currentConfig;
@@ -111,9 +134,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config) throws ConfigException
  {
    // Make sure that a configuration entry was provided.  If not, then we will
@@ -130,9 +155,12 @@
    currentConfig = (BackupBackendCfg)config;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -231,16 +259,9 @@
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the
   * Directory Server shutdown process or if a backend is disabled with the
   * server online.  It must not return until the backend is closed.
   * <BR><BR>
   * This method may not throw any exceptions.  If any problems are encountered,
   * then they may be logged but the closure should progress as completely as
   * possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    currentConfig.removeBackupChangeListener(this);
@@ -261,10 +282,9 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return  The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -275,6 +295,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    int numEntries = 1;
@@ -307,23 +328,33 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return  <CODE>true</CODE> if the data associated with this backend may be
   *          considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
@@ -341,9 +372,12 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public long numSubordinates(DN entryDN) throws DirectoryException
  {
    // If the requested entry was null, then return undefined.
@@ -417,17 +451,12 @@
    }
  }
  /**
   * Retrieves the requested entry from this backend.
   *
   * @param  entryDN  The distinguished name of the entry to retrieve.
   *
   * @return  The requested entry, or <CODE>null</CODE> if the entry does not
   *          exist.
   *
   * @throws  DirectoryException  If a problem occurs while trying to retrieve
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -797,18 +826,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param  entry         The entry to add to this backend.
   * @param  addOperation  The add operation with which the new entry is
   *                       associated.  This may be <CODE>null</CODE> for adds
   *                       performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to add the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -819,19 +839,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param  entryDN          The DN of the entry to remove from this backend.
   * @param  deleteOperation  The delete operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          deletes performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to remove the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -842,19 +852,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param  entry            The new entry to use in place of the existing
   *                          entry with the same DN.
   * @param  modifyOperation  The modify operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modifications performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to replace
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -865,20 +865,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.
   *
   * @param  currentDN          The current DN of the entry to be replaced.
   * @param  entry              The new content to use for the entry.
   * @param  modifyDNOperation  The modify DN operation with which this action
   *                            is associated.  This may be <CODE>null</CODE>
   *                            for modify DN operations performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to perform
   *                              the rename.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                                   ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -890,15 +879,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param  searchOperation  The search operation to be processed.
   *
   * @throws  DirectoryException  If a problem occurs while processing the
   *                              search.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -1092,10 +1075,9 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return  The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -1104,10 +1086,9 @@
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return  The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -1116,12 +1097,9 @@
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF export
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // We do not support LDIF exports.
@@ -1133,6 +1111,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -1143,12 +1122,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF import
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
@@ -1160,6 +1136,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -1171,16 +1148,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return  <CODE>true</CODE> if this backend provides any kind of backup
   *          mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -1190,20 +1160,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param  backupConfig       The configuration of the backup for which to
   *                            make the determination.
   * @param  unsupportedReason  A buffer to which a message can be appended
   *                            explaining why the requested backup is not
   *                            supported.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          performing backups with the provided configuration, or
   *          <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -1216,6 +1175,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
  throws DirectoryException
  {
@@ -1227,17 +1187,9 @@
  /**
   * Removes the specified backup if it is possible to do so.
   *
   * @param  backupDirectory  The backup directory structure with which the
   *                          specified backup is associated.
   * @param  backupID         The backup ID for the backup to be removed.
   *
   * @throws  DirectoryException  If it is not possible to remove the specified
   *                              backup for some reason (e.g., no such backup
   *                              exists or there are other backups that are
   *                              dependent upon it).
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -1250,11 +1202,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -1266,6 +1216,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -1289,6 +1240,7 @@
  }
  /**
   * {@inheritDoc}
   */
@@ -1310,6 +1262,8 @@
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Create a new child DN from a given parent DN.  The child RDN is formed
   * from a given attribute type and string value.
@@ -1325,7 +1279,5 @@
         new AttributeValue(rdnAttrType, rdnStringValue);
    return parentDN.concat(RDN.create(rdnAttrType, attrValue));
  }
}
opendj-sdk/opends/src/server/org/opends/server/backends/LDIFBackend.java
@@ -51,6 +51,7 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.AttributeType;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.ConditionResult;
@@ -61,6 +62,7 @@
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.ExistingFileBehavior;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
@@ -170,7 +172,8 @@
    {
      try
      {
        DirectoryServer.registerBaseDN(dn, this, false);
        DirectoryServer.registerBaseDN(dn, this,
                                       currentConfig.isIsPrivateBackend());
      }
      catch (Exception e)
      {
@@ -445,6 +448,18 @@
   * {@inheritDoc}
   */
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
opendj-sdk/opends/src/server/org/opends/server/backends/MemoryBackend.java
@@ -28,7 +28,11 @@
import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Set;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
@@ -42,6 +46,7 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.AttributeType;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.ConditionResult;
@@ -50,6 +55,7 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
@@ -63,7 +69,6 @@
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.Validator;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
@@ -109,6 +114,8 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The base DNs for this backend.
  private DN[] baseDNs;
@@ -157,7 +164,9 @@
  /**
   * {@inheritDoc}
   */
  public void configureBackend(Configuration config) throws ConfigException
  @Override()
  public void configureBackend(Configuration config)
         throws ConfigException
  {
    if (config != null)
    {
@@ -172,6 +181,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void initializeBackend()
       throws ConfigException, InitializationException
  {
@@ -235,6 +245,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void finalizeBackend()
  {
    clearMemoryBackend();
@@ -260,6 +271,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -270,6 +282,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized long getEntryCount()
  {
    if (entryMap != null)
@@ -285,16 +298,33 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public synchronized ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
@@ -314,7 +344,9 @@
  /**
   * {@inheritDoc}
   */
  public long numSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public synchronized long numSubordinates(DN entryDN)
         throws DirectoryException
  {
    // Try to look up the immediate children for the DN
    Set<DN> children = childDNs.get(entryDN);
@@ -334,6 +366,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized Entry getEntry(DN entryDN)
  {
    Entry entry = entryMap.get(entryDN);
@@ -350,6 +383,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized boolean entryExists(DN entryDN)
  {
    return entryMap.containsKey(entryDN);
@@ -360,6 +394,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -414,6 +449,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void deleteEntry(DN entryDN,
                                       DeleteOperation deleteOperation)
         throws DirectoryException
@@ -503,6 +539,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void replaceEntry(Entry entry,
                                        ModifyOperation modifyOperation)
         throws DirectoryException
@@ -528,6 +565,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void renameEntry(DN currentDN, Entry entry,
                                       ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -609,6 +647,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -673,6 +712,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -683,6 +723,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -693,6 +734,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    return true;
@@ -703,6 +745,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -764,6 +807,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    return true;
@@ -774,6 +818,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -858,6 +903,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -869,6 +915,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -881,6 +928,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -893,6 +941,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -906,6 +955,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -917,6 +967,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
opendj-sdk/opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -63,6 +63,7 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
@@ -78,7 +79,6 @@
import org.opends.server.util.TimeThread;
import org.opends.server.util.Validator;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.BackendMessages.*;
@@ -104,6 +104,7 @@
  private static final DebugTracer TRACER = getTracer();
  // The set of user-defined attributes that will be included in the base
  // monitor entry.
  private ArrayList<Attribute> userDefinedAttributes;
@@ -147,7 +148,9 @@
  /**
   * {@inheritDoc}
   */
  public void configureBackend(Configuration config) throws ConfigException
  @Override()
  public void configureBackend(Configuration config)
         throws ConfigException
  {
    Validator.ensureNotNull(config);
    Validator.ensureTrue(config instanceof MonitorBackendCfg);
@@ -234,9 +237,12 @@
    currentConfig = cfg;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -265,16 +271,9 @@
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the
   * Directory Server shutdown process or if a backend is disabled with the
   * server online.  It must not return until the backend is closed.
   * <BR><BR>
   * This method may not throw any exceptions.  If any problems are encountered,
   * then they may be logged but the closure should progress as completely as
   * possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    currentConfig.removeMonitorChangeListener(this);
@@ -322,10 +321,9 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return  The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -336,6 +334,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    return DirectoryServer.getMonitorProviders().size() + 1;
@@ -344,24 +343,35 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return  <CODE>true</CODE> if the data associated with this backend may be
   *          considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
@@ -378,10 +388,14 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  public long numSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public long numSubordinates(DN entryDN)
         throws DirectoryException
  {
    // If the requested entry was null, then return undefined.
    if (entryDN == null)
@@ -428,17 +442,12 @@
    return 0;
  }
  /**
   * Retrieves the requested entry from this backend.
   *
   * @param  entryDN  The distinguished name of the entry to retrieve.
   *
   * @return  The requested entry, or <CODE>null</CODE> if the entry does not
   *          exist.
   *
   * @throws  DirectoryException  If a problem occurs while trying to retrieve
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -511,20 +520,9 @@
  /**
   * Indicates whether an entry with the specified DN exists in the backend.
   * The default implementation obtains a read lock and calls
   * <CODE>getEntry</CODE>, but backend implementations may override this with a
   * more efficient version that does not require a lock.  The caller is not
   * required to hold any locks on the specified DN.
   *
   * @param  entryDN  The DN of the entry for which to determine existence.
   *
   * @return  <CODE>true</CODE> if the specified entry exists in this backend,
   *          or <CODE>false</CODE> if it does not.
   *
   * @throws  DirectoryException  If a problem occurs while trying to make the
   *                              determination.
   * {@inheritDoc}
   */
  @Override()
  public boolean entryExists(DN entryDN)
         throws DirectoryException
  {
@@ -820,18 +818,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param  entry         The entry to add to this backend.
   * @param  addOperation  The add operation with which the new entry is
   *                       associated.  This may be <CODE>null</CODE> for adds
   *                       performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to add the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -843,19 +832,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param  entryDN          The DN of the entry to remove from this backend.
   * @param  deleteOperation  The delete operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          deletes performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to remove the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -867,19 +846,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param  entry            The new entry to use in place of the existing
   *                          entry with the same DN.
   * @param  modifyOperation  The modify operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modifications performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to replace
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -891,20 +860,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.
   *
   * @param  currentDN          The current DN of the entry to be replaced.
   * @param  entry              The new content to use for the entry.
   * @param  modifyDNOperation  The modify DN operation with which this action
   *                            is associated.  This may be <CODE>null</CODE>
   *                            for modify DN operations performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to perform
   *                              the rename.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                                   ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -917,15 +875,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param  searchOperation  The search operation to be processed.
   *
   * @throws  DirectoryException  If a problem occurs while processing the
   *                              search.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -991,10 +943,9 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return  The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -1003,10 +954,9 @@
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return  The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -1015,12 +965,9 @@
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF export
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // We can export all the monitor entries as a point-in-time snapshot.
@@ -1034,6 +981,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -1144,12 +1092,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF import
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
@@ -1161,6 +1106,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -1172,16 +1118,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return  <CODE>true</CODE> if this backend provides any kind of backup
   *          mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -1191,20 +1130,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param  backupConfig       The configuration of the backup for which to
   *                            make the determination.
   * @param  unsupportedReason  A buffer to which a message can be appended
   *                            explaining why the requested backup is not
   *                            supported.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          performing backups with the provided configuration, or
   *          <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -1217,6 +1145,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -1228,17 +1157,9 @@
  /**
   * Removes the specified backup if it is possible to do so.
   *
   * @param  backupDirectory  The backup directory structure with which the
   *                          specified backup is associated.
   * @param  backupID         The backup ID for the backup to be removed.
   *
   * @throws  DirectoryException  If it is not possible to remove the specified
   *                              backup for some reason (e.g., no such backup
   *                              exists or there are other backups that are
   *                              dependent upon it).
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -1251,11 +1172,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -1267,6 +1186,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -1278,18 +1198,7 @@
  /**
   * Indicates whether the provided configuration entry has an acceptable
   * configuration for this component.  If it does not, then detailed
   * information about the problem(s) should be added to the provided list.
   *
   * @param  backendCfg          The configuration entry for which to make the
   *                              determination.
   * @param  unacceptableReasons  A list that can be used to hold messages about
   *                              why the provided entry does not have an
   *                              acceptable configuration.
   *
   * @return  <CODE>true</CODE> if the provided entry has an acceptable
   *          configuration for this component, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  public boolean isConfigurationChangeAcceptable(
       MonitorBackendCfg backendCfg,
opendj-sdk/opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -25,7 +25,6 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.backends;
import org.opends.messages.Message;
@@ -39,6 +38,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.RootDSEBackendCfg;
@@ -57,17 +57,17 @@
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.Validator;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.BackendMessages.*;
import static org.opends.messages.ConfigMessages.
     ERR_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines a backend to hold the Directory Server root DSE.  It is a
 * kind of meta-backend in that it will dynamically generate the root DSE entry
@@ -89,6 +89,8 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The set of standard "static" attributes that we will always include in the
  // root DSE entry and won't change while the server is running.
  private ArrayList<Attribute> staticDSEAttributes;
@@ -141,9 +143,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config)
         throws ConfigException
  {
@@ -153,9 +157,12 @@
    configEntryDN = config.dn();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -301,16 +308,9 @@
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the
   * Directory Server shutdown process or if a backend is disabled with the
   * server online.  It must not return until the backend is closed.
   * <BR><BR>
   * This method may not throw any exceptions.  If any problems are encountered,
   * then they may be logged but the closure should progress as completely as
   * possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    currentConfig.removeChangeListener(this);
@@ -343,10 +343,9 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return  The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -357,6 +356,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized long getEntryCount()
  {
    // There is always just a single entry in this backend.
@@ -366,24 +366,35 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return  <CODE>true</CODE> if the data associated with this backend may be
   *          considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
@@ -400,10 +411,14 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  public long numSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public long numSubordinates(DN entryDN)
         throws DirectoryException
  {
    if (entryDN == null || ! entryDN.isNullDN())
    {
@@ -424,10 +439,7 @@
    for (DN subBase : baseMap.keySet())
    {
      Backend b = baseMap.get(subBase);
      Entry subBaseEntry = b.getEntry(subBase);
      if (subBaseEntry != null)
      if (DirectoryServer.entryExists(subBase))
      {
        count++;
      }
@@ -436,17 +448,12 @@
    return count;
  }
  /**
   * Retrieves the requested entry from this backend.
   *
   * @param  entryDN  The distinguished name of the entry to retrieve.
   *
   * @return  The requested entry, or <CODE>null</CODE> if the entry does not
   *          exist.
   *
   * @throws  DirectoryException  If a problem occurs while trying to retrieve
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -815,20 +822,9 @@
  /**
   * Indicates whether an entry with the specified DN exists in the backend.
   * The default implementation obtains a read lock and calls
   * <CODE>getEntry</CODE>, but backend implementations may override this with a
   * more efficient version that does not require a lock.  The caller is not
   * required to hold any locks on the specified DN.
   *
   * @param  entryDN  The DN of the entry for which to determine existence.
   *
   * @return  <CODE>true</CODE> if the specified entry exists in this backend,
   *          or <CODE>false</CODE> if it does not.
   *
   * @throws  DirectoryException  If a problem occurs while trying to make the
   *                              determination.
   * {@inheritDoc}
   */
  @Override()
  public boolean entryExists(DN entryDN)
         throws DirectoryException
  {
@@ -869,18 +865,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param  entry         The entry to add to this backend.
   * @param  addOperation  The add operation with which the new entry is
   *                       associated.  This may be <CODE>null</CODE> for adds
   *                       performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to add the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -892,19 +879,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param  entryDN          The DN of the entry to remove from this backend.
   * @param  deleteOperation  The delete operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          deletes performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to remove the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -916,19 +893,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param  entry            The new entry to use in place of the existing
   *                          entry with the same DN.
   * @param  modifyOperation  The modify operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modifications performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to replace
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -940,20 +907,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.
   *
   * @param  currentDN          The current DN of the entry to be replaced.
   * @param  entry              The new content to use for the entry.
   * @param  modifyDNOperation  The modify DN operation with which this action
   *                            is associated.  This may be <CODE>null</CODE>
   *                            for modify DN operations performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to perform
   *                              the rename.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                                   ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -966,19 +922,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param  searchOperation  The search operation to be processed.
   *
   * @throws  DirectoryException  If a problem occurs while processing the
   *                              search.
   *
   * @throws  CancelledOperationException  If this backend noticed and reacted
   *                                       to a request to cancel or abandon the
   *                                       add operation.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException, CancelledOperationException
  {
@@ -1115,10 +1061,9 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return  The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -1127,10 +1072,9 @@
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return  The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -1139,12 +1083,9 @@
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF export
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // We will only export the DSE entry itself.
@@ -1156,6 +1097,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -1216,12 +1158,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF import
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
@@ -1233,6 +1172,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -1244,16 +1184,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return  <CODE>true</CODE> if this backend provides any kind of backup
   *          mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -1263,20 +1196,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param  backupConfig       The configuration of the backup for which to
   *                            make the determination.
   * @param  unsupportedReason  A buffer to which a message can be appended
   *                            explaining why the requested backup is not
   *                            supported.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          performing backups with the provided configuration, or
   *          <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -1289,6 +1211,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -1300,17 +1223,9 @@
  /**
   * Removes the specified backup if it is possible to do so.
   *
   * @param  backupDirectory  The backup directory structure with which the
   *                          specified backup is associated.
   * @param  backupID         The backup ID for the backup to be removed.
   *
   * @throws  DirectoryException  If it is not possible to remove the specified
   *                              backup for some reason (e.g., no such backup
   *                              exists or there are other backups that are
   *                              dependent upon it).
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -1323,11 +1238,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -1339,6 +1252,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -53,6 +53,10 @@
import java.util.zip.ZipOutputStream;
import javax.crypto.Mac;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.std.server.SchemaBackendCfg;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.Backend;
import org.opends.server.api.ClientConnection;
@@ -66,6 +70,9 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SchemaConfigManager;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.schema.AttributeTypeSyntax;
import org.opends.server.schema.DITContentRuleSyntax;
import org.opends.server.schema.DITStructureRuleSyntax;
@@ -73,27 +80,53 @@
import org.opends.server.schema.MatchingRuleUseSyntax;
import org.opends.server.schema.NameFormSyntax;
import org.opends.server.schema.ObjectClassSyntax;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.BackupInfo;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.CryptoManager;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DITContentRule;
import org.opends.server.types.DITStructureRule;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.ExistingFileBehavior;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.MatchingRuleUse;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.NameForm;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.ObjectClassType;
import org.opends.server.types.Privilege;
import org.opends.server.types.RDN;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.Schema;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.util.DynamicConstants;
import org.opends.server.util.LDIFException;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.Validator;
import org.opends.server.types.*;
import static org.opends.messages.BackendMessages.*;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.loggers.ErrorLogger.*;
import org.opends.server.loggers.ErrorLogger;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.admin.std.server.SchemaBackendCfg;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.Configuration;
import static org.opends.messages.ConfigMessages.*;
import org.opends.messages.Message;
import org.opends.server.protocols.asn1.ASN1OctetString;
/**
@@ -211,9 +244,10 @@
  //Regular expression used to strip minimum upper bound value from
  //syntax Attribute Type Description. The value looks like: {count}.
  private String stripMinUpperBoundRegEx = "\\{\\d+\\}";
  /**
   * Creates a new backend with the provided information.  All backend
   * implementations must implement a default constructor that use
@@ -227,9 +261,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config)
       throws ConfigException
  {
@@ -353,9 +389,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -496,16 +534,9 @@
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the
   * Directory Server shutdown process or if a backend is disabled with the
   * server online.  It must not return until the backend is closed.
   * <BR><BR>
   * This method may not throw any exceptions.  If any problems are encountered,
   * then they may be logged but the closure should progress as completely as
   * possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    currentConfig.removeSchemaChangeListener(this);
@@ -562,10 +593,9 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return  The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -576,6 +606,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    // There is always only a single entry in this backend.
@@ -585,75 +616,57 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return  <CODE>true</CODE> if the data associated with this backend may be
   *          considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
    {
      return ConditionResult.UNDEFINED;
    }
    else if(ret == 0)
    {
      return ConditionResult.FALSE;
    }
    else
    {
      return ConditionResult.TRUE;
    }
  }
  /**
   * {@inheritDoc}
   */
  public long numSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    boolean found = false;
    for (DN dn : baseDNs)
    {
      if (dn.equals(entryDN))
      {
        found = true;
        break;
      }
    }
    if (! found)
    {
      return -1;
    }
    return 0;
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * Retrieves the requested entry from this backend.
   *
   * @param  entryDN  The distinguished name of the entry to retrieve.
   *
   * @return  The requested entry, or <CODE>null</CODE> if the entry does not
   *          exist.
   *
   * @throws  DirectoryException  If a problem occurs while trying to retrieve
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    return ConditionResult.FALSE;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public long numSubordinates(DN entryDN)
         throws DirectoryException
  {
    return 0L;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -970,20 +983,9 @@
  /**
   * Indicates whether an entry with the specified DN exists in the backend.
   * The default implementation obtains a read lock and calls
   * <CODE>getEntry</CODE>, but backend implementations may override this with a
   * more efficient version that does not require a lock.  The caller is not
   * required to hold any locks on the specified DN.
   *
   * @param  entryDN  The DN of the entry for which to determine existence.
   *
   * @return  <CODE>true</CODE> if the specified entry exists in this backend,
   *          or <CODE>false</CODE> if it does not.
   *
   * @throws  DirectoryException  If a problem occurs while trying to make the
   *                              determination.
   * {@inheritDoc}
   */
  @Override()
  public boolean entryExists(DN entryDN)
         throws DirectoryException
  {
@@ -1003,18 +1005,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param  entry         The entry to add to this backend.
   * @param  addOperation  The add operation with which the new entry is
   *                       associated.  This may be <CODE>null</CODE> for adds
   *                       performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to add the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -1026,19 +1019,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param  entryDN          The DN of the entry to remove from this backend.
   * @param  deleteOperation  The delete operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          deletes performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to remove the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -1050,19 +1033,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param  entry            The new entry to use in place of the existing
   *                          entry with the same DN.
   * @param  modifyOperation  The modify operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modifications performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to replace
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -3914,20 +3887,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.
   *
   * @param  currentDN          The current DN of the entry to be replaced.
   * @param  entry              The new content to use for the entry.
   * @param  modifyDNOperation  The modify DN operation with which this action
   *                            is associated.  This may be <CODE>null</CODE>
   *                            for modify DN operations performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to perform
   *                              the rename.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                                   ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -3940,15 +3902,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param  searchOperation  The search operation to be processed.
   *
   * @throws  DirectoryException  If a problem occurs while processing the
   *                              search.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -4002,10 +3958,9 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return  The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -4014,10 +3969,9 @@
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return  The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -4026,12 +3980,9 @@
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF export
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // We will only export the DSE entry itself.
@@ -4043,6 +3994,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -4103,12 +4055,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF import
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
@@ -4121,6 +4070,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -4132,16 +4082,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return  <CODE>true</CODE> if this backend provides any kind of backup
   *          mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // We do support an online backup mechanism for the schema.
@@ -4151,20 +4094,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param  backupConfig       The configuration of the backup for which to
   *                            make the determination.
   * @param  unsupportedReason  A buffer to which a message can be appended
   *                            explaining why the requested backup is not
   *                            supported.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          performing backups with the provided configuration, or
   *          <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -4180,6 +4112,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -4526,17 +4459,9 @@
  /**
   * Removes the specified backup if it is possible to do so.
   *
   * @param  backupDirectory  The backup directory structure with which the
   *                          specified backup is associated.
   * @param  backupID         The backup ID for the backup to be removed.
   *
   * @throws  DirectoryException  If it is not possible to remove the specified
   *                              backup for some reason (e.g., no such backup
   *                              exists or there are other backups that are
   *                              dependent upon it).
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -4549,11 +4474,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // We will provide a restore, but only for offline operations.
@@ -4565,6 +4488,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -5242,11 +5166,7 @@
  /**
   * Retrieves the DN of the configuration entry with which this alert generator
   * is associated.
   *
   * @return  The DN of the configuration entry with which this alert generator
   *          is associated.
   * {@inheritDoc}
   */
  public DN getComponentEntryDN()
  {
@@ -5256,11 +5176,7 @@
  /**
   * Retrieves the fully-qualified name of the Java class for this alert
   * generator implementation.
   *
   * @return  The fully-qualified name of the Java class for this alert
   *          generator implementation.
   * {@inheritDoc}
   */
  public String getClassName()
  {
@@ -5270,14 +5186,7 @@
  /**
   * Retrieves information about the set of alerts that this generator may
   * produce.  The map returned should be between the notification type for a
   * particular notification and the human-readable description for that
   * notification.  This alert generator must not generate any alerts with types
   * that are not contained in this list.
   *
   * @return  Information about the set of alerts that this generator may
   *          produce.
   * {@inheritDoc}
   */
  public LinkedHashMap<String,String> getAlerts()
  {
@@ -5291,6 +5200,8 @@
    return alerts;
  }
  /**
   * Returns an attribute that has the minimum upper bound value removed from
   * all of its attribute values.
opendj-sdk/opends/src/server/org/opends/server/backends/TrustStoreBackend.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.backends;
@@ -36,11 +36,28 @@
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.FileOutputStream;
import java.util.*;
import java.net.UnknownHostException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Key;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Random;
import java.util.SortedSet;
import javax.naming.ldap.Rdn;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.TrustStoreBackendCfg;
import org.opends.server.api.Backend;
import org.opends.server.config.ConfigException;
import org.opends.server.core.AddOperation;
@@ -49,30 +66,42 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.FilePermission;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.ObjectClass;
import org.opends.server.types.RDN;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.util.CertificateManager;
import org.opends.server.util.Validator;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.types.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.util.Validator;
import org.opends.server.util.CertificateManager;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.TrustStoreBackendCfg;
import org.opends.server.admin.Configuration;
import org.opends.messages.Message;
import static org.opends.messages.BackendMessages.*;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.naming.ldap.Rdn;
import java.security.cert.Certificate;
import java.net.UnknownHostException;
/**
@@ -88,6 +117,8 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The current configuration state.
  private TrustStoreBackendCfg configuration;
@@ -119,6 +150,7 @@
  private CertificateManager certificateManager;
  /**
   * Creates a new backend.  All backend
   * implementations must implement a default constructor that use
@@ -132,9 +164,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config) throws ConfigException
  {
    Validator.ensureNotNull(config);
@@ -143,9 +177,12 @@
    configuration = (TrustStoreBackendCfg)config;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -387,6 +424,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    configuration.addTrustStoreChangeListener(this);
@@ -409,6 +447,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -419,6 +458,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    int numEntries = 1;
@@ -447,6 +487,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
@@ -458,6 +499,19 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -599,6 +653,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -637,6 +692,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -663,6 +719,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -675,6 +732,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                          ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -688,6 +746,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -787,6 +846,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -797,6 +857,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -807,6 +868,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // We do not support LDIF exports.
@@ -818,6 +880,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -830,6 +893,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
@@ -841,6 +905,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -854,6 +919,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -865,6 +931,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -877,6 +944,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
       throws DirectoryException
  {
@@ -890,6 +958,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -904,6 +973,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -915,6 +985,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -924,22 +995,30 @@
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  {
    return ConditionResult.UNDEFINED;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    return ConditionResult.UNDEFINED;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public long numSubordinates(DN entryDN) throws DirectoryException
  {
    return -1;
  }
  /**
   * {@inheritDoc}
   */
@@ -1084,6 +1163,7 @@
  }
  /**
   * {@inheritDoc}
   */
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -41,6 +41,7 @@
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.RunRecoveryException;
import org.opends.server.admin.std.meta.JEIndexCfgDefn;
import org.opends.server.admin.std.server.MonitorProviderCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.MonitorProvider;
@@ -115,10 +116,20 @@
      new ArrayList<MonitorProvider>();
  /**
   * The base DNs defined for this backend instance.
   */
  private DN[] baseDNs;
  /**
   * The controls supported by this backend.
   */
  private static HashSet<String> supportedControls;
  /**
   * The features supported by this backend.
   */
  private static HashSet<String> supportedFeatures = new HashSet<String>(0);
  static
@@ -292,6 +303,10 @@
    Validator.ensureTrue(cfg instanceof JEBackendCfg);
    this.cfg = (JEBackendCfg)cfg;
    Set<DN> dnSet = this.cfg.getBackendBaseDN();
    baseDNs = new DN[dnSet.size()];
    dnSet.toArray(baseDNs);
  }
@@ -299,6 +314,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
      throws ConfigException, InitializationException
  {
@@ -367,15 +383,12 @@
    cfg.addJEChangeListener(this);
  }
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the Directory
   * Server shutdown process or if a backend is disabled with the server online.
   * It must not return until the backend is closed. <BR><BR> This method may
   * not throw any exceptions.  If any problems are encountered, then they may
   * be logged but the closure should progress as completely as possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    // Deregister as a change listener.
@@ -441,14 +454,9 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return <CODE>true</CODE> if the data associated with this backend may be
   *         considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    return true;
@@ -457,12 +465,64 @@
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return <CODE>true</CODE> if this backend provides an LDIF export
   *         mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    try
    {
      EntryContainer ec = rootContainer.getEntryContainer(baseDNs[0]);
      AttributeIndex ai = ec.getAttributeIndex(attributeType);
      if (ai == null)
      {
        return false;
      }
      Set<JEIndexCfgDefn.IndexType> indexTypes =
           ai.getConfiguration().getIndexType();
      switch (indexType)
      {
        case PRESENCE:
          return indexTypes.contains(JEIndexCfgDefn.IndexType.PRESENCE);
        case EQUALITY:
          return indexTypes.contains(JEIndexCfgDefn.IndexType.EQUALITY);
        case SUBSTRING:
        case SUBINITIAL:
        case SUBANY:
        case SUBFINAL:
          return indexTypes.contains(JEIndexCfgDefn.IndexType.SUBSTRING);
        case GREATER_OR_EQUAL:
        case LESS_OR_EQUAL:
          return indexTypes.contains(JEIndexCfgDefn.IndexType.ORDERING);
        case APPROXIMATE:
          return indexTypes.contains(JEIndexCfgDefn.IndexType.APPROXIMATE);
        default:
          return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      return false;
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    return true;
@@ -471,12 +531,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return <CODE>true</CODE> if this backend provides an LDIF import
   *         mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    return true;
@@ -485,16 +542,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return <CODE>true</CODE> if this backend provides any kind of backup
   *         mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    return true;
@@ -503,19 +553,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param backupConfig      The configuration of the backup for which to make
   *                          the determination.
   * @param unsupportedReason A buffer to which a message can be appended
   *                          explaining why the requested backup is not
   *                          supported.
   * @return <CODE>true</CODE> if this backend provides a mechanism for
   *         performing backups with the provided configuration, or
   *         <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -525,11 +565,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return <CODE>true</CODE> if this backend provides a mechanism for
   *         restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    return true;
@@ -538,10 +576,9 @@
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return new HashSet<String>();  //NYI
@@ -550,10 +587,9 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -562,15 +598,12 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    Set<DN> dnSet = cfg.getBackendBaseDN();
    DN[] baseDNs = new DN[dnSet.size()];
    return dnSet.toArray(baseDNs);
    return baseDNs;
  }
@@ -578,6 +611,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    if (rootContainer != null)
@@ -598,10 +632,14 @@
    return -1;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
@@ -618,9 +656,12 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public long numSubordinates(DN entryDN) throws DirectoryException
  {
    EntryContainer ec;
@@ -667,16 +708,12 @@
    }
  }
  /**
   * Retrieves the requested entry from this backend.  Note that the caller must
   * hold a read or write lock on the specified DN.
   *
   * @param entryDN The distinguished name of the entry to retrieve.
   * @return The requested entry, or <CODE>null</CODE> if the entry does not
   *         exist.
   * @throws DirectoryException If a problem occurs while trying to retrieve the
   *                            entry.
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN) throws DirectoryException
  {
    readerBegin();
@@ -728,17 +765,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param entry        The entry to add to this backend.
   * @param addOperation The add operation with which the new entry is
   *                     associated.  This may be <CODE>null</CODE> for adds
   *                     performed internally.
   * @throws DirectoryException If a problem occurs while trying to add the
   *                            entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
      throws DirectoryException
  {
@@ -789,18 +818,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param entryDN         The DN of the entry to remove from this backend.
   * @param deleteOperation The delete operation with which this action is
   *                        associated.  This may be <CODE>null</CODE> for
   *                        deletes performed internally.
   * @throws DirectoryException If a problem occurs while trying to remove the
   *                            entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
      throws DirectoryException
  {
@@ -850,18 +870,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param entry           The new entry to use in place of the existing entry
   *                        with the same DN.
   * @param modifyOperation The modify operation with which this action is
   *                        associated.  This may be <CODE>null</CODE> for
   *                        modifications performed internally.
   * @throws DirectoryException If a problem occurs while trying to replace the
   *                            entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
      throws DirectoryException
  {
@@ -913,23 +924,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.  The caller must hold write locks on both
   * the current DN and the new DN for the entry.
   *
   * @param currentDN         The current DN of the entry to be replaced.
   * @param entry             The new content to use for the entry.
   * @param modifyDNOperation The modify DN operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modify DN operations performed internally.
   * @throws org.opends.server.types.DirectoryException
   *          If a problem occurs while trying to perform the rename.
   * @throws org.opends.server.types.CancelledOperationException
   *          If this backend noticed and reacted to a request to cancel or
   *          abandon the modify DN operation.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                          ModifyDNOperation modifyDNOperation)
      throws DirectoryException, CancelledOperationException
@@ -991,14 +988,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param searchOperation The search operation to be processed.
   * @throws org.opends.server.types.DirectoryException
   *          If a problem occurs while processing the search.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
      throws DirectoryException
  {
@@ -1051,6 +1043,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
      throws DirectoryException
  {
@@ -1160,6 +1153,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
      throws DirectoryException
  {
@@ -1459,6 +1453,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
      throws DirectoryException
  {
@@ -1472,6 +1467,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory, String backupID)
      throws DirectoryException
  {
@@ -1485,6 +1481,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
      throws DirectoryException
  {
@@ -1554,14 +1551,14 @@
    {
      if(rootContainer != null)
      {
        DN[] baseDNs = new DN[newCfg.getBackendBaseDN().size()];
        baseDNs = newCfg.getBackendBaseDN().toArray(baseDNs);
        DN[] newBaseDNs = new DN[newCfg.getBackendBaseDN().size()];
        newBaseDNs = newCfg.getBackendBaseDN().toArray(newBaseDNs);
        // Check for changes to the base DNs.
        for (DN baseDN : cfg.getBackendBaseDN())
        {
          boolean found = false;
          for (DN dn : baseDNs)
          for (DN dn : newBaseDNs)
          {
            if (dn.equals(baseDN))
            {
@@ -1578,7 +1575,7 @@
          }
        }
        for (DN baseDN : baseDNs)
        for (DN baseDN : newBaseDNs)
        {
          if (!rootContainer.getBaseDNs().contains(baseDN))
          {
@@ -1608,6 +1605,8 @@
            }
          }
        }
        baseDNs = newBaseDNs;
      }
      // Put the new configuration in place.
      this.cfg = newCfg;
@@ -1708,12 +1707,8 @@
    return new DirectoryException(resultCode, message, e);
  }
   /**
   * Retrieves the fully-qualified name of the Java class for this alert
   * generator implementation.
   *
   * @return  The fully-qualified name of the Java class for this alert
   *          generator implementation.
  /**
   * {@inheritDoc}
   */
  public String getClassName()
  {
@@ -1721,14 +1716,7 @@
  }
  /**
   * Retrieves information about the set of alerts that this generator may
   * produce.  The map returned should be between the notification type for a
   * particular notification and the human-readable description for that
   * notification.  This alert generator must not generate any alerts with types
   * that are not contained in this list.
   *
   * @return  Information about the set of alerts that this generator may
   *          produce.
   * {@inheritDoc}
   */
  public LinkedHashMap<String,String> getAlerts()
  {
@@ -1740,11 +1728,7 @@
  }
  /**
   * Retrieves the DN of the configuration entry with which this alert generator
   * is associated.
   *
   * @return  The DN of the configuration entry with which this alert generator
   *          is associated.
   * {@inheritDoc}
   */
  public DN getComponentEntryDN()
  {
opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -25,7 +25,6 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.backends.task;
import org.opends.messages.Message;
@@ -37,6 +36,7 @@
import java.util.List;
import java.util.concurrent.locks.Lock;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.TaskBackendCfg;
@@ -50,16 +50,39 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.CancelledOperationException;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.LockManager;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.util.Validator;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class provides an implementation of a Directory Server backend that may
 * be used to execute various kinds of administrative tasks on a one-time or
@@ -74,6 +97,8 @@
   */
  private static final DebugTracer TRACER = getTracer();
  // The current configuration state.
  private TaskBackendCfg currentConfig;
@@ -129,9 +154,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config)
         throws ConfigException
  {
@@ -237,9 +264,12 @@
    currentConfig = cfg;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -273,16 +303,9 @@
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the
   * Directory Server shutdown process or if a backend is disabled with the
   * server online.  It must not return until the backend is closed.
   * <BR><BR>
   * This method may not throw any exceptions.  If any problems are encountered,
   * then they may be logged but the closure should progress as completely as
   * possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    currentConfig.removeTaskChangeListener(this);
@@ -332,10 +355,9 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return  The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -346,6 +368,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    if (taskScheduler != null)
@@ -359,24 +382,35 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return  <CODE>true</CODE> if the data associated with this backend may be
   *          considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
@@ -393,9 +427,12 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public long numSubordinates(DN entryDN) throws DirectoryException
  {
    if (entryDN == null)
@@ -439,17 +476,12 @@
    }
  }
  /**
   * Retrieves the requested entry from this backend.
   *
   * @param  entryDN  The distinguished name of the entry to retrieve.
   *
   * @return  The requested entry, or <CODE>null</CODE> if the entry does not
   *          exist.
   *
   * @throws  DirectoryException  If a problem occurs while trying to retrieve
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -496,18 +528,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param  entry         The entry to add to this backend.
   * @param  addOperation  The add operation with which the new entry is
   *                       associated.  This may be <CODE>null</CODE> for adds
   *                       performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to add the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -553,19 +576,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param  entryDN          The DN of the entry to remove from this backend.
   * @param  deleteOperation  The delete operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          deletes performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to remove the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -635,19 +648,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param  entry            The new entry to use in place of the existing
   *                          entry with the same DN.
   * @param  modifyOperation  The modify operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modifications performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to replace
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -808,20 +811,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.
   *
   * @param  currentDN          The current DN of the entry to be replaced.
   * @param  entry              The new content to use for the entry.
   * @param  modifyDNOperation  The modify DN operation with which this action
   *                            is associated.  This may be <CODE>null</CODE>
   *                            for modify DN operations performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to perform
   *                              the rename.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                                   ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -833,19 +825,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param  searchOperation  The search operation to be processed.
   *
   * @throws  DirectoryException  If a problem occurs while processing the
   *                              search.
   *
   * @throws  CancelledOperationException  If this backend noticed and reacted
   *                                       to a request to cancel or abandon the
   *                                       add operation.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException, CancelledOperationException
  {
@@ -1061,10 +1043,9 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return  The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
@@ -1073,10 +1054,9 @@
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return  The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
@@ -1085,12 +1065,9 @@
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF export
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // LDIF exports are supported.
@@ -1102,6 +1079,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -1111,12 +1089,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF import
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    // This backend does not support LDIF imports.
@@ -1128,6 +1103,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -1139,16 +1115,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return  <CODE>true</CODE> if this backend provides any kind of backup
   *          mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does provide a backup/restore mechanism.
@@ -1158,20 +1127,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param  backupConfig       The configuration of the backup for which to
   *                            make the determination.
   * @param  unsupportedReason  A buffer to which a message can be appended
   *                            explaining why the requested backup is not
   *                            supported.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          performing backups with the provided configuration, or
   *          <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -1184,6 +1142,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -1193,17 +1152,9 @@
  /**
   * Removes the specified backup if it is possible to do so.
   *
   * @param  backupDirectory  The backup directory structure with which the
   *                          specified backup is associated.
   * @param  backupID         The backup ID for the backup to be removed.
   *
   * @throws  DirectoryException  If it is not possible to remove the specified
   *                              backup for some reason (e.g., no such backup
   *                              exists or there are other backups that are
   *                              dependent upon it).
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -1214,11 +1165,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // This backend does provide a backup/restore mechanism.
@@ -1230,6 +1179,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
opendj-sdk/opends/src/server/org/opends/server/core/BackendConfigManager.java
@@ -900,36 +900,6 @@
    }
    // If the backend is a configurable component, then make sure that its
    // configuration is valid.
//    if (backend instanceof ConfigurableComponent)
//    {
//      ConfigurableComponent cc = (ConfigurableComponent) backend;
//      LinkedList<String> errorMessages = new LinkedList<String>();
//      if (! cc.hasAcceptableConfiguration(configEntry, errorMessages))
//      {
//        if (errorMessages.isEmpty())
//        {
//          int message = ERR_CONFIG_BACKEND_UNACCEPTABLE_CONFIG.get();
//          unacceptableReason.add(getMessage(msgID,
//                                            String.valueOf(configEntryDN)));
//        }
//        else
//        {
//          Iterator<String> iterator = errorMessages.iterator();
//          unacceptableReason.add(iterator.next());
//          while (iterator.hasNext())
//          {
//            unacceptableReason.add("  ");
//            unacceptableReason.add(iterator.next());
//          }
//        }
//
//        return false;
//      }
//    }
    // Make sure that all of the base DNs are acceptable for use in the server.
    BaseDnRegistry reg = DirectoryServer.copyBaseDnRegistry();
    for (DN baseDN : baseDNs)
opendj-sdk/opends/src/server/org/opends/server/core/GroupManager.java
@@ -25,7 +25,6 @@
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -36,7 +35,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.server.workflowelement.localbackend.*;
import org.opends.messages.Message;
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.server.ConfigurationAddListener;
import org.opends.server.admin.server.ConfigurationChangeListener;
@@ -59,8 +58,6 @@
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultEntry;
@@ -70,11 +67,13 @@
import org.opends.server.types.operation.PostResponseDeleteOperation;
import org.opends.server.types.operation.PostResponseModifyOperation;
import org.opends.server.types.operation.PostResponseModifyDNOperation;
import org.opends.server.workflowelement.localbackend.
            LocalBackendSearchOperation;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -584,12 +583,18 @@
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    for (Group groupImplementation : groupImplementations.values())
    for (DN configEntryDN : groupImplementations.keySet())
    {
      SearchFilter filter;
      Group groupImplementation = groupImplementations.get(configEntryDN);
      try
      {
        filter = groupImplementation.getGroupDefinitionFilter();
        if (! backend.isIndexed(filter))
        {
          logError(WARN_GROUP_FILTER_NOT_INDEXED.get(String.valueOf(filter),
                        String.valueOf(configEntryDN), backend.getBackendID()));
        }
      }
      catch (Exception e)
      {
opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
@@ -56,6 +56,8 @@
import javax.crypto.Mac;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.admin.Configuration;
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ConfigAddListener;
@@ -70,13 +72,34 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.schema.GeneralizedTimeSyntax;
import org.opends.server.tools.LDIFModify;
import org.opends.server.types.AttributeType;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.BackupDirectory;
import org.opends.server.types.BackupInfo;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.CryptoManager;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryEnvironmentConfig;
import org.opends.server.types.*;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.ExistingFileBehavior;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
import org.opends.server.types.Modification;
import org.opends.server.types.Privilege;
import org.opends.server.types.RestoreConfig;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.util.DynamicConstants;
import org.opends.server.util.LDIFException;
import org.opends.server.util.LDIFReader;
@@ -87,12 +110,9 @@
import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.messages.ConfigMessages.*;
import org.opends.messages.MessageBuilder;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.admin.Configuration;
/**
@@ -108,6 +128,8 @@
   */
  private static final DebugTracer TRACER = getTracer();
  /**
   * The fully-qualified name of this class.
   */
@@ -117,6 +139,22 @@
  /**
   * The set of supported control OIDs for this backend.
   */
  private static final HashSet<String> SUPPORTED_CONTROLS =
                            new HashSet<String>(0);
  /**
   * The set of supported feature OIDs for this backend.
   */
  private static final HashSet<String> SUPPORTED_FEATURES =
                            new HashSet<String>(0);
  /**
   * The privilege array containing both the CONFIG_READ and CONFIG_WRITE
   * privileges.
   */
@@ -177,20 +215,9 @@
  /**
   * Bootstraps this configuration handler using the information in the provided
   * configuration file.  Depending on this configuration handler
   * implementation, the provided file may contain either the entire server
   * configuration or information that is needed to access the configuration in
   * some other location or repository.
   *
   * @param  configFile   The path to the file to use to initialize this
   *                      configuration handler.
   * @param  checkSchema  Indicates whether to perform schema checking on the
   *                      configuration data.
   *
   * @throws  InitializationException  If a problem occurs while attempting to
   *                                   initialize this configuration handler.
   * {@inheritDoc}
   */
  @Override()
  public void initializeConfigHandler(String configFile, boolean checkSchema)
         throws InitializationException
  {
@@ -1015,12 +1042,9 @@
  /**
   * Finalizes this configuration handler so that it will release any resources
   * associated with it so that it will no longer be used.  This will be called
   * when the Directory Server is shutting down, as well as in the startup
   * process once the schema has been read so that the configuration can be
   * re-read using the updated schema.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeConfigHandler()
  {
    try
@@ -1039,33 +1063,20 @@
  /**
   * Performs any necessary work to finalize this backend, including closing any
   * underlying databases or connections and deregistering any suffixes that it
   * manages with the Directory Server.  This may be called during the
   * Directory Server shutdown process or if a backend is disabled with the
   * server online.  It must not return until the backend is closed.
   * <BR><BR>
   * This method may not throw any exceptions.  If any problems are encountered,
   * then they may be logged but the closure should progress as completely as
   * possible.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeBackend()
  {
    // NYI
    // No implementation is required.
  }
  /**
   * Retrieves the entry that is at the root of the Directory Server
   * configuration.
   *
   * @return  The entry that is at the root of the Directory Server
   *          configuration.
   *
   * @throws  ConfigException  If a problem occurs while interacting with the
   *                           configuration.
   * {@inheritDoc}
   */
  @Override()
  public ConfigEntry getConfigRootEntry()
         throws ConfigException
  {
@@ -1075,16 +1086,9 @@
  /**
   * Retrieves the requested entry from the configuration.
   *
   * @param  entryDN  The distinguished name of the configuration entry to
   *                  retrieve.
   *
   * @return  The requested configuration entry.
   *
   * @throws  ConfigException  If a problem occurs while interacting with the
   *                           configuration.
   * {@inheritDoc}
   */
  @Override()
  public ConfigEntry getConfigEntry(DN entryDN)
         throws ConfigException
  {
@@ -1094,27 +1098,32 @@
  /**
   * Retrieves the absolute path of the Directory Server instance root.
   *
   * @return  The absolute path of the Directory Server instance root.
   * {@inheritDoc}
   */
  @Override()
  public String getServerRoot()
  {
    return serverRoot;
  }
  /**
   * {@inheritDoc}
   */
  public void configureBackend(Configuration cfg) throws ConfigException
  {
    // No action is required.
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration cfg)
         throws ConfigException
  {
    // No action is required.
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void initializeBackend()
         throws ConfigException, InitializationException
  {
@@ -1125,10 +1134,9 @@
  /**
   * Retrieves the set of base-level DNs that may be used within this backend.
   *
   * @return  The set of base-level DNs that may be used within this backend.
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
@@ -1139,6 +1147,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public long getEntryCount()
  {
    return configEntries.size();
@@ -1147,24 +1156,35 @@
  /**
   * Indicates whether the data associated with this backend may be considered
   * local (i.e., in a repository managed by the Directory Server) rather than
   * remote (i.e., in an external repository accessed by the Directory Server
   * but managed through some other means).
   *
   * @return  <CODE>true</CODE> if the data associated with this backend may be
   *          considered local, or <CODE>false</CODE> if it is remote.
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    // The configuration information will always be local.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
  {
    long ret = numSubordinates(entryDN);
    if(ret < 0)
@@ -1181,10 +1201,14 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  public long numSubordinates(DN entryDN) throws DirectoryException
  @Override()
  public long numSubordinates(DN entryDN)
         throws DirectoryException
  {
    ConfigEntry baseEntry = configEntries.get(entryDN);
    if (baseEntry == null)
@@ -1195,17 +1219,12 @@
    return baseEntry.getChildren().size();
  }
  /**
   * Retrieves the requested entry from this backend.
   *
   * @param  entryDN  The distinguished name of the entry to retrieve.
   *
   * @return  The requested entry, or <CODE>null</CODE> if the entry does not
   *          exist.
   *
   * @throws  DirectoryException  If a problem occurs while trying to retrieve
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public Entry getEntry(DN entryDN)
         throws DirectoryException
  {
@@ -1221,20 +1240,9 @@
  /**
   * Indicates whether an entry with the specified DN exists in the backend.
   * The default implementation obtains a read lock and calls
   * <CODE>getEntry</CODE>, but backend implementations may override this with a
   * more efficient version that does not require a lock.  The caller is not
   * required to hold any locks on the specified DN.
   *
   * @param  entryDN  The DN of the entry for which to determine existence.
   *
   * @return  <CODE>true</CODE> if the specified entry exists in this backend,
   *          or <CODE>false</CODE> if it does not.
   *
   * @throws  DirectoryException  If a problem occurs while trying to make the
   *                              determination.
   * {@inheritDoc}
   */
  @Override()
  public boolean entryExists(DN entryDN)
         throws DirectoryException
  {
@@ -1244,18 +1252,9 @@
  /**
   * Adds the provided entry to this backend.  This method must ensure that the
   * entry is appropriate for the backend and that no entry already exists with
   * the same DN.
   *
   * @param  entry         The entry to add to this backend.
   * @param  addOperation  The add operation with which the new entry is
   *                       associated.  This may be <CODE>null</CODE> for adds
   *                       performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to add the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -1419,19 +1418,9 @@
  /**
   * Removes the specified entry from this backend.  This method must ensure
   * that the entry exists and that it does not have any subordinate entries
   * (unless the backend supports a subtree delete operation and the client
   * included the appropriate information in the request).
   *
   * @param  entryDN          The DN of the entry to remove from this backend.
   * @param  deleteOperation  The delete operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          deletes performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to remove the
   *                              entry.
   * {@inheritDoc}
   */
  @Override()
  public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
         throws DirectoryException
  {
@@ -1589,19 +1578,9 @@
  /**
   * Replaces the specified entry with the provided entry in this backend.  The
   * backend must ensure that an entry already exists with the same DN as the
   * provided entry.
   *
   * @param  entry            The new entry to use in place of the existing
   *                          entry with the same DN.
   * @param  modifyOperation  The modify operation with which this action is
   *                          associated.  This may be <CODE>null</CODE> for
   *                          modifications performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to replace
   *                              the entry.
   * {@inheritDoc}
   */
  @Override()
  public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
         throws DirectoryException
  {
@@ -1765,20 +1744,9 @@
  /**
   * Moves and/or renames the provided entry in this backend, altering any
   * subordinate entries as necessary.  This must ensure that an entry already
   * exists with the provided current DN, and that no entry exists with the
   * target DN of the provided entry.
   *
   * @param  currentDN          The current DN of the entry to be replaced.
   * @param  entry              The new content to use for the entry.
   * @param  modifyDNOperation  The modify DN operation with which this action
   *                            is associated.  This may be <CODE>null</CODE>
   *                            for modify DN operations performed internally.
   *
   * @throws  DirectoryException  If a problem occurs while trying to perform
   *                              the rename.
   * {@inheritDoc}
   */
  @Override()
  public void renameEntry(DN currentDN, Entry entry,
                          ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -1808,15 +1776,9 @@
  /**
   * Processes the specified search in this backend.  Matching entries should be
   * provided back to the core server using the
   * <CODE>SearchOperation.returnEntry</CODE> method.
   *
   * @param  searchOperation  The search operation to be processed.
   *
   * @throws  DirectoryException  If a problem occurs while processing the
   *                              search.
   * {@inheritDoc}
   */
  @Override()
  public void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -1964,13 +1926,9 @@
  /**
   * Writes an updated version of the configuration file to disk.  This will
   * archive the previous configuration in a ZIP file before overwriting the
   * main config file.
   *
   * @throws  DirectoryException  If a problem is encountered while writing the
   *                              updated configuration.
   * {@inheritDoc}
   */
  @Override()
  public void writeUpdatedConfig()
         throws DirectoryException
  {
@@ -2280,6 +2238,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void writeSuccessfulStartupConfig()
  {
    if (useLastKnownGoodConfig)
@@ -2457,38 +2416,31 @@
  /**
   * Retrieves the OIDs of the controls that may be supported by this backend.
   *
   * @return  The OIDs of the controls that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    // NYI
    return null;
    return SUPPORTED_CONTROLS;
  }
  /**
   * Retrieves the OIDs of the features that may be supported by this backend.
   *
   * @return  The OIDs of the features that may be supported by this backend.
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    // NYI
    return null;
    return SUPPORTED_FEATURES;
  }
  /**
   * Indicates whether this backend provides a mechanism to export the data it
   * contains to an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF export
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    // TODO We would need export-ldif to initialize this backend.
@@ -2500,6 +2452,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -2509,6 +2462,14 @@
  /**
   * Writes the current configuration to LDIF with the provided export
   * configuration.
   *
   * @param  exportConfig  The configuration to use for the export.
   *
   * @throws  DirectoryException  If a problem occurs while writing the LDIF.
   */
  private void writeLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -2598,12 +2559,9 @@
  /**
   * Indicates whether this backend provides a mechanism to import its data from
   * an LDIF file.
   *
   * @return  <CODE>true</CODE> if this backend provides an LDIF import
   *          mechanism, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    return false;
@@ -2614,6 +2572,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -2624,16 +2583,9 @@
  /**
   * Indicates whether this backend provides a backup mechanism of any kind.
   * This method is used by the backup process when backing up all backends to
   * determine whether this backend is one that should be skipped.  It should
   * only return <CODE>true</CODE> for backends that it is not possible to
   * archive directly (e.g., those that don't store their data locally, but
   * rather pass through requests to some other repository).
   *
   * @return  <CODE>true</CODE> if this backend provides any kind of backup
   *          mechanism, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // We do support an online backup mechanism for the configuration.
@@ -2643,20 +2595,9 @@
  /**
   * Indicates whether this backend provides a mechanism to perform a backup of
   * its contents in a form that can be restored later, based on the provided
   * configuration.
   *
   * @param  backupConfig       The configuration of the backup for which to
   *                            make the determination.
   * @param  unsupportedReason  A buffer to which a message can be appended
   *                            explaining why the requested backup is not
   *                            supported.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          performing backups with the provided configuration, or
   *          <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
@@ -2672,6 +2613,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -3061,17 +3003,9 @@
  /**
   * Removes the specified backup if it is possible to do so.
   *
   * @param  backupDirectory  The backup directory structure with which the
   *                          specified backup is associated.
   * @param  backupID         The backup ID for the backup to be removed.
   *
   * @throws  DirectoryException  If it is not possible to remove the specified
   *                              backup for some reason (e.g., no such backup
   *                              exists or there are other backups that are
   *                              dependent upon it).
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -3082,11 +3016,9 @@
  /**
   * Indicates whether this backend provides a mechanism to restore a backup.
   *
   * @return  <CODE>true</CODE> if this backend provides a mechanism for
   *          restoring backups, or <CODE>false</CODE> if not.
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    // We will provide a restore, but only for offline operations.
@@ -3098,6 +3030,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -3590,11 +3523,7 @@
  /**
   * Retrieves the DN of the configuration entry with which this alert generator
   * is associated.
   *
   * @return  The DN of the configuration entry with which this alert generator
   *          is associated.
   * {@inheritDoc}
   */
  public DN getComponentEntryDN()
  {
@@ -3604,11 +3533,7 @@
  /**
   * Retrieves the fully-qualified name of the Java class for this alert
   * generator implementation.
   *
   * @return  The fully-qualified name of the Java class for this alert
   *          generator implementation.
   * {@inheritDoc}
   */
  public String getClassName()
  {
@@ -3618,14 +3543,7 @@
  /**
   * Retrieves information about the set of alerts that this generator may
   * produce.  The map returned should be between the notification type for a
   * particular notification and the human-readable description for that
   * notification.  This alert generator must not generate any alerts with types
   * that are not contained in this list.
   *
   * @return  Information about the set of alerts that this generator may
   *          produce.
   * {@inheritDoc}
   */
  public LinkedHashMap<String,String> getAlerts()
  {
opendj-sdk/opends/src/server/org/opends/server/plugins/ReferentialIntegrityPlugin.java
@@ -26,33 +26,69 @@
 */
package org.opends.server.plugins;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.ReferentialIntegrityPluginCfg;
import org.opends.server.admin.std.server.PluginCfg;
import org.opends.server.admin.std.meta.PluginCfgDefn;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.api.plugin.*;
import org.opends.server.api.Backend;
import org.opends.server.api.DirectoryThread;
import org.opends.server.api.ServerShutdownListener;
import org.opends.server.api.plugin.DirectoryServerPlugin;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.api.plugin.PostOperationPluginResult;
import org.opends.server.api.plugin.SubordinateModifyDNPluginResult;
import org.opends.server.config.ConfigException;
import org.opends.server.types.*;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
import org.opends.server.types.operation.SubordinateModifyDNOperation;
import org.opends.server.types.operation.PostOperationModifyDNOperation;
import org.opends.server.types.operation.PostOperationDeleteOperation;
import org.opends.messages.Message;
import static org.opends.messages.PluginMessages.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.schema.SchemaConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.*;
import java.io.*;
/**
 * This class implements a Directory Server post operation plugin that performs
@@ -62,22 +98,23 @@
 * base DNs to search for entries that might need referential integrity
 * processing. If none of these base DNs are specified in the configuration,
 * then the public naming contexts are used as the base DNs by default.
 *
 * <BR><BR>
 * The plugin also has an option to process changes in background using
 * a thread that wakes up periodically looking for change records in a log
 * file.
 *
 **/
 */
public class ReferentialIntegrityPlugin
        extends DirectoryServerPlugin<ReferentialIntegrityPluginCfg>
        implements ConfigurationChangeListener<ReferentialIntegrityPluginCfg>,
        ServerShutdownListener {
                   ServerShutdownListener
{
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  //Current plugin configuration.
  private ReferentialIntegrityPluginCfg currentConfiguration;
@@ -115,7 +152,6 @@
   * the old entry DNs and the new entry DNs related to a modify DN rename to
   * new superior operation.
   */
  public static final String MODIFYDN_DNS="modifyDNs";
  //The buffered reader that is used to read the log file by the background
@@ -126,83 +162,135 @@
  //when the plugin is in background processing mode.
  private BufferedWriter writer;
  /**
   * {@inheritDoc}
   */
  public final void initializePlugin(Set<PluginType> pluginTypes,
                                     ReferentialIntegrityPluginCfg pluginCfg)
          throws ConfigException {
         throws ConfigException
  {
    pluginCfg.addReferentialIntegrityChangeListener(this);
    currentConfiguration = pluginCfg;
    for (PluginType t : pluginTypes)
      switch (t)  {
    {
      switch (t)
      {
        case POST_OPERATION_DELETE:
        case POST_OPERATION_MODIFY_DN:
        case SUBORDINATE_MODIFY_DN:
          // These are acceptable.
          break;
        default:
          throw new
             ConfigException(ERR_PLUGIN_REFERINT_INVALID_PLUGIN_TYPE.
                             get(t.toString()));
             ConfigException(ERR_PLUGIN_REFERENT_INVALID_PLUGIN_TYPE.get(
                                  t.toString()));
      }
    for(DN baseDN : pluginCfg.getReferentialIntegrityBaseDN())
      baseDNs.add(baseDN);
    //Iterate through attributes and check that each has a valid syntax
    //before adding it to the list.
    for(AttributeType type : pluginCfg.getReferentialIntegrityAttributeType()) {
      if(!isAttributeSyntaxValid(type))
        throw new
          ConfigException(ERR_PLUGIN_REFERENT_INVALID_ATTRIBUTE_SYNTAX.
                          get(type.getNameOrOID(),
                              type.getSyntax().getSyntaxName()));
    }
    Set<DN> cfgBaseDNs = pluginCfg.getReferentialIntegrityBaseDN();
    if ((cfgBaseDNs == null) || cfgBaseDNs.isEmpty())
    {
      cfgBaseDNs = DirectoryServer.getPublicNamingContexts().keySet();
    }
    else
    {
      baseDNs.addAll(cfgBaseDNs);
    }
    // Iterate through all of the defined attribute types and ensure that they
    // have acceptable syntaxes and that they are indexed for equality below all
    // base DNs.
    for (AttributeType type : pluginCfg.getReferentialIntegrityAttributeType())
    {
      if (! isAttributeSyntaxValid(type))
      {
        throw new ConfigException(
                       ERR_PLUGIN_REFERENT_INVALID_ATTRIBUTE_SYNTAX.get(
                            type.getNameOrOID(),
                             type.getSyntax().getSyntaxName()));
      }
      for (DN baseDN : cfgBaseDNs)
      {
        Backend b = DirectoryServer.getBackend(baseDN);
        if ((b != null) && (! b.isIndexed(type, IndexType.EQUALITY)))
        {
          throw new ConfigException(ERR_PLUGIN_REFERENT_ATTR_UNINDEXED.get(
                                         pluginCfg.dn().toString(),
                                         type.getNameOrOID(),
                                         b.getBackendID()));
        }
      }
      attributeTypes.add(type);
    }
    //Set up log file. Note: t is not allowed to change once the plugin
    //is active.
    // Set up log file. Note: it is not allowed to change once the plugin is
    // active.
    setUpLogFile(pluginCfg.getReferentialIntegrityLogFile());
    interval=pluginCfg.getReferentialIntegrityUpdateInterval();
    //Set up background processing if interval > 0.
    if(interval > 0)
    {
      setUpBackGroundProcessing();
    }
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(
          ReferentialIntegrityPluginCfg newConfiguration) {
    ResultCode resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
          ReferentialIntegrityPluginCfg newConfiguration)
  {
    ResultCode         resultCode          = ResultCode.SUCCESS;
    boolean            adminActionRequired = false;
    ArrayList<Message> messages            = new ArrayList<Message>();
    LinkedHashSet<DN> newConfiguredBaseDNs = new LinkedHashSet<DN>();
    //Load base DNs from new configuration.
    LinkedHashSet<DN> newConfiguredBaseDNs = new LinkedHashSet<DN>();
    for(DN baseDN : newConfiguration.getReferentialIntegrityBaseDN())
    {
      newConfiguredBaseDNs.add(baseDN);
    }
    //Load attribute types from new configuration.
    LinkedHashSet<AttributeType> newAttributeTypes =
            new LinkedHashSet<AttributeType>();
    //Load attribute types from new configuration.
    for(AttributeType type :
            newConfiguration.getReferentialIntegrityAttributeType())
    {
      newAttributeTypes.add(type);
    String newLogFileName=newConfiguration.getReferentialIntegrityLogFile();
    }
    //User is not allowed to change the logfile name, append a message that the
    //server needs restarting for change to take effect.
    if(!logFileName.equals(newLogFileName)) {
    String newLogFileName=newConfiguration.getReferentialIntegrityLogFile();
    if(!logFileName.equals(newLogFileName))
    {
      adminActionRequired=true;
      messages.add(INFO_PLUGIN_REFERENT_LOGFILE_CHANGE_REQUIRES_RESTART.
                   get(logFileName, newLogFileName));
      messages.add(
           INFO_PLUGIN_REFERENT_LOGFILE_CHANGE_REQUIRES_RESTART.get(logFileName,
                newLogFileName));
    }
    //Switch to the new lists.
    baseDNs = newConfiguredBaseDNs;
    attributeTypes = newAttributeTypes;
    long newInterval=newConfiguration.getReferentialIntegrityUpdateInterval();
    //If the plugin is enabled and the interval has changed, process that
    //change. The change might start or stop the background processing thread.
    long newInterval=newConfiguration.getReferentialIntegrityUpdateInterval();
    if(newConfiguration.isEnabled() && newInterval != interval)
      processIntervalChange(newInterval, messages);
    currentConfiguration = newConfiguration;
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
@@ -216,7 +304,7 @@
                                           List<Message> unacceptableReasons)
  {
    ReferentialIntegrityPluginCfg cfg =
                       (ReferentialIntegrityPluginCfg) configuration;
         (ReferentialIntegrityPluginCfg) configuration;
    return isConfigurationChangeAcceptable(cfg, unacceptableReasons);
  }
@@ -226,86 +314,119 @@
   */
  public boolean isConfigurationChangeAcceptable(
          ReferentialIntegrityPluginCfg configuration,
          List<Message> unacceptableReasons) {
          List<Message> unacceptableReasons)
  {
    boolean configAcceptable = true;
    for (PluginCfgDefn.PluginType pluginType : configuration.getPluginType()) {
      switch (pluginType)  {
    for (PluginCfgDefn.PluginType pluginType : configuration.getPluginType())
    {
      switch (pluginType)
      {
        case POSTOPERATIONDELETE:
        case POSTOPERATIONMODIFYDN:
        case SUBORDINATEMODIFYDN:
          // These are acceptable.
          break;
        default:
          unacceptableReasons.add(ERR_PLUGIN_REFERINT_INVALID_PLUGIN_TYPE.
          unacceptableReasons.add(ERR_PLUGIN_REFERENT_INVALID_PLUGIN_TYPE.
                                  get(pluginType.toString()));
          configAcceptable = false;
      }
      if(!configAcceptable)
           break;
    }
    // Iterate through the set of base DNs that we will check and ensure that
    // the corresponding backend is indexed appropriately.
    Set<DN> cfgBaseDNs = configuration.getReferentialIntegrityBaseDN();
    if ((cfgBaseDNs == null) || cfgBaseDNs.isEmpty())
    {
      cfgBaseDNs = DirectoryServer.getPublicNamingContexts().keySet();
    }
    else
    {
      baseDNs.addAll(cfgBaseDNs);
    }
    //Iterate through attributes and check that each has a valid syntax
    for(AttributeType type :
            configuration.getReferentialIntegrityAttributeType())
      if(!isAttributeSyntaxValid(type)) {
        unacceptableReasons.add(ERR_PLUGIN_REFERENT_INVALID_ATTRIBUTE_SYNTAX.
                                get(type.getNameOrOID(),
                                    type.getSyntax().getSyntaxName()));
    for (AttributeType type :
         configuration.getReferentialIntegrityAttributeType())
    {
      if (!isAttributeSyntaxValid(type))
      {
        unacceptableReasons.add(
             ERR_PLUGIN_REFERENT_INVALID_ATTRIBUTE_SYNTAX.get(
                  type.getNameOrOID(), type.getSyntax().getSyntaxName()));
        configAcceptable = false;
        break;
      }
      for (DN baseDN : cfgBaseDNs)
      {
        Backend b = DirectoryServer.getBackend(baseDN);
        if ((b != null) && (! b.isIndexed(type, IndexType.EQUALITY)))
        {
          unacceptableReasons.add(ERR_PLUGIN_REFERENT_ATTR_UNINDEXED.get(
                                       configuration.dn().toString(),
                                       type.getNameOrOID(), b.getBackendID()));
          configAcceptable = false;
        }
      }
    }
    return configAcceptable;
  }
  /**
   * {@inheritDoc}
   */
  @SuppressWarnings("unchecked")
  public PostOperationPluginResult
         doPostOperation(PostOperationModifyDNOperation
          modifyDNOperation) {
          modifyDNOperation)
  {
    // If the operation itself failed, then we don't need to do anything because
    // nothing changed.
    if (modifyDNOperation.getResultCode() != ResultCode.SUCCESS)
    {
      return PostOperationPluginResult.SUCCESS;
    }
    //If the core operation failed, then append an error message and skip
    //processing.
    if(modifyDNOperation.getResultCode() != ResultCode.SUCCESS)
         return  PostOperationPluginResult.SUCCESS;
 //     modifyDNOperation.appendErrorMessage(
 ////             ERR_PLUGIN_REFERENT_SKIP_MODIFY_DN_PROCESSING.
  //                    get(modifyDNOperation.getEntryDN().toString()));
    else if(modifyDNOperation.getNewSuperior() == null) {
      //Core operation was a rename entry.
    if (modifyDNOperation.getNewSuperior() == null)
    {
      // The entry was simply renamed below the same parent.
      DN oldEntryDN=modifyDNOperation.getOriginalEntry().getDN();
      DN newEntryDN=modifyDNOperation.getUpdatedEntry().getDN();
      Map<DN,DN> modDNmap=new LinkedHashMap<DN,DN>();
      modDNmap.put(oldEntryDN, newEntryDN);
      processModifyDN(modDNmap,(interval != 0));
    } else {
      //Core operation is a move to a new superior, use the save map of
      //old DNs and new DNs from the operation attachment.
      //
      //This cast causes an unchecked cast warning, suppress it since the
      //cast is ok.
    }
    else
    {
      // The entry was moved below a new parent.  Use the saved map of old DNs
      // and new DNs from the operation attachment.
      Map<DN,DN> modDNmap =
              (Map<DN, DN>) modifyDNOperation.getAttachment(MODIFYDN_DNS);
           (Map<DN, DN>) modifyDNOperation.getAttachment(MODIFYDN_DNS);
      processModifyDN(modDNmap, (interval != 0));
    }
    return  PostOperationPluginResult.SUCCESS;
    return PostOperationPluginResult.SUCCESS;
  }
  /**
   * {@inheritDoc}
   */
  public PostOperationPluginResult
  doPostOperation(PostOperationDeleteOperation deleteOperation) {
    //If the core operation failed, then append an error message and skip
    //processing.
    if(deleteOperation.getResultCode() != ResultCode.SUCCESS)
       return  PostOperationPluginResult.SUCCESS;
 //     deleteOperation.appendErrorMessage(
 //             ERR_PLUGIN_REFERENT_SKIP_DELETE_PROCESSING.
  //                    get(deleteOperation.getEntryDN().toString()));
    else
      processDelete(deleteOperation.getEntryDN(), (interval != 0));
  public PostOperationPluginResult doPostOperation(
              PostOperationDeleteOperation deleteOperation)
  {
    // If the operation itself failed, then we don't need to do anything because
    // nothing changed.
    if (deleteOperation.getResultCode() != ResultCode.SUCCESS)
    {
      return PostOperationPluginResult.SUCCESS;
    }
    processDelete(deleteOperation.getEntryDN(), (interval != 0));
    return  PostOperationPluginResult.SUCCESS;
  }
@@ -315,12 +436,14 @@
  @SuppressWarnings("unchecked")
  public SubordinateModifyDNPluginResult processSubordinateModifyDN(
          SubordinateModifyDNOperation modifyDNOperation, Entry oldEntry,
          Entry newEntry, List<Modification> modifications) {
          Entry newEntry, List<Modification> modifications)
  {
    //This cast gives an unchecked cast warning, suppress it since the cast
    //is ok.
    Map<DN,DN>modDNmap=
            (Map<DN, DN>) modifyDNOperation.getAttachment(MODIFYDN_DNS);
    if(modDNmap == null) {
         (Map<DN, DN>) modifyDNOperation.getAttachment(MODIFYDN_DNS);
    if(modDNmap == null)
    {
      //First time through, create the map and set it in the operation
      //attachment.
      modDNmap=new LinkedHashMap<DN,DN>();
@@ -340,7 +463,8 @@
   * @return  Returns <code>true</code> if the attribute has a valid syntax.
   *
   */
  private boolean isAttributeSyntaxValid(AttributeType attribute) {
  private boolean isAttributeSyntaxValid(AttributeType attribute)
  {
    return (attribute.getSyntaxOID().equals(SYNTAX_DN_OID) ||
            attribute.getSyntaxOID().equals(SYNTAX_NAME_AND_OPTIONAL_UID_OID));
  }
@@ -403,13 +527,21 @@
   *            a later time.
   *
   */
  private void processModifyDN(Map<DN, DN> modDNMap, boolean log) {
    if(modDNMap != null) {
  private void processModifyDN(Map<DN, DN> modDNMap, boolean log)
  {
    if(modDNMap != null)
    {
      if(log)
      {
        writeLog(modDNMap);
      }
      else
      {
        for(DN baseDN : getBaseDNsToSearch())
        {
          doBaseDN(baseDN, modDNMap);
        }
      }
    }
  }
@@ -434,12 +566,19 @@
   *            a later time.
   *
   */
  private void processDelete(DN entryDN, boolean log) {
  private void processDelete(DN entryDN, boolean log)
  {
    if(log)
    {
      writeLog(entryDN);
    }
    else
    {
      for(DN baseDN : getBaseDNsToSearch())
      {
        searchBaseDN(baseDN, entryDN, null);
      }
    }
  }
  /**
@@ -453,9 +592,12 @@
   * @param newEntryDN The entry DN after the modify DN operation.
   *
   */
  private void processModifyDN(DN oldEntryDN, DN newEntryDN) {
  private void processModifyDN(DN oldEntryDN, DN newEntryDN)
  {
    for(DN baseDN : getBaseDNsToSearch())
    {
      searchBaseDN(baseDN, oldEntryDN, newEntryDN);
    }
  }
  /**
@@ -466,12 +608,16 @@
   * @return A set of DNs to use in the reference searches.
   *
   */
  private Set<DN>
  getBaseDNsToSearch() {
  private Set<DN> getBaseDNsToSearch()
  {
    if(baseDNs.isEmpty())
    {
      return DirectoryServer.getPublicNamingContexts().keySet();
    }
    else
    {
      return baseDNs;
    }
  }
  /**
@@ -488,38 +634,44 @@
   *                   if the original operation was a delete.
   *
   */
  private void
  searchBaseDN(DN baseDN, DN oldEntryDN, DN newEntryDN) {
    HashSet<SearchFilter> componentFilters=new HashSet<SearchFilter>();
  private void searchBaseDN(DN baseDN, DN oldEntryDN, DN newEntryDN)
  {
    //Build an equality search with all of the configured attribute types
    //and the old entry DN.
    HashSet<SearchFilter> componentFilters=new HashSet<SearchFilter>();
    for(AttributeType attributeType : attributeTypes)
    {
      componentFilters.add(SearchFilter.createEqualityFilter(attributeType,
              new AttributeValue(attributeType, oldEntryDN.toString())));
    }
    InternalClientConnection conn =
            InternalClientConnection.getRootConnection();
         InternalClientConnection.getRootConnection();
    InternalSearchOperation operation = conn.processSearch(baseDN,
            SearchScope.WHOLE_SUBTREE,
            DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false,
            SearchFilter.createORFilter(componentFilters),
            null);
    switch (operation.getResultCode()) {
         SearchScope.WHOLE_SUBTREE, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0,
         false, SearchFilter.createORFilter(componentFilters), null);
    switch (operation.getResultCode())
    {
      case SUCCESS:
        break;
      case NO_SUCH_OBJECT:
        Message message=
                INFO_PLUGIN_REFERENT_SEARCH_NO_SUCH_OBJECT.
                                                         get(baseDN.toString());
        logError(message);
        logError(INFO_PLUGIN_REFERENT_SEARCH_NO_SUCH_OBJECT.get(
                      baseDN.toString()));
        return;
      default:
        Message message1 = ERR_PLUGIN_REFERENT_SEARCH_FAILED.
                get(String.valueOf(operation.getErrorMessage()));
        logError(message1);
        return;
    }
    for (SearchResultEntry entry : operation.getSearchEntries())
    {
      deleteAddAttributesEntry(entry, oldEntryDN, newEntryDN);
    }
  }
  /**
@@ -533,10 +685,12 @@
   * @param modifyDNmap The map containing the modify DN old and new entry DNs.
   *
   */
  private void
  doBaseDN(DN baseDN, Map<DN,DN> modifyDNmap) {
  private void doBaseDN(DN baseDN, Map<DN,DN> modifyDNmap)
  {
    for(Map.Entry<DN,DN> mapEntry: modifyDNmap.entrySet())
    {
      searchBaseDN(baseDN, mapEntry.getKey(), mapEntry.getValue());
    }
  }
  /**
@@ -554,38 +708,46 @@
   *                   null.
   *
   */
  private void
  deleteAddAttributesEntry(Entry e, DN oldEntryDN, DN newEntryDN) {
  private void deleteAddAttributesEntry(Entry e, DN oldEntryDN, DN newEntryDN)
  {
    LinkedList<Modification> mods = new LinkedList<Modification>();
    DN entryDN=e.getDN();
    for(AttributeType type : attributeTypes) {
      if(e.hasAttribute(type)) {
              AttributeValue deleteValue=
                                new AttributeValue(type, oldEntryDN.toString());
    for(AttributeType type : attributeTypes)
    {
      if(e.hasAttribute(type))
      {
        AttributeValue deleteValue=
             new AttributeValue(type, oldEntryDN.toString());
        LinkedHashSet<AttributeValue> deleteValues=
                                            new LinkedHashSet<AttributeValue>();
             new LinkedHashSet<AttributeValue>();
        deleteValues.add(deleteValue);
        mods.add(new Modification(ModificationType.DELETE,
                new Attribute(type, type.getNameOrOID(), deleteValues)));
        //If the new entry DN exists, create an ADD modification for it.
        if(newEntryDN != null) {
        if(newEntryDN != null)
        {
          LinkedHashSet<AttributeValue> addValues=
                                            new LinkedHashSet<AttributeValue>();
               new LinkedHashSet<AttributeValue>();
          AttributeValue addValue=
                                new AttributeValue(type, newEntryDN.toString());
               new AttributeValue(type, newEntryDN.toString());
          addValues.add(addValue);
          mods.add(new Modification(ModificationType.ADD,
                  new Attribute(type, type.getNameOrOID(), addValues)));
        }
      }
    }
    InternalClientConnection conn =
            InternalClientConnection.getRootConnection();
    ModifyOperation modifyOperation =
            conn.processModify(entryDN, mods);
    if(modifyOperation.getResultCode() != ResultCode.SUCCESS)
    {
      logError(ERR_PLUGIN_REFERENT_MODIFY_FAILED.get(entryDN.toString(),
                      String.valueOf(modifyOperation.getErrorMessage())));
    }
  }
  /**
@@ -600,16 +762,22 @@
   *
   */
  private void setUpLogFile(String logFileName)
          throws ConfigException {
          throws ConfigException
  {
    this.logFileName=logFileName;
    logFile=getFileForPath(logFileName);
    try {
      if(!logFile.exists()) logFile.createNewFile();
    } catch (IOException io) {
      Message message=
              ERR_PLUGIN_REFERENT_CREATE_LOGFILE.get(io.getMessage());
      throw new ConfigException(message);
    try
    {
      if(!logFile.exists())
      {
        logFile.createNewFile();
      }
    }
    catch (IOException io)
    {
      throw new ConfigException(ERR_PLUGIN_REFERENT_CREATE_LOGFILE.get(
                                     io.getMessage()), io);
    }
  }
@@ -647,20 +815,23 @@
   *
   */
  private void writeLog(Map<DN,DN> modDNmap) {
    synchronized(logFile) {
      try  {
    synchronized(logFile)
    {
      try
      {
        setupWriter();
        for(Map.Entry<DN,DN> mapEntry : modDNmap.entrySet()) {
        for(Map.Entry<DN,DN> mapEntry : modDNmap.entrySet())
        {
          writer.write(mapEntry.getKey().toNormalizedString() + "\t" +
                  mapEntry.getValue().toNormalizedString());
          writer.newLine();
        }
        writer.flush();
        writer.close();
      } catch (IOException io) {
        Message message =
                ERR_PLUGIN_REFERENT_CLOSE_LOGFILE.get(io.getMessage());
        logError(message);
      }
      catch (IOException io)
      {
        logError(ERR_PLUGIN_REFERENT_CLOSE_LOGFILE.get(io.getMessage()));
      }
    }
  }
@@ -680,10 +851,10 @@
        writer.newLine();
        writer.flush();
        writer.close();
      } catch (IOException io) {
        Message message =
                ERR_PLUGIN_REFERENT_CLOSE_LOGFILE.get(io.getMessage());
        logError(message);
      }
      catch (IOException io)
      {
        logError(ERR_PLUGIN_REFERENT_CLOSE_LOGFILE.get(io.getMessage()));
      }
    }
  }
@@ -702,7 +873,10 @@
    synchronized(logFile) {
      try {
        if(logFile.length() == 0)
        {
          return;
        }
        setupReader();
        String line;
        while((line=reader.readLine()) != null) {
@@ -729,9 +903,7 @@
        logFile.delete();
        logFile.createNewFile();
      } catch (IOException io) {
        Message message =
                ERR_PLUGIN_REFERENT_REPLACE_LOGFILE.get(io.getMessage());
        logError(message);
        logError(ERR_PLUGIN_REFERENT_REPLACE_LOGFILE.get(io.getMessage()));
      }
    }
  }
@@ -754,7 +926,9 @@
  public final void finalizePlugin() {
    currentConfiguration.removeReferentialIntegrityChangeListener(this);
    if(interval > 0)
    {
      processServerShutdown(null);
    }
  }
  /**
@@ -853,3 +1027,4 @@
    }
  }
}
opendj-sdk/opends/src/server/org/opends/server/plugins/UniqueAttributePlugin.java
@@ -40,6 +40,7 @@
import org.opends.server.admin.std.server.PluginCfg;
import org.opends.server.admin.std.server.UniqueAttributePluginCfg;
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.Backend;
import org.opends.server.api.plugin.DirectoryServerPlugin;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.api.plugin.PreOperationPluginResult;
@@ -57,6 +58,7 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.Modification;
import org.opends.server.types.RDN;
import org.opends.server.types.ResultCode;
@@ -157,6 +159,27 @@
      }
    }
    Set<DN> cfgBaseDNs = configuration.getUniqueAttributeBaseDN();
    if ((cfgBaseDNs == null) || cfgBaseDNs.isEmpty())
    {
      cfgBaseDNs = DirectoryServer.getPublicNamingContexts().keySet();
    }
    for (AttributeType t : configuration.getUniqueAttributeType())
    {
      for (DN baseDN : cfgBaseDNs)
      {
        Backend b = DirectoryServer.getBackend(baseDN);
        if ((b != null) && (! b.isIndexed(t, IndexType.EQUALITY)))
        {
          throw new ConfigException(ERR_PLUGIN_UNIQUEATTR_ATTR_UNINDEXED.get(
                                         configuration.dn().toString(),
                                         t.getNameOrOID(),
                                         b.getBackendID()));
        }
      }
    }
  }
@@ -836,6 +859,7 @@
                      List<Message> unacceptableReasons)
  {
    boolean configAcceptable = true;
    for (PluginCfgDefn.PluginType pluginType : configuration.getPluginType())
    {
      switch (pluginType)
@@ -856,6 +880,28 @@
          configAcceptable = false;
      }
    }
    Set<DN> cfgBaseDNs = configuration.getUniqueAttributeBaseDN();
    if ((cfgBaseDNs == null) || cfgBaseDNs.isEmpty())
    {
      cfgBaseDNs = DirectoryServer.getPublicNamingContexts().keySet();
    }
    for (AttributeType t : configuration.getUniqueAttributeType())
    {
      for (DN baseDN : cfgBaseDNs)
      {
        Backend b = DirectoryServer.getBackend(baseDN);
        if ((b != null) && (! b.isIndexed(t, IndexType.EQUALITY)))
        {
          unacceptableReasons.add(ERR_PLUGIN_UNIQUEATTR_ATTR_UNINDEXED.get(
                                       configuration.dn().toString(),
                                       t.getNameOrOID(), b.getBackendID()));
          configAcceptable = false;
        }
      }
    }
    return configAcceptable;
  }
opendj-sdk/opends/src/server/org/opends/server/replication/server/ReplicationBackend.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.replication.server;
import static org.opends.messages.BackendMessages.*;
@@ -84,6 +84,7 @@
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.LDIFImportConfig;
@@ -188,9 +189,11 @@
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config) throws ConfigException
  {
    if (config != null)
@@ -205,9 +208,12 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void initializeBackend()
       throws ConfigException, InitializationException
  {
@@ -232,7 +238,7 @@
    {
      try
      {
        DirectoryServer.registerBaseDN(dn, this, false);
        DirectoryServer.registerBaseDN(dn, this, true);
      }
      catch (Exception e)
      {
@@ -251,18 +257,9 @@
  /**
   * Removes any data that may have been stored in this backend.
   */
  public synchronized void clearMemoryBackend()
  {
    childDNs.clear();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void finalizeBackend()
  {
    for (DN dn : baseDNs)
@@ -281,49 +278,79 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public DN[] getBaseDNs()
  {
    return baseDNs;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized long getEntryCount()
  {
    return -1;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean isLocal()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // This needs to be updated when the backend implementation is complete.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized Entry getEntry(DN entryDN)
  {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized boolean entryExists(DN entryDN)
  {
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -331,9 +358,12 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void deleteEntry(DN entryDN,
                                       DeleteOperation deleteOperation)
         throws DirectoryException
@@ -342,9 +372,12 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void replaceEntry(Entry entry,
                                        ModifyOperation modifyOperation)
         throws DirectoryException
@@ -353,9 +386,12 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void renameEntry(DN currentDN, Entry entry,
                                       ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -364,33 +400,45 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  {
    return supportedControls;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  {
    return supportedFeatures;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFExport()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void exportLDIF(LDIFExportConfig exportConfig)
  throws DirectoryException
  {
@@ -784,17 +832,23 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsLDIFImport()
  {
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -806,6 +860,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
@@ -817,15 +872,19 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -839,6 +898,7 @@
  /**
   * {@inheritDoc}
   */
  @Override()
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -848,17 +908,23 @@
    backupManager.removeBackup(this.backendDirectory, backupID);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean supportsRestore()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -867,44 +933,30 @@
    backupManager.restoreBackup(cfg, restoreConfig);
  }
  /**
   * Retrieves the number of subordinates for the requested entry.
   *
   * @param entryDN The distinguished name of the entry.
   *
   * @return The number of subordinate entries for the requested entry
   *         or -1 if it can not be determined.
   *
   * @throws DirectoryException  If a problem occurs while trying to
   *                              retrieve the entry.
   * {@inheritDoc}
   */
  @Override()
  public long numSubordinates(DN entryDN)
      throws DirectoryException
  {
    Message message = WARN_ROOTDSE_GET_ENTRY_NONROOT.
    get(entryDN.toNormalizedString());
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
                                 ERR_NUM_SUBORDINATES_NOT_SUPPORTED.get());
  }
  /**
   * Indicates whether the requested entry has any subordinates.
   *
   * @param entryDN The distinguished name of the entry.
   *
   * @return {@code ConditionResult.TRUE} if the entry has one or more
   *         subordinates or {@code ConditionResult.FALSE} otherwise
   *         or {@code ConditionResult.UNDEFINED} if it can not be
   *         determined.
   *
   * @throws DirectoryException  If a problem occurs while trying to
   *                              retrieve the entry.
   * {@inheritDoc}
   */
  @Override()
  public ConditionResult hasSubordinates(DN entryDN)
        throws DirectoryException
  {
    Message message = WARN_ROOTDSE_GET_ENTRY_NONROOT.
      get(entryDN.toNormalizedString());
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
                                 ERR_HAS_SUBORDINATES_NOT_SUPPORTED.get());
  }
  /**
@@ -966,9 +1018,12 @@
    }
  };
  /**
   * {@inheritDoc}
   */
  @Override()
  public synchronized void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -1161,3 +1216,4 @@
    }
  }
}
opendj-sdk/opends/src/server/org/opends/server/types/IndexType.java
New file
@@ -0,0 +1,216 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.types;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class implements an enumeration that may be used to define the
 * ways in which an attribute may be indexed within the server.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
     mayInstantiate=false,
     mayExtend=false,
     mayInvoke=true)
public enum IndexType
{
  /**
   * Used to denote a presence index, which may be used to identify
   * entries containing the associated attribute (regardless of the
   * value for that attribute).
   */
  PRESENCE("presence"),
  /**
   * Used to denote an equality index, which may be used to identify
   * entries containing a specified value for the associated
   * attribute.
   */
  EQUALITY("equality"),
  /**
   * Used to denote a substring index, which may be used to identify
   * entries with one or more values for the associated attribute that
   * match a given substring assertion.  That substring assertion may
   * contain any or all of subInitial, subAny, and subFinal elements.
   */
  SUBSTRING("substring"),
  /**
   * Used to denote a subInitial index, which may be used to identify
   * entries with one or more values for the associated attribute that
   * begin with a specified string.
   */
  SUBINITIAL("subinitial"),
  /**
   * Used to denote a subAny index, which may be used to identify
   * entries with one or more values for the associated attribute that
   * contain a specified string.
   */
  SUBANY("subany"),
  /**
   * Used to denote a subFinal index, which may be used to identify
   * entries with one or more values for the associated attribute that
   * end with a specified string.
   */
  SUBFINAL("subfinal"),
  /**
   * Used to denote a greater-or-equal index, which may be used to
   * identify entries with one or more values that are greater than or
   * equal to a specified value.
   */
  GREATER_OR_EQUAL("greater-or-equal"),
  /**
   * Used to denote a less-or-equal index, which may be used to
   * identify entries with one or more values that are less than or
   * equal to a specified value.
   */
  LESS_OR_EQUAL("less-or-equal"),
  /**
   * Used to denote an approximate index, which may be used to
   * identify entries with one or more values that are approximately
   * equal to a specified value.
   */
  APPROXIMATE("approximate");
  // The human-readable name for this index type.
  private final String indexName;
  /**
   * Creates a new index type with the specified name.
   *
   * @param  indexName  The human-readable name for this index type.
   */
  private IndexType(String indexName)
  {
    this.indexName = indexName;
  }
  /**
   * Retrieves the index type for the specified name.
   *
   * @param  indexName  The name for which to retrieve the
   *                    associated index type.
   *
   * @return  The requested index type, or {@code null} if there is no
   *          such index type.
   */
  public static IndexType forName(String indexName)
  {
    String lowerName = toLowerCase(indexName);
    if (lowerName.equals("presence") || lowerName.equals("pres"))
    {
      return PRESENCE;
    }
    else if (lowerName.equals("equality") || lowerName.equals("eq"))
    {
      return EQUALITY;
    }
    else if (lowerName.equals("substring") || lowerName.equals("sub"))
    {
      return SUBSTRING;
    }
    else if (lowerName.equals("subinitial"))
    {
      return SUBINITIAL;
    }
    else if (lowerName.equals("subany"))
    {
      return SUBANY;
    }
    else if (lowerName.equals("subfinal"))
    {
      return SUBFINAL;
    }
    else if (lowerName.equals("greater-or-equal") ||
             lowerName.equals("greaterorequal") ||
             lowerName.equals("greater-than-or-equal-to") ||
             lowerName.equals("greaterthanorequalto"))
    {
      return GREATER_OR_EQUAL;
    }
    else if (lowerName.equals("less-or-equal") ||
             lowerName.equals("lessorequal") ||
             lowerName.equals("less-than-or-equal-to") ||
             lowerName.equals("lessthanorequalto"))
    {
      return LESS_OR_EQUAL;
    }
    else if (lowerName.equals("approximate") ||
             lowerName.equals("approx"))
    {
      return APPROXIMATE;
    }
    return null;
  }
  /**
   * Retrieves the human-readable name for this index type.
   *
   * @return  The human-readable name for this index type.
   */
  public String toString()
  {
    return indexName;
  }
}
opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
@@ -432,6 +432,55 @@
ds-cfg-backend-deadlock-retry-limit: 10
ds-cfg-database-cache-percent: 2
dn: ds-cfg-index-attribute=oncRpcNumber,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: oncRpcNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=bootParameter,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: bootParameter
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: employeeNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=seeAlso,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: seeAlso
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mobile,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mobile
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=facsimileTelephoneNumber,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: facsimileTelephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=pager,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: pager
ds-cfg-index-type: equality
dn: cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -449,6 +498,90 @@
ds-cfg-index-type: ordering
ds-cfg-index-type: approximate
dn: ds-cfg-index-attribute=oncRpcNumber,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: oncRpcNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=bootParameter,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: bootParameter
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: employeeNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=seeAlso,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: seeAlso
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mobile,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mobile
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=facsimileTelephoneNumber,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: facsimileTelephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=pager,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: pager
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=sn,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: sn
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=member,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: member
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uniuqeMember,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uniqueMember
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=telephoneNumber,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: telephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uid,cn=Index,ds-cfg-backend-id=unindexedRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uid
ds-cfg-index-type: equality
dn: ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -506,6 +639,90 @@
ds-cfg-index-type: ordering
ds-cfg-index-type: approximate
dn: ds-cfg-index-attribute=oncRpcNumber,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: oncRpcNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=bootParameter,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: bootParameter
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: employeeNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=seeAlso,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: seeAlso
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mobile,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mobile
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=facsimileTelephoneNumber,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: facsimileTelephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=pager,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: pager
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uid,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uid
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=sn,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: sn
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=member,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: member
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uniuqeMember,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uniqueMember
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=telephoneNumber,cn=Index,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: telephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -547,6 +764,103 @@
ds-cfg-vlv-je-index-filter: (objectClass=*)
ds-cfg-vlv-je-index-sort-order: givenname -sn +uid
dn: cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-branch
cn: Index
dn: ds-cfg-index-attribute=oncRpcNumber,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: oncRpcNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=bootParameter,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: bootParameter
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: employeeNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mail,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mail
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=seeAlso,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: seeAlso
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mobile,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mobile
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=facsimileTelephoneNumber,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: facsimileTelephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=pager,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: pager
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=sn,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: sn
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=member,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: member
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uniuqeMember,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uniqueMember
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=telephoneNumber,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: telephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uid,cn=Index,ds-cfg-backend-id=importRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uid
ds-cfg-index-type: equality
dn: ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -628,6 +942,13 @@
ds-cfg-index-attribute: member
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uniqueMember,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uniqueMember
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=sn,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -667,6 +988,55 @@
ds-cfg-index-attribute: entryuuid
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=oncRpcNumber,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: oncRpcNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=bootParameter,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: bootParameter
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: employeeNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=seeAlso,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: seeAlso
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mobile,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mobile
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=facsimileTelephoneNumber,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: facsimileTelephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=pager,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: pager
ds-cfg-index-type: equality
dn: ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -776,6 +1146,13 @@
ds-cfg-index-attribute: member
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=uniqueMember,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: uniqueMember
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=sn,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
@@ -801,6 +1178,48 @@
ds-cfg-index-attribute: uid
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=oncRpcNumber,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: oncRpcNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=bootParameter,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: bootParameter
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=seeAlso,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: seeAlso
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=mobile,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: mobile
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=facsimileTelephoneNumber,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: facsimileTelephoneNumber
ds-cfg-index-type: equality
dn: ds-cfg-index-attribute=pager,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
changetype: add
objectClass: top
objectClass: ds-cfg-je-index
ds-cfg-index-attribute: pager
ds-cfg-index-type: equality
dn: cn=Virtual Static member,cn=Virtual Attributes,cn=config
changetype: modify
replace: ds-cfg-allow-retrieving-membership
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/api/ConfigChangeListenerTestCase.java
@@ -145,7 +145,9 @@
    ConfigEntry e = DirectoryServer.getConfigEntry(dn);
    assertNotNull(e);
    assertTrue(l.configChangeIsAcceptable(e, new MessageBuilder()));
    MessageBuilder unacceptableReason = new MessageBuilder();
    assertTrue(l.configChangeIsAcceptable(e, unacceptableReason),
               unacceptableReason.toString());
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -140,6 +140,7 @@
        "homePhone: 546-786-4099",
        "pager: 508-261-3187",
        "mobile: 377-267-7824",
        "carLicense: 377-267-7824",
        "street: 78113 Fifth Street",
        "l: Chico",
        "st: TN",
@@ -164,6 +165,7 @@
        "homePhone: 955-899-7308",
        "pager: 710-832-9316",
        "mobile: 688-388-4525",
        "carLicense: 688-388-4525",
        "street: 59208 Elm Street",
        "l: Youngstown",
        "st: HI",
@@ -188,6 +190,7 @@
        "homePhone: 512-782-9966",
        "pager: 322-646-5118",
        "mobile: 360-957-9137",
        "carLicense: 360-957-9137",
        "street: 25074 Hill Street",
        "l: Toledo",
        "st: OR",
@@ -212,6 +215,7 @@
        "homePhone: 196-877-2684",
        "pager: 910-998-4607",
        "mobile: 123-239-8262",
        "carLicense: 123-239-8262",
        "street: 81512 Sunset Street",
        "l: Chattanooga",
        "st: WV",
@@ -236,6 +240,7 @@
        "homePhone: 078-254-3960",
        "pager: 281-936-8197",
        "mobile: 559-822-7712",
        "carLicense: 559-822-7712",
        "street: 31988 Central Street",
        "l: Chico",
        "st: MS",
@@ -260,6 +265,7 @@
        "homePhone: 459-123-0553",
        "pager: 799-151-2688",
        "mobile: 953-582-7252",
        "carLicense: 953-582-7252",
        "street: 60100 Dogwood Street",
        "l: Hartford",
        "st: NE",
@@ -284,6 +290,7 @@
        "homePhone: 174-724-6390",
        "pager: 733-217-8194",
        "mobile: 879-706-0172",
        "carLicense: 879-706-0172",
        "street: 77693 Oak Street",
        "l: Philadelphia",
        "st: MN",
@@ -308,6 +315,7 @@
        "homePhone: 039-769-3372",
        "pager: 226-950-2371",
        "mobile: 587-709-2996",
        "carLicense: 587-709-2996",
        "street: 23230 Hill Street",
        "l: Little Rock",
        "st: AR",
@@ -329,6 +337,7 @@
        "homePhone: 770-780-5917",
        "pager: 537-074-8005",
        "mobile: 120-204-7597",
        "carLicense: 120-204-7597",
        "street: 47952 Center Street",
        "l: Butte",
        "st: TN",
@@ -353,6 +362,7 @@
        "homePhone: 931-305-5452",
        "pager: 118-165-7194",
        "mobile: 553-729-5572",
        "carLicense: 553-729-5572",
        "street: 54262 Highland Street",
        "l: Spartanburg",
        "st: PA",
@@ -377,6 +387,7 @@
        "homePhone: 524-765-8780",
        "pager: 985-331-1308",
        "mobile: 279-423-0188",
        "carLicense: 279-423-0188",
        "street: 81170 Taylor Street",
        "l: Syracuse",
        "st: WV",
@@ -401,6 +412,7 @@
        "homePhone: 181-995-6635",
        "pager: 586-905-4185",
        "mobile: 826-857-7592",
        "carLicense: 826-857-7592",
        "street: 46168 Mill Street",
        "l: Charleston",
        "st: CO",
@@ -425,6 +437,7 @@
        "homePhone: 798-076-5683",
        "pager: 034-026-9411",
        "mobile: 948-743-9197",
        "carLicense: 948-743-9197",
        "street: 81028 Forest Street",
        "l: Wheeling",
        "st: IA",
@@ -450,6 +463,7 @@
        "homePhone: 707-626-3913",
        "pager: 456-345-7750",
        "mobile: 366-674-7274",
        "carLicense: 366-674-7274",
        "street: 99262 Eleventh Street",
        "l: Salem",
        "st: NM",
@@ -475,6 +489,7 @@
        "homePhone: 181-995-6635",
        "pager: 586-905-4185",
        "mobile: 826-857-7592",
        "carLicense: 826-857-7592",
        "street: 46168 Mill Street",
        "l: Charleston",
        "st: CO",
@@ -499,6 +514,7 @@
        "homePhone: 798-076-5683",
        "pager: 034-026-9411",
        "mobile: 948-743-9197",
        "carLicense: 948-743-9197",
        "street: 81028 Forest Street",
        "l: Wheeling",
        "st: IA",
@@ -1511,7 +1527,7 @@
            0,
            false,
            LDAPFilter.decode("(mobile=377*)").toSearchFilter(),
            LDAPFilter.decode("(carLicense=377*)").toSearchFilter(),
            attribs);
    LinkedList<SearchResultEntry> result = search.getSearchEntries();
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java
@@ -278,6 +278,7 @@
        "cn: test1 user",
        "givenName: user",
        "sn: test1",
        "carLicense: test1",
        "",
        "dn: cn=test2 user,dc=unindexed,dc=jeb",
        "objectClass: top",
@@ -286,7 +287,8 @@
        "objectClass: inetOrgPerson",
        "cn: test2 user",
        "givenName: user",
        "sn: test2"
        "sn: test2",
        "carLicense: test2"
    );
  }
@@ -428,7 +430,7 @@
    InternalSearchOperation searchOperation =
        conn.processSearch(DN.decode("dc=unindexed,dc=jeb"), SearchScope.WHOLE_SUBTREE,
             SearchFilter.createFilterFromString("(sn=test*)"));
             SearchFilter.createFilterFromString("(carLicense=test*)"));
    if (hasPrivilege)
    {
      assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);