From d782e4facdae0897de52f560e4ebbf30bd800318 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 15 Jun 2010 14:39:37 +0000
Subject: [PATCH] DN normalization enhancements:
---
sdk/src/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java | 276 ++++++++++++++++++++++++++++--------------------------
1 files changed, 143 insertions(+), 133 deletions(-)
diff --git a/sdk/src/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java b/sdk/src/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java
index 83ae0ca..eb0a820 100644
--- a/sdk/src/org/opends/sdk/schema/DistinguishedNameEqualityMatchingRuleImpl.java
+++ b/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;
}
}
--
Gitblit v1.10.0