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

Jean-Noel Rouvignac
22.44.2014 1345ac0dfae9a555abb7b74ed48452d9bc92b8c3
opends/src/server/org/opends/server/backends/MemoryBackend.java
@@ -22,11 +22,11 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2014 ForgeRock AS
 */
package org.opends.server.backends;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -34,7 +34,6 @@
import java.util.Set;
import org.opends.messages.Message;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.std.server.MemoryBackendCfg;
import org.opends.server.api.Backend;
import org.opends.server.config.ConfigException;
@@ -67,15 +66,12 @@
import org.opends.server.util.LDIFException;
import org.opends.server.util.LDIFReader;
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.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines a very simple backend that stores its information in
 * memory.  This is primarily intended for testing purposes with small data
@@ -104,7 +100,7 @@
 * entry has any children (which must not be the case for delete operations).
 */
public class MemoryBackend
       extends Backend
       extends Backend<MemoryBackendCfg>
{
  /**
   * The tracer object for the debug logger.
@@ -113,22 +109,20 @@
  // The base DNs for this backend.
  /** The base DNs for this backend. */
  private DN[] baseDNs;
  // The mapping between parent DNs and their immediate children.
  /** The mapping between parent DNs and their immediate children. */
  private HashMap<DN,HashSet<DN>> childDNs;
  // The base DNs for this backend, in a hash set.
  /** The base DNs for this backend, in a hash set. */
  private HashSet<DN> baseDNSet;
  // The set of supported controls for this backend.
  private HashSet<String> supportedControls;
  /** The set of supported controls for this backend. */
  private final Set<String> supportedControls =
      Collections.singleton(OID_SUBTREE_DELETE_CONTROL);
  // The set of supported features for this backend.
  private HashSet<String> supportedFeatures;
  // The mapping between entry DNs and the corresponding entries.
  /** The mapping between entry DNs and the corresponding entries. */
  private LinkedHashMap<DN,Entry> entryMap;
@@ -157,28 +151,21 @@
    this.baseDNs = baseDNs;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void configureBackend(Configuration config)
         throws ConfigException
  /** {@inheritDoc} */
  @Override
  public void configureBackend(MemoryBackendCfg config) throws ConfigException
  {
    if (config != null)
    {
      Validator.ensureTrue(config instanceof MemoryBackendCfg);
      MemoryBackendCfg cfg = (MemoryBackendCfg)config;
      MemoryBackendCfg cfg = config;
      DN[] baseDNs = new DN[cfg.getBaseDN().size()];
      cfg.getBaseDN().toArray(baseDNs);
      setBaseDNs(baseDNs);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void initializeBackend()
       throws ConfigException, InitializationException
  {
@@ -186,7 +173,7 @@
    // implementation.  If we were to add such support in the future, we would
    // likely want to separate the data for each base DN into a separate entry
    // map.
    if ((baseDNs == null) || (baseDNs.length != 1))
    if (baseDNs == null || baseDNs.length != 1)
    {
      Message message = ERR_MEMORYBACKEND_REQUIRE_EXACTLY_ONE_BASE.get();
      throw new ConfigException(message);
@@ -201,11 +188,6 @@
    entryMap = new LinkedHashMap<DN,Entry>();
    childDNs = new HashMap<DN,HashSet<DN>>();
    supportedControls = new HashSet<String>();
    supportedControls.add(OID_SUBTREE_DELETE_CONTROL);
    supportedFeatures = new HashSet<String>();
    for (DN dn : baseDNs)
    {
      try
@@ -237,12 +219,8 @@
    childDNs.clear();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void finalizeBackend()
  {
    clearMemoryBackend();
@@ -263,23 +241,15 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public DN[] getBaseDNs()
  {
    return baseDNs;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized long getEntryCount()
  {
    if (entryMap != null)
@@ -290,35 +260,23 @@
    return -1;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean isLocal()
  {
    // For the purposes of this method, this is a local backend.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean isIndexed(AttributeType attributeType, IndexType indexType)
  {
    // All searches in this backend will always be considered indexed.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public synchronized ConditionResult hasSubordinates(DN entryDN)
         throws DirectoryException
@@ -338,10 +296,8 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized long numSubordinates(DN entryDN, boolean subtree)
         throws DirectoryException
  {
@@ -373,10 +329,8 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized Entry getEntry(DN entryDN)
  {
    Entry entry = entryMap.get(entryDN);
@@ -388,23 +342,15 @@
    return entry;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized boolean entryExists(DN entryDN)
  {
    return entryMap.containsKey(entryDN);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void addEntry(Entry entry, AddOperation addOperation)
         throws DirectoryException
  {
@@ -454,12 +400,8 @@
    children.add(entryDN);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void deleteEntry(DN entryDN,
                                       DeleteOperation deleteOperation)
         throws DirectoryException
@@ -467,21 +409,14 @@
    // Make sure the entry exists.  If not, then throw an exception.
    if (! entryMap.containsKey(entryDN))
    {
      Message message =
          ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(entryDN));
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
          ERR_BACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(entryDN), getBackendID()));
    }
    // Check to see if the entry contains a subtree delete control.
    boolean subtreeDelete = false;
    if (deleteOperation != null
        && deleteOperation
            .getRequestControl(SubtreeDeleteControl.DECODER) != null)
    {
      subtreeDelete = true;
    }
    boolean subtreeDelete = deleteOperation != null
        && deleteOperation.getRequestControl(SubtreeDeleteControl.DECODER) != null;
    HashSet<DN> children = childDNs.get(entryDN);
    if (subtreeDelete)
@@ -511,7 +446,7 @@
    {
      // Make sure the entry doesn't have any children.  If it does, then throw
      // an exception.
      if ((children != null) && (! children.isEmpty()))
      if (children != null && !children.isEmpty())
      {
        Message message = ERR_MEMORYBACKEND_CANNOT_DELETE_ENTRY_WITH_CHILDREN.
            get(String.valueOf(entryDN));
@@ -541,12 +476,8 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void replaceEntry(Entry oldEntry, Entry newEntry,
      ModifyOperation modifyOperation) throws DirectoryException
  {
@@ -556,9 +487,8 @@
    DN entryDN = e.getDN();
    if (! entryMap.containsKey(entryDN))
    {
      Message message =
          ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(entryDN));
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
          ERR_BACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(entryDN), getBackendID()));
    }
@@ -566,12 +496,8 @@
    entryMap.put(entryDN, e);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void renameEntry(DN currentDN, Entry entry,
                                       ModifyDNOperation modifyDNOperation)
         throws DirectoryException
@@ -581,9 +507,8 @@
    // Make sure that the target entry exists.
    if (! entryMap.containsKey(currentDN))
    {
      Message message =
          ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(currentDN));
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT,
          ERR_BACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(currentDN), getBackendID()));
    }
@@ -635,7 +560,7 @@
    // Make sure that the parent of the new entry exists.
    DN parentDN = e.getDN().getParentDNInSuffix();
    if ((parentDN == null) || (! entryMap.containsKey(parentDN)))
    if (parentDN == null || !entryMap.containsKey(parentDN))
    {
      Message message = ERR_MEMORYBACKEND_RENAME_PARENT_DOESNT_EXIST.get(
          String.valueOf(currentDN), String.valueOf(parentDN));
@@ -648,12 +573,8 @@
    addEntry(e, null);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void search(SearchOperation searchOperation)
         throws DirectoryException
  {
@@ -665,7 +586,7 @@
    // Make sure the base entry exists if it's supposed to be in this backend.
    Entry baseEntry = entryMap.get(baseDN);
    if ((baseEntry == null) && handlesEntry(baseDN))
    if (baseEntry == null && handlesEntry(baseDN))
    {
      DN matchedDN = baseDN.getParentDNInSuffix();
      while (matchedDN != null)
@@ -679,7 +600,7 @@
      }
      Message message =
          ERR_MEMORYBACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(baseDN));
          ERR_BACKEND_ENTRY_DOESNT_EXIST.get(String.valueOf(baseDN), getBackendID());
      throw new DirectoryException(
              ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
    }
@@ -713,45 +634,29 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedControls()
  /** {@inheritDoc} */
  @Override
  public Set<String> getSupportedControls()
  {
    return supportedControls;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public HashSet<String> getSupportedFeatures()
  /** {@inheritDoc} */
  @Override
  public Set<String> getSupportedFeatures()
  {
    return supportedFeatures;
    return Collections.emptySet();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsLDIFExport()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized void exportLDIF(LDIFExportConfig exportConfig)
         throws DirectoryException
  {
@@ -794,37 +699,19 @@
    }
    finally
    {
      try
      {
        ldifWriter.close();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
      }
      close(ldifWriter);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsLDIFImport()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public synchronized LDIFImportResult importLDIF(LDIFImportConfig importConfig)
         throws DirectoryException
  {
@@ -904,37 +791,23 @@
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsBackup()
  {
    // This backend does not provide a backup/restore mechanism.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsBackup(BackupConfig backupConfig,
                                StringBuilder unsupportedReason)
  {
    // This backend does not provide a backup/restore mechanism.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void createBackup(BackupConfig backupConfig)
         throws DirectoryException
  {
@@ -942,12 +815,8 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void removeBackup(BackupDirectory backupDirectory,
                           String backupID)
         throws DirectoryException
@@ -956,24 +825,15 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public boolean supportsRestore()
  {
    // This backend does not provide a backup/restore mechanism.
    return false;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  /** {@inheritDoc} */
  @Override
  public void restoreBackup(RestoreConfig restoreConfig)
         throws DirectoryException
  {
@@ -981,11 +841,7 @@
    throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
  }
  /**
   * {@inheritDoc}
   */
  /** {@inheritDoc} */
  @Override
  public void preloadEntryCache() throws UnsupportedOperationException {
    throw new UnsupportedOperationException("Operation not supported.");