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

matthew_swift
15.39.2010 1c845e121b14b549308383e431c9040917984d6c
opendj-sdk/sdk/src/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java
@@ -22,17 +22,18 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 */
package org.opends.sdk.schema;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeSet;
import java.util.Iterator;
import org.opends.sdk.*;
import com.sun.opends.sdk.util.StaticUtils;
import static com.sun.opends.sdk.util.StaticUtils.getBytes;
/**
@@ -42,166 +43,175 @@
final class DistinguishedNameEqualityMatchingRuleImpl extends
    AbstractMatchingRuleImpl
{
  private static final Comparator<AVA> ATV_COMPARATOR = new Comparator<AVA>()
  {
    public int compare(final AVA o1, final AVA o2)
    {
      return o1.getAttributeType().compareTo(o2.getAttributeType());
    }
  };
  @Override
  public Assertion getAssertion(final Schema schema, final ByteSequence value)
      throws DecodeException
  {
    DN assertion;
    try
    {
      assertion = DN.valueOf(value.toString(), schema);
    }
    catch (final LocalizedIllegalArgumentException e)
    {
      throw DecodeException.error(e.getMessageObject());
    }
    final DN finalAssertion = assertion;
    return new Assertion()
    {
      public ConditionResult matches(final ByteSequence attributeValue)
      {
        try
        {
          final DN attribute = DN.valueOf(attributeValue.toString(), schema);
          return matchDNs(finalAssertion, attribute);
        }
        catch (final LocalizedIllegalArgumentException e)
        {
          return ConditionResult.UNDEFINED;
        }
      }
    };
  }
  /**
   * {@inheritDoc}
   */
  public ByteString normalizeAttributeValue(final Schema schema,
      final ByteSequence value) throws DecodeException
  {
    try
    {
      return ByteString.valueOf(DN.valueOf(value.toString(), schema)
          .toNormalizedString());
      DN dn = DN.valueOf(value.toString(), schema.nonStrict());
      StringBuilder builder = new StringBuilder(value.length());
      return ByteString.valueOf(normalizeDN(builder, dn));
    }
    catch (final LocalizedIllegalArgumentException e)
    {
      throw DecodeException.error(e.getMessageObject());
    }
  }
  private ConditionResult matchAVAs(final AVA ava1, final AVA ava2)
  {
    final AttributeType type = ava1.getAttributeType();
    if (!type.equals(ava2.getAttributeType()))
    catch (final Exception e)
    {
      return ConditionResult.FALSE;
    }
    final MatchingRule matchingRule = type.getEqualityMatchingRule();
    if (matchingRule != null)
    {
      try
      {
        final ByteString nv1 = matchingRule.normalizeAttributeValue(ava1
            .getAttributeValue());
        final ByteString nv2 = matchingRule.normalizeAttributeValue(ava2
            .getAttributeValue());
        return nv1.equals(nv2) ? ConditionResult.TRUE : ConditionResult.FALSE;
      }
      catch (final DecodeException de)
      {
        return ConditionResult.UNDEFINED;
      }
    }
    return ConditionResult.UNDEFINED;
  }
  private ConditionResult matchDNs(final DN dn1, final DN dn2)
  {
    final int sz1 = dn1.size();
    final int sz2 = dn2.size();
    if (sz1 != sz2)
    {
      return ConditionResult.FALSE;
    }
    else
    {
      final RDN rdn1 = dn1.rdn();
      final RDN rdn2 = dn2.rdn();
      while (rdn1 != null)
      {
        final ConditionResult result = matchRDNs(rdn1, rdn2);
        if (result != ConditionResult.TRUE)
        {
          return result;
        }
      }
      return ConditionResult.TRUE;
      throw DecodeException.error(LocalizableMessage.raw(e.toString()));
    }
  }
  private ConditionResult matchRDNs(final RDN rdn1, final RDN rdn2)
  /**
   * Returns the normalized string representation of a DN.
   *
   * @param builder The StringBuilder to use to construct the normalized string.
   * @param dn The DN.
   * @return The normalized string representation of the provided DN.
   */
  private static StringBuilder normalizeDN(final StringBuilder builder,
                                          final DN dn)
  {
    final int sz1 = rdn1.size();
    final int sz2 = rdn2.size();
    if (sz1 != sz2)
    if(dn.rdn() == null)
    {
      return ConditionResult.FALSE;
      return builder;
    }
    else if (sz1 == 1)
    int i = dn.size() - 1;
    normalizeRDN(builder, dn.parent(i).rdn());
    for (i--; i >= 0; i--)
    {
      return matchAVAs(rdn1.getFirstAVA(), rdn2.getFirstAVA());
      builder.append('\u0000');
      normalizeRDN(builder, dn.parent(i).rdn());
    }
    return builder;
  }
  /**
   * Returns the normalized string representation of a RDN.
   *
   * @param builder The StringBuilder to use to construct the normalized string.
   * @param rdn The RDN.
   * @return The normalized string representation of the provided RDN.
   */
  private static StringBuilder normalizeRDN(final StringBuilder builder,
                                           final RDN rdn)
  {
    final int sz = rdn.size();
    if (sz == 1)
    {
      return normalizeAVA(builder, rdn.getFirstAVA());
    }
    else
    {
      // Need to sort the AVAs before comparing.
      final AVA[] a1 = new AVA[sz1];
      int i = 0;
      for (final AVA ava : rdn1)
      TreeSet<AVA> a = new TreeSet<AVA>();
      for(AVA ava : rdn)
      {
        a1[i++] = ava;
        a.add(ava);
      }
      Arrays.sort(a1, ATV_COMPARATOR);
      final AVA[] a2 = new AVA[sz1];
      i = 0;
      for (final AVA ava : rdn2)
      Iterator<AVA> i = a.iterator();
      // Normalize the first AVA.
      normalizeAVA(builder, i.next());
      while(i.hasNext())
      {
        a2[i++] = ava;
        builder.append('\u0001');
        normalizeAVA(builder, i.next());
      }
      Arrays.sort(a2, ATV_COMPARATOR);
      for (i = 0; i < sz1; i++)
      return builder;
    }
  }
  /**
   * Returns the normalized string representation of an AVA.
   *
   * @param builder The StringBuilder to use to construct the normalized string.
   * @param ava The AVA.
   * @return The normalized string representation of the provided AVA.
   */
  private static StringBuilder normalizeAVA(final StringBuilder builder,
                                           final AVA ava)
  {
    ByteString value = ava.getAttributeValue();
    final MatchingRule matchingRule =
        ava.getAttributeType().getEqualityMatchingRule();
    if (matchingRule != null)
    {
      try
      {
        final ConditionResult result = matchAVAs(a1[i], a2[i]);
        if (result != ConditionResult.TRUE)
        value =
            matchingRule.normalizeAttributeValue(ava.getAttributeValue());
      }
      catch (final DecodeException de)
      {
        // Ignore - we'll drop back to the user provided value.
      }
    }
    if (!ava.getAttributeType().getNames().iterator().hasNext())
    {
      builder.append(ava.getAttributeType().getOID());
      builder.append("=#");
      StaticUtils.toHex(value, builder);
    }
    else
    {
      final String name = ava.getAttributeType().getNameOrOID();
      // Normalizing.
      StaticUtils.toLowerCase(name, builder);
      builder.append("=");
      final Syntax syntax = ava.getAttributeType().getSyntax();
      if (!syntax.isHumanReadable())
      {
        builder.append("#");
        StaticUtils.toHex(value, builder);
      }
      else
      {
        final String str = value.toString();
        if (str.length() == 0)
        {
          return result;
          return builder;
        }
        char c = str.charAt(0);
        int startPos = 0;
        if ((c == ' ') || (c == '#'))
        {
          builder.append('\\');
          builder.append(c);
          startPos = 1;
        }
        final int length = str.length();
        for (int si = startPos; si < length; si++)
        {
          c = str.charAt(si);
          if (c < ' ')
          {
            for (final byte b : getBytes(String.valueOf(c)))
            {
              builder.append('\\');
              builder.append(StaticUtils.byteToLowerHex(b));
            }
          }
          else
          {
            if ((c == ' ' && si == length - 1)
                || (c == '"' || c == '+' || c == ',' || c == ';' || c == '<'
                    || c == '=' || c == '>' || c == '\\' || c == '\u0000'))
            {
              builder.append('\\');
            }
            builder.append(c);
          }
        }
      }
      return ConditionResult.TRUE;
    }
    return builder;
  }
}