From f2160f4bd1c8ac67e5a86a6710d431e8932877f9 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 28 May 2010 11:47:51 +0000
Subject: [PATCH] Synchronize SDK on java.net with internal repository.

---
 sdk/src/org/opends/sdk/RDN.java |  729 +++++++------------------------------------------------
 1 files changed, 101 insertions(+), 628 deletions(-)

diff --git a/sdk/src/org/opends/sdk/RDN.java b/sdk/src/org/opends/sdk/RDN.java
index c5b840a..458965f 100644
--- a/sdk/src/org/opends/sdk/RDN.java
+++ b/sdk/src/org/opends/sdk/RDN.java
@@ -22,329 +22,72 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2009 Sun Microsystems, Inc.
+ *      Copyright 2009-2010 Sun Microsystems, Inc.
  */
 
 package org.opends.sdk;
 
 
 
-import static com.sun.opends.sdk.messages.Messages.*;
-import static com.sun.opends.sdk.util.StaticUtils.*;
+import static com.sun.opends.sdk.messages.Messages.ERR_RDN_TYPE_NOT_FOUND;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 
-import org.opends.sdk.schema.*;
+import org.opends.sdk.schema.AttributeType;
+import org.opends.sdk.schema.Schema;
+import org.opends.sdk.schema.UnknownSchemaElementException;
 
-import com.sun.opends.sdk.util.*;
+import com.sun.opends.sdk.util.Iterators;
+import com.sun.opends.sdk.util.SubstringReader;
 
 
 
 /**
- * A relative distinguished name (RDN) as defined in RFC 4512 section
- * 2.3 is the name of an entry relative to its immediate superior. An
- * RDN is composed of an unordered set of one or more attribute value
- * assertions (AVA) consisting of an attribute description with zero
- * options and an attribute value. These AVAs are chosen to match
- * attribute values (each a distinguished value) of the entry.
+ * A relative distinguished name (RDN) as defined in RFC 4512 section 2.3 is the
+ * name of an entry relative to its immediate superior. An RDN is composed of an
+ * unordered set of one or more attribute value assertions (AVA) consisting of
+ * an attribute description with zero options and an attribute value. These AVAs
+ * are chosen to match attribute values (each a distinguished value) of the
+ * entry.
  * <p>
- * An entry's relative distinguished name must be unique among all
- * immediate subordinates of the entry's immediate superior (i.e. all
- * siblings).
+ * An entry's relative distinguished name must be unique among all immediate
+ * subordinates of the entry's immediate superior (i.e. all siblings).
  * <p>
  * The following are examples of string representations of RDNs:
- * 
+ *
  * <pre>
  * uid=12345
  * ou=Engineering
  * cn=Kurt Zeilenga+L=Redwood Shores
  * </pre>
- * 
- * The last is an example of a multi-valued RDN; that is, an RDN
- * composed of multiple AVAs.
- * 
- * @see <a href="http://tools.ietf.org/html/rfc4512#section-2.3">RFC
- *      4512 - Lightweight Directory Access Protocol (LDAP): Directory
- *      Information Models </a>
+ *
+ * The last is an example of a multi-valued RDN; that is, an RDN composed of
+ * multiple AVAs.
+ *
+ * @see <a href="http://tools.ietf.org/html/rfc4512#section-2.3">RFC 4512 -
+ *      Lightweight Directory Access Protocol (LDAP): Directory Information
+ *      Models </a>
  */
-public final class RDN implements Iterable<RDN.AVA>, Comparable<RDN>
+public final class RDN implements Iterable<AVA>, Comparable<RDN>
 {
   /**
-   * An attribute value assertion (AVA) as defined in RFC 4512 section
-   * 2.3 consists of an attribute description with zero options and an
-   * attribute value.
-   */
-  public static final class AVA implements Comparable<AVA>
-  {
-    private final AttributeType attributeType;
-
-    private final ByteString attributeValue;
-
-
-
-    /**
-     * Creates a new attribute value assertion (AVA) using the provided
-     * attribute type and value.
-     * 
-     * @param attributeType
-     *          The attribute type.
-     * @param attributeValue
-     *          The attribute value.
-     * @throws NullPointerException
-     *           If {@code attributeType} or {@code attributeValue} was
-     *           {@code null}.
-     */
-    public AVA(AttributeType attributeType, ByteString attributeValue)
-        throws NullPointerException
-    {
-      Validator.ensureNotNull(attributeType, attributeValue);
-
-      this.attributeType = attributeType;
-      this.attributeValue = attributeValue;
-    }
-
-
-
-    /**
-     * Creates a new attribute value assertion (AVA) using the provided
-     * attribute type and value decoded using the default schema.
-     * <p>
-     * If {@code attributeValue} is not an instance of {@code
-     * ByteString} then it will be converted using the
-     * {@link ByteString#valueOf(Object)} method.
-     * 
-     * @param attributeType
-     *          The attribute type.
-     * @param attributeValue
-     *          The attribute value.
-     * @throws UnknownSchemaElementException
-     *           If {@code attributeType} was not found in the default
-     *           schema.
-     * @throws NullPointerException
-     *           If {@code attributeType} or {@code attributeValue} was
-     *           {@code null}.
-     */
-    public AVA(String attributeType, Object attributeValue)
-        throws UnknownSchemaElementException, NullPointerException
-    {
-      Validator.ensureNotNull(attributeType, attributeValue);
-
-      this.attributeType = Schema.getDefaultSchema().getAttributeType(
-          attributeType);
-      this.attributeValue = ByteString.valueOf(attributeValue);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public int compareTo(AVA ava)
-    {
-      int result = attributeType.compareTo(ava.attributeType);
-
-      if (result == 0)
-      {
-        final ByteString nv1 = getNormalizeValue();
-        final ByteString nv2 = ava.getNormalizeValue();
-        result = nv1.compareTo(nv2);
-      }
-
-      return result;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean equals(Object obj)
-    {
-      if (this == obj)
-      {
-        return true;
-      }
-      else if (obj instanceof AVA)
-      {
-        return compareTo((AVA) obj) == 0;
-      }
-      else
-      {
-        return false;
-      }
-    }
-
-
-
-    /**
-     * Returns the attribute type associated with this AVA.
-     * 
-     * @return The attribute type associated with this AVA.
-     */
-    public AttributeType getAttributeType()
-    {
-      return attributeType;
-    }
-
-
-
-    /**
-     * Returns the attribute value associated with this AVA.
-     * 
-     * @return The attribute value associated with this AVA.
-     */
-    public ByteString getAttributeValue()
-    {
-      return attributeValue;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public int hashCode()
-    {
-      return attributeType.hashCode() * 31
-          + getNormalizeValue().hashCode();
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public String toString()
-    {
-      final StringBuilder builder = new StringBuilder();
-      return toString(builder).toString();
-    }
-
-
-
-    private ByteString getNormalizeValue()
-    {
-      final MatchingRule matchingRule = attributeType
-          .getEqualityMatchingRule();
-      if (matchingRule != null)
-      {
-        try
-        {
-          return matchingRule.normalizeAttributeValue(attributeValue);
-        }
-        catch (final DecodeException de)
-        {
-          // Ignore - we'll drop back to the user provided value.
-        }
-      }
-      return attributeValue;
-    }
-
-
-
-    private StringBuilder toNormalizedString(StringBuilder builder)
-    {
-      return toString(builder, true);
-    }
-
-
-
-    private StringBuilder toString(StringBuilder builder)
-    {
-      return toString(builder, false);
-    }
-
-
-
-    private StringBuilder toString(StringBuilder builder,
-        boolean normalize)
-    {
-      final ByteString value = normalize ? getNormalizeValue()
-          : attributeValue;
-
-      if (!attributeType.getNames().iterator().hasNext())
-      {
-        builder.append(attributeType.getOID());
-        builder.append("=#");
-        StaticUtils.toHex(value, builder);
-      }
-      else
-      {
-        final String name = attributeType.getNameOrOID();
-        if (normalize)
-        {
-          // Normalizing.
-          StaticUtils.toLowerCase(name, builder);
-        }
-        else
-        {
-          builder.append(name);
-        }
-
-        builder.append("=");
-
-        final Syntax syntax = attributeType.getSyntax();
-        if (!syntax.isHumanReadable())
-        {
-          builder.append("#");
-          StaticUtils.toHex(value, builder);
-        }
-        else
-        {
-          final String str = value.toString();
-          char c;
-          for (int si = 0; si < str.length(); si++)
-          {
-            c = str.charAt(si);
-            if (c == ' ' || c == '#' || c == '"' || c == '+'
-                || c == ',' || c == ';' || c == '<' || c == '='
-                || c == '>' || c == '\\' || c == '\u0000')
-            {
-              builder.append('\\');
-            }
-            builder.append(c);
-          }
-        }
-      }
-      return builder;
-    }
-  }
-
-
-
-  private static final char[] SPECIAL_CHARS = new char[] { '\"', '+',
-      ',', ';', '<', '>', ' ', '#', '=', '\\' };
-
-  private static final char[] DELIMITER_CHARS = new char[] { '+', ',',
-      ';' };
-
-  private static final char[] DQUOTE_CHAR = new char[] { '\"' };
-
-  private static final Comparator<AVA> ATV_COMPARATOR = new Comparator<AVA>()
-  {
-    public int compare(AVA o1, AVA o2)
-    {
-      return o1.getAttributeType().compareTo(o2.getAttributeType());
-    }
-  };
-
-
-
-  /**
-   * Parses the provided LDAP string representation of an RDN using the
-   * default schema.
-   * 
+   * Parses the provided LDAP string representation of an RDN using the default
+   * schema.
+   *
    * @param rdn
    *          The LDAP string representation of a RDN.
    * @return The parsed RDN.
    * @throws LocalizedIllegalArgumentException
-   *           If {@code rdn} is not a valid LDAP string representation
-   *           of a RDN.
+   *           If {@code rdn} is not a valid LDAP string representation of a
+   *           RDN.
    * @throws NullPointerException
    *           If {@code rdn} was {@code null}.
    */
-  public static RDN valueOf(String rdn)
-      throws LocalizedIllegalArgumentException
+  public static RDN valueOf(final String rdn)
+      throws LocalizedIllegalArgumentException, NullPointerException
   {
     return valueOf(rdn, Schema.getDefaultSchema());
   }
@@ -352,22 +95,22 @@
 
 
   /**
-   * Parses the provided LDAP string representation of a RDN using the
-   * provided schema.
-   * 
+   * Parses the provided LDAP string representation of a RDN using the provided
+   * schema.
+   *
    * @param rdn
    *          The LDAP string representation of a RDN.
    * @param schema
    *          The schema to use when parsing the RDN.
    * @return The parsed RDN.
    * @throws LocalizedIllegalArgumentException
-   *           If {@code rdn} is not a valid LDAP string representation
-   *           of a RDN.
+   *           If {@code rdn} is not a valid LDAP string representation of a
+   *           RDN.
    * @throws NullPointerException
    *           If {@code rdn} or {@code schema} was {@code null}.
    */
-  public static RDN valueOf(String rdn, Schema schema)
-      throws LocalizedIllegalArgumentException
+  public static RDN valueOf(final String rdn, final Schema schema)
+      throws LocalizedIllegalArgumentException, NullPointerException
   {
     final SubstringReader reader = new SubstringReader(rdn);
     try
@@ -384,285 +127,13 @@
 
 
 
-  private static AVA readAttributeTypeAndValue(SubstringReader reader,
-      Schema schema) throws LocalizedIllegalArgumentException,
-      UnknownSchemaElementException
-  {
-    // Skip over any spaces at the beginning.
-    reader.skipWhitespaces();
-
-    final AttributeType attribute = readDNAttributeName(reader, schema);
-
-    // Make sure that we're not at the end of the DN string because
-    // that would be invalid.
-    if (reader.remaining() == 0)
-    {
-      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME
-          .get(reader.getString(), attribute.getNameOrOID());
-      throw new LocalizedIllegalArgumentException(message);
-    }
-
-    // The next character must be an equal sign. If it is not, then
-    // that's an error.
-    char c;
-    if ((c = reader.read()) != '=')
-    {
-      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_NO_EQUAL.get(reader
-          .getString(), attribute.getNameOrOID(), c);
-      throw new LocalizedIllegalArgumentException(message);
-    }
-
-    // Skip over any spaces after the equal sign.
-    reader.skipWhitespaces();
-
-    // Parse the value for this RDN component.
-    final ByteString value = readDNAttributeValue(reader);
-
-    return new AVA(attribute, value);
-  }
-
-
-
-  private static AttributeType readDNAttributeName(
-      SubstringReader reader, Schema schema)
-      throws LocalizedIllegalArgumentException,
-      UnknownSchemaElementException
-  {
-    int length = 1;
-    reader.mark();
-
-    // The next character must be either numeric (for an OID) or
-    // alphabetic (for
-    // an attribute description).
-    char c = reader.read();
-    if (isDigit(c))
-    {
-      boolean lastWasPeriod = false;
-      do
-      {
-        if (c == '.')
-        {
-          if (lastWasPeriod)
-          {
-            final LocalizableMessage message = ERR_ATTR_SYNTAX_OID_CONSECUTIVE_PERIODS
-                .get(reader.getString(), reader.pos() - 1);
-            throw new LocalizedIllegalArgumentException(message);
-          }
-          else
-          {
-            lastWasPeriod = true;
-          }
-        }
-        else if (!isDigit(c))
-        {
-          // This must have been an illegal character.
-          final LocalizableMessage message = ERR_ATTR_SYNTAX_OID_ILLEGAL_CHARACTER
-              .get(reader.getString(), reader.pos() - 1);
-          throw new LocalizedIllegalArgumentException(message);
-        }
-        else
-        {
-          lastWasPeriod = false;
-        }
-        length++;
-      } while ((c = reader.read()) != '=');
-    }
-    if (isAlpha(c))
-    {
-      // This must be an attribute description. In this case, we will
-      // only
-      // accept alphabetic characters, numeric digits, and the hyphen.
-      while ((c = reader.read()) != '=')
-      {
-        if (length == 0 && !isAlpha(c))
-        {
-          // This is an illegal character.
-          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR
-              .get(reader.getString(), c, reader.pos() - 1);
-          throw new LocalizedIllegalArgumentException(message);
-        }
-
-        if (!isAlpha(c) && !isDigit(c) && c != '-')
-        {
-          // This is an illegal character.
-          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR
-              .get(reader.getString(), c, reader.pos() - 1);
-          throw new LocalizedIllegalArgumentException(message);
-        }
-
-        length++;
-      }
-    }
-    else
-    {
-      final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(
-          reader.getString(), c, reader.pos() - 1);
-      throw new LocalizedIllegalArgumentException(message);
-    }
-
-    reader.reset();
-
-    // Return the position of the first non-space character after the
-    // token.
-
-    return schema.getAttributeType(reader.read(length));
-  }
-
-
-
-  private static ByteString readDNAttributeValue(SubstringReader reader)
-      throws LocalizedIllegalArgumentException
-  {
-    // All leading spaces have already been stripped so we can start
-    // reading the value. However, it may be empty so check for that.
-    if (reader.remaining() == 0)
-    {
-      return ByteString.empty();
-    }
-
-    reader.mark();
-
-    // Look at the first character. If it is an octothorpe (#), then
-    // that means that the value should be a hex string.
-    char c = reader.read();
-    int length = 0;
-    if (c == '#')
-    {
-      // The first two characters must be hex characters.
-      reader.mark();
-      if (reader.remaining() < 2)
-      {
-        final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT
-            .get(reader.getString());
-        throw new LocalizedIllegalArgumentException(message);
-      }
-
-      for (int i = 0; i < 2; i++)
-      {
-        c = reader.read();
-        if (isHexDigit(c))
-        {
-          length++;
-        }
-        else
-        {
-          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT
-              .get(reader.getString(), c);
-          throw new LocalizedIllegalArgumentException(message);
-        }
-      }
-
-      // The rest of the value must be a multiple of two hex
-      // characters. The end of the value may be designated by the
-      // end of the DN, a comma or semicolon, or a space.
-      while (reader.remaining() > 0)
-      {
-        c = reader.read();
-        if (isHexDigit(c))
-        {
-          length++;
-
-          if (reader.remaining() > 0)
-          {
-            c = reader.read();
-            if (isHexDigit(c))
-            {
-              length++;
-            }
-            else
-            {
-              final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT
-                  .get(reader.getString(), c);
-              throw new LocalizedIllegalArgumentException(message);
-            }
-          }
-          else
-          {
-            final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT
-                .get(reader.getString());
-            throw new LocalizedIllegalArgumentException(message);
-          }
-        }
-        else if ((c == ' ') || (c == ',') || (c == ';'))
-        {
-          // This denotes the end of the value.
-          break;
-        }
-        else
-        {
-          final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT
-              .get(reader.getString(), c);
-          throw new LocalizedIllegalArgumentException(message);
-        }
-      }
-
-      // At this point, we should have a valid hex string. Convert it
-      // to a byte array and set that as the value of the provided
-      // octet string.
-      try
-      {
-        reader.reset();
-        return ByteString
-            .wrap(hexStringToByteArray(reader.read(length)));
-      }
-      catch (final Exception e)
-      {
-        final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE
-            .get(reader.getString(), String.valueOf(e));
-        throw new LocalizedIllegalArgumentException(message);
-      }
-    }
-
-    // If the first character is a quotation mark, then the value
-    // should continue until the corresponding closing quotation mark.
-    else if (c == '"')
-    {
-      try
-      {
-        return StaticUtils.evaluateEscapes(reader, DQUOTE_CHAR, false);
-      }
-      catch (final DecodeException e)
-      {
-        throw new LocalizedIllegalArgumentException(e
-            .getMessageObject());
-      }
-    }
-
-    // Otherwise, use general parsing to find the end of the value.
-    else
-    {
-      reader.reset();
-      ByteString bytes;
-      try
-      {
-        bytes = StaticUtils.evaluateEscapes(reader, SPECIAL_CHARS,
-            DELIMITER_CHARS, true);
-      }
-      catch (final DecodeException e)
-      {
-        throw new LocalizedIllegalArgumentException(e
-            .getMessageObject());
-      }
-      if (bytes.length() == 0)
-      {
-        // We don't allow an empty attribute value.
-        final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_REQUIRES_ESCAPE_CHAR
-            .get(reader.getString(), reader.pos());
-        throw new LocalizedIllegalArgumentException(message);
-      }
-      return bytes;
-    }
-  }
-
-
-
   // FIXME: ensure that the decoded RDN does not contain multiple AVAs
   // with the same type.
-  static RDN decode(String rdnString, SubstringReader reader,
-      Schema schema) throws LocalizedIllegalArgumentException,
+  static RDN decode(final String rdnString, final SubstringReader reader,
+      final Schema schema) throws LocalizedIllegalArgumentException,
       UnknownSchemaElementException
   {
-    final AVA firstAVA = readAttributeTypeAndValue(reader, schema);
+    final AVA firstAVA = AVA.decode(reader, schema);
 
     // Skip over any spaces that might be after the attribute value.
     reader.skipWhitespaces();
@@ -675,21 +146,22 @@
 
       do
       {
-        avas.add(readAttributeTypeAndValue(reader, schema));
+        avas.add(AVA.decode(reader, schema));
 
         // Skip over any spaces that might be after the attribute value.
         reader.skipWhitespaces();
 
         reader.mark();
-      } while (reader.read() == '+');
+      }
+      while (reader.remaining() > 0 && reader.read() == '+');
 
       reader.reset();
-      return new RDN(avas.toArray(new AVA[avas.size()]), rdnString);
+      return new RDN(avas.toArray(new AVA[avas.size()]), null);
     }
     else
     {
       reader.reset();
-      return new RDN(new AVA[] { firstAVA }, rdnString);
+      return new RDN(new AVA[] { firstAVA }, null);
     }
   }
 
@@ -706,16 +178,16 @@
 
   /**
    * Creates a new RDN using the provided attribute type and value.
-   * 
+   *
    * @param attributeType
    *          The attribute type.
    * @param attributeValue
    *          The attribute value.
    * @throws NullPointerException
-   *           If {@code attributeType} or {@code attributeValue} was
-   *           {@code null}.
+   *           If {@code attributeType} or {@code attributeValue} was {@code
+   *           null}.
    */
-  public RDN(AttributeType attributeType, ByteString attributeValue)
+  public RDN(final AttributeType attributeType, final ByteString attributeValue)
       throws NullPointerException
   {
     this.avas = new AVA[] { new AVA(attributeType, attributeValue) };
@@ -724,25 +196,23 @@
 
 
   /**
-   * Creates a new RDN using the provided attribute type and value
-   * decoded using the default schema.
+   * Creates a new RDN using the provided attribute type and value decoded using
+   * the default schema.
    * <p>
-   * If {@code attributeValue} is not an instance of {@code ByteString}
-   * then it will be converted using the
-   * {@link ByteString#valueOf(Object)} method.
-   * 
+   * If {@code attributeValue} is not an instance of {@code ByteString} then it
+   * will be converted using the {@link ByteString#valueOf(Object)} method.
+   *
    * @param attributeType
    *          The attribute type.
    * @param attributeValue
    *          The attribute value.
    * @throws UnknownSchemaElementException
-   *           If {@code attributeType} was not found in the default
-   *           schema.
+   *           If {@code attributeType} was not found in the default schema.
    * @throws NullPointerException
-   *           If {@code attributeType} or {@code attributeValue} was
-   *           {@code null}.
+   *           If {@code attributeType} or {@code attributeValue} was {@code
+   *           null}.
    */
-  public RDN(String attributeType, Object attributeValue)
+  public RDN(final String attributeType, final Object attributeValue)
       throws UnknownSchemaElementException, NullPointerException
   {
     this.avas = new AVA[] { new AVA(attributeType, attributeValue) };
@@ -750,7 +220,7 @@
 
 
 
-  private RDN(AVA[] avas, String stringValue)
+  private RDN(final AVA[] avas, final String stringValue)
   {
     this.avas = avas;
     this.stringValue = stringValue;
@@ -761,14 +231,14 @@
   /**
    * {@inheritDoc}
    */
-  public int compareTo(RDN rdn)
+  public int compareTo(final RDN rdn)
   {
     final int sz1 = avas.length;
     final int sz2 = rdn.avas.length;
 
     if (sz1 != sz2)
     {
-      return sz1 - sz2;
+      return sz1 - sz2 > 0 ? 1 : -1;
     }
 
     if (sz1 == 1)
@@ -779,11 +249,11 @@
     // Need to sort the AVAs before comparing.
     final AVA[] a1 = new AVA[sz1];
     System.arraycopy(avas, 0, a1, 0, sz1);
-    Arrays.sort(a1, ATV_COMPARATOR);
+    Arrays.sort(a1);
 
     final AVA[] a2 = new AVA[sz1];
     System.arraycopy(rdn.avas, 0, a2, 0, sz1);
-    Arrays.sort(a2, ATV_COMPARATOR);
+    Arrays.sort(a2);
 
     for (int i = 0; i < sz1; i++)
     {
@@ -802,7 +272,8 @@
   /**
    * {@inheritDoc}
    */
-  public boolean equals(Object obj)
+  @Override
+  public boolean equals(final Object obj)
   {
     if (this == obj)
     {
@@ -821,15 +292,15 @@
 
 
   /**
-   * Returns the attribute value contained in this RDN which is
-   * associated with the provided attribute type, or {@code null} if
-   * this RDN does not include such an attribute value.
-   * 
+   * Returns the attribute value contained in this RDN which is associated with
+   * the provided attribute type, or {@code null} if this RDN does not include
+   * such an attribute value.
+   *
    * @param attributeType
    *          The attribute type.
    * @return The attribute value.
    */
-  public ByteString getAttributeValue(AttributeType attributeType)
+  public ByteString getAttributeValue(final AttributeType attributeType)
   {
     for (final AVA ava : avas)
     {
@@ -845,7 +316,7 @@
 
   /**
    * Returns the first AVA contained in this RDN.
-   * 
+   *
    * @return The first AVA contained in this RDN.
    */
   public AVA getFirstAVA()
@@ -858,13 +329,14 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public int hashCode()
   {
     // Avoid an algorithm that requires the AVAs to be sorted.
     int hash = 0;
-    for (int i = 0; i < avas.length; i++)
+    for (final AVA ava : avas)
     {
-      hash += avas[i].hashCode();
+      hash += ava.hashCode();
     }
     return hash;
   }
@@ -873,9 +345,9 @@
 
   /**
    * Returns {@code true} if this RDN contains more than one AVA.
-   * 
-   * @return {@code true} if this RDN contains more than one AVA,
-   *         otherwise {@code false}.
+   *
+   * @return {@code true} if this RDN contains more than one AVA, otherwise
+   *         {@code false}.
    */
   public boolean isMultiValued()
   {
@@ -885,13 +357,13 @@
 
 
   /**
-   * Returns an iterator of the AVAs contained in this RDN. The AVAs
-   * will be returned in the user provided order.
+   * Returns an iterator of the AVAs contained in this RDN. The AVAs will be
+   * returned in the user provided order.
    * <p>
-   * Attempts to remove AVAs using an iterator's {@code remove()} method
-   * are not permitted and will result in an {@code
-   * UnsupportedOperationException} being thrown.
-   * 
+   * Attempts to remove AVAs using an iterator's {@code remove()} method are not
+   * permitted and will result in an {@code UnsupportedOperationException} being
+   * thrown.
+   *
    * @return An iterator of the AVAs contained in this RDN.
    */
   public Iterator<AVA> iterator()
@@ -903,7 +375,7 @@
 
   /**
    * Returns the number of AVAs in this RDN.
-   * 
+   *
    * @return The number of AVAs in this RDN.
    */
   public int size()
@@ -915,12 +387,13 @@
 
   /**
    * Returns the RFC 4514 string representation of this RDN.
-   * 
+   *
    * @return The RFC 4514 string representation of this RDN.
-   * @see <a href="http://tools.ietf.org/html/rfc4514">RFC 4514 -
-   *      Lightweight Directory Access Protocol (LDAP): String
-   *      Representation of Distinguished Names </a>
+   * @see <a href="http://tools.ietf.org/html/rfc4514">RFC 4514 - Lightweight
+   *      Directory Access Protocol (LDAP): String Representation of
+   *      Distinguished Names </a>
    */
+  @Override
   public String toString()
   {
     // We don't care about potential race conditions here.
@@ -930,7 +403,7 @@
       avas[0].toString(builder);
       for (int i = 1; i < avas.length; i++)
       {
-        builder.append(',');
+        builder.append('+');
         avas[i].toString(builder);
       }
       stringValue = builder.toString();
@@ -940,7 +413,7 @@
 
 
 
-  StringBuilder toNormalizedString(StringBuilder builder)
+  StringBuilder toNormalizedString(final StringBuilder builder)
   {
     final int sz = avas.length;
     if (sz == 1)
@@ -952,12 +425,12 @@
       // Need to sort the AVAs before comparing.
       final AVA[] a = new AVA[sz];
       System.arraycopy(avas, 0, a, 0, sz);
-      Arrays.sort(a, ATV_COMPARATOR);
-
-      a[0].toString(builder);
+      Arrays.sort(a);
+      // Normalize the first AVA.
+      a[0].toNormalizedString(builder);
       for (int i = 1; i < sz; i++)
       {
-        builder.append(',');
+        builder.append('+');
         a[i].toNormalizedString(builder);
       }
 
@@ -967,7 +440,7 @@
 
 
 
-  StringBuilder toString(StringBuilder builder)
+  StringBuilder toString(final StringBuilder builder)
   {
     return builder.append(toString());
   }

--
Gitblit v1.10.0