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

matthew_swift
25.03.2006 09fcb137f6d46e0c32f03b0313ac445a2ee7ecc3
Implement test suite for org.opends.server.types.AttributeType and
make it immutable (it's still not 100% immutable - the constructors
do not perform deep copies of the extra properties).
1 files added
8 files modified
2170 ■■■■ changed files
opends/src/server/org/opends/server/core/DirectoryServer.java 25 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/Schema.java 6 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/SchemaConfigManager.java 2 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java 22 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java 25 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/synchronization/Historical.java 11 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AttributeType.java 787 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/RDNComparator.java 4 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAttributeType.java 1288 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -29,6 +29,7 @@
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Properties;
@@ -3078,10 +3079,6 @@
      if (directoryServer.objectClassAttributeType == null)
      {
        ConcurrentHashMap<String,String> typeNames =
             new ConcurrentHashMap<String,String>();
        typeNames.put(OBJECTCLASS_ATTRIBUTE_TYPE_NAME, "objectClass");
        AttributeSyntax oidSyntax =
             directoryServer.schema.getSyntax(SYNTAX_OID_NAME);
        if (oidSyntax == null)
@@ -3099,7 +3096,8 @@
        }
        directoryServer.objectClassAttributeType =
             new AttributeType("objectClass", typeNames,
             new AttributeType("objectClass",
                               Collections.singleton("objectClass"),
                               OBJECTCLASS_ATTRIBUTE_TYPE_OID, null, null,
                               oidSyntax, AttributeUsage.USER_APPLICATIONS,
                               false, false, false, false);
@@ -3137,15 +3135,7 @@
                      String.valueOf(name));
    String lowerName = toLowerCase(name);
    ConcurrentHashMap<String,String> names =
         new ConcurrentHashMap<String,String>(1);
    names.put(lowerName, name);
    return new AttributeType(name, names, lowerName, null, null,
                             getDefaultAttributeSyntax(),
                             AttributeUsage.USER_APPLICATIONS, false, false,
                             false, false);
    return getDefaultAttributeType(name, getDefaultAttributeSyntax());
  }
@@ -3169,11 +3159,8 @@
    String lowerName = toLowerCase(name);
    ConcurrentHashMap<String,String> names =
         new ConcurrentHashMap<String,String>(1);
    names.put(lowerName, name);
    return new AttributeType(name, names, lowerName, null, null, syntax,
    return new AttributeType(name, Collections.singleton(name),
                             lowerName, null, null, syntax,
                             AttributeUsage.USER_APPLICATIONS, false, false,
                             false, false);
  }
opends/src/server/org/opends/server/core/Schema.java
@@ -296,7 +296,7 @@
                                       msgID);
        }
        for (String name : attributeType.getNames().keySet())
        for (String name : attributeType.getNormalizedNames())
        {
          if (attributeTypes.containsKey(name))
          {
@@ -313,7 +313,7 @@
      attributeTypes.put(toLowerCase(attributeType.getOID()), attributeType);
      for (String name : attributeType.getNames().keySet())
      for (String name : attributeType.getNormalizedNames())
      {
        attributeTypes.put(name, attributeType);
      }
@@ -344,7 +344,7 @@
    {
      attributeTypes.remove(toLowerCase(attributeType.getOID()), attributeType);
      for (String name : attributeType.getNames().keySet())
      for (String name : attributeType.getNormalizedNames())
      {
        attributeTypes.remove(name, attributeType);
      }
opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -933,8 +933,6 @@
            {
              attrType = attrTypeSyntax.decodeAttributeType(v.getValue(),
                                                            schema);
              attrType.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
              attrType.setSchemaFile(schemaFile);
            }
            catch (DirectoryException de)
            {
opends/src/server/org/opends/server/plugins/EntryUUIDPlugin.java
@@ -29,6 +29,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -74,6 +75,13 @@
  /**
   * The name of the entryUUID attribute type.
   */
  private static final String ENTRYUUID = "entryuuid";
  // The attribute type for the "entryUUID" attribute.
  private AttributeType entryUUIDType;
@@ -144,13 +152,17 @@
    // Get the entryUUID attribute type.
    entryUUIDType = DirectoryServer.getAttributeType("entryuuid");
    entryUUIDType = DirectoryServer.getAttributeType(ENTRYUUID);
    if (entryUUIDType == null)
    {
      entryUUIDType = DirectoryServer.getDefaultAttributeType("entryUUID");
      entryUUIDType.setUsage(AttributeUsage.DIRECTORY_OPERATION);
      entryUUIDType.setNoUserModification(true);
      entryUUIDType.setSingleValue(true);
      entryUUIDType = new AttributeType(ENTRYUUID,
          Collections.singleton(ENTRYUUID),
          ENTRYUUID,
          null,
          null,
          DirectoryServer.getDefaultAttributeSyntax(),
          AttributeUsage.DIRECTORY_OPERATION,
          false, true, false, true);
    }
  }
opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java
@@ -28,9 +28,10 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.EqualityMatchingRule;
@@ -476,8 +477,7 @@
    // we get to the end of the value.  But before we start, set default values
    // for everything else we might need to know.
    String  primaryName = oid;
    ConcurrentHashMap<String,String> typeNames =
         new ConcurrentHashMap<String,String>();
    List<String> typeNames = new LinkedList<String>();
    String description = null;
    AttributeType superiorType = null;
    AttributeSyntax syntax = DirectoryServer.getDefaultAttributeSyntax();
@@ -490,8 +490,8 @@
    boolean isNoUserModification = false;
    boolean isObsolete = false;
    boolean isSingleValue = false;
    ConcurrentHashMap<String,CopyOnWriteArrayList<String>> extraProperties =
         new ConcurrentHashMap<String,CopyOnWriteArrayList<String>>();
    HashMap<String,List<String>> extraProperties =
         new HashMap<String,List<String>>();
    while (true)
@@ -526,7 +526,7 @@
          pos = readQuotedString(valueStr, lowerStr, userBuffer, lowerBuffer,
                                 (pos-1));
          primaryName = userBuffer.toString();
          typeNames.put(lowerBuffer.toString(), primaryName);
          typeNames.add(primaryName);
        }
        else if (c == '(')
        {
@@ -535,7 +535,7 @@
          pos = readQuotedString(valueStr, lowerStr, userBuffer, lowerBuffer,
                                 pos);
          primaryName = userBuffer.toString();
          typeNames.put(lowerBuffer.toString(), primaryName);
          typeNames.add(primaryName);
          while (true)
@@ -558,7 +558,7 @@
              pos = readQuotedString(valueStr, lowerStr, userBuffer,
                                     lowerBuffer, pos);
              typeNames.put(lowerBuffer.toString(), userBuffer.toString());
              typeNames.add(userBuffer.toString());
            }
          }
        }
@@ -918,8 +918,7 @@
        // either a single value in single quotes or an open parenthesis
        // followed by one or more values in single quotes separated by spaces
        // followed by a close parenthesis.
        CopyOnWriteArrayList<String> valueList =
             new CopyOnWriteArrayList<String>();
        List<String> valueList = new ArrayList<String>();
        pos = readExtraParameterValues(valueStr, valueList, pos);
        extraProperties.put(tokenName, valueList);
      }
@@ -1350,7 +1349,7 @@
   *                              the value.
   */
  private static int readExtraParameterValues(String valueStr,
                          CopyOnWriteArrayList<String> valueList, int startPos)
                          List<String> valueList, int startPos)
          throws DirectoryException
  {
    assert debugEnter(CLASS_NAME, "readExtraParameterValues",
opends/src/server/org/opends/server/synchronization/Historical.java
@@ -345,7 +345,7 @@
          String strValue;
          if (valInfo.getValueDeleteTime() != null)
          {
            strValue = type.getLowerName() + optionsString + ":" +
            strValue = type.getNormalizedPrimaryName() + optionsString + ":" +
            valInfo.getValueDeleteTime().toString() +
            ":del:" + valInfo.getValue().toString();
            AttributeValue val = new AttributeValue(historicalAttrType,
@@ -356,14 +356,14 @@
          {
            if (delAttr && valInfo.getValueUpdateTime() == deleteTime)
            {
              strValue = type.getLowerName() + optionsString + ":" +
              strValue = type.getNormalizedPrimaryName() + optionsString + ":" +
              valInfo.getValueUpdateTime().toString() +  ":repl:" +
              valInfo.getValue().toString();
              delAttr = false;
            }
            else
            {
              strValue = type.getLowerName() + optionsString + ":" +
              strValue = type.getNormalizedPrimaryName() + optionsString + ":" +
              valInfo.getValueUpdateTime().toString() +
              ":add:" + valInfo.getValue().toString();
            }
@@ -376,8 +376,9 @@
        if (delAttr)
        {
          String strValue = type.getLowerName() + optionsString + ":"
          + deleteTime.toString() + ":attrDel";
          String strValue = type.getNormalizedPrimaryName()
              + optionsString + ":" + deleteTime.toString()
              + ":attrDel";
          delAttr = false;
          AttributeValue val = new AttributeValue(historicalAttrType, strValue);
          hist.add(val);
opends/src/server/org/opends/server/types/AttributeType.java
@@ -28,10 +28,12 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
import java.util.Map;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.EqualityMatchingRule;
@@ -55,7 +57,7 @@
 * of an attribute and the syntax and matching rules that should be
 * used when interacting with it.
 */
public class AttributeType
public final class AttributeType
{
  /**
   * The fully-qualified name of this class for debugging purposes.
@@ -66,99 +68,105 @@
  // The approximate matching rule for this attribute type.
  private ApproximateMatchingRule approximateMatchingRule;
  private final ApproximateMatchingRule approximateMatchingRule;
  // The syntax for this attribute type.
  private AttributeSyntax syntax;
  private final AttributeSyntax syntax;
  // The superior attribute type from which this attribute type
  // inherits.
  private AttributeType superiorType;
  private final AttributeType superiorType;
  // The attribute usage for this attribute type.
  private AttributeUsage attributeUsage;
  private final AttributeUsage attributeUsage;
  // Indicates whether this attribute type is declared "collective".
  private boolean isCollective;
  private final boolean isCollective;
  // Indicates whether this attribute type is declared
  // "no-user-modification".
  private boolean isNoUserModification;
  private final boolean isNoUserModification;
  // Indicates whether this attribute type is the objectclass type.
  private boolean isObjectClassType;
  private final boolean isObjectClassType;
  // Indicates whether this attribute type is declared "obsolete".
  private boolean isObsolete;
  private final boolean isObsolete;
  // Indicates whether this attribute type is declared "single-value".
  private boolean isSingleValue;
  private final boolean isSingleValue;
  // The set of additional name-value pairs associated with this
  // attribute type definition.
  private ConcurrentHashMap<String,CopyOnWriteArrayList<String>>
               extraProperties;
  private final Map<String,List<String>> extraProperties;
  // The set of names for this attribute type, in a mapping between
  // the all-lowercase form and the user-defined form.
  private ConcurrentHashMap<String,String> typeNames;
  private final Map<String,String> typeNames;
  // The equality matching rule for this attribute type.
  private EqualityMatchingRule equalityMatchingRule;
  private final EqualityMatchingRule equalityMatchingRule;
  // The ordering matching rule for this attribute type.
  private OrderingMatchingRule orderingMatchingRule;
  private final OrderingMatchingRule orderingMatchingRule;
  // The description for this attribute type.
  private String description;
  private final String description;
  // The OID that may be used to reference this attribute type.
  private String oid;
  private final String oid;
  // The primary name to use for this attribute type.
  private String primaryName;
  private final String primaryName;
  // The lower case name for this attribute type.
  private String lowerName;
  // The path to the schema configuration file that contains this
  // attribute type definition.
  private String schemaFile;
  private final String lowerName;
  // The substring matching rule for this attribute type.
  private SubstringMatchingRule substringMatchingRule;
  private final SubstringMatchingRule substringMatchingRule;
  /**
   * Creates a new attribute type with the provided information.
   *
   * @param  primaryName           The primary name for this attribute
   *                               type.
   * @param  typeNames             The full set of names for this
   *                               attribute type, mapping the
   *                               lowercase names with the
   *                               user-defined values.
   * @param  oid                   The OID for this attribute type.
   * @param  description           The description for the attribute
   *                               type.
   * @param  superiorType          The reference to the superior type
   *                               for this attribute type.
   * @param  syntax                The syntax for this attribute type.
   * @param  attributeUsage        The attribute usage for this
   *                               attribute type.
   * @param  isCollective          Indicates whether this attribute
   *                               type is declared "collective".
   * @param  isNoUserModification  Indicates whether this attribute
   *                               type is declared
   *                               "no-user-modification".
   * @param  isObsolete            Indicates whether this attribute
   *                               type is declared "obsolete".
   * @param  isSingleValue         Indicates whether this attribute
   *                               type is declared "single-value".
   * @param primaryName
   *          The primary name for this attribute type, or
   *          <code>null</code> if there is no primary name.
   * @param typeNames
   *          The full set of names for this attribute type, or
   *          <code>null</code> if there are no names.
   * @param oid
   *          The OID for this attribute type (must not be
   *          <code>null</code>).
   * @param description
   *          The description for the attribute type, or
   *          <code>null</code> if there is no description.
   * @param superiorType
   *          The reference to the superior type for this attribute
   *          type, or <code>null</code> if there is no superior
   *          type.
   * @param syntax
   *          The syntax for this attribute type, or <code>null</code>
   *          if there is no syntax.
   * @param attributeUsage
   *          The attribute usage for this attribute type, or
   *          <code>null</code> to default to user applications.
   * @param isCollective
   *          Indicates whether this attribute type is declared
   *          "collective".
   * @param isNoUserModification
   *          Indicates whether this attribute type is declared
   *          "no-user-modification".
   * @param isObsolete
   *          Indicates whether this attribute type is declared
   *          "obsolete".
   * @param isSingleValue
   *          Indicates whether this attribute type is declared
   *          "single-value".
   */
  public AttributeType(String primaryName,
                       ConcurrentHashMap<String,String> typeNames,
                       Collection<String> typeNames,
                       String oid, String description,
                       AttributeType superiorType,
                       AttributeSyntax syntax,
@@ -167,60 +175,10 @@
                       boolean isNoUserModification,
                       boolean isObsolete, boolean isSingleValue)
  {
    assert debugConstructor(CLASS_NAME,
                            new String[]
                            {
                              String.valueOf(primaryName),
                              String.valueOf(typeNames),
                              String.valueOf(oid),
                              String.valueOf(description),
                              String.valueOf(superiorType),
                              String.valueOf(syntax),
                              String.valueOf(attributeUsage),
                              String.valueOf(isCollective),
                              String.valueOf(isNoUserModification),
                              String.valueOf(isObsolete),
                              String.valueOf(isSingleValue),
                            });
    this.primaryName             = primaryName;
    this.lowerName               = toLowerCase(primaryName);
    this.typeNames               = typeNames;
    this.oid                     = oid;
    this.description             = description;
    this.superiorType            = superiorType;
    this.syntax                  = syntax;
    this.approximateMatchingRule =
         syntax.getApproximateMatchingRule();
    this.equalityMatchingRule    = syntax.getEqualityMatchingRule();
    this.orderingMatchingRule    = syntax.getOrderingMatchingRule();
    this.substringMatchingRule   = syntax.getSubstringMatchingRule();
    this.attributeUsage          = attributeUsage;
    this.isCollective            = isCollective;
    this.isNoUserModification    = isNoUserModification;
    this.isObsolete              = isObsolete;
    this.isSingleValue           = isSingleValue;
    this.schemaFile              = null;
    this.extraProperties         =
         new ConcurrentHashMap<String,
                               CopyOnWriteArrayList<String>>(0);
    isObjectClassType = false;
    if ((oid != null) && oid.equals(OBJECTCLASS_ATTRIBUTE_TYPE_OID))
    {
      isObjectClassType = true;
    }
    else
    {
      for (String lowerName : typeNames.keySet())
      {
        if (lowerName.equals(OBJECTCLASS_ATTRIBUTE_TYPE_NAME))
        {
          isObjectClassType = true;
        }
      }
    }
    this(primaryName, typeNames, oid, description,
        superiorType, syntax, null, null, null,
        null, attributeUsage, isCollective,
        isNoUserModification, isObsolete, isSingleValue, null);
  }
@@ -228,43 +186,58 @@
  /**
   * Creates a new attribute type with the provided information.
   *
   * @param  primaryName              The primary name for this
   *                                  attribute type.
   * @param  typeNames                The full set of names for this
   *                                  attribute type, mapping the
   *                                  lowercase names with the
   *                                  user-defined values.
   * @param  oid                      The OID for this attribute type.
   * @param  description              The description for the
   *                                  attribute type.
   * @param  superiorType             The reference to the superior
   *                                  type for this attribute type.
   * @param  syntax                   The syntax for this attribute
   *                                  type.
   * @param  approximateMatchingRule  The approximate matching rule
   *                                  for this attribute type.
   * @param  equalityMatchingRule     The equality matching rule for
   *                                  this attribute type.
   * @param  orderingMatchingRule     The ordering matching rule for
   *                                  this attribute type.
   * @param  substringMatchingRule    The substring matching rule for
   *                                  this attribute type.
   * @param  attributeUsage           The attribute usage for this
   *                                  attribute type.
   * @param  isCollective             Indicates whether this attribute
   *                                  type is declared "collective".
   * @param  isNoUserModification     Indicates whether this attribute
   *                                  type is declared
   *                                  "no-user-modification".
   * @param  isObsolete               Indicates whether this attribute
   *                                  type is declared "obsolete".
   * @param  isSingleValue            Indicates whether this attribute
   *                                  type is declared "single-value".
   * @param  extraProperties          A set of extra properties for
   *                                  this attribute type.
   * @param primaryName
   *          The primary name for this attribute type, or
   *          <code>null</code> if there is no primary name.
   * @param typeNames
   *          The full set of names for this attribute type, or
   *          <code>null</code> if there are no names.
   * @param oid
   *          The OID for this attribute type (must not be
   *          <code>null</code>).
   * @param description
   *          The description for the attribute type, or
   *          <code>null</code> if there is no description.
   * @param superiorType
   *          The reference to the superior type for this attribute
   *          type, or <code>null</code> if there is no superior
   *          type.
   * @param syntax
   *          The syntax for this attribute type, or <code>null</code>
   *          if there is no syntax.
   * @param approximateMatchingRule
   *          The approximate matching rule for this attribute type,
   *          or <code>null</code> if there is no rule.
   * @param equalityMatchingRule
   *          The equality matching rule for this attribute type, or
   *          <code>null</code> if there is no rule.
   * @param orderingMatchingRule
   *          The ordering matching rule for this attribute type, or
   *          <code>null</code> if there is no rule.
   * @param substringMatchingRule
   *          The substring matching rule for this attribute type, or
   *          <code>null</code> if there is no rule.
   * @param attributeUsage
   *          The attribute usage for this attribute type, or
   *          <code>null</code> to default to user applications.
   * @param isCollective
   *          Indicates whether this attribute type is declared
   *          "collective".
   * @param isNoUserModification
   *          Indicates whether this attribute type is declared
   *          "no-user-modification".
   * @param isObsolete
   *          Indicates whether this attribute type is declared
   *          "obsolete".
   * @param isSingleValue
   *          Indicates whether this attribute type is declared
   *          "single-value".
   * @param extraProperties
   *          A set of extra properties for this attribute type, or
   *          <code>null</code> if there is no rule.
   */
  public AttributeType(String primaryName,
                       ConcurrentHashMap<String,String> typeNames,
                       Collection<String> typeNames,
                       String oid, String description,
                       AttributeType superiorType,
                       AttributeSyntax syntax,
@@ -277,14 +250,9 @@
                       boolean isCollective,
                       boolean isNoUserModification,
                       boolean isObsolete, boolean isSingleValue,
                       ConcurrentHashMap<String,
                                         CopyOnWriteArrayList<String>>
                            extraProperties)
                       Map<String,List<String>> extraProperties)
  {
    assert debugConstructor(CLASS_NAME,
                            new String[]
                            {
                              String.valueOf(primaryName),
    assert debugConstructor(CLASS_NAME,String.valueOf(primaryName),
                              String.valueOf(typeNames),
                              String.valueOf(oid),
                              String.valueOf(description),
@@ -299,33 +267,44 @@
                              String.valueOf(isNoUserModification),
                              String.valueOf(isObsolete),
                              String.valueOf(isSingleValue),
                              String.valueOf(extraProperties)
                            });
                              String.valueOf(extraProperties));
    this.primaryName             = primaryName;
    this.lowerName               = toLowerCase(primaryName);
    this.typeNames               = typeNames;
    this.oid                     = oid;
    this.description             = description;
    this.superiorType            = superiorType;
    this.isCollective            = isCollective;
    this.isNoUserModification    = isNoUserModification;
    this.isObsolete              = isObsolete;
    this.isSingleValue           = isSingleValue;
    this.extraProperties         = extraProperties;
    this.schemaFile              = null;
    if (attributeUsage == null)
    // Make sure mandatory parameters are specified.
    if (oid == null)
    {
      this.attributeUsage = AttributeUsage.USER_APPLICATIONS;
      throw new NullPointerException(
          "No oid specified in constructor");
    }
    this.primaryName = primaryName;
    this.lowerName = toLowerCase(primaryName);
    this.oid = oid;
    this.description = description;
    this.superiorType = superiorType;
    this.isCollective = isCollective;
    this.isNoUserModification = isNoUserModification;
    this.isObsolete = isObsolete;
    this.isSingleValue = isSingleValue;
    // Construct the normalized attribute name mapping.
    if (typeNames != null)
    {
      this.typeNames = new HashMap<String, String>(typeNames.size());
      for (String name : typeNames)
      {
        this.typeNames.put(toLowerCase(name), name);
      }
    }
    else
    {
      this.attributeUsage = attributeUsage;
      this.typeNames = new HashMap<String, String>();
    }
    // Add the primary name to the type names if it is not present.
    if (lowerName != null && !this.typeNames.containsKey(lowerName))
    {
      this.typeNames.put(lowerName, this.primaryName);
    }
    if (syntax == null)
    {
@@ -335,7 +314,7 @@
      }
      else
      {
        syntax = DirectoryServer.getDefaultAttributeSyntax();
        this.syntax = DirectoryServer.getDefaultAttributeSyntax();
      }
    }
    else
@@ -346,11 +325,8 @@
    if (approximateMatchingRule == null)
    {
      if (syntax != null)
      {
        this.approximateMatchingRule =
             syntax.getApproximateMatchingRule();
      }
      this.approximateMatchingRule =
             this.syntax.getApproximateMatchingRule();
    }
    else
    {
@@ -360,10 +336,8 @@
    if (equalityMatchingRule == null)
    {
      if (syntax != null)
      {
        this.equalityMatchingRule = syntax.getEqualityMatchingRule();
      }
      this.equalityMatchingRule =
        this.syntax.getEqualityMatchingRule();
    }
    else
    {
@@ -373,10 +347,8 @@
    if (orderingMatchingRule == null)
    {
      if (syntax != null)
      {
        this.orderingMatchingRule = syntax.getOrderingMatchingRule();
      }
      this.orderingMatchingRule =
        this.syntax.getOrderingMatchingRule();
    }
    else
    {
@@ -386,31 +358,41 @@
    if (substringMatchingRule == null)
    {
      if (syntax != null)
      {
        this.substringMatchingRule =
             syntax.getSubstringMatchingRule();
      }
      this.substringMatchingRule =
        this.syntax.getSubstringMatchingRule();
    }
    else
    {
      this.substringMatchingRule = substringMatchingRule;
    }
    isObjectClassType = false;
    if ((oid != null) && oid.equals(OBJECTCLASS_ATTRIBUTE_TYPE_OID))
    if (attributeUsage != null)
    {
      this.attributeUsage = attributeUsage;
    }
    else
    {
      this.attributeUsage = AttributeUsage.USER_APPLICATIONS;
    }
    if (oid.equals(OBJECTCLASS_ATTRIBUTE_TYPE_OID))
    {
      isObjectClassType = true;
    }
    else
    {
      for (String lowerName : typeNames.keySet())
      {
        if (lowerName.equals(OBJECTCLASS_ATTRIBUTE_TYPE_NAME))
        {
          isObjectClassType = true;
        }
      }
      isObjectClassType =
        this.typeNames.containsKey(OBJECTCLASS_ATTRIBUTE_TYPE_NAME);
    }
    if (extraProperties != null)
    {
      this.extraProperties =
        new HashMap<String, List<String>>(extraProperties);
    }
    else
    {
      this.extraProperties = Collections.emptyMap();
    }
  }
@@ -419,7 +401,8 @@
  /**
   * Retrieves the primary name for this attribute type.
   *
   * @return  The primary name for this attribute type.
   * @return The primary name for this attribute type, or
   *         <code>null</code> if there is no primary name.
   */
  public String getPrimaryName()
  {
@@ -431,67 +414,50 @@
  /**
   * Retrieve the lower case name for this attribute type.
   * Retrieve the normalized primary name for this attribute type.
   *
   * @return The lower case name for this attribute type.
   * @return Returns the normalized primary name for this attribute
   *         type, or <code>null</code> if there is no primary name.
   */
  public String getLowerName()
  public String getNormalizedPrimaryName()
  {
    assert debugEnter(CLASS_NAME, "getNormalizedPrimaryName");
    return lowerName;
  }
  /**
   * Specifies the primary name for this attribute type.
   * Retrieves an iterable over the set of normalized names that may
   * be used to reference this attribute type. The normalized form of
   * an attribute name is defined as the user-defined name converted
   * to lower-case.
   *
   * @param  primaryName  The primary name for this attribute type.
   * @return Returns an iterable over the set of normalized names that
   *         may be used to reference this attribute type.
   */
  public void setPrimaryName(String primaryName)
  public Iterable<String> getNormalizedNames()
  {
    assert debugEnter(CLASS_NAME, "setPrimaryName",
                      String.valueOf(primaryName));
    assert debugEnter(CLASS_NAME, "getNormalizedNames");
    this.primaryName = primaryName;
    this.lowerName = toLowerCase(primaryName);
    typeNames.put(this.lowerName, primaryName);
    return typeNames.keySet();
  }
  /**
   * Retrieves the set of names that may be used to reference this
   * attribute type.  The returned mapping will be between an all
   * lower-case form of the name and a name in the user-defined form
   * (which may include mixed capitalization).
   * Retrieves an iterable over the set of user-defined names that may
   * be used to reference this attribute type.
   *
   * @return  The set of names that may be used to reference this
   *          attribute type.
   * @return Returns an iterable over the set of user-defined names
   *         that may be used to reference this attribute type.
   */
  public ConcurrentHashMap<String,String> getNames()
  public Iterable<String> getUserDefinedNames()
  {
    assert debugEnter(CLASS_NAME, "getNames");
    assert debugEnter(CLASS_NAME, "getUserDefinedNames");
    return typeNames;
  }
  /**
   * Specifies the set of names that may be used to reference this
   * attribute type.  The provided set must contain a mapping between
   * each name in all lowercase characters and the name in a
   * user-defined form (which may include mixed capitalization).
   *
   * @param  names  The set of names that may be used to reference
   *                this attribute type.
   */
  public void setNames(ConcurrentHashMap<String,String> names)
  {
    assert debugEnter(CLASS_NAME, "setNames", String.valueOf(names));
    this.typeNames = names;
    return typeNames.values();
  }
@@ -516,52 +482,6 @@
  /**
   * Adds the specified name to the set of names for this attribute
   * type.
   *
   * @param  name  The name to add to the set of names for this
   *               attribute type.
   */
  public void addName(String name)
  {
    assert debugEnter(CLASS_NAME, "addName", String.valueOf(name));
    String lowerName = toLowerCase(name);
    typeNames.put(lowerName, name);
  }
  /**
   * Removes the specified name from the set of names for this
   * attribute type.  This will have no effect if the specified name
   * is not associated with this attribute type.
   *
   * @param  lowerName  The lowercase name to remove from the set of
   *                    names for this attribute type.
   */
  public void removeName(String lowerName)
  {
    assert debugEnter(CLASS_NAME, "removeName",
                      String.valueOf(lowerName));
    typeNames.remove(lowerName);
    if (lowerName.equalsIgnoreCase(primaryName))
    {
      if (typeNames.isEmpty())
      {
        primaryName = null;
      }
      else
      {
        primaryName = typeNames.values().iterator().next();
      }
    }
  }
  /**
   * Retrieves the OID for this attribute type.
   *
   * @return  The OID for this attribute type.
@@ -576,20 +496,6 @@
  /**
   * Specifies the OID for this attribute type.
   *
   * @param  oid  The OID for this attribute type.
   */
  public void setOID(String oid)
  {
    assert debugEnter(CLASS_NAME, "setOID", String.valueOf(oid));
    this.oid = toLowerCase(oid);
  }
  /**
   * Retrieves the name or OID for this attribute type.  If it has one
   * or more names, then the primary name will be returned.  If it
   * does not have any names, then the OID will be returned.
@@ -655,24 +561,13 @@
  {
    assert debugEnter(CLASS_NAME, "getSchemaFile");
    return schemaFile;
  }
    List<String> values =
      extraProperties.get(SCHEMA_PROPERTY_FILENAME);
    if (values != null && !values.isEmpty()) {
      return values.get(0);
    }
  /**
   * Specifies the path to the schema file that contains the
   * definition for this attribute type.
   *
   * @param  schemaFile  The path to the schema file that contains the
   *                     definition for this attribute type.
   */
  public void setSchemaFile(String schemaFile)
  {
    assert debugEnter(CLASS_NAME, "setSchemaFile",
                      String.valueOf(schemaFile));
    this.schemaFile = schemaFile;
    return null;
  }
@@ -680,7 +575,8 @@
  /**
   * Retrieves the description for this attribute type.
   *
   * @return  The description for this attribute type.
   * @return  The description for this attribute type, or
   *         <code>null</code> if there is no description.
   */
  public String getDescription()
  {
@@ -692,20 +588,6 @@
  /**
   * Specifies the description for this attribute type.
   *
   * @param  description  The description for this attribute type.
   */
  public void setDescription(String description)
  {
    assert debugEnter(CLASS_NAME, "setDescription", description);
    this.description = description;
  }
  /**
   * Retrieves the superior type for this attribute type.
   *
   * @return  The superior type for this attribute type, or
@@ -721,22 +603,6 @@
  /**
   * Specifies the superior type to use for this attribute type.  It
   * may be <CODE>null</CODE> if it should not have a superior type.
   *
   * @param  superiorType  The superior type for this attribute type.
   */
  public void setSuperiorType(AttributeType superiorType)
  {
    assert debugEnter(CLASS_NAME, "setSuperiorType",
                      String.valueOf(superiorType));
    this.superiorType = superiorType;
  }
  /**
   * Retrieves the syntax for this attribute type.
   *
   * @return  The syntax for this attribute type.
@@ -767,21 +633,6 @@
  /**
   * Specifies the syntax for this attribute type.
   *
   * @param  syntax  The syntax for this attribute type.
   */
  public void setSyntax(AttributeSyntax syntax)
  {
    assert debugEnter(CLASS_NAME, "setSyntax",
                      String.valueOf(syntax));
    this.syntax = syntax;
  }
  /**
   * Retrieves the matching rule that should be used for approximate
   * matching with this attribute type.
   *
@@ -798,25 +649,6 @@
  /**
   * Specifies the matching rule that should be used for approximate
   * matching with this attribute type.
   *
   * @param  approximateMatchingRule  The matching rule that should be
   *                                  used for approximate matching
   *                                  with this attribute type.
   */
  public void setApproximateMatchingRule(ApproximateMatchingRule
                                              approximateMatchingRule)
  {
    assert debugEnter(CLASS_NAME, "setApproximateMatchingRule",
                      String.valueOf(approximateMatchingRule));
    this.approximateMatchingRule = approximateMatchingRule;
  }
  /**
   * Retrieves the matching rule that should be used for equality
   * matching with this attribute type.
   *
@@ -833,25 +665,6 @@
  /**
   * Specifies the matching rule that should be used for equality
   * matching with this attribute type.
   *
   * @param  equalityMatchingRule  The matching rule that should be
   *                               used for equality matching with
   *                               this attribute type.
   */
  public void setEqualityMatchingRule(EqualityMatchingRule
                                           equalityMatchingRule)
  {
    assert debugEnter(CLASS_NAME, "setEqualityMatchingRule",
                      String.valueOf(equalityMatchingRule));
    this.equalityMatchingRule = equalityMatchingRule;
  }
  /**
   * Retrieves the matching rule that should be used for ordering with
   * this attribute type.
   *
@@ -868,25 +681,6 @@
  /**
   * Specifies the matching rule that should be used for ordering with
   * this attribute type.
   *
   * @param  orderingMatchingRule  The matching rule that should be
   *                               used for ordering with this
   *                               attribute type.
   */
  public void setOrderingMatchingRule(OrderingMatchingRule
                                           orderingMatchingRule)
  {
    assert debugEnter(CLASS_NAME, "setOrderingMatchingRule",
                      String.valueOf(orderingMatchingRule));
    this.orderingMatchingRule = orderingMatchingRule;
  }
  /**
   * Retrieves the matching rule that should be used for substring
   * matching with this attribute type.
   *
@@ -903,25 +697,6 @@
  /**
   * Specifies the matching rule that should be used for substring
   * matching with this attribute type.
   *
   * @param  substringMatchingRule  The matching rule that should be
   *                                used for substring matching with
   *                                this attribute type.
   */
  public void setSubstringMatchingRule(SubstringMatchingRule
                                            substringMatchingRule)
  {
    assert debugEnter(CLASS_NAME, "setSubstringMatchingRule",
                      String.valueOf(substringMatchingRule));
    this.substringMatchingRule = substringMatchingRule;
  }
  /**
   * Retrieves the usage indicator for this attribute type.
   *
   * @return  The usage indicator for this attribute type.
@@ -936,22 +711,6 @@
  /**
   * Specifies the usage indicator for this attribute type.
   *
   * @param  attributeUsage  The usage indicator for this attribute
   *                         type.
   */
  public void setUsage(AttributeUsage attributeUsage)
  {
    assert debugEnter(CLASS_NAME, "setUsage",
                      String.valueOf(attributeUsage));
    this.attributeUsage = attributeUsage;
  }
  /**
   * Indicates whether this is an operational attribute.  An
   * operational attribute is one with a usage of
   * "directoryOperation", "distributedOperation", or "dSAOperation"
@@ -1000,22 +759,6 @@
  /**
   * Specifies whether this attribute type is declared "collective".
   *
   * @param  isCollective  Specifies whether this attribute type is
   *                       declared "collective".
   */
  public void setCollective(boolean isCollective)
  {
    assert debugEnter(CLASS_NAME, "setCollective",
                      String.valueOf(isCollective));
    this.isCollective = isCollective;
  }
  /**
   * Indicates whether this attribute type is declared
   * "no-user-modification".
   *
@@ -1032,24 +775,6 @@
  /**
   * Specifies whether this attribute type is declared
   * "no-user-modification".
   *
   * @param  isNoUserModification  Specifies whether this attribute
   *                               type is declared
   *                               "no-user-modification".
   */
  public void setNoUserModification(boolean isNoUserModification)
  {
    assert debugEnter(CLASS_NAME, "setNoUserModification",
                      String.valueOf(isNoUserModification));
    this.isNoUserModification = isNoUserModification;
  }
  /**
   * Indicates whether this attribute type is declared "obsolete".
   *
   * @return  <CODE>true</CODE> if this attribute type is declared
@@ -1065,22 +790,6 @@
  /**
   * Specifies whether this attribute type is declared "obsolete".
   *
   * @param  isObsolete  Specifies whether this attribute type is
   *                     declared "obsolete".
   */
  public void setObsolete(boolean isObsolete)
  {
    assert debugEnter(CLASS_NAME, "setObsolete",
                      String.valueOf(isObsolete));
    this.isObsolete = isObsolete;
  }
  /**
   * Indicates whether this attribute type is declared "single-value".
   *
   * @return  <CODE>true</CODE> if this attribute type is declared
@@ -1096,54 +805,33 @@
  /**
   * Specifies whether this attribute type is declared "single-value".
   * Retrieves an iterable over the names of "extra" properties
   * associated with this attribute type.
   *
   * @param  isSingleValue  Specifies whether this attribute type is
   *                        declared "single-value".
   * @return Returns an iterable over the names of "extra" properties
   *         associated with this attribute type.
   */
  public void setSingleValue(boolean isSingleValue)
  public Iterable<String> getExtraPropertyNames()
  {
    assert debugEnter(CLASS_NAME, "setSingleValue",
                      String.valueOf(isSingleValue));
    assert debugEnter(CLASS_NAME, "getExtraPropertyNames");
    this.isSingleValue = isSingleValue;
    return extraProperties.keySet();
  }
  /**
   * Retrieves a mapping between the names of any extra non-standard
   * properties that may be associated with this attribute type and
   * the value for that property.  The caller may alter the contents
   * of this mapping.
   * Retrieves an iterable over the value(s) of the specified "extra"
   * property for this attribute type.
   *
   * @return  A mapping between the names of any extra non-standard
   *          properties that may be associated with this attribute
   *          type and the value for that property.
   * @param propertyName
   *          The name of the "extra" property for which to retrieve
   *          the value(s).
   * @return Returns an iterable over the value(s) of the specified
   *         "extra" property for this attribute type, or
   *         <CODE>null</CODE> if no such property is defined.
   */
  public ConcurrentHashMap<String,CopyOnWriteArrayList<String>>
              getExtraProperties()
  {
    assert debugEnter(CLASS_NAME, "getExtraProperties");
    return extraProperties;
  }
  /**
   * Retrieves the value of the specified "extra" property for this
   * attribute type.
   *
   * @param  propertyName  The name of the "extra" property for which
   *                       to retrieve the value.
   *
   * @return  The value of the specified "extra" property for this
   *          attribute type, or <CODE>null</CODE> if no such property
   *          is defined.
   */
  public CopyOnWriteArrayList<String>
              getExtraProperty(String propertyName)
  public Iterable<String> getExtraProperty(String propertyName)
  {
    assert debugEnter(CLASS_NAME, "getExtraProperty",
                      String.valueOf(propertyName));
@@ -1445,10 +1133,17 @@
    if (! extraProperties.isEmpty())
    {
      for (String property : extraProperties.keySet())
      {
        CopyOnWriteArrayList<String> valueList =
             extraProperties.get(property);
      for (Map.Entry<String, List<String>> e :
        extraProperties.entrySet()) {
        String property = e.getKey();
        if (!includeFileElement
            && property.equals(SCHEMA_PROPERTY_FILENAME)) {
          // Don't include the schema file if it was not requested.
          continue;
        }
        List<String> valueList = e.getValue();
        buffer.append(" ");
        buffer.append(property);
@@ -1475,16 +1170,6 @@
      }
    }
    if (includeFileElement && (schemaFile != null) &&
        (! extraProperties.containsKey(SCHEMA_PROPERTY_FILENAME)))
    {
      buffer.append(" ");
      buffer.append(SCHEMA_PROPERTY_FILENAME);
      buffer.append(" '");
      buffer.append(schemaFile);
      buffer.append("'");
    }
    buffer.append(" )");
  }
}
opends/src/server/org/opends/server/types/RDNComparator.java
@@ -107,8 +107,8 @@
          }
          else
          {
            return types1[index].getLowerName().compareTo(
                        types2[index].getLowerName());
            return types1[index].getNormalizedPrimaryName().compareTo(
                        types2[index].getNormalizedPrimaryName());
          }
        }
        else
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAttributeType.java
New file
@@ -0,0 +1,1288 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 */
package org.opends.server.types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.EqualityMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.api.SubstringMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.util.ServerConstants;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * This class defines a set of tests for the
 * {@link org.opends.server.types.AttributeType} class.
 */
public final class TestAttributeType extends TypesTestCase {
  /**
   * Internal class to simplify construction of attribute types.
   */
  private static final class AttributeTypeBuilder {
    // The primary name to use for this attribute type.
    private String primaryName;
    // The set of names for this attribute type.
    private List<String> typeNames;
    // The OID that may be used to reference this attribute type.
    private String oid;
    // The description for this attribute type.
    private String description;
    // The superior attribute type from which this attribute type
    // inherits.
    private AttributeType superiorType;
    // The syntax for this attribute type.
    private AttributeSyntax syntax;
    // The approximate matching rule for this attribute type.
    private ApproximateMatchingRule approximateMatchingRule;
    // The equality matching rule for this attribute type.
    private EqualityMatchingRule equalityMatchingRule;
    // The ordering matching rule for this attribute type.
    private OrderingMatchingRule orderingMatchingRule;
    // The substring matching rule for this attribute type.
    private SubstringMatchingRule substringMatchingRule;
    // The attribute usage for this attribute type.
    private AttributeUsage attributeUsage;
    // Indicates whether this attribute type is declared "collective".
    private boolean isCollective;
    // Indicates whether this attribute type is declared
    // "no-user-modification".
    private boolean isNoUserModification;
    // Indicates whether this attribute type is declared "obsolete".
    private boolean isObsolete;
    // Indicates whether this attribute type is declared
    // "single-value".
    private boolean isSingleValue;
    // The set of additional name-value pairs associated with this
    // attribute type definition.
    private Map<String, List<String>> extraProperties;
    // Reset the builder to its initial state.
    private void reset() {
      this.primaryName = null;
      this.typeNames = null;
      this.oid = null;
      this.description = null;
      this.superiorType = null;
      this.syntax = null;
      this.approximateMatchingRule = null;
      this.equalityMatchingRule = null;
      this.orderingMatchingRule = null;
      this.substringMatchingRule = null;
      this.attributeUsage = AttributeUsage.USER_APPLICATIONS;
      this.isCollective = false;
      this.isNoUserModification = false;
      this.isObsolete = false;
      this.isSingleValue = false;
      this.extraProperties = null;
    }
    /**
     * Create a new attribute type builder.
     */
    public AttributeTypeBuilder() {
      reset();
    }
    /**
     * Create a new attribute type builder.
     *
     * @param primaryName
     *          The attribute type primary name.
     * @param oid
     *          The attribute type OID.
     */
    public AttributeTypeBuilder(String primaryName, String oid) {
      reset();
      this.primaryName = primaryName;
      this.oid = oid;
    }
    /**
     * Construct an attribute type based on the properties of the
     * builder.
     *
     * @return The new attribute type.
     */
    public AttributeType getAttributeType() {
      if (oid == null) {
        throw new IllegalStateException("Null OID.");
      }
      AttributeType type = new AttributeType(primaryName, typeNames,
          oid, description, superiorType, syntax,
          approximateMatchingRule, equalityMatchingRule,
          orderingMatchingRule, substringMatchingRule,
          attributeUsage, isCollective, isNoUserModification,
          isObsolete, isSingleValue, extraProperties);
      // Reset the internal state.
      reset();
      return type;
    }
    /**
     * Set the approximateMatchingRule.
     *
     * @param approximateMatchingRule
     *          The approximateMatchingRule.
     */
    public void setApproximateMatchingRule(
        ApproximateMatchingRule approximateMatchingRule) {
      this.approximateMatchingRule = approximateMatchingRule;
    }
    /**
     * Set the attributeUsage.
     *
     * @param attributeUsage
     *          The attributeUsage.
     */
    public void setAttributeUsage(AttributeUsage attributeUsage) {
      this.attributeUsage = attributeUsage;
    }
    /**
     * Set the description.
     *
     * @param description
     *          The description.
     */
    public void setDescription(String description) {
      this.description = description;
    }
    /**
     * Set the equalityMatchingRule.
     *
     * @param equalityMatchingRule
     *          The equalityMatchingRule.
     */
    public void setEqualityMatchingRule(
        EqualityMatchingRule equalityMatchingRule) {
      this.equalityMatchingRule = equalityMatchingRule;
    }
    /**
     * Add extra property value(s).
     *
     * @param name
     *          The name of the extra property.
     * @param values
     *          The value(s) of the extra property.
     */
    public void addExtraProperty(String name, String... values) {
      if (name == null) {
        throw new NullPointerException("Null extra property name");
      }
      if (values == null) {
        throw new NullPointerException("Null extra property values");
      }
      if (extraProperties == null) {
        extraProperties = new HashMap<String, List<String>>();
      }
      List<String> l = extraProperties.get(name);
      if (l == null) {
        l = new ArrayList<String>();
        extraProperties.put(name, l);
      }
      l.addAll(Arrays.asList(values));
    }
    /**
     * Set the isCollective.
     *
     * @param isCollective
     *          The isCollective.
     */
    public void setCollective(boolean isCollective) {
      this.isCollective = isCollective;
    }
    /**
     * Set the isNoUserModification.
     *
     * @param isNoUserModification
     *          The isNoUserModification.
     */
    public void setNoUserModification(boolean isNoUserModification) {
      this.isNoUserModification = isNoUserModification;
    }
    /**
     * Set the isObsolete.
     *
     * @param isObsolete
     *          The isObsolete.
     */
    public void setObsolete(boolean isObsolete) {
      this.isObsolete = isObsolete;
    }
    /**
     * Set the isSingleValue.
     *
     * @param isSingleValue
     *          The isSingleValue.
     */
    public void setSingleValue(boolean isSingleValue) {
      this.isSingleValue = isSingleValue;
    }
    /**
     * Set the oid.
     *
     * @param oid
     *          The oid.
     */
    public void setOid(String oid) {
      if (oid == null) {
        throw new NullPointerException("Null OID");
      }
      this.oid = oid;
    }
    /**
     * Set the orderingMatchingRule.
     *
     * @param orderingMatchingRule
     *          The orderingMatchingRule.
     */
    public void setOrderingMatchingRule(
        OrderingMatchingRule orderingMatchingRule) {
      this.orderingMatchingRule = orderingMatchingRule;
    }
    /**
     * Set the primaryName.
     *
     * @param primaryName
     *          The primaryName.
     */
    public void setPrimaryName(String primaryName) {
      this.primaryName = primaryName;
    }
    /**
     * Set the substringMatchingRule.
     *
     * @param substringMatchingRule
     *          The substringMatchingRule.
     */
    public void setSubstringMatchingRule(
        SubstringMatchingRule substringMatchingRule) {
      this.substringMatchingRule = substringMatchingRule;
    }
    /**
     * Set the superiorType.
     *
     * @param superiorType
     *          The superiorType.
     */
    public void setSuperiorType(AttributeType superiorType) {
      this.superiorType = superiorType;
    }
    /**
     * Set the syntax.
     *
     * @param syntax
     *          The syntax.
     */
    public void setSyntax(AttributeSyntax syntax) {
      this.syntax = syntax;
    }
    /**
     * Add attribute type name(s).
     *
     * @param names
     *          The attribute type name(s) to add.
     */
    public void addTypeNames(String... names) {
      if (names == null) {
        throw new NullPointerException("Null names");
      }
      if (typeNames == null) {
        typeNames = new LinkedList<String>();
      }
      typeNames.addAll(Arrays.asList(names));
    }
  }
  /**
   * Once-only initialization.
   *
   * @throws Exception
   *           If an unexpected error occurred.
   */
  @BeforeClass
  public void setUp() throws Exception {
    // This test suite depends on having the schema available, so
    // we'll
    // start the server.
    TestCaseUtils.startServer();
  }
  /**
   * Check that the simple constructor throws an NPE when mandatory
   * parameters are not specified.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(expectedExceptions = NullPointerException.class)
  public void testSimpleConstructorNPE() throws Exception {
    new AttributeType(null, null, null, null, null, null, null,
        false, false, false, false);
  }
  /**
   * Check that the complex constructor throws an NPE when mandatory
   * parameters are not specified.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(expectedExceptions = NullPointerException.class)
  public void testComplexConstructorNPE() throws Exception {
    new AttributeType(null, null, null, null, null, null, null, null,
        null, null, null, false, false, false, false, null);
  }
  /**
   * Check that the complex constructor does not throw an exception
   * when all optional parameters are not specified.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testComplexConstructorDefault() throws Exception {
    AttributeType type = new AttributeType(null, null, "1.2.3", null,
        null, null, null, null, null, null, null, false, false,
        false, false, null);
    Assert.assertNull(type.getPrimaryName());
  }
  /**
   * Check that the primary name is added to the set of names.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorPrimaryName() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertTrue(type.hasName("testtype"));
    Assert.assertFalse(type.hasName("xxx"));
  }
  /**
   * Check that the type names are accessible.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorTypeNames() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    builder.addTypeNames("testNameAlias", "anotherNameAlias");
    AttributeType type = builder.getAttributeType();
    Assert.assertTrue(type.hasName("testtype"));
    Assert.assertTrue(type.hasName("testnamealias"));
    Assert.assertTrue(type.hasName("anothernamealias"));
  }
  /**
   * Check constructor sets the default usage correctly.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorDefaultUsage() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getUsage(),
        AttributeUsage.USER_APPLICATIONS);
  }
  /**
   * Check constructor sets the default syntax correctly.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorDefaultSyntax() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getSyntax(), DirectoryServer
        .getDefaultAttributeSyntax());
  }
  /**
   * Check constructor sets the syntax correctly.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorSyntax() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    builder.setSyntax(DirectoryServer.getDefaultIntegerSyntax());
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getSyntax(), DirectoryServer
        .getDefaultIntegerSyntax());
  }
  /**
   * Check constructor inherits the syntax from the parent type when
   * required.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dependsOnMethods = "testConstructorSyntax")
  public void testConstructorInheritsSyntax() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "parentType", "1.2.3");
    builder.setSyntax(DirectoryServer.getDefaultIntegerSyntax());
    AttributeType parent = builder.getAttributeType();
    builder.setPrimaryName("childType");
    builder.setOid("4.5.6");
    builder.setSuperiorType(parent);
    AttributeType child = builder.getAttributeType();
    Assert.assertEquals(parent.getSyntax(), child.getSyntax());
  }
  /**
   * Check constructor sets the default matching rules correctly.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorDefaultMatchingRules() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    AttributeSyntax syntax = DirectoryServer
        .getDefaultAttributeSyntax();
    Assert.assertEquals(type.getApproximateMatchingRule(), syntax
        .getApproximateMatchingRule());
    Assert.assertEquals(type.getEqualityMatchingRule(), syntax
        .getEqualityMatchingRule());
    Assert.assertEquals(type.getOrderingMatchingRule(), syntax
        .getOrderingMatchingRule());
    Assert.assertEquals(type.getSubstringMatchingRule(), syntax
        .getSubstringMatchingRule());
  }
  /**
   * Check constructor sets the matching rules correctly.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testConstructorMatchingRules() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeSyntax syntax = DirectoryServer.getDefaultStringSyntax();
    builder.setApproximateMatchingRule(syntax
        .getApproximateMatchingRule());
    builder.setEqualityMatchingRule(syntax.getEqualityMatchingRule());
    builder.setOrderingMatchingRule(syntax.getOrderingMatchingRule());
    builder.setSubstringMatchingRule(syntax
        .getSubstringMatchingRule());
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getApproximateMatchingRule(), syntax
        .getApproximateMatchingRule());
    Assert.assertEquals(type.getEqualityMatchingRule(), syntax
        .getEqualityMatchingRule());
    Assert.assertEquals(type.getOrderingMatchingRule(), syntax
        .getOrderingMatchingRule());
    Assert.assertEquals(type.getSubstringMatchingRule(), syntax
        .getSubstringMatchingRule());
  }
  /**
   * Check constructor inherits the matching rules from the parent
   * type when required.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dependsOnMethods = "testConstructorMatchingRules")
  public void testConstructorInheritsMatchingRules() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "parentType", "1.2.3");
    AttributeSyntax syntax = DirectoryServer.getDefaultStringSyntax();
    builder.setApproximateMatchingRule(syntax
        .getApproximateMatchingRule());
    builder.setEqualityMatchingRule(syntax.getEqualityMatchingRule());
    builder.setOrderingMatchingRule(syntax.getOrderingMatchingRule());
    builder.setSubstringMatchingRule(syntax
        .getSubstringMatchingRule());
    AttributeType parent = builder.getAttributeType();
    builder.setPrimaryName("childType");
    builder.setOid("4.5.6");
    builder.setSuperiorType(parent);
    AttributeType child = builder.getAttributeType();
    Assert.assertEquals(parent.getApproximateMatchingRule(), child
        .getApproximateMatchingRule());
    Assert.assertEquals(parent.getEqualityMatchingRule(), child
        .getEqualityMatchingRule());
    Assert.assertEquals(parent.getOrderingMatchingRule(), child
        .getOrderingMatchingRule());
    Assert.assertEquals(parent.getSubstringMatchingRule(), child
        .getSubstringMatchingRule());
  }
  /**
   * Create test data for testing the
   * {@link AttributeType#isObjectClassType()} method.
   *
   * @return Returns the array of test data.
   */
  @DataProvider(name = "isObjectClassTypeTestData")
  public Object[][] createIsObjectClassTypeTestData() {
    return new Object[][] { { "testType", false },
        { "objectclass", true }, { "objectClass", true },
        { "OBJECTCLASS", true } };
  }
  /**
   * Check that the objectClass attribute type is correctly
   * identified.
   *
   * @param name
   *          The primary name.
   * @param result
   *          The expected result.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "isObjectClassTypeTestData")
  public void testIsObjectClassType(String name, boolean result)
      throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(name,
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.isObjectClassType(), result);
  }
  /**
   * Create test data for testing the
   * {@link AttributeType#equals(Object)} method.
   *
   * @return Returns the array of test data.
   */
  @DataProvider(name = "equalsTestData")
  public Object[][] createEqualsTestData() {
    return new Object[][] {
        { "testType", "1.2.3", "testType", "1.2.3", true },
        { "testType", "1.2.3", "xxx", "1.2.3", true },
        { "testType", "1.2.3", "testType", "1.2.4", false },
        { "testType", "1.2.3", "xxx", "1.2.4", false } };
  }
  /**
   * Check that the equals operator works as expected.
   *
   * @param name1
   *          The first primary name.
   * @param oid1
   *          The first oid.
   * @param name2
   *          The second primary name.
   * @param oid2
   *          The second oid.
   * @param result
   *          The expected result.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "equalsTestData")
  public void testEquals(String name1, String oid1, String name2,
      String oid2, boolean result) throws Exception {
    AttributeTypeBuilder builder1 = new AttributeTypeBuilder(name1,
        oid1);
    AttributeType type1 = builder1.getAttributeType();
    AttributeTypeBuilder builder2 = new AttributeTypeBuilder(name2,
        oid2);
    AttributeType type2 = builder2.getAttributeType();
    Assert.assertEquals(type1.equals(type2), result);
    Assert.assertEquals(type2.equals(type1), result);
  }
  /**
   * Check that the hasCode method operator works as expected.
   *
   * @param name1
   *          The first primary name.
   * @param oid1
   *          The first oid.
   * @param name2
   *          The second primary name.
   * @param oid2
   *          The second oid.
   * @param result
   *          The expected result.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "equalsTestData")
  public void testHashCode(String name1, String oid1, String name2,
      String oid2, boolean result) throws Exception {
    AttributeTypeBuilder builder1 = new AttributeTypeBuilder(name1,
        oid1);
    AttributeType type1 = builder1.getAttributeType();
    AttributeTypeBuilder builder2 = new AttributeTypeBuilder(name2,
        oid2);
    AttributeType type2 = builder2.getAttributeType();
    Assert.assertEquals(type1.hashCode() == type2.hashCode(), result);
  }
  /**
   * Create test data for testing the
   * {@link AttributeType#generateHashCode(AttributeValue)} method.
   *
   * @return Returns the array of test data.
   */
  @DataProvider(name = "generateHashCodeTestData")
  public Object[][] createGenerateHashCodeTestData() {
    return new Object[][] { { "one", "one", true },
        { "one", "ONE", true }, { "one", "  oNe  ", true },
        { "one two", " one  two  ", true },
        { "one two", "onetwo", false }, { "one", "two", false } };
  }
  /**
   * Check that the
   * {@link AttributeType#generateHashCode(AttributeValue)} method
   * works as expected.
   *
   * @param value1
   *          The first test value.
   * @param value2
   *          The second test value.
   * @param result
   *          The expected result.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "generateHashCodeTestData")
  public void testGenerateHashCodeTestData(String value1,
      String value2, boolean result) throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    builder.setSyntax(DirectoryServer.getDefaultStringSyntax());
    AttributeType type = builder.getAttributeType();
    AttributeValue av1 = new AttributeValue(type, value1);
    AttributeValue av2 = new AttributeValue(type, value2);
    int h1 = type.generateHashCode(av1);
    int h2 = type.generateHashCode(av2);
    Assert.assertEquals(h1 == h2, result);
  }
  /**
   * Check that the {@link AttributeType#normalize(ByteString)} method
   * works as expected.
   *
   * @param value1
   *          The first test value.
   * @param value2
   *          The second test value.
   * @param result
   *          The expected result.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "generateHashCodeTestData")
  public void testNormalize(String value1, String value2,
      boolean result) throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    builder.setSyntax(DirectoryServer.getDefaultStringSyntax());
    AttributeType type = builder.getAttributeType();
    ByteString b1 = new ASN1OctetString(value1);
    ByteString b2 = new ASN1OctetString(value2);
    ByteString r1 = type.normalize(b1);
    ByteString r2 = type.normalize(b2);
    Assert.assertEquals(r1.equals(r2), result);
  }
  /**
   * Check that the {@link AttributeType#getDescription()} method
   * returns <code>null</code> when there is no description.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetDescriptionDefault() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertNull(type.getDescription());
  }
  /**
   * Check that the {@link AttributeType#getDescription()} method
   * returns a description.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetDescription() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    builder.setDescription("hello");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getDescription(), "hello");
  }
  /**
   * Check that the {@link AttributeType#getExtraProperty(String)}
   * method returns <code>null</code> when there is no property.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetExtraPropertyDefault() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertNull(type.getExtraProperty("test"));
  }
  /**
   * Check that the {@link AttributeType#getExtraProperty(String)}
   * method returns values.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetExtraProperty() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    String[] expectedValues = new String[] { "one", "two" };
    builder.addExtraProperty("test", expectedValues);
    AttributeType type = builder.getAttributeType();
    Assert.assertNotNull(type.getExtraProperty("test"));
    int i = 0;
    for (String value : type.getExtraProperty("test")) {
      Assert.assertEquals(value, expectedValues[i]);
      i++;
    }
  }
  /**
   * Check that the {@link AttributeType#getExtraPropertyNames()}
   * method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetExtraPropertyNames() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder("test",
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertFalse(type.getExtraPropertyNames().iterator()
        .hasNext());
  }
  /**
   * Check that the {@link AttributeType#getNameOrOID()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetNameOrOIDReturnsOID() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getNameOrOID(), "1.2.3");
  }
  /**
   * Check that the {@link AttributeType#getNameOrOID()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetNameOrOIDReturnsPrimaryName() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getNameOrOID(), "testType");
  }
  /**
   * Check that the {@link AttributeType#getNameOrOID()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetNameOrOIDReturnsOtherName() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    builder.addTypeNames("anotherName");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getNameOrOID(), "anotherName");
  }
  /**
   * Check that the {@link AttributeType#getNormalizedNames()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetNormalizedNames() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    builder.addTypeNames("anotherName", "yetAnotherName");
    AttributeType type = builder.getAttributeType();
    boolean gotTestType = false;
    boolean gotAnotherName = false;
    boolean gotYetAnotherName = false;
    for (String name : type.getNormalizedNames()) {
      if (name.equals("testtype")) {
        gotTestType = true;
      } else if (name.equals("anothername")) {
        gotAnotherName = true;
      } else if (name.equals("yetanothername")) {
        gotYetAnotherName = true;
      } else {
        Assert.fail("Got unexpected normalized name: " + name);
      }
    }
    Assert.assertTrue(gotTestType && gotAnotherName
        && gotYetAnotherName);
  }
  /**
   * Check that the {@link AttributeType#getUserDefinedNames()}
   * method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetUserDefinedNames() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    builder.addTypeNames("anotherName", "yetAnotherName");
    AttributeType type = builder.getAttributeType();
    boolean gotTestType = false;
    boolean gotAnotherName = false;
    boolean gotYetAnotherName = false;
    for (String name : type.getUserDefinedNames()) {
      if (name.equals("testType")) {
        gotTestType = true;
      } else if (name.equals("anotherName")) {
        gotAnotherName = true;
      } else if (name.equals("yetAnotherName")) {
        gotYetAnotherName = true;
      } else {
        Assert.fail("Got unexpected user defined name: " + name);
      }
    }
    Assert.assertTrue(gotTestType && gotAnotherName
        && gotYetAnotherName);
  }
  /**
   * Check that the {@link AttributeType#getNormalizedPrimaryName()}
   * method returns <code>null</code> when there is no primary name.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetNormalizedPrimaryNameDefault() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertNull(type.getNormalizedPrimaryName());
  }
  /**
   * Check that the {@link AttributeType#getNormalizedPrimaryName()}
   * method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetNormalizedPrimaryName() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getNormalizedPrimaryName(), "testtype");
  }
  /**
   * Check that the {@link AttributeType#getOID()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetOID() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getOID(), "1.2.3");
  }
  /**
   * Check that the {@link AttributeType#getPrimaryName()} method
   * returns <code>null</code> when there is no primary name.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetPrimaryNameDefault() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertNull(type.getPrimaryName());
  }
  /**
   * Check that the {@link AttributeType#getPrimaryName()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetPrimaryName() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getPrimaryName(), "testType");
  }
  /**
   * Check that the {@link AttributeType#getSchemaFile()} method
   * returns <code>null</code> when there is no schema file.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetSchemaFileDefault() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertNull(type.getSchemaFile());
  }
  /**
   * Check that the {@link AttributeType#getSchemaFile()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testGetSchemaFile() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    builder.addExtraProperty(
        ServerConstants.SCHEMA_PROPERTY_FILENAME, "/foo/bar");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.getSchemaFile(), "/foo/bar");
  }
  /**
   * Check that the {@link AttributeType#hasNameOrOID(String)} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testHasNameOrOID() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertTrue(type.hasNameOrOID("testtype"));
    Assert.assertTrue(type.hasNameOrOID("1.2.3"));
    Assert.assertFalse(type.hasNameOrOID("x.y.z"));
  }
  /**
   * Check that the {@link AttributeType#isCollective()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testIsCollective() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertFalse(type.isCollective());
    builder = new AttributeTypeBuilder("testType", "1.2.3");
    builder.setCollective(true);
    type = builder.getAttributeType();
    Assert.assertTrue(type.isCollective());
  }
  /**
   * Check that the {@link AttributeType#isNoUserModification()}
   * method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testIsNoUserModification() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertFalse(type.isNoUserModification());
    builder = new AttributeTypeBuilder("testType", "1.2.3");
    builder.setNoUserModification(true);
    type = builder.getAttributeType();
    Assert.assertTrue(type.isNoUserModification());
  }
  /**
   * Check that the {@link AttributeType#isObsolete()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testIsObsolete() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertFalse(type.isObsolete());
    builder = new AttributeTypeBuilder("testType", "1.2.3");
    builder.setObsolete(true);
    type = builder.getAttributeType();
    Assert.assertTrue(type.isObsolete());
  }
  /**
   * Check that the {@link AttributeType#isSingleValue()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testIsSingleValue() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertFalse(type.isSingleValue());
    builder = new AttributeTypeBuilder("testType", "1.2.3");
    builder.setSingleValue(true);
    type = builder.getAttributeType();
    Assert.assertTrue(type.isSingleValue());
  }
  /**
   * Create test data for testing the
   * {@link AttributeType#isOperational()} method.
   *
   * @return Returns the array of test data.
   */
  @DataProvider(name = "isOperationalTestData")
  public Object[][] createIsOperationalTestData() {
    return new Object[][] { { null, false },
        { AttributeUsage.USER_APPLICATIONS, false },
        { AttributeUsage.DIRECTORY_OPERATION, true },
        { AttributeUsage.DISTRIBUTED_OPERATION, true },
        { AttributeUsage.DSA_OPERATION, true } };
  }
  /**
   * Check that the {@link AttributeType#isOperational()} method.
   *
   * @param usage
   *          The attribute usage.
   * @param result
   *          Expected result.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "isOperationalTestData")
  public void testIsOperational(AttributeUsage usage, boolean result)
      throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    builder.setAttributeUsage(usage);
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.isOperational(), result);
  }
  /**
   * Check that the {@link AttributeType#toString()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testToStringDefault() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(null,
        "1.2.3");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.toString(), "( 1.2.3 "
        + "EQUALITY caseIgnoreMatch "
        + "ORDERING caseIgnoreOrderingMatch "
        + "SUBSTR caseIgnoreSubstringsMatch "
        + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
        + "USAGE userApplications )");
  }
  /**
   * Check that the {@link AttributeType#toString()} method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test
  public void testToString() throws Exception {
    AttributeTypeBuilder builder = new AttributeTypeBuilder(
        "testType", "1.2.3");
    builder.addTypeNames("anotherName");
    builder.setAttributeUsage(AttributeUsage.DIRECTORY_OPERATION);
    builder.setSingleValue(true);
    builder.setSyntax(DirectoryServer.getDefaultBooleanSyntax());
    builder.addExtraProperty(
        ServerConstants.SCHEMA_PROPERTY_FILENAME, "/foo/bar");
    AttributeType type = builder.getAttributeType();
    Assert.assertEquals(type.toString(), "( 1.2.3 "
        + "NAME ( 'anotherName' 'testType' ) "
        + "EQUALITY booleanMatch "
        + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 " + "SINGLE-VALUE "
        + "USAGE directoryOperation " + "X-SCHEMA-FILE '/foo/bar' )");
  }
}