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

Matthew Swift
17.47.2014 0f08cc0ba7dfb3a3ad5217e6fdd137aa53abebfa
OPENDJ-1368 (CR-3177) Remove AttributeValue

Removed cached attribute value sets in Schema as well as associated DirectoryServer getters. Simplified schema entry construction in SchemaBackend.
5 files modified
834 ■■■■ changed files
opendj3-server-dev/src/server/org/opends/server/backends/SchemaBackend.java 438 ●●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java 115 ●●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/schema/AttributeTypeSyntax.java 3 ●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/types/Schema.java 270 ●●●●● patch | view | raw | blame | history
opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java 8 ●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/backends/SchemaBackend.java
@@ -35,6 +35,7 @@
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -55,7 +56,6 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ConditionResult;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.ResultCode;
@@ -713,271 +713,47 @@
      for (int i = 0; i < numAVAs; i++)
      {
        AttributeType attrType = rdn.getAttributeType(i);
        Attribute a = Attributes.create(attrType, rdn
            .getAttributeValue(i));
        ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
        attrList.add(a);
        if (attrType.isOperational())
        {
          operationalAttrs.put(attrType, attrList);
        }
        else
        {
          userAttrs.put(attrType, attrList);
        }
        Attribute attribute = Attributes.create(attrType,
            rdn.getAttributeValue(i));
        addAttributeToSchemaEntry(attribute, userAttrs, operationalAttrs);
      }
    }
    /*
     * Add the schema definition attributes.
     */
    Schema schema = DirectoryServer.getSchema();
    buildSchemaAttribute(schema.getAttributeTypes().values(), userAttrs,
        operationalAttrs, attributeTypesType, includeSchemaFile,
        AttributeTypeSyntax.isStripSyntaxMinimumUpperBound(),
        ignoreShowAllOption);
    buildSchemaAttribute(schema.getObjectClasses().values(), userAttrs,
        operationalAttrs, objectClassesType, includeSchemaFile, false,
        ignoreShowAllOption);
    buildSchemaAttribute(schema.getMatchingRules().values(), userAttrs,
        operationalAttrs, matchingRulesType, includeSchemaFile, false,
        ignoreShowAllOption);
    // Add the "attributeTypes" attribute.
    Set<AttributeValue> valueSet = DirectoryServer.getAttributeTypeSet();
    // Add the file name to the description of the attribute type if
    // this was requested by the caller.
    if (includeSchemaFile)
    {
      Set<AttributeValue> newValueSet =
        new LinkedHashSet<AttributeValue>(valueSet.size());
      for (AttributeValue value : valueSet)
      {
        try
        {
          // Build a new attribute from this value,
          // get the File name from this attribute, build a new
          // attribute including this file name.
          AttributeType attrType = AttributeTypeSyntax.decodeAttributeType(
              value.getValue(), schema, false);
          attrType = DirectoryServer.getAttributeType(attrType.getOID());
          newValueSet.add(
              AttributeValues.create(attributeTypesType,
              getDefinitionWithFileName(attrType)));
        }
        catch (DirectoryException e)
        {
          newValueSet.add(value);
        }
      }
      valueSet = newValueSet;
    }
    AttributeBuilder builder = new AttributeBuilder(attributeTypesType,
        ATTR_ATTRIBUTE_TYPES);
    builder.setInitialCapacity(valueSet.size());
    if (AttributeTypeSyntax.isStripSyntaxMinimumUpperBound())
    {
      for (AttributeValue v : valueSet)
      {
        // If it exists, strip the minimum upper bound value from the
        // attribute value.
        if (v.toString().indexOf('{') != -1)
        {
          // Create an attribute value from the stripped string and
          // add it to the valueset.
          String strippedStr = v.toString().replaceFirst(
              stripMinUpperBoundRegEx, "");
          ByteString s = ByteString.valueOf(strippedStr);
          AttributeValue strippedVal = AttributeValues.create(s, s);
          builder.add(strippedVal);
        }
        else
        {
          builder.add(v);
        }
      }
    }
    else
    {
      builder.addAll(valueSet);
    }
    ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
    attrList.add(builder.toAttribute());
    if (attributeTypesType.isOperational() &&
        (ignoreShowAllOption || (!showAllAttributes)))
    {
      operationalAttrs.put(attributeTypesType, attrList);
    }
    else
    {
      userAttrs.put(attributeTypesType, attrList);
    }
    // Add the "objectClasses" attribute.
    valueSet = DirectoryServer.getObjectClassSet();
    // Add the file name to the description if this was requested by
    // the caller.
    if (includeSchemaFile)
    {
      Set<AttributeValue> newValueSet =
        new LinkedHashSet<AttributeValue>(valueSet.size());
      for (AttributeValue value : valueSet)
      {
        try
        {
          // Build a new attribute from this value, get the File name
          // from this attribute, build a new attribute including this
          // file name.
          ObjectClass oc = ObjectClassSyntax.decodeObjectClass(
              value.getValue(), schema, false);
          oc = DirectoryServer.getObjectClass(oc.getOID());
          newValueSet.add(AttributeValues.create(
              objectClassesType, getDefinitionWithFileName(oc)));
        }
        catch (DirectoryException e)
        {
          newValueSet.add(value);
        }
      }
      valueSet = newValueSet;
    }
    builder = new AttributeBuilder(objectClassesType, ATTR_OBJECTCLASSES);
    builder.addAll(valueSet);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(builder.toAttribute());
    if (objectClassesType.isOperational() &&
        (ignoreShowAllOption || (!showAllAttributes)))
    {
      operationalAttrs.put(objectClassesType, attrList);
    }
    else
    {
      userAttrs.put(objectClassesType, attrList);
    }
    // Add the "matchingRules" attribute.
    builder = new AttributeBuilder(matchingRulesType, ATTR_MATCHING_RULES);
    builder.addAll(DirectoryServer.getMatchingRuleSet());
    attrList = new ArrayList<Attribute>(1);
    attrList.add(builder.toAttribute());
    if (matchingRulesType.isOperational() &&
        (ignoreShowAllOption || (!showAllAttributes)))
    {
      operationalAttrs.put(matchingRulesType, attrList);
    }
    else
    {
      userAttrs.put(matchingRulesType, attrList);
    }
    // Add the "ldapSyntaxes" attribute.
    builder = new AttributeBuilder(ldapSyntaxesType, ATTR_LDAP_SYNTAXES);
    builder.addAll(DirectoryServer.getAttributeSyntaxSet());
    attrList = new ArrayList<Attribute>(1);
    attrList.add(builder.toAttribute());
    // Note that we intentionally ignore showAllAttributes for
    // attribute syntaxes, name forms, matching rule uses, DIT content
    // rules, and DIT structure rules because those attributes aren't
    // allowed in the subschema objectclass, and treating them as user
    // attributes would cause schema updates to fail. This means that
    // you'll always have to explicitly request these attributes in
    // order to be able to see them.
    if (ldapSyntaxesType.isOperational())
    {
      operationalAttrs.put(ldapSyntaxesType, attrList);
    }
    else
    {
      userAttrs.put(ldapSyntaxesType, attrList);
    }
    // If there are any name forms defined, then add them.
    valueSet = DirectoryServer.getNameFormSet();
    if (!valueSet.isEmpty())
    {
      builder = new AttributeBuilder(nameFormsType, ATTR_NAME_FORMS);
      builder.addAll(valueSet);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(builder.toAttribute());
      if (nameFormsType.isOperational())
      {
        operationalAttrs.put(nameFormsType, attrList);
      }
      else
      {
        userAttrs.put(nameFormsType, attrList);
      }
    }
    // If there are any DIT content rules defined, then add them.
    valueSet = DirectoryServer.getDITContentRuleSet();
    if (!valueSet.isEmpty())
    {
      builder = new AttributeBuilder(ditContentRulesType,
          ATTR_DIT_CONTENT_RULES);
      builder.addAll(valueSet);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(builder.toAttribute());
      if (ditContentRulesType.isOperational())
      {
        operationalAttrs.put(ditContentRulesType, attrList);
      }
      else
      {
        userAttrs.put(ditContentRulesType, attrList);
      }
    }
    // If there are any DIT structure rules defined, then add them.
    valueSet = DirectoryServer.getDITStructureRuleSet();
    if (!valueSet.isEmpty())
    {
      builder = new AttributeBuilder(ditStructureRulesType,
          ATTR_DIT_STRUCTURE_RULES);
      builder.addAll(valueSet);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(builder.toAttribute());
      if (ditStructureRulesType.isOperational())
      {
        operationalAttrs.put(ditStructureRulesType, attrList);
      }
      else
      {
        userAttrs.put(ditStructureRulesType, attrList);
      }
    }
    // If there are any matching rule uses defined, then add them.
    valueSet = DirectoryServer.getMatchingRuleUseSet();
    if (!valueSet.isEmpty())
    {
      builder = new AttributeBuilder(matchingRuleUsesType,
          ATTR_MATCHING_RULE_USE);
      builder.addAll(valueSet);
      attrList = new ArrayList<Attribute>(1);
      attrList.add(builder.toAttribute());
      if (matchingRuleUsesType.isOperational())
      {
        operationalAttrs.put(matchingRuleUsesType, attrList);
      }
      else
      {
        userAttrs.put(matchingRuleUsesType, attrList);
      }
    }
    /*
     * Note that we intentionally ignore showAllAttributes for attribute
     * syntaxes, name forms, matching rule uses, DIT content rules, and DIT
     * structure rules because those attributes aren't allowed in the subschema
     * objectclass, and treating them as user attributes would cause schema
     * updates to fail. This means that you'll always have to explicitly request
     * these attributes in order to be able to see them.
     */
    buildSchemaAttribute(schema.getSyntaxes().values(), userAttrs,
        operationalAttrs, ldapSyntaxesType, includeSchemaFile, false, true);
    buildSchemaAttribute(schema.getNameFormsByNameOrOID().values(), userAttrs,
        operationalAttrs, nameFormsType, includeSchemaFile, false, true);
    buildSchemaAttribute(schema.getDITContentRules().values(), userAttrs,
        operationalAttrs, ditContentRulesType, includeSchemaFile, false, true);
    buildSchemaAttribute(schema.getDITStructureRulesByID().values(), userAttrs,
        operationalAttrs, ditStructureRulesType, includeSchemaFile, false, true);
    buildSchemaAttribute(schema.getMatchingRuleUses().values(), userAttrs,
        operationalAttrs, matchingRuleUsesType, includeSchemaFile, false, true);
    // Add the lastmod attributes.
    attrList = new ArrayList<Attribute>(1);
    attrList.add(Attributes.create(creatorsNameType, creatorsName));
    operationalAttrs.put(creatorsNameType, attrList);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(Attributes.create(createTimestampType, createTimestamp));
    operationalAttrs.put(createTimestampType, attrList);
    if (DirectoryServer.getSchema().getYoungestModificationTime() != modifyTime)
    {
      synchronized (this)
@@ -987,58 +763,30 @@
            .createGeneralizedTimeValue(modifyTime);
      }
    }
    attrList = new ArrayList<Attribute>(1);
    attrList.add(Attributes.create(modifiersNameType, modifiersName));
    operationalAttrs.put(modifiersNameType, attrList);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(Attributes.create(modifyTimestampType, modifyTimestamp));
    operationalAttrs.put(modifyTimestampType, attrList);
    addAttributeToSchemaEntry(
        Attributes.create(creatorsNameType, creatorsName), userAttrs,
        operationalAttrs);
    addAttributeToSchemaEntry(
        Attributes.create(createTimestampType, createTimestamp), userAttrs,
        operationalAttrs);
    addAttributeToSchemaEntry(
        Attributes.create(modifiersNameType, modifiersName), userAttrs,
        operationalAttrs);
    addAttributeToSchemaEntry(
        Attributes.create(modifyTimestampType, modifyTimestamp), userAttrs,
        operationalAttrs);
    // Add the extra attributes.
    Map<String, Attribute> attributes = DirectoryServer.getSchema()
        .getExtraAttributes();
    for (Attribute attribute : attributes.values())
    for (Attribute attribute : DirectoryServer.getSchema().getExtraAttributes()
        .values())
    {
      attrList = new ArrayList<Attribute>(1);
      attrList.add(attribute);
      operationalAttrs.put(attribute.getAttributeType(), attrList);
      addAttributeToSchemaEntry(attribute, userAttrs, operationalAttrs);
    }
    // Add all the user-defined attributes.
    for (Attribute a : userDefinedAttributes)
    for (Attribute attribute : userDefinedAttributes)
    {
      AttributeType type = a.getAttributeType();
      if (type.isOperational())
      {
        List<Attribute> attrs = operationalAttrs.get(type);
        if (attrs == null)
        {
          attrs = new ArrayList<Attribute>();
          attrs.add(a);
          operationalAttrs.put(type, attrs);
        }
        else
        {
          attrs.add(a);
        }
      }
      else
      {
        List<Attribute> attrs = userAttrs.get(type);
        if (attrs == null)
        {
          attrs = new ArrayList<Attribute>();
          attrs.add(a);
          userAttrs.put(type, attrs);
        }
        else
        {
          attrs.add(a);
        }
      }
      addAttributeToSchemaEntry(attribute, userAttrs, operationalAttrs);
    }
    // Construct and return the entry.
@@ -1050,6 +798,88 @@
  private void addAttributeToSchemaEntry(Attribute attribute,
      Map<AttributeType, List<Attribute>> userAttrs,
      Map<AttributeType, List<Attribute>> operationalAttrs)
  {
    AttributeType type = attribute.getAttributeType();
    if (type.isOperational())
    {
      List<Attribute> attrs = operationalAttrs.get(type);
      if (attrs == null)
      {
        attrs = new ArrayList<Attribute>(1);
        operationalAttrs.put(type, attrs);
      }
      attrs.add(attribute);
    }
    else
    {
      List<Attribute> attrs = userAttrs.get(type);
      if (attrs == null)
      {
        attrs = new ArrayList<Attribute>();
        userAttrs.put(type, attrs);
      }
      attrs.add(attribute);
    }
  }
  private void buildSchemaAttribute(Collection<?> elements,
      Map<AttributeType, List<Attribute>> userAttrs,
      Map<AttributeType, List<Attribute>> operationalAttrs,
      AttributeType schemaAttributeType, boolean includeSchemaFile,
      final boolean stripSyntaxMinimumUpperBound, boolean ignoreShowAllOption)
  {
    // Skip the schema attribute if it is empty.
    if (elements.isEmpty())
    {
      return;
    }
    AttributeBuilder builder = new AttributeBuilder(schemaAttributeType);
    builder.setInitialCapacity(elements.size());
    for (Object element : elements)
    {
      /*
       * Add the file name to the description of the element if this was
       * requested by the caller.
       */
      String value;
      if (includeSchemaFile && element instanceof CommonSchemaElements)
      {
        value = getDefinitionWithFileName((CommonSchemaElements) element);
      }
      else
      {
        value = element.toString();
      }
      if (stripSyntaxMinimumUpperBound && value.indexOf('{') != -1)
      {
        // Strip the minimum upper bound value from the attribute value.
        value = value.replaceFirst(stripMinUpperBoundRegEx, "");
      }
      builder.add(value);
    }
    ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
    Attribute attribute = builder.toAttribute();
    attrList.add(attribute);
    if (attribute.getAttributeType().isOperational()
        && (ignoreShowAllOption || (!showAllAttributes)))
    {
      operationalAttrs.put(attribute.getAttributeType(), attrList);
    }
    else
    {
      userAttrs.put(attribute.getAttributeType(), attrList);
    }
  }
  /**
   * {@inheritDoc}
   */
opendj3-server-dev/src/server/org/opends/server/core/DirectoryServer.java
@@ -196,7 +196,6 @@
import org.opends.server.tools.ConfigureWindowsService;
import org.opends.server.types.AcceptRejectWarn;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.BackupConfig;
import org.opends.server.types.Control;
import org.opends.server.types.DITContentRule;
@@ -3049,20 +3048,6 @@
  /**
   * Retrieves the set of encoded matching rules that have been defined in the
   * Directory Server.
   *
   * @return  The set of encoded matching rules that have been defined in the
   *          Directory Server.
   */
  public static Set<AttributeValue> getMatchingRuleSet()
  {
    return directoryServer.schema.getMatchingRuleSet();
  }
  /**
   * Retrieves the matching rule with the specified name or OID.
   *
   * @param  lowerName  The lowercase name or OID for the matching rule to
@@ -3123,7 +3108,7 @@
  public static MatchingRule
                     getApproximateMatchingRule(String lowerName)
  {
    return (MatchingRule) directoryServer.schema.getMatchingRule(lowerName);
    return directoryServer.schema.getMatchingRule(lowerName);
  }
@@ -3298,20 +3283,6 @@
  /**
   * Retrieves the set of encoded objectclasses that have been defined in the
   * Directory Server.
   *
   * @return  The set of encoded objectclasses that have been defined in the
   *          Directory Server.
   */
  public static Set<AttributeValue> getObjectClassSet()
  {
    return directoryServer.schema.getObjectClassSet();
  }
  /**
   * Retrieves the objectclass for the provided lowercase name or OID.
   *
   * @param  lowerName  The lowercase name or OID for the objectclass to
@@ -3502,20 +3473,6 @@
  /**
   * Retrieves the set of encoded attribute types that have been defined in the
   * Directory Server.
   *
   * @return  The set of encoded attribute types that have been defined in the
   *          Directory Server.
   */
  public static Set<AttributeValue> getAttributeTypeSet()
  {
    return directoryServer.schema.getAttributeTypeSet();
  }
  /**
   * Retrieves the attribute type for the provided lowercase name or OID.
   *
   * @param  lowerName  The lowercase attribute name or OID for the attribute
@@ -3712,20 +3669,6 @@
    return directoryServer.schema.getSyntaxes();
  }
  /**
   * Retrieves the set of encoded attribute syntaxes that have been defined in
   * the Directory Server.
   *
   * @return  The set of encoded attribute syntaxes that have been defined in
   *          the Directory Server.
   */
  public static Set<AttributeValue> getAttributeSyntaxSet()
  {
    return directoryServer.schema.getSyntaxSet();
  }
  /**
   * Retrieves the default attribute syntax that should be used for attributes
   * that are not defined in the server schema.
@@ -3833,20 +3776,6 @@
  /**
   * Retrieves the set of encoded matching rule uses that have been defined in
   * the Directory Server.
   *
   * @return  The set of encoded matching rule uses that have been defined in
   *          the Directory Server.
   */
  public static Set<AttributeValue> getMatchingRuleUseSet()
  {
    return directoryServer.schema.getMatchingRuleUseSet();
  }
  /**
   * Retrieves the matching rule use associated with the provided matching rule.
   *
   * @param  matchingRule  The matching rule for which to retrieve the matching
@@ -3913,20 +3842,6 @@
  /**
   * Retrieves the set of encoded DIT content rules that have been defined in
   * the Directory Server.
   *
   * @return  The set of encoded DIT content rules that have been defined in the
   *          Directory Server.
   */
  public static Set<AttributeValue> getDITContentRuleSet()
  {
    return directoryServer.schema.getDITContentRuleSet();
  }
  /**
   * Retrieves the DIT content rule associated with the specified objectclass.
   *
   * @param  objectClass  The objectclass for which to retrieve the associated
@@ -3992,20 +3907,6 @@
  /**
   * Retrieves the set of encoded DIT structure rules that have been defined in
   * the Directory Server.
   *
   * @return  The set of encoded DIT structure rules that have been defined in
   *          the Directory Server.
   */
  public static Set<AttributeValue> getDITStructureRuleSet()
  {
    return directoryServer.schema.getDITStructureRuleSet();
  }
  /**
   * Retrieves the DIT structure rule associated with the provided rule ID.
   *
   * @param  ruleID  The rule ID for which to retrieve the associated DIT
@@ -4088,20 +3989,6 @@
  /**
   * Retrieves the set of encoded name forms that have been defined in the
   * Directory Server.
   *
   * @return  The set of encoded name forms that have been defined in the
   *          Directory Server.
   */
  public static Set<AttributeValue> getNameFormSet()
  {
    return directoryServer.schema.getNameFormSet();
  }
  /**
   * Retrieves the name forms associated with the specified objectclass.
   *
   * @param  objectClass  The objectclass for which to retrieve the associated
opendj3-server-dev/src/server/org/opends/server/schema/AttributeTypeSyntax.java
@@ -913,8 +913,7 @@
    {
      String ruleName  = approxRules.get(0);
      String lowerName = toLowerCase(ruleName);
      MatchingRule amr =
           (MatchingRule) schema.getMatchingRule(lowerName);
      MatchingRule amr = schema.getMatchingRule(lowerName);
      if (amr == null)
      {
        // This is bad because we have no idea what the approximate matching
opendj3-server-dev/src/server/org/opends/server/types/Schema.java
@@ -41,7 +41,6 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.ResultCode;
import org.opends.server.admin.std.server.DirectoryStringAttributeSyntaxCfg;
@@ -55,7 +54,6 @@
import org.opends.server.schema.MatchingRuleUseSyntax;
import org.opends.server.schema.NameFormSyntax;
import org.opends.server.schema.ObjectClassSyntax;
import org.opends.server.schema.CaseIgnoreEqualityMatchingRule;
import org.opends.server.util.StaticUtils;
import static org.opends.messages.BackendMessages.*;
@@ -90,15 +88,6 @@
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /**
   * The matching rule that will be used to normalize schema element
   * definitions.
   */
  private MatchingRule normalizationMatchingRule;
  /**
   * The set of subordinate attribute types registered within the server schema.
   */
@@ -184,30 +173,6 @@
  private ConcurrentHashMap<String,LDAPSyntaxDescription>
          ldapSyntaxDescriptions;
  /** The set of pre-encoded attribute syntax representations. */
  private Set<AttributeValue> syntaxSet;
  /** The set of pre-encoded attribute type representations. */
  private Set<AttributeValue> attributeTypeSet;
  /** The set of pre-encoded DIT content rule representations. */
  private Set<AttributeValue> ditContentRuleSet;
  /** The set of pre-encoded DIT structure rule representations. */
  private Set<AttributeValue> ditStructureRuleSet;
  /** The set of pre-encoded matching rule representations. */
  private Set<AttributeValue> matchingRuleSet;
  /** The set of pre-encoded matching rule use representations. */
  private Set<AttributeValue> matchingRuleUseSet;
  /** The set of pre-encoded name form representations. */
  private Set<AttributeValue> nameFormSet;
  /** The set of pre-encoded objectclass representations. */
  private Set<AttributeValue> objectClassSet;
  /** The oldest modification timestamp for any schema configuration file. */
  private long oldestModificationTime;
@@ -251,17 +216,6 @@
    subordinateTypes =
         new ConcurrentHashMap<AttributeType,List<AttributeType>>();
    syntaxSet           = new LinkedHashSet<AttributeValue>();
    attributeTypeSet    = new LinkedHashSet<AttributeValue>();
    ditContentRuleSet   = new LinkedHashSet<AttributeValue>();
    ditStructureRuleSet = new LinkedHashSet<AttributeValue>();
    matchingRuleSet     = new LinkedHashSet<AttributeValue>();
    matchingRuleUseSet  = new LinkedHashSet<AttributeValue>();
    nameFormSet         = new LinkedHashSet<AttributeValue>();
    objectClassSet      = new LinkedHashSet<AttributeValue>();
    normalizationMatchingRule = new CaseIgnoreEqualityMatchingRule();
    oldestModificationTime    = System.currentTimeMillis();
    youngestModificationTime  = oldestModificationTime;
  }
@@ -286,18 +240,6 @@
  /**
   * Retrieves the set of defined attribute types for this schema.
   *
   * @return  The set of defined attribute types for this schema.
   */
  public Set<AttributeValue> getAttributeTypeSet()
  {
    return attributeTypeSet;
  }
  /**
   * Indicates whether this schema definition includes an attribute
   * type with the provided name or OID.
   *
@@ -402,21 +344,6 @@
      {
        registerSubordinateType(attributeType, superiorType);
      }
      attributeTypeSet.add(createAttrValueForAdd(attributeType));
    }
  }
  private ByteString normalizeAttributeValue(ByteString rawValue)
      throws DirectoryException
  {
    try
    {
      return normalizationMatchingRule.normalizeAttributeValue(rawValue);
    }
    catch (DecodeException e)
    {
      throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
          e.getMessageObject(), e);
    }
  }
@@ -449,47 +376,10 @@
      {
        deregisterSubordinateType(attributeType, superiorType);
      }
      attributeTypeSet.remove(createAttrValueForRemove(attributeType));
    }
  }
  /**
   * We'll use an attribute value including the normalized value rather than the
   * attribute type because otherwise it would use a very expensive matching
   * rule (OID first component match) that would kill performance.
   */
  private AttributeValue createAttrValueForRemove(Object elem)
  {
    final String valueString = elem.toString();
    final ByteString rawValue = ByteString.valueOf(valueString);
    final ByteString normValue = normalizeAttrValue(valueString, rawValue);
    return AttributeValues.create(rawValue, normValue);
  }
  private ByteString normalizeAttrValue(String valueString, ByteString rawValue)
  {
    try
    {
      return normalizeAttributeValue(rawValue);
    }
    catch (Exception e)
    {
      return ByteString.valueOf(toLowerCase(valueString));
    }
  }
  private AttributeValue createAttrValueForAdd(Object elem)
      throws DirectoryException
  {
    final String valueString = elem.toString();
    final ByteString rawValue = ByteString.valueOf(valueString);
    final ByteString normValue = normalizeAttributeValue(rawValue);
    return AttributeValues.create(rawValue, normValue);
  }
  /**
   * Registers the provided attribute type as a subtype of the given
   * superior attribute type, recursively following any additional
@@ -600,18 +490,6 @@
  /**
   * Retrieves the set of defined objectclasses for this schema.
   *
   * @return  The set of defined objectclasses for this schema.
   */
  public Set<AttributeValue> getObjectClassSet()
  {
    return objectClassSet;
  }
  /**
   * Indicates whether this schema definition includes an objectclass
   * with the provided name or OID.
   *
@@ -709,7 +587,6 @@
      {
        objectClasses.put(name, objectClass);
      }
      objectClassSet.add(createAttrValueForAdd(objectClass));
    }
  }
@@ -736,7 +613,6 @@
      {
        objectClasses.remove(name, objectClass);
      }
      objectClassSet.remove(createAttrValueForRemove(objectClass));
    }
  }
@@ -759,18 +635,6 @@
  /**
   * Retrieves the set of defined attribute syntaxes for this schema.
   *
   * @return  The set of defined attribute syntaxes for this schema.
   */
  public Set<AttributeValue> getSyntaxSet()
  {
    return syntaxSet;
  }
  /**
   * Indicates whether this schema definition includes an attribute
   * syntax with the provided name or OID.
   *
@@ -798,9 +662,9 @@
   *         syntax is unknown and the caller has indicated that the default is
   *         acceptable, or <CODE>null</CODE> otherwise.
   */
  public AttributeSyntax getSyntax(String oid, boolean allowDefault)
  public AttributeSyntax<?> getSyntax(String oid, boolean allowDefault)
  {
    AttributeSyntax syntax = getSyntax(oid);
    AttributeSyntax<?> syntax = getSyntax(oid);
    if (syntax == null && allowDefault)
    {
      return getDefaultSyntax();
@@ -830,7 +694,7 @@
   * @return  The default attribute syntax that should be used for attributes
   *          that are not defined in the server schema.
   */
  public AttributeSyntax getDefaultSyntax()
  public AttributeSyntax<?> getDefaultSyntax()
  {
    return defaultSyntax;
  }
@@ -888,7 +752,6 @@
      }
      syntaxes.put(toLowerCase(syntax.getOID()), syntax);
      syntaxSet.add(createAttrValueForAdd(syntax));
    }
  }
@@ -906,7 +769,6 @@
    synchronized (syntaxes)
    {
      syntaxes.remove(toLowerCase(syntax.getOID()), syntax);
      syntaxSet.remove(createAttrValueForRemove(syntax));
    }
  }
@@ -1071,18 +933,6 @@
  /**
   * Retrieves the set of defined matching rules for this schema.
   *
   * @return  The set of defined matching rules for this schema.
   */
  public Set<AttributeValue> getMatchingRuleSet()
  {
    return matchingRuleSet;
  }
  /**
   * Indicates whether this schema definition includes a matching rule
   * with the provided name or OID.
   *
@@ -1178,7 +1028,6 @@
          matchingRules.put(toLowerCase(name), matchingRule);
        }
      }
      matchingRuleSet.add(createAttrValueForAdd(matchingRule));
    }
  }
@@ -1203,7 +1052,6 @@
          matchingRules.remove(toLowerCase(name), matchingRule);
        }
      }
      matchingRuleSet.remove(createAttrValueForRemove(matchingRule));
    }
  }
@@ -1227,18 +1075,6 @@
  /**
   * Retrieves the set of defined matching rule uses for this schema.
   *
   * @return  The set of defined matching rule uses for this schema.
   */
  public Set<AttributeValue> getMatchingRuleUseSet()
  {
    return matchingRuleUseSet;
  }
  /**
   * Indicates whether this schema definition includes a matching rule
   * use for the provided matching rule.
   *
@@ -1312,7 +1148,6 @@
      }
      matchingRuleUses.put(matchingRule, matchingRuleUse);
      matchingRuleUseSet.add(createAttrValueForAdd(matchingRuleUse));
    }
  }
@@ -1332,7 +1167,6 @@
    {
      matchingRuleUses.remove(matchingRuleUse.getMatchingRule(),
                              matchingRuleUse);
      matchingRuleUseSet.remove(createAttrValueForRemove(matchingRuleUse));
    }
  }
@@ -1356,18 +1190,6 @@
  /**
   * Retrieves the set of defined DIT content rules for this schema.
   *
   * @return  The set of defined DIT content rules for this schema.
   */
  public Set<AttributeValue> getDITContentRuleSet()
  {
    return ditContentRuleSet;
  }
  /**
   * Indicates whether this schema definition includes a DIT content
   * rule for the provided objectclass.
   *
@@ -1441,7 +1263,6 @@
      }
      ditContentRules.put(objectClass, ditContentRule);
      ditContentRuleSet.add(createAttrValueForAdd(ditContentRule));
    }
  }
@@ -1460,25 +1281,12 @@
    {
      ditContentRules.remove(ditContentRule.getStructuralClass(),
                             ditContentRule);
      ditContentRuleSet.remove(createAttrValueForRemove(ditContentRule));
    }
  }
  /**
   * Retrieves the set of defined DIT structure rules for this schema.
   *
   * @return  The set of defined DIT structure rules for this schema.
   */
  public Set<AttributeValue> getDITStructureRuleSet()
  {
    return ditStructureRuleSet;
  }
  /**
   * Retrieves the DIT structure rule definitions for this schema, as
   * a mapping between the rule ID for the rule and the DIT structure
   * rule itself.  Each DIT structure rule should only be present
@@ -1638,7 +1446,6 @@
      ditStructureRulesByNameForm.put(nameForm, ditStructureRule);
      ditStructureRulesByID.put(ruleID, ditStructureRule);
      ditStructureRuleSet.add(createAttrValueForAdd(ditStructureRule));
    }
  }
@@ -1660,25 +1467,12 @@
           ditStructureRule.getNameForm(), ditStructureRule);
      ditStructureRulesByID.remove(ditStructureRule.getRuleID(),
                                   ditStructureRule);
      ditStructureRuleSet.remove(createAttrValueForRemove(ditStructureRule));
    }
  }
  /**
   * Retrieves the set of defined name forms for this schema.
   *
   * @return  The set of defined name forms for this schema.
   */
  public Set<AttributeValue> getNameFormSet()
  {
    return nameFormSet;
  }
  /**
   * Retrieves the name form definitions for this schema, as a mapping
   * between the objectclass for the name forms and the name forms
   * themselves.
@@ -1859,7 +1653,6 @@
      {
        nameFormsByName.put(name, nameForm);
      }
      nameFormSet.add(createAttrValueForAdd(nameForm));
    }
  }
@@ -1892,7 +1685,6 @@
      {
        nameFormsByName.remove(name, nameForm);
      }
      nameFormSet.remove(createAttrValueForRemove(nameForm));
    }
  }
@@ -2281,14 +2073,6 @@
    dupSchema.nameFormsByOC.putAll(nameFormsByOC);
    dupSchema.nameFormsByName.putAll(nameFormsByName);
    dupSchema.ldapSyntaxDescriptions.putAll(ldapSyntaxDescriptions);
    dupSchema.syntaxSet.addAll(syntaxSet);
    dupSchema.attributeTypeSet.addAll(attributeTypeSet);
    dupSchema.ditContentRuleSet.addAll(ditContentRuleSet);
    dupSchema.ditStructureRuleSet.addAll(ditStructureRuleSet);
    dupSchema.matchingRuleSet.addAll(matchingRuleSet);
    dupSchema.matchingRuleUseSet.addAll(matchingRuleUseSet);
    dupSchema.nameFormSet.addAll(nameFormSet);
    dupSchema.objectClassSet.addAll(objectClassSet);
    dupSchema.oldestModificationTime   = oldestModificationTime;
    dupSchema.youngestModificationTime = youngestModificationTime;
    if (extraAttributes != null)
@@ -2780,24 +2564,12 @@
      attributeTypes = null;
    }
    if (attributeTypeSet != null)
    {
      attributeTypeSet.clear();
      attributeTypeSet = null;
    }
    if (ditContentRules != null)
    {
      ditContentRules.clear();
      ditContentRules = null;
    }
    if (ditContentRuleSet != null)
    {
      ditContentRuleSet.clear();
      ditContentRuleSet = null;
    }
    if (ditStructureRulesByID != null)
    {
      ditStructureRulesByID.clear();
@@ -2810,36 +2582,18 @@
      ditStructureRulesByNameForm = null;
    }
    if (ditStructureRuleSet != null)
    {
      ditStructureRuleSet.clear();
      ditStructureRuleSet = null;
    }
    if (matchingRules != null)
    {
      matchingRules.clear();
      matchingRules = null;
    }
    if (matchingRuleSet != null)
    {
      matchingRuleSet.clear();
      matchingRuleSet = null;
    }
    if (matchingRuleUses != null)
    {
      matchingRuleUses.clear();
      matchingRuleUses = null;
    }
    if (matchingRuleUseSet != null)
    {
      matchingRuleUseSet.clear();
      matchingRuleUseSet = null;
    }
    if (nameFormsByName != null)
    {
      nameFormsByName.clear();
@@ -2852,24 +2606,12 @@
      nameFormsByOC = null;
    }
    if (nameFormSet != null)
    {
      nameFormSet.clear();
      nameFormSet = null;
    }
    if (objectClasses != null)
    {
      objectClasses.clear();
      objectClasses = null;
    }
    if (objectClassSet != null)
    {
      objectClassSet.clear();
      objectClassSet = null;
    }
    if (subordinateTypes != null)
    {
      subordinateTypes.clear();
@@ -2888,12 +2630,6 @@
      syntaxes = null;
    }
    if (syntaxSet != null)
    {
      syntaxSet.clear();
      syntaxSet = null;
    }
    if(ldapSyntaxDescriptions != null)
    {
      ldapSyntaxDescriptions.clear();
opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
@@ -30,10 +30,10 @@
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
@@ -48,11 +48,13 @@
import org.forgerock.opendj.ldap.SearchScope;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
 * Test the LDAPSyntaxDescriptionSyntax.
 */
@SuppressWarnings("javadoc")
public class LDAPSyntaxTest extends AttributeSyntaxTest
{
@@ -60,7 +62,7 @@
   * {@inheritDoc}
   */
  @Override
  protected AttributeSyntax getRule()
  protected AttributeSyntax<?> getRule()
  {
    return new LDAPSyntaxDescriptionSyntax();
  }
@@ -265,8 +267,6 @@
        syntaxList.add(getOIDFromLdapSyntax(val.toString()));
      }
      assertTrue(syntaxList.size() ==
              DirectoryServer.getAttributeSyntaxSet().size() ) ;
      //Check if we find our OID.
      assertTrue(syntaxList.contains("9.9.9"));
      //DirectoryString.