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

Jean-Noël Rouvignac
25.42.2016 d82f97fc8059ea49e82961fefc73a2ae536619a2
Prep work for OPENDJ-2803 Migrate Attribute

Replace custom parsing with AttributeDescription.valueOf()
4 files modified
350 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java 10 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/protocols/ldap/LDAPFilter.java 129 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/HistoricalAttributeValue.java 79 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java 132 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java
@@ -89,6 +89,8 @@
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.ConfigurationFramework;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.schema.Syntax;
@@ -117,7 +119,6 @@
import org.opends.server.core.LockFileManager;
import org.opends.server.schema.SchemaConstants;
import org.opends.server.schema.SomeSchemaElement;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.Schema;
import org.opends.server.util.ServerConstants;
@@ -1473,12 +1474,7 @@
   */
  public static String getAttributeNameWithoutOptions(String attrName)
  {
    int index = attrName.indexOf(";");
    if (index != -1)
    {
      attrName = attrName.substring(0, index);
    }
    return attrName;
    return AttributeDescription.valueOf(attrName).getNameOrOID();
  }
  /**
opendj-server-legacy/src/main/java/org/opends/server/protocols/ldap/LDAPFilter.java
@@ -18,13 +18,15 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Set;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ResultCode;
@@ -76,8 +78,8 @@
  /** The filter component for NOT filters. */
  private RawFilter notComponent;
  /** The attribute type for several filter types. */
  private String attributeType;
  /** The attribute description for several filter types. */
  private String attributeDescription;
  /** The matching rule ID for extensible matching filters. */
  private String matchingRuleID;
@@ -94,7 +96,7 @@
   * @param  filterType         The filter type for this filter.
   * @param  filterComponents   The filter components for AND and OR filters.
   * @param  notComponent       The filter component for NOT filters.
   * @param  attributeType      The attribute type for this filter.
   * @param  attributeDescription The attribute description for this filter.
   * @param  assertionValue     The assertion value for this filter.
   * @param  subInitialElement  The subInitial element for substring filters.
   * @param  subAnyElements     The subAny elements for substring filters.
@@ -104,7 +106,7 @@
   */
  public LDAPFilter(FilterType filterType,
                    ArrayList<RawFilter> filterComponents,
                    RawFilter notComponent, String attributeType,
                    RawFilter notComponent, String attributeDescription,
                    ByteString assertionValue, ByteString subInitialElement,
                    ArrayList<ByteString> subAnyElements,
                    ByteString subFinalElement, String matchingRuleID,
@@ -113,7 +115,7 @@
    this.filterType        = filterType;
    this.filterComponents  = filterComponents;
    this.notComponent      = notComponent;
    this.attributeType     = attributeType;
    this.attributeDescription = attributeDescription;
    this.assertionValue    = assertionValue;
    this.subInitialElement = subInitialElement;
    this.subAnyElements    = subAnyElements;
@@ -145,7 +147,7 @@
        }
        notComponent      = null;
        attributeType     = null;
        attributeDescription     = null;
        assertionValue    = null;
        subInitialElement = null;
        subAnyElements    = null;
@@ -157,7 +159,7 @@
        notComponent = new LDAPFilter(filter.getNotComponent());
        filterComponents  = null;
        attributeType     = null;
        attributeDescription     = null;
        assertionValue    = null;
        subInitialElement = null;
        subAnyElements    = null;
@@ -169,7 +171,7 @@
      case GREATER_OR_EQUAL:
      case LESS_OR_EQUAL:
      case APPROXIMATE_MATCH:
        attributeType  = filter.getAttributeType().getNameOrOID();
        attributeDescription  = filter.getAttributeType().getNameOrOID();
        assertionValue = filter.getAssertionValue();
        filterComponents  = null;
@@ -181,7 +183,7 @@
        dnAttributes      = false;
        break;
      case SUBSTRING:
        attributeType  = filter.getAttributeType().getNameOrOID();
        attributeDescription  = filter.getAttributeType().getNameOrOID();
        ByteString bs = filter.getSubInitialElement();
        if (bs == null)
@@ -220,7 +222,7 @@
        dnAttributes      = false;
        break;
      case PRESENT:
        attributeType  = filter.getAttributeType().getNameOrOID();
        attributeDescription  = filter.getAttributeType().getNameOrOID();
        filterComponents  = null;
        notComponent      = null;
@@ -238,11 +240,11 @@
        AttributeType attrType = filter.getAttributeType();
        if (attrType == null)
        {
          attributeType = null;
          attributeDescription = null;
        }
        else
        {
          attributeType = attrType.getNameOrOID();
          attributeDescription = attrType.getNameOrOID();
        }
        assertionValue    = filter.getAssertionValue();
@@ -423,12 +425,11 @@
    }
    // The part of the filter string before the equal sign should be the
    // attribute type.  Make sure that the characters it contains are acceptable
    // for attribute types, including those allowed by attribute name
    // exceptions (ASCII letters and digits, the dash, and the underscore).  We
    // also need to allow attribute options, which includes the semicolon and
    // the equal sign.
    // The part of the filter string before the equal sign should be the attribute description.
    // Make sure that the characters it contains are acceptable for attribute descriptions,
    // including those allowed by attribute name exceptions
    // (ASCII letters and digits, the dash, and the underscore).
    // We also need to allow attribute options, which includes the semicolon and the equal sign.
    String attrType = filterString.substring(startPos, attrEndPos);
    for (int i=0; i < attrType.length(); i++)
    {
@@ -856,10 +857,10 @@
   *
   * @param  filterString  The filter string containing the information to
   *                       decode.
   * @param  attrType      The attribute type for this substring filter
   * @param  attrDesc      The attribute description for this substring filter
   *                       component.
   * @param  equalPos      The location of the equal sign separating the
   *                       attribute type from the value.
   *                       attribute description from the value.
   * @param  endPos        The position of the first character after the end of
   *                       the substring value.
   *
@@ -869,7 +870,7 @@
   *                         substring filter.
   */
  private static LDAPFilter decodeSubstringFilter(String filterString,
                                                  String attrType, int equalPos,
                                                  String attrDesc, int equalPos,
                                                  int endPos)
          throws LDAPException
  {
@@ -1403,7 +1404,7 @@
    }
    return new LDAPFilter(FilterType.SUBSTRING, null, null, attrType, null,
    return new LDAPFilter(FilterType.SUBSTRING, null, null, attrDesc, null,
                          subInitial, subAny, subFinal, null, false);
  }
@@ -1440,13 +1441,12 @@
    // Look at the first character.  If it is a colon, then it must be followed
    // by either the string "dn" or the matching rule ID.  If it is not, then
    // must be the attribute type.
    // must be the attribute description.
    String lowerLeftStr =
         toLowerCase(filterString.substring(startPos, equalPos));
    if (filterString.charAt(startPos) == ':')
    {
      // See if it starts with ":dn".  Otherwise, it much be the matching rule
      // ID.
      // See if it starts with ":dn".  Otherwise, it much be the matching rule ID.
      if (lowerLeftStr.startsWith(":dn:"))
      {
        dnAttributes = true;
@@ -1724,16 +1724,16 @@
  /**
   * Retrieves the attribute type for this search filter.  This will not be
   * Retrieves the attribute description for this search filter.  This will not be
   * applicable for AND, OR, or NOT filters.
   *
   * @return  The attribute type for this search filter, or <CODE>null</CODE> if
   * @return  The attribute description for this search filter, or <CODE>null</CODE> if
   *          there is none.
   */
  @Override
  public String getAttributeType()
  {
    return attributeType;
    return attributeDescription;
  }
@@ -1886,38 +1886,16 @@
      notComp = notComponent.toSearchFilter();
    }
    AttributeType attrType;
    HashSet<String> options;
    if (attributeType == null)
    AttributeDescription attrDesc = null;
    AttributeType attributeType = null;
    Set<String> options = Collections.emptySet();
    if (attributeDescription != null)
    {
      attrType = null;
      options  = null;
      attrDesc = AttributeDescription.valueOf(attributeDescription);
      attributeType = attrDesc.getAttributeType();
      options = toSet(attrDesc);
    }
    else
    {
      int semicolonPos = attributeType.indexOf(';');
      if (semicolonPos > 0)
      {
        String baseName = attributeType.substring(0, semicolonPos);
        attrType = DirectoryServer.getAttributeType(baseName);
        options = new HashSet<>();
        StringTokenizer tokenizer =
             new StringTokenizer(attributeType.substring(semicolonPos+1), ";");
        while (tokenizer.hasMoreTokens())
        {
          options.add(tokenizer.nextToken());
        }
      }
      else
      {
        options = null;
        attrType = DirectoryServer.getAttributeType(attributeType);
      }
    }
    if (assertionValue != null && attrType == null)
    if (assertionValue != null && attrDesc == null)
    {
      if (matchingRuleID == null)
      {
@@ -1935,12 +1913,21 @@
    ArrayList<ByteString> subAnyComps =
        subAnyElements != null ? new ArrayList<ByteString>(subAnyElements) : null;
    return new SearchFilter(filterType, subComps, notComp, attrType,
                            options, assertionValue, subInitialElement, subAnyComps,
    return new SearchFilter(filterType, subComps, notComp, attributeType, options,
                            assertionValue, subInitialElement, subAnyComps,
                            subFinalElement, matchingRuleID, dnAttributes);
  }
  private Set<String> toSet(AttributeDescription attrDesc)
  {
    LinkedHashSet<String> results = new LinkedHashSet<>();
    for (String option : attrDesc.getOptions())
    {
      results.add(option);
    }
    return results;
  }
  /**
@@ -1977,14 +1964,14 @@
        break;
      case EQUALITY:
        buffer.append("(");
        buffer.append(attributeType);
        buffer.append(attributeDescription);
        buffer.append("=");
        valueToFilterString(buffer, assertionValue);
        buffer.append(")");
        break;
      case SUBSTRING:
        buffer.append("(");
        buffer.append(attributeType);
        buffer.append(attributeDescription);
        buffer.append("=");
        if (subInitialElement != null)
@@ -2012,26 +1999,26 @@
        break;
      case GREATER_OR_EQUAL:
        buffer.append("(");
        buffer.append(attributeType);
        buffer.append(attributeDescription);
        buffer.append(">=");
        valueToFilterString(buffer, assertionValue);
        buffer.append(")");
        break;
      case LESS_OR_EQUAL:
        buffer.append("(");
        buffer.append(attributeType);
        buffer.append(attributeDescription);
        buffer.append("<=");
        valueToFilterString(buffer, assertionValue);
        buffer.append(")");
        break;
      case PRESENT:
        buffer.append("(");
        buffer.append(attributeType);
        buffer.append(attributeDescription);
        buffer.append("=*)");
        break;
      case APPROXIMATE_MATCH:
        buffer.append("(");
        buffer.append(attributeType);
        buffer.append(attributeDescription);
        buffer.append("~=");
        valueToFilterString(buffer, assertionValue);
        buffer.append(")");
@@ -2039,9 +2026,9 @@
      case EXTENSIBLE_MATCH:
        buffer.append("(");
        if (attributeType != null)
        if (attributeDescription != null)
        {
          buffer.append(attributeType);
          buffer.append(attributeDescription);
        }
        if (dnAttributes)
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/HistoricalAttributeValue.java
@@ -19,15 +19,9 @@
import static org.opends.server.replication.plugin.HistAttrModificationKey.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.opends.server.core.DirectoryServer;
import org.opends.server.replication.common.CSN;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
@@ -74,12 +68,12 @@
  private final CSN csn;
  private final HistAttrModificationKey histKey;
  private final String stringValue;
  private boolean attrTypeIsNull;
  /**
   * This flag indicates that this value was generated to store the last date
   * when the entry was renamed.
   */
  private boolean isModDN;
  private final boolean isModDN;
  /**
   * Create a new object from the String encoded form.
@@ -91,43 +85,14 @@
  {
    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)
      {
        options.add(optionsToken[index]);
        index ++;
      }
      attrString = toLowerCase(optionsToken[0]);
    }
    else
    {
      options = Collections.emptySet();
      attrString = toLowerCase(token[0]);
    }
    AttributeType attrType;
    if (attrString.compareTo("dn") != 0)
    {
      // This HistVal was used to store the date when some
      // modifications were done to the entries.
      attrType = DirectoryServer.getAttributeType(attrString);
    }
    else
    {
      // This HistVal is used to store the date when the entry
      // was added to the directory or when it was last renamed.
      attrType = null;
      if (token.length >= 3 && token[2].compareTo("moddn") == 0)
      {
        isModDN = true;
      }
    }
    this.attrDesc = attrType != null ? AttributeDescription.create(attrType, options) : null;
    attrDesc = AttributeDescription.valueOf(token[0]);
    attrString = toLowerCase(attrDesc.getNameOrOID());
    // This HistVal was used to store the date when some
    // modifications were done to the entries.
    attrTypeIsNull = attrString.equalsIgnoreCase("dn");
    // This HistVal is used to store the date when the entry
    // was added to the directory or when it was last renamed.
    isModDN = attrTypeIsNull && token.length >= 3 && token[2].compareTo("moddn") == 0;
    csn = new CSN(token[1]);
    histKey = HistAttrModificationKey.decodeKey(token[2]);
@@ -151,16 +116,6 @@
    }
  }
  private AttributeType getAttributeType()
  {
    return attrDesc != null ? attrDesc.getAttributeType() : null;
  }
  private Iterable<String> getOptions()
  {
    return attrDesc != null ? attrDesc.getOptions() : Collections.<String> emptySet();
  }
  /**
   * Get the String form of the attribute type.
   *
@@ -218,8 +173,8 @@
   */
  public Modification generateMod()
  {
    AttributeBuilder builder = new AttributeBuilder(getAttributeType(), attrString);
    builder.setOptions(getOptions());
    AttributeBuilder builder = new AttributeBuilder(attrDesc.getAttributeType(), attrString);
    builder.setOptions(attrDesc.getOptions());
    if (histKey != ATTRDEL)
    {
@@ -249,7 +204,7 @@
   */
  public boolean isADDOperation()
  {
    return getAttributeType() == null && !isModDN;
    return attrTypeIsNull && !isModDN;
  }
  /**
@@ -260,18 +215,14 @@
   */
  public boolean isMODDNOperation()
  {
    return getAttributeType() == null && isModDN;
    return attrTypeIsNull && isModDN;
  }
  @Override
  public String toString()
  {
    final StringBuilder sb = new StringBuilder();
    sb.append(attrString);
    for (String option : getOptions())
    {
      sb.append(";").append(option);
    }
    sb.append(attrDesc);
    sb.append(":").append(csn).append(":").append(getModificationType());
    if (stringValue != null)
    {
opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java
@@ -3556,7 +3556,6 @@
      int endPos;
      for (int i=0; i < attrs; i++)
      {
        // First, we have the zero-terminated attribute name.
        startPos = entryBuffer.position();
        while (entryBuffer.readByte() != 0x00)
@@ -3566,38 +3565,9 @@
        String name = entryBuffer.readStringUtf8(endPos - startPos);
        entryBuffer.skip(1);
        AttributeType attributeType;
        int semicolonPos = name.indexOf(';');
        if (semicolonPos > 0)
        {
          builder.setAttributeType(name.substring(0, semicolonPos));
          attributeType = builder.getAttributeType();
          int nextPos = name.indexOf(';', semicolonPos+1);
          while (nextPos > 0)
          {
            String option = name.substring(semicolonPos+1, nextPos);
            if (option.length() > 0)
            {
              builder.setOption(option);
            }
            semicolonPos = nextPos;
            nextPos = name.indexOf(';', semicolonPos+1);
          }
          String option = name.substring(semicolonPos+1);
          if (option.length() > 0)
          {
            builder.setOption(option);
          }
        }
        else
        {
          builder.setAttributeType(name);
          attributeType = builder.getAttributeType();
        }
        AttributeDescription attrDesc = AttributeDescription.valueOf(name);
        builder.setAttributeType(attrDesc.getAttributeType(), attrDesc.getNameOrOID());
        builder.setOptions(attrDesc.getOptions());
        // Next, we have the number of values.
        int numValues = entryBuffer.readBERLength();
@@ -3606,15 +3576,13 @@
        for (int j=0; j < numValues; j++)
        {
          int valueLength = entryBuffer.readBERLength();
          ByteString valueBytes =
              entryBuffer.readByteSequence(valueLength).toByteString();
          builder.add(valueBytes);
          builder.add(entryBuffer.readByteSequence(valueLength).toByteString());
        }
        // Create the attribute and add it to the set of attributes.
        Attribute a = builder.toAttribute();
        AttributeType attributeType = a.getAttributeDescription().getAttributeType();
        List<Attribute> attrList = attributes.get(attributeType);
        if (attrList == null)
        {
@@ -4470,55 +4438,30 @@
          continue;
        }
        String name;
        Set<String> options;
        int semicolonPos = attrName.indexOf(';');
        if (semicolonPos > 0)
        {
          String tmpName = attrName.substring(0, semicolonPos);
          name = tmpName;
          int nextPos = attrName.indexOf(';', semicolonPos+1);
          options = new HashSet<>();
          while (nextPos > 0)
          {
            options.add(attrName.substring(semicolonPos+1, nextPos));
            semicolonPos = nextPos;
            nextPos = attrName.indexOf(';', semicolonPos+1);
          }
          options.add(attrName.substring(semicolonPos+1));
          attrName = tmpName;
        }
        else
        {
          name = attrName;
          options = null;
        }
        AttributeType attrType = DirectoryServer.getAttributeType(name);
        AttributeDescription attrDesc = AttributeDescription.valueOf(attrName);
        attrName = attrDesc.getNameOrOID();
        final AttributeType attrType = attrDesc.getAttributeType();
        if (attrType.isPlaceHolder())
        {
          // Unrecognized attribute type - do best effort search.
          for (Map.Entry<AttributeType, List<Attribute>> e :
            userAttributes.entrySet())
          for (Map.Entry<AttributeType, List<Attribute>> e : userAttributes.entrySet())
          {
            AttributeType t = e.getKey();
            if (t.hasNameOrOID(name))
            if (t.hasNameOrOID(attrName))
            {
              mergeAttributeLists(e.getValue(), userAttrsCopy, t,
                  attrName, options, omitValues, omitReal, omitVirtual);
              mergeAttributeLists(e.getValue(), userAttrsCopy, attrDesc,
                  omitValues, omitReal, omitVirtual);
              continue;
            }
          }
          for (Map.Entry<AttributeType, List<Attribute>> e :
            operationalAttributes.entrySet())
          for (Map.Entry<AttributeType, List<Attribute>> e : operationalAttributes.entrySet())
          {
            AttributeType t = e.getKey();
            if (t.hasNameOrOID(name))
            if (t.hasNameOrOID(attrName))
            {
              mergeAttributeLists(e.getValue(), operationalAttrsCopy,
                  t, attrName, options, omitValues, omitReal, omitVirtual);
              mergeAttributeLists(e.getValue(), operationalAttrsCopy, attrDesc,
                 omitValues, omitReal, omitVirtual);
              continue;
            }
          }
@@ -4556,17 +4499,16 @@
            List<Attribute> attrList = getUserAttribute(attrType);
            if (!attrList.isEmpty())
            {
              mergeAttributeLists(attrList, userAttrsCopy, attrType,
                  attrName, options, omitValues, omitReal, omitVirtual);
              mergeAttributeLists(attrList, userAttrsCopy, attrDesc,
                  omitValues, omitReal, omitVirtual);
            }
            else
            {
              attrList = getOperationalAttribute(attrType);
              if (!attrList.isEmpty())
              {
                mergeAttributeLists(attrList, operationalAttrsCopy,
                    attrType, attrName, options, omitValues, omitReal,
                    omitVirtual);
                mergeAttributeLists(attrList, operationalAttrsCopy, attrDesc,
                    omitValues, omitReal, omitVirtual);
              }
            }
          }
@@ -4578,39 +4520,8 @@
                     operationalAttrsCopy);
  }
  /**
   * Copies the provided list of attributes into the destination
   * attribute map according to the provided criteria.
   *
   * @param sourceList
   *          The list containing the attributes to be copied.
   * @param destMap
   *          The map where the attributes should be copied to.
   * @param attrType
   *          The attribute type.
   * @param attrName
   *          The user-provided attribute name.
   * @param options
   *          The user-provided attribute options.
   * @param omitValues
   *          Indicates whether to exclude attribute values.
   * @param omitReal
   *          Indicates whether to exclude real attributes.
   * @param omitVirtual
   *          Indicates whether to exclude virtual attributes.
   */
  private void mergeAttributeLists(List<Attribute> sourceList,
      Map<AttributeType, List<Attribute>> destMap,
      AttributeType attrType, String attrName, Set<String> options,
      boolean omitValues, boolean omitReal, boolean omitVirtual)
  {
    AttributeDescription attrDesc = AttributeDescription.create(attrType, options);
    mergeAttributeLists(sourceList, destMap, attrDesc, attrName, omitValues, omitReal, omitVirtual);
  }
  private void mergeAttributeLists(List<Attribute> sourceList,
      Map<AttributeType, List<Attribute>> destMap,
      AttributeDescription attrDesc, String attrName,
      Map<AttributeType, List<Attribute>> destMap, AttributeDescription attrDesc,
      boolean omitValues, boolean omitReal, boolean omitVirtual)
  {
    if (sourceList == null)
@@ -4618,6 +4529,7 @@
      return;
    }
    final String attrName = attrDesc.getNameOrOID();
    for (Attribute attribute : sourceList)
    {
      if (attribute.isEmpty()