OPENDJ-1689: Remove MatchingRule.comparator() and MatchingRuleImpl.comparator()
All matching rules now return a normalized representation which can be compared using the default byte string comparator. Also removed redundant equal length approximate matching rules which were only used for tests and weren't really needed.
Seeing the amount of boilerplate implementation in the server specific matching rules makes we wonder whether we should consider making the various AbstractMatchingRuleImpls public. Nicolas mentioned this when he was migrating the matching rules, and I think that I agree now I've had a closer look.
2 files deleted
15 files modified
| | |
| | | <method>boolean copyTo(java.nio.CharBuffer, java.nio.charset.CharsetDecoder)</method> |
| | | <justification>OPENDJ-1585: Added new utility method copyTo for a char buffer</justification> |
| | | </difference> |
| | | <difference> |
| | | <className>org/forgerock/opendj/ldap/schema/MatchingRule</className> |
| | | <differenceType>7002</differenceType> |
| | | <method>java.util.Comparator comparator()</method> |
| | | <justification>OPENDJ-1689 method has been removed because all matching rules should support the default comparator</justification> |
| | | </difference> |
| | | <difference> |
| | | <className>org/forgerock/opendj/ldap/schema/MatchingRuleImpl</className> |
| | | <differenceType>7002</differenceType> |
| | | <method>java.util.Comparator comparator(org.forgerock.opendj.ldap.schema.Schema)</method> |
| | | <justification>OPENDJ-1689 method has been removed because all matching rules should support the default comparator</justification> |
| | | </difference> |
| | | </differences> |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2012 ForgeRock AS. |
| | | * Portions copyright 2011-2015 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | |
| | | import java.nio.charset.Charset; |
| | | import java.nio.charset.CharsetDecoder; |
| | | import java.nio.charset.CodingErrorAction; |
| | | import java.util.Comparator; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | |
| | | |
| | | final ByteString normalizedValue = getOrderingNormalizedValue(); |
| | | final ByteString otherNormalizedValue = ava.getOrderingNormalizedValue(); |
| | | final MatchingRule rule = attributeType.getOrderingMatchingRule(); |
| | | if (rule != null) { |
| | | final Comparator<ByteSequence> comparator = rule.comparator(); |
| | | return comparator.compare(normalizedValue, otherNormalizedValue); |
| | | } else { |
| | | return normalizedValue.compareTo(otherNormalizedValue); |
| | | } |
| | | return normalizedValue.compareTo(otherNormalizedValue); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | |
| | | |
| | | final ByteString normalizedValue = getEqualityNormalizedValue(); |
| | | final ByteString otherNormalizedValue = ava.getEqualityNormalizedValue(); |
| | | final MatchingRule rule = attributeType.getEqualityMatchingRule(); |
| | | if (rule != null) { |
| | | final Comparator<ByteSequence> comparator = rule.comparator(); |
| | | return comparator.compare(normalizedValue, otherNormalizedValue) == 0; |
| | | } else { |
| | | return normalizedValue.equals(otherNormalizedValue); |
| | | } |
| | | return normalizedValue.equals(otherNormalizedValue); |
| | | } else { |
| | | return false; |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2012-2013 ForgeRock AS. |
| | | * Portions copyright 2012-2015 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | private static final class EntryComparator implements Comparator<Entry> { |
| | | private final AttributeDescription attributeDescription; |
| | | private final MatchingRule matchingRule; |
| | | private final Comparator<ByteSequence> valueComparator; |
| | | private final boolean isReverseOrder; |
| | | |
| | | private EntryComparator(final AttributeDescription attributeDescription, |
| | | final MatchingRule matchingRule, final boolean isReverseOrder) { |
| | | this.attributeDescription = attributeDescription; |
| | | this.matchingRule = matchingRule; |
| | | this.valueComparator = matchingRule.comparator(); |
| | | this.isReverseOrder = isReverseOrder; |
| | | } |
| | | |
| | |
| | | } else if (normalizedValue2 == null) { |
| | | return -1; |
| | | } else if (isReverseOrder) { |
| | | return valueComparator.compare(normalizedValue2, normalizedValue1); |
| | | return normalizedValue2.compareTo(normalizedValue1); |
| | | } else { |
| | | return valueComparator.compare(normalizedValue1, normalizedValue2); |
| | | return normalizedValue1.compareTo(normalizedValue2); |
| | | } |
| | | } |
| | | |
| | |
| | | for (final ByteString value : attribute) { |
| | | try { |
| | | final ByteString tmp = matchingRule.normalizeAttributeValue(value); |
| | | if (normalizedValue == null) { |
| | | normalizedValue = tmp; |
| | | } else if (valueComparator.compare(tmp, normalizedValue) < 0) { |
| | | if (normalizedValue == null || tmp.compareTo(normalizedValue) < 0) { |
| | | normalizedValue = tmp; |
| | | } |
| | | } catch (final DecodeException ignored) { |
| | |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2014 ForgeRock AS |
| | | * Portions copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.forgerock.opendj.ldap.schema; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Comparator<ByteSequence> comparator(final Schema schema) { |
| | | return ByteSequence.COMPARATOR; |
| | | } |
| | | |
| | | @Override |
| | | public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue) |
| | | throws DecodeException { |
| | | return UNDEFINED_ASSERTION; |
| | |
| | | return UNDEFINED_ASSERTION; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexingSupported() { |
| | | return !getIndexers().isEmpty(); |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2013-2014 ForgeRock AS. |
| | | * Portions copyright 2013-2015 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap.schema; |
| | | |
| | |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Get a comparator that can be used to compare the attribute values |
| | | * normalized by this matching rule. |
| | | * |
| | | * @return A comparator that can be used to compare the attribute values |
| | | * normalized by this matching rule. |
| | | */ |
| | | public Comparator<ByteSequence> comparator() { |
| | | return impl.comparator(schema); |
| | | } |
| | | |
| | | /** |
| | | * Returns {@code true} if the provided object is a matching rule having the |
| | | * same numeric OID as this matching rule. |
| | | * |
| | |
| | | /** |
| | | * Returns the normalized form of the provided attribute value, which is |
| | | * best suited for efficiently performing matching operations on that value. |
| | | * The returned normalized representation can be compared for equality with |
| | | * other values normalized with this matching rule using |
| | | * {@link ByteSequence#equals(Object)}. In addition, normalized values can |
| | | * be compared using {@link ByteSequence#compareTo(ByteSequence)}, although |
| | | * the sort order is only defined for ordering matching rules. |
| | | * |
| | | * @param value |
| | | * The attribute value to be normalized. |
| | | * @return The normalized version of the provided attribute value. |
| | | * @throws DecodeException |
| | | * if the syntax of the value is not valid. |
| | | * If the syntax of the value is not valid. |
| | | */ |
| | | public ByteString normalizeAttributeValue(final ByteSequence value) throws DecodeException { |
| | | return impl.normalizeAttributeValue(schema, value); |
| | |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2014 ForgeRock AS |
| | | * Portions copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.forgerock.opendj.ldap.schema; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | |
| | | public interface MatchingRuleImpl { |
| | | |
| | | /** |
| | | * Get a comparator that can be used to compare the attribute values |
| | | * normalized by this matching rule. |
| | | * |
| | | * @param schema |
| | | * The schema in which this matching rule is defined. |
| | | * @return A comparator that can be used to compare the attribute values |
| | | * normalized by this matching rule. |
| | | */ |
| | | Comparator<ByteSequence> comparator(Schema schema); |
| | | |
| | | /** |
| | | * Retrieves the normalized form of the provided assertion value, which is |
| | | * best suited for efficiently performing less than matching operations on |
| | | * that value. The assertion value is guaranteed to be valid against this |
| | |
| | | /** |
| | | * Retrieves the normalized form of the provided attribute value, which is |
| | | * best suited for efficiently performing matching operations on that value. |
| | | * Equality and ordering matching rules should return a normalized |
| | | * representation which can be compared with other normalized values using |
| | | * {@link ByteSequence#equals(Object)} and |
| | | * {@link ByteSequence#compareTo(ByteSequence)}. |
| | | * |
| | | * @param schema |
| | | * The schema in which this matching rule is defined. |
| | |
| | | * The attribute value to be normalized. |
| | | * @return The normalized version of the provided attribute value. |
| | | * @throws DecodeException |
| | | * if an syntax error occurred while parsing the value. |
| | | * If an syntax error occurred while parsing the value. |
| | | */ |
| | | ByteString normalizeAttributeValue(Schema schema, ByteSequence value) throws DecodeException; |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2014 ForgeRock AS |
| | | * Portions copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.forgerock.opendj.ldap.schema; |
| | | |
| | |
| | | ruleInstance.normalizeAttributeValue(ByteString.valueOf(value2)); |
| | | |
| | | // Test the comparator |
| | | final int comp = ruleInstance.comparator().compare(normalizedValue1, normalizedValue2); |
| | | final int comp = normalizedValue1.compareTo(normalizedValue2); |
| | | if (comp == 0) { |
| | | Assert.assertEquals(comp, result); |
| | | } else if (comp > 0) { |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.jeb; |
| | | |
| | | import java.util.Comparator; |
| | | |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | |
| | | return -1; |
| | | } |
| | | |
| | | final Comparator<ByteSequence> comp = orderingRules[j].comparator(); |
| | | final ByteString val1 = ByteString.valueOf(b1Bytes); |
| | | final ByteString val2 = ByteString.valueOf(b2Bytes); |
| | | final int result = ascending[j] ? comp.compare(val1, val2) : comp.compare(val2, val1); |
| | | |
| | | final int result = ascending[j] ? val1.compareTo(val2) : val2.compareTo(val1); |
| | | if(result != 0) |
| | | { |
| | | return result; |
| | |
| | | return -1; |
| | | } |
| | | |
| | | final Comparator<ByteSequence> comp = orderingRules[j].comparator(); |
| | | final int result = ascending[j] ? comp.compare(b1Bytes, b2Bytes) : comp.compare(b2Bytes, b1Bytes); |
| | | |
| | | final int result = ascending[j] ? b1Bytes.compareTo(b2Bytes) : b2Bytes.compareTo(b1Bytes); |
| | | if(result != 0) |
| | | { |
| | | return result; |
| | |
| | | import static org.opends.messages.JebMessages.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | import java.util.Comparator; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | |
| | | return -1; |
| | | } |
| | | |
| | | final Comparator<ByteSequence> comp = orderingRule.comparator(); |
| | | final int result = ascending ? comp.compare(b1Bytes, b2Bytes) : comp |
| | | .compare(b2Bytes, b1Bytes); |
| | | |
| | | final int result = ascending ? b1Bytes.compareTo(b2Bytes) : b2Bytes.compareTo(b1Bytes); |
| | | if (result != 0) |
| | | { |
| | | return result; |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2012-2014 ForgeRock AS. |
| | | * Portions Copyright 2012-2015 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Compare two ByteString values containing historical information. |
| | | * |
| | | * @param value1 first value to compare |
| | | * @param value2 second value to compare |
| | | * @return 0 when equals, -1 or 1 to establish order |
| | | */ |
| | | private int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return value1.compareTo(value2); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public ByteString normalizeAttributeValue(Schema schema, ByteSequence value) throws DecodeException |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Comparator<ByteSequence> comparator(Schema schema) |
| | | { |
| | | return new Comparator<ByteSequence>() |
| | | { |
| | | @Override |
| | | public int compare(final ByteSequence o1, final ByteSequence o2) |
| | | { |
| | | return compareValues(o1, o2); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getAssertion(final Schema schema, final ByteSequence value) throws DecodeException |
| | | { |
| | | final ByteString normAssertion = normalizeAttributeValue(schema, value); |
| | |
| | | @Override |
| | | public ConditionResult matches(final ByteSequence attributeValue) |
| | | { |
| | | return ConditionResult.valueOf(compareValues(attributeValue, normAssertion) < 0); |
| | | return ConditionResult.valueOf(attributeValue.compareTo(normAssertion) < 0); |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public ConditionResult matches(final ByteSequence normalizedAttributeValue) |
| | | { |
| | | return ConditionResult.valueOf(compareValues(normalizedAttributeValue, normAssertion) >= 0); |
| | | return ConditionResult.valueOf(normalizedAttributeValue.compareTo(normAssertion) >= 0); |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public ConditionResult matches(final ByteSequence normalizedAttributeValue) |
| | | { |
| | | return ConditionResult.valueOf(compareValues(normalizedAttributeValue, normAssertion) <= 0); |
| | | return ConditionResult.valueOf(normalizedAttributeValue.compareTo(normAssertion) <= 0); |
| | | } |
| | | |
| | | @Override |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | |
| | | } |
| | | }); |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Comparator<ByteSequence> comparator(Schema schema) |
| | | { |
| | | return ByteSequence.COMPARATOR; |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the normalized form of the provided value, which is best suited |
| | | * for efficiently performing matching operations on that value. |
| | |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | private static final char HEX_STRING_SEPARATOR = '%'; |
| | | |
| | | /** The set of attribute types for the elements in this RDN. */ |
| | | private AttributeType[] attributeTypes; |
| | | |
| | |
| | | { |
| | | val1 = rule.normalizeAttributeValue(val1); |
| | | val2 = rule.normalizeAttributeValue(val2); |
| | | return rule.comparator().compare(val1, val2); |
| | | return val1.compareTo(val2); |
| | | } |
| | | catch (DecodeException e) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | |
| | | { |
| | | final ByteString val1 = rule.normalizeAttributeValue(value1); |
| | | final ByteString val2 = rule.normalizeAttributeValue(value2); |
| | | if (ascending) |
| | | { |
| | | return rule.comparator().compare(val1, val2); |
| | | } |
| | | else |
| | | { |
| | | return rule.comparator().compare(val2, val1); |
| | | } |
| | | return ascending ? val1.compareTo(val2) : val2.compareTo(val1); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | |
| | | caseIgnoreMatchingRule = CoreSchema.getCaseIgnoreMatchingRule(); |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the normalized form of the provided value, which is best suited |
| | | * for efficiently performing matching operations on that value. |
| | | * |
| | | * @param value The value to be normalized. |
| | | * |
| | | * @return The normalized version of the provided value. |
| | | * |
| | | * @throws DecodeException If the provided value is invalid according to |
| | | * the associated attribute syntax. |
| | | */ |
| | | @Override |
| | | public ByteString normalizeAttributeValue(Schema schema, ByteSequence value) |
| | | throws DecodeException |
| | |
| | | return caseIgnoreMatchingRule.normalizeAttributeValue(value); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Comparator<ByteSequence> comparator(Schema schema) |
| | | { |
| | | return caseIgnoreMatchingRule.comparator(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getAssertion(Schema schema, ByteSequence assertionValue) throws DecodeException |
| | | { |
| | | return caseIgnoreMatchingRule.getAssertion(assertionValue); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getSubstringAssertion(Schema schema, ByteSequence subInitial, |
| | | List<? extends ByteSequence> subAnyElements, ByteSequence subFinal) throws DecodeException |
| | |
| | | return caseIgnoreMatchingRule.getSubstringAssertion(subInitial, subAnyElements, subFinal); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getGreaterOrEqualAssertion(Schema schema, ByteSequence value) throws DecodeException |
| | | { |
| | | return caseIgnoreMatchingRule.getGreaterOrEqualAssertion(value); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getLessOrEqualAssertion(Schema schema, ByteSequence value) throws DecodeException |
| | | { |
| | | return caseIgnoreMatchingRule.getLessOrEqualAssertion(value); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Collection<? extends Indexer> getIndexers() |
| | | { |
| | | return caseIgnoreMatchingRule.getIndexers(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexingSupported() |
| | | { |
| | |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | | import org.forgerock.opendj.ldap.SearchScope; |
| | | import org.forgerock.opendj.ldap.schema.CoreSchema; |
| | | import org.forgerock.opendj.ldap.schema.MatchingRule; |
| | | import org.forgerock.opendj.ldap.schema.SchemaBuilder; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.api.AttributeSyntax; |
| | | import org.opends.server.core.DirectoryServer; |
| | |
| | | |
| | | import static org.opends.server.protocols.internal.InternalClientConnection.*; |
| | | import static org.opends.server.protocols.internal.Requests.*; |
| | | import static org.opends.server.schema.EqualLengthApproximateMatchingRule.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | /** |
| | |
| | | @Test |
| | | public void testXAPPROXExtension() throws Exception |
| | | { |
| | | // Create and register the approximate matching rule for testing purposes. |
| | | MatchingRule testApproxRule = new SchemaBuilder(CoreSchema.getInstance()) |
| | | .buildMatchingRule(EQUAL_LENGTH_APPROX_MR_OID) |
| | | .names(EQUAL_LENGTH_APPROX_MR_NAME).implementation(new EqualLengthApproximateMatchingRule()) |
| | | .syntaxOID(EQUAL_LENGTH_APPROX_MR_SYNTAX_OID) |
| | | .addToSchema() |
| | | .toSchema().getMatchingRule(EQUAL_LENGTH_APPROX_MR_OID); |
| | | DirectoryServer.registerMatchingRule(testApproxRule, false); |
| | | |
| | | |
| | | MatchingRule mrule = Schema.getCoreSchema().getMatchingRule("ds-mr-double-metaphone-approx"); |
| | | |
| | | // Get a reference to the attribute type syntax implementation in the |
| | | // server. |
| | | AttributeTypeSyntax attrTypeSyntax = |
| | |
| | | false); |
| | | assertNotNull(attrType); |
| | | assertNotNull(attrType.getApproximateMatchingRule()); |
| | | assertEquals(attrType.getApproximateMatchingRule(), testApproxRule); |
| | | assertEquals(attrType.getApproximateMatchingRule(), mrule); |
| | | } |
| | | |
| | | |