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

Jean-Noël Rouvignac
01.21.2015 f05415834a643dd0c065a1865808ae4df45d5952
Replaced AttrHistoricalWithOptions by a new class AttributeDescription

AttributeDescription is temporarily added until code is migrated to the equivalent SDK type
1 files deleted
1 files added
3 files modified
453 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/AttrHistoricalWithOptions.java 78 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/AttrValueHistorical.java 13 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/EntryHistorical.java 233 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/HistoricalAttributeValue.java 39 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/AttributeDescription.java 90 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/AttrHistoricalWithOptions.java
File was deleted
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/AttrValueHistorical.java
@@ -29,7 +29,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.replication.common.CSN;
/** Store historical information for an attribute value. */
/** AttrValueHistorical is the historical information of the modification of one attribute value. */
public class AttrValueHistorical
{
  private ByteString value;
@@ -50,12 +50,6 @@
    this.valueDeleteTime = csnDelete;
  }
  /**
   * Compares this object with another ValueInfo object.
   * Object are said equals when their values matches.
   * @param obj object to be compared with this object
   * @return true if equal, false otherwise
   */
  @Override
  public boolean equals(Object obj)
  {
@@ -67,11 +61,6 @@
    return false;
  }
  /**
   * Calculates the hasCode for this object.
   * Only value is used when calculating the hashCode
   * @return the hashcode
   */
  @Override
  public int hashCode()
  {
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/EntryHistorical.java
@@ -100,55 +100,14 @@
   */
  private int lastPurgedValuesCount;
  /**
   * The in-memory historical information is made of.
   *
   * EntryHistorical ::= ADDDate MODDNDate attributesInfo
   * ADDDate       ::= CSN  // the date the entry was added
   * MODDNDate     ::= CSN  // the date the entry was last renamed
   *
   * attributesInfo      ::= (AttrInfoWithOptions)*
   *                         one AttrInfoWithOptions by attributeType
   *
   * AttrInfoWithOptions ::= (AttributeInfo)*
   *                         one AttributeInfo by attributeType and option
   *
   * AttributeInfo       ::= AttrInfoSingle | AttrInfoMultiple
   *
   * AttrInfoSingle      ::= AddTime DeleteTime ValueInfo
   *
   * AttrInfoMultiple    ::= AddTime DeleteTime ValuesInfo
   *
   * ValuesInfo          ::= (AttrValueHistorical)*
   *                         AttrValueHistorical is the historical of the
   *                         the modification of one value
   *
   * AddTime             ::= CSN // last time the attribute was added to the entry
   * DeleteTime          ::= CSN // last time the attribute was deleted from the entry
   *
   * AttrValueHistorical ::= AttributeValue valueDeleteTime valueUpdateTime
   * valueDeleteTime     ::= CSN
   * valueUpdateTime     ::= CSN
   *
   * - a list indexed on AttributeType of AttrInfoWithOptions :
   *     each value is the historical for this attribute
   *     an AttrInfoWithOptions is a set indexed on the optionValue(string) of
   *     AttributeInfo
   */
  /** The date when the entry was added. */
  private CSN entryADDDate;
  /** The date when the entry was last renamed. */
  private CSN entryMODDNDate;
  /**
   * Contains Historical information for each attribute sorted by attribute
   * type. key:AttributeType value:AttrInfoWithOptions
   */
  private final HashMap<AttributeType,AttrHistoricalWithOptions> attributesHistorical = new HashMap<>();
  /** Contains Historical information for each attribute description. */
  private final Map<AttributeDescription, AttrHistorical> attributesHistorical = new HashMap<>();
  /** {@inheritDoc} */
  @Override
  public String toString()
  {
@@ -341,28 +300,15 @@
      // used to store the historical information.
      return null;
    }
    Set<String> modOptions = modAttr.getOptions();
    AttributeType modAttrType = modAttr.getAttributeType();
    // Read from this entryHistorical,
    // Create one empty if none was existing in this entryHistorical.
    AttrHistoricalWithOptions attrHistWithOptions = attributesHistorical.get(modAttrType);
    AttrHistorical attrHist;
    if (attrHistWithOptions != null)
    {
      attrHist = attrHistWithOptions.get(modOptions);
    }
    else
    {
      attrHistWithOptions = new AttrHistoricalWithOptions();
      attributesHistorical.put(modAttrType, attrHistWithOptions);
      attrHist = null;
    }
    AttributeDescription attrDesc = new AttributeDescription(modAttr);
    AttrHistorical attrHist = attributesHistorical.get(attrDesc);
    if (attrHist == null)
    {
      attrHist = AttrHistorical.createAttributeHistorical(modAttrType);
      attrHistWithOptions.put(modOptions, attrHist);
      attrHist = AttrHistorical.createAttributeHistorical(modAttr.getAttributeType());
      attributesHistorical.put(attrDesc, attrHist);
    }
    return attrHist;
  }
@@ -401,81 +347,73 @@
    AttributeType historicalAttrType = DirectoryServer.getAttributeType(HISTORICAL_ATTRIBUTE_NAME);
    AttributeBuilder builder = new AttributeBuilder(historicalAttrType);
    for (Map.Entry<AttributeType, AttrHistoricalWithOptions> entryWithOptions :
          attributesHistorical.entrySet())
    for (Map.Entry<AttributeDescription, AttrHistorical> mapEntry : attributesHistorical.entrySet())
    {
      // Encode an attribute type
      AttributeType type = entryWithOptions.getKey();
      Map<Set<String>, AttrHistorical> attrWithOptions =
                                entryWithOptions.getValue().getAttributesInfo();
      AttributeDescription attrDesc = mapEntry.getKey();
      AttributeType type = attrDesc.attributeType;
      String optionsString = attrDesc.toOptionsString();
      AttrHistorical attrHist = mapEntry.getValue();
      for (Map.Entry<Set<String>, AttrHistorical> entry : attrWithOptions.entrySet())
      CSN deleteTime = attrHist.getDeleteTime();
      /* generate the historical information for deleted attributes */
      boolean attrDel = deleteTime != null;
      for (AttrValueHistorical attrValHist : attrHist.getValuesHistorical())
      {
        // Encode an (attribute type/option)
        String optionsString = toOptionsString(entry.getKey());
        AttrHistorical attrHist = entry.getValue();
        final ByteString value = attrValHist.getAttributeValue();
        CSN deleteTime = attrHist.getDeleteTime();
        /* generate the historical information for deleted attributes */
        boolean attrDel = deleteTime != null;
        for (AttrValueHistorical attrValHist : attrHist.getValuesHistorical())
        // Encode an attribute value
        if (attrValHist.getValueDeleteTime() != null)
        {
          final ByteString value = attrValHist.getAttributeValue();
          // Encode an attribute value
          if (attrValHist.getValueDeleteTime() != null)
          {
            if (needsPurge(attrValHist.getValueDeleteTime(), purgeDate))
            {
              // this hist must be purged now, so skip its encoding
              continue;
            }
            String strValue = encode(DEL, type, optionsString, attrValHist.getValueDeleteTime(), value);
            builder.add(strValue);
          }
          else if (attrValHist.getValueUpdateTime() != null)
          {
            if (needsPurge(attrValHist.getValueUpdateTime(), purgeDate))
            {
              // this hist must be purged now, so skip its encoding
              continue;
            }
            String strValue;
            final CSN updateTime = attrValHist.getValueUpdateTime();
            // FIXME very suspicious use of == in the next if statement,
            // unit tests do not like changing it
            if (attrDel && updateTime == deleteTime && value != null)
            {
              strValue = encode(REPL, type, optionsString, updateTime, value);
              attrDel = false;
            }
            else if (value != null)
            {
              strValue = encode(ADD, type, optionsString, updateTime, value);
            }
            else
            {
              // "add" without any value is suspicious. Tests never go there.
              // Is this used to encode "add" with an empty string?
              strValue = encode(ADD, type, optionsString, updateTime);
            }
            builder.add(strValue);
          }
        }
        if (attrDel)
        {
          if (needsPurge(deleteTime, purgeDate))
          if (needsPurge(attrValHist.getValueDeleteTime(), purgeDate))
          {
            // this hist must be purged now, so skip its encoding
            continue;
          }
          String strValue = encode(ATTRDEL, type, optionsString, deleteTime);
          String strValue = encode(DEL, type, optionsString, attrValHist.getValueDeleteTime(), value);
          builder.add(strValue);
        }
        else if (attrValHist.getValueUpdateTime() != null)
        {
          if (needsPurge(attrValHist.getValueUpdateTime(), purgeDate))
          {
            // this hist must be purged now, so skip its encoding
            continue;
          }
          String strValue;
          final CSN updateTime = attrValHist.getValueUpdateTime();
          // FIXME very suspicious use of == in the next if statement,
          // unit tests do not like changing it
          if (attrDel && updateTime == deleteTime && value != null)
          {
            strValue = encode(REPL, type, optionsString, updateTime, value);
            attrDel = false;
          }
          else if (value != null)
          {
            strValue = encode(ADD, type, optionsString, updateTime, value);
          }
          else
          {
            // "add" without any value is suspicious. Tests never go there.
            // Is this used to encode "add" with an empty string?
            strValue = encode(ADD, type, optionsString, updateTime);
          }
          builder.add(strValue);
        }
      }
      if (attrDel)
      {
        if (needsPurge(deleteTime, purgeDate))
        {
          // this hist must be purged now, so skip its encoding
          continue;
        }
        String strValue = encode(ATTRDEL, type, optionsString, deleteTime);
        builder.add(strValue);
      }
    }
@@ -496,20 +434,6 @@
    return builder.toAttribute();
  }
  private String toOptionsString(Set<String> options)
  {
    if (options != null)
    {
      StringBuilder optionsBuilder = new StringBuilder();
      for (String s : options)
      {
        optionsBuilder.append(';').append(s);
      }
      return optionsBuilder.toString();
    }
    return "";
  }
  private boolean needsPurge(CSN csn, long purgeDate)
  {
    boolean needsPurge = purgeDelayInMillisec > 0 && csn.getTime() <= purgeDate;
@@ -606,11 +530,6 @@
    try
    {
      AttributeType lastAttrType = null;
      Set<String> lastOptions = new HashSet<>();
      AttrHistorical attrInfo = null;
      AttrHistoricalWithOptions attrInfoWithOptions = null;
      // For each value of the historical attr read (mod. on a user attribute)
      //   build an AttrInfo sub-object
@@ -638,8 +557,8 @@
          }
          else
          {
            AttributeType attrType = histVal.getAttrType();
            if (attrType == null)
            AttributeDescription attrDesc = histVal.getAttributeDescription();
            if (attrDesc == null)
            {
              /*
               * This attribute is unknown from the schema
@@ -658,28 +577,12 @@
             *   AttrInfo that we add to AttrInfoWithOptions
             * if both match we keep everything
             */
            Set<String> options = histVal.getOptions();
            if (attrType != lastAttrType)
            AttrHistorical attrInfo = newHistorical.attributesHistorical.get(attrDesc);
            if (attrInfo == null)
            {
              attrInfo = AttrHistorical.createAttributeHistorical(attrType);
              // Create attrInfoWithOptions and store inside the attrInfo
              attrInfoWithOptions = new AttrHistoricalWithOptions();
              attrInfoWithOptions.put(options, attrInfo);
              // Store this attrInfoWithOptions in the newHistorical object
              newHistorical.attributesHistorical.put(attrType, attrInfoWithOptions);
              lastAttrType = attrType;
              lastOptions = options;
              attrInfo = AttrHistorical.createAttributeHistorical(attrDesc.attributeType);
              newHistorical.attributesHistorical.put(attrDesc, attrInfo);
            }
            else if (!options.equals(lastOptions))
            {
              attrInfo = AttrHistorical.createAttributeHistorical(attrType);
              attrInfoWithOptions.put(options, attrInfo);
              lastOptions = options;
            }
            attrInfo.assign(histVal.getHistKey(), histVal.getAttributeValue(), csn);
          }
        }
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/HistoricalAttributeValue.java
@@ -28,6 +28,7 @@
import static org.opends.server.replication.plugin.HistAttrModificationKey.*;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -37,6 +38,7 @@
import org.opends.server.replication.common.CSN;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeDescription;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Modification;
@@ -74,11 +76,10 @@
 */
class HistoricalAttributeValue
{
  private final AttributeType attrType;
  private final AttributeDescription attrDesc;
  private final String attrString;
  private final ByteString attributeValue;
  private final CSN csn;
  private final Set<String> options = new LinkedHashSet<>();
  private final HistAttrModificationKey histKey;
  private final String stringValue;
@@ -98,8 +99,10 @@
  {
    String[] token = strVal.split(":", 4);
    Set<String> options;
    if (token[0].contains(";"))
    {
      options = new LinkedHashSet<>();
      String[] optionsToken = token[0].split(";");
      int index = 1;
      while (index < optionsToken.length)
@@ -111,9 +114,11 @@
    }
    else
    {
      options = Collections.emptySet();
      attrString = token[0];
    }
    AttributeType attrType;
    if (attrString.compareTo("dn") != 0)
    {
      // This HistVal was used to store the date when some
@@ -130,6 +135,7 @@
        isModDN = true;
      }
    }
    this.attrDesc = attrType != null ? new AttributeDescription(attrType, options) : null;
    csn = new CSN(token[1]);
    histKey = HistAttrModificationKey.decodeKey(token[2]);
@@ -164,14 +170,14 @@
  }
  /**
   * Get the type of this HistVal.
   * Get the attribute description of this HistVal.
   *
   * @return Returns the type of this HistVal.
   *         Can return NULL if the HistVal was generated for a ADD Operation.
   * @return Returns the attribute description of this HistVal.
   *         Can return {@code null} if the HistVal was generated for a ADD Operation.
   */
  public AttributeType getAttrType()
  AttributeDescription getAttributeDescription()
  {
    return attrType;
    return attrDesc;
  }
  /**
@@ -193,15 +199,6 @@
  }
  /**
   * Get the options or an empty set if there are no options.
   * @return Returns the options.
   */
  public Set<String> getOptions()
  {
    return options;
  }
  /**
   * Get the Attribute Value.
   * @return The Attribute Value.
   */
@@ -219,8 +216,8 @@
   */
  public Modification generateMod()
  {
    AttributeBuilder builder = new AttributeBuilder(attrType, attrString);
    builder.setOptions(options);
    AttributeBuilder builder = new AttributeBuilder(attrDesc.attributeType, attrString);
    builder.setOptions(attrDesc.options);
    if (histKey != ATTRDEL)
    {
@@ -250,7 +247,7 @@
   */
  public boolean isADDOperation()
  {
    return attrType == null && !isModDN;
    return attrDesc.attributeType == null && !isModDN;
  }
  /**
@@ -261,7 +258,7 @@
   */
  public boolean isMODDNOperation()
  {
    return attrType == null && isModDN;
    return attrDesc.attributeType == null && isModDN;
  }
  @Override
@@ -269,7 +266,7 @@
  {
    final StringBuilder sb = new StringBuilder();
    sb.append(attrString);
    for (String option : this.options)
    for (String option : attrDesc.options)
    {
      sb.append(";").append(option);
    }
opendj-server-legacy/src/main/java/org/opends/server/types/AttributeDescription.java
New file
@@ -0,0 +1,90 @@
/*
 * 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 legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * 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 legal-notices/CDDLv1_0.txt.
 * 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
 *
 *      Copyright 2015 ForgeRock AS
 */
package org.opends.server.types;
import java.util.Set;
/** Temporary class until we move to {@link org.forgerock.opendj.ldap.AttributeDescription}. */
public final class AttributeDescription
{
  final AttributeType attributeType;
  final Set<String> options;
  AttributeDescription(Attribute attr)
  {
    this(attr.getAttributeType(), attr.getOptions());
  }
  AttributeDescription(AttributeType attributeType, Set<String> options)
  {
    this.attributeType = attributeType;
    this.options = options;
  }
  String toOptionsString()
  {
    if (options != null)
    {
      StringBuilder optionsBuilder = new StringBuilder();
      for (String s : options)
      {
        optionsBuilder.append(';').append(s);
      }
      return optionsBuilder.toString();
    }
    return "";
  }
  @Override
  public boolean equals(Object obj)
  {
    if (obj == this)
    {
      return true;
    }
    if (!(obj instanceof AttributeDescription))
    {
      return false;
    }
    final AttributeDescription other = (AttributeDescription) obj;
    return attributeType.equals(other.attributeType) && options.equals(other.options);
  }
  @Override
  public int hashCode()
  {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((attributeType == null) ? 0 : attributeType.hashCode());
    result = prime * result + ((options == null) ? 0 : options.hashCode());
    return result;
  }
  @Override
  public String toString()
  {
    return getClass().getSimpleName() + "(" + "attributeType=" + attributeType + ", options=" + options + ")";
  }
}