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

sin
17.11.2009 76c87042a9fb3ac7f1a25cc9d836da521eb8547f
issue# 3774: Sort control doesn't work for collation matching rules
1 files added
18 files modified
884 ■■■■■ changed files
opends/src/server/org/opends/server/api/AbstractMatchingRule.java 249 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/ApproximateMatchingRule.java 6 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/EqualityMatchingRule.java 6 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/ExtensibleMatchingRule.java 10 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/MatchingRule.java 149 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/OrderingMatchingRule.java 53 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/SubstringMatchingRule.java 35 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java 7 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/CaseExactOrderingMatchingRule.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/CaseIgnoreOrderingMatchingRule.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java 123 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/GeneralizedTimeOrderingMatchingRule.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/IntegerOrderingMatchingRule.java 7 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/NumericStringOrderingMatchingRule.java 11 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java 11 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/UUIDOrderingMatchingRule.java 11 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/Schema.java 8 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/StaticUtils.java 1 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/CollationMatchingRuleTest.java 170 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/AbstractMatchingRule.java
New file
@@ -0,0 +1,249 @@
/*
 * 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
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
import java.util.Collection;
import org.opends.server.types.ByteSequence;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.DirectoryException;
/**
 * This class provides default implementation of MatchingRule. A
 * matching rule implemented by a Directory Server module must extend
 * this class.
 */
@org.opends.server.types.PublicAPI(
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class AbstractMatchingRule implements MatchingRule
{
  /**
   * {@inheritDoc}
   */
  public abstract String getName();
  /**
   * {@inheritDoc}
   */
  public abstract Collection<String> getAllNames();
  /**
   * {@inheritDoc}
   */
  public abstract String getOID();
  /**
   * {@inheritDoc}
   */
  public ByteString normalizeAssertionValue(ByteSequence value)
      throws DirectoryException
  {
    // Default implementation is to use attribute value normalization.
    return normalizeValue(value);
  }
  /**
   * {@inheritDoc}
   */
  public final String getNameOrOID()
  {
    String name = getName();
    if ((name == null) || (name.length() == 0))
    {
      return getOID();
    }
    else
    {
      return name;
    }
  }
  /**
   * {@inheritDoc}
   */
  public abstract String getDescription();
  /**
   * {@inheritDoc}
   */
  public abstract String getSyntaxOID();
  /**
   * {@inheritDoc}
   */
  public boolean isObsolete()
  {
    return false;
  }
  /**
   * {@inheritDoc}
   */
  public abstract ByteString normalizeValue(ByteSequence value)
      throws DirectoryException;
  /**
   * {@inheritDoc}
   */
  public ConditionResult valuesMatch(
      ByteSequence attributeValue, ByteSequence assertionValue)
  {
    //Default implementation of most rule types.
    return ConditionResult.UNDEFINED;
  }
  /**
   * Retrieves the hash code for this matching rule. It will be
   * calculated as the sum of the characters in the OID.
   *
   * @return The hash code for this matching rule.
   */
  @Override
  public final int hashCode()
  {
    int hashCode = 0;
    String oidString = getOID();
    int oidLength = oidString.length();
    for (int i = 0; i < oidLength; i++)
    {
      hashCode += oidString.charAt(i);
    }
    return hashCode;
  }
  /**
   * Indicates whether the provided object is equal to this matching
   * rule. The provided object will be considered equal to this
   * matching rule only if it is a matching rule with the same OID.
   *
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is equal to this
   *         matching rule, or {@code false} if it is not.
   */
  @Override
  public final boolean equals(Object o)
  {
    if (o == null)
    {
      return false;
    }
    if (this == o)
    {
      return true;
    }
    if (!(o instanceof MatchingRule))
    {
      return false;
    }
    return getOID().equals(((MatchingRule) o).getOID());
  }
  /**
   * Retrieves a string representation of this matching rule in the
   * format defined in RFC 2252.
   *
   * @return A string representation of this matching rule in the
   *         format defined in RFC 2252.
   */
  @Override
  public final String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * {@inheritDoc}
   */
  public final void toString(StringBuilder buffer)
  {
    buffer.append("( ");
    buffer.append(getOID());
    buffer.append(" NAME '");
    buffer.append(getName());
    String description = getDescription();
    if ((description != null) && (description.length() > 0))
    {
      buffer.append("' DESC '");
      buffer.append(description);
    }
    if (isObsolete())
    {
      buffer.append("' OBSOLETE SYNTAX ");
    }
    else
    {
      buffer.append("' SYNTAX ");
    }
    buffer.append(getSyntaxOID());
    buffer.append(" )");
  }
}
opends/src/server/org/opends/server/api/ApproximateMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
@@ -43,7 +43,8 @@
     mayExtend=true,
     mayInvoke=false)
public abstract class ApproximateMatchingRule
       extends MatchingRule
       extends AbstractMatchingRule
       implements MatchingRule
{
  /**
   * Indicates whether the two provided normalized values are
@@ -81,6 +82,7 @@
   *          if it does not match, or {@code UNDEFINED} if the result
   *          is undefined.
   */
  @Override
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
opends/src/server/org/opends/server/api/EqualityMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
@@ -42,7 +42,9 @@
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
public abstract class EqualityMatchingRule extends MatchingRule
public abstract class EqualityMatchingRule
        extends AbstractMatchingRule
        implements MatchingRule
{
  /**
   * Indicates whether the two provided normalized values are equal to
opends/src/server/org/opends/server/api/ExtensibleMatchingRule.java
@@ -37,7 +37,7 @@
/**
 * This class defines the set of methods and structures that must be
 * This interface defines the set of methods that must be
 * implemented by a Directory Server module that implements an
 * Extensible matching rule.
 */
@@ -46,7 +46,7 @@
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class ExtensibleMatchingRule extends MatchingRule
public interface ExtensibleMatchingRule extends MatchingRule
{
  /**
   * Returns a collection of extensible indexers associated with this
@@ -58,7 +58,7 @@
   * @return The collection of extensible indexers associated with
   *         this matching rule.
   */
  public abstract Collection<ExtensibleIndexer> getIndexers(
  Collection<ExtensibleIndexer> getIndexers(
      IndexConfig config);
@@ -79,6 +79,6 @@
   * @throws DirectoryException
   *           If an error occurs while generating the index query.
   */
  public abstract <T> T createIndexQuery(ByteSequence assertionValue,
  <T> T createIndexQuery(ByteSequence assertionValue,
      IndexQueryFactory<T> factory) throws DirectoryException;
}
}
opends/src/server/org/opends/server/api/MatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.api;
@@ -38,16 +38,15 @@
/**
 * This class defines the set of methods and structures that must be
 * implemented by a Directory Server module that implements a matching
 * rule.
 * This interface defines the set of methods that must be implemented
 * by a Directory Server module that implements a matching rule.
 */
@org.opends.server.types.PublicAPI(
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
public abstract class MatchingRule
public interface MatchingRule
{
  /**
   * Retrieves the common name for this matching rule.
@@ -55,7 +54,7 @@
   * @return The common name for this matching rule, or {@code null}
   *         if it does not have a name.
   */
  public abstract String getName();
  String getName();
@@ -64,7 +63,7 @@
   *
   * @return All names for this matching rule.
   */
  public abstract Collection<String> getAllNames();
  Collection<String> getAllNames();
@@ -73,7 +72,7 @@
   *
   * @return The OID for this matching rule.
   */
  public abstract String getOID();
  String getOID();
@@ -89,12 +88,8 @@
   *           If the provided value is invalid according to the
   *           associated attribute syntax.
   */
  public ByteString normalizeAssertionValue(ByteSequence value)
      throws DirectoryException
  {
    // Default implementation is to use attribute value normalization.
    return normalizeValue(value);
  }
  ByteString normalizeAssertionValue(ByteSequence value)
      throws DirectoryException;
@@ -105,18 +100,7 @@
   *
   * @return The name or OID for this matching rule.
   */
  public final String getNameOrOID()
  {
    String name = getName();
    if ((name == null) || (name.length() == 0))
    {
      return getOID();
    }
    else
    {
      return name;
    }
  }
  String getNameOrOID();
@@ -126,7 +110,7 @@
   * @return The description for this matching rule, or {@code null}
   *         if there is none.
   */
  public abstract String getDescription();
  String getDescription();
@@ -137,7 +121,7 @@
   * @return The OID of the syntax with which this matching rule is
   *         associated.
   */
  public abstract String getSyntaxOID();
  String getSyntaxOID();
@@ -151,10 +135,7 @@
   * @return {@code true} if this matching rule is declared
   *         "OBSOLETE", or {@code false} if not.
   */
  public boolean isObsolete()
  {
    return false;
  }
  boolean isObsolete();
@@ -170,7 +151,7 @@
   *           If the provided value is invalid according to the
   *           associated attribute syntax.
   */
  public abstract ByteString normalizeValue(ByteSequence value)
  ByteString normalizeValue(ByteSequence value)
      throws DirectoryException;
@@ -193,115 +174,17 @@
   *         if it does not match, or {@code UNDEFINED} if the result
   *         is undefined.
   */
  public abstract ConditionResult valuesMatch(
  ConditionResult valuesMatch(
      ByteSequence attributeValue, ByteSequence assertionValue);
  /**
   * Retrieves the hash code for this matching rule. It will be
   * calculated as the sum of the characters in the OID.
   *
   * @return The hash code for this matching rule.
   */
  @Override
  public final int hashCode()
  {
    int hashCode = 0;
    String oidString = getOID();
    int oidLength = oidString.length();
    for (int i = 0; i < oidLength; i++)
    {
      hashCode += oidString.charAt(i);
    }
    return hashCode;
  }
  /**
   * Indicates whether the provided object is equal to this matching
   * rule. The provided object will be considered equal to this
   * matching rule only if it is a matching rule with the same OID.
   *
   * @param o
   *          The object for which to make the determination.
   * @return {@code true} if the provided object is equal to this
   *         matching rule, or {@code false} if it is not.
   */
  @Override
  public final boolean equals(Object o)
  {
    if (o == null)
    {
      return false;
    }
    if (this == o)
    {
      return true;
    }
    if (!(o instanceof MatchingRule))
    {
      return false;
    }
    return getOID().equals(((MatchingRule) o).getOID());
  }
  /**
   * Retrieves a string representation of this matching rule in the
   * format defined in RFC 2252.
   *
   * @return A string representation of this matching rule in the
   *         format defined in RFC 2252.
   */
  @Override
  public final String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends a string representation of this matching rule in the
   * format defined in RFC 2252 to the provided buffer.
   *
   * @param buffer
   *          The buffer to which the information should be appended.
   */
  public final void toString(StringBuilder buffer)
  {
    buffer.append("( ");
    buffer.append(getOID());
    buffer.append(" NAME '");
    buffer.append(getName());
    String description = getDescription();
    if ((description != null) && (description.length() > 0))
    {
      buffer.append("' DESC '");
      buffer.append(description);
    }
    if (isObsolete())
    {
      buffer.append("' OBSOLETE SYNTAX ");
    }
    else
    {
      buffer.append("' SYNTAX ");
    }
    buffer.append(getSyntaxOID());
    buffer.append(" )");
  }
  void toString(StringBuilder buffer);
}
opends/src/server/org/opends/server/api/OrderingMatchingRule.java
@@ -30,14 +30,13 @@
import java.io.Serializable;
import java.util.Comparator;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ByteSequence;
/**
 * This class defines the set of methods and structures that must be
 * implemented by a Directory Server module that implements a matching
 * This interface defines the set of methods that must be implemented
 * by a Directory Server module that implements a matching
 * rule used for determining the correct order of values when sorting
 * or processing range filters.
 */
@@ -46,21 +45,10 @@
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
public abstract class OrderingMatchingRule
       extends MatchingRule
       implements Comparator<byte[]>, Serializable
public interface OrderingMatchingRule
        extends MatchingRule,Comparator<byte[]>,Serializable
{
  /**
   * The serial version identifier required to satisfy the compiler
   * because this class implements the {@code java.io.Serializable}
   * interface.  This value was generated using the {@code serialver}
   * command-line utility included with the Java SDK.
   */
  private static final long serialVersionUID = -5322529685787024597L;
  /**
   * Compares the first value to the second and returns a value that
   * indicates their relative order.
   *
@@ -77,35 +65,4 @@
   */
  public abstract int compareValues(ByteSequence value1,
                                    ByteSequence value2);
  /**
   * Indicates whether the provided attribute value should be
   * considered a match for the given assertion value.  This will only
   * be used for the purpose of extensible matching.
   * <BR><BR>
   * Note that ordering matching rules by default do not support
   * extensible matching, and therefore this method will always return
   * {@code UNDEFINED}.  If an ordering matching rule does support
   * extensible matching operations, then it should override this
   * method and provide an appropriate implementation.
   *
   * @param  attributeValue  The attribute value in a form that has
   *                         been normalized according to this
   *                         matching rule.
   * @param  assertionValue  The assertion value in a form that has
   *                         been normalized according to this
   *                         matching rule.
   *
   * @return  {@code true} if the attribute value should be considered
   *          a match for the provided assertion value, or
   *          {@code false} if not.
   */
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
    return ConditionResult.UNDEFINED;
  }
}
opends/src/server/org/opends/server/api/SubstringMatchingRule.java
@@ -43,7 +43,9 @@
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=false)
public abstract class SubstringMatchingRule extends MatchingRule
public abstract class SubstringMatchingRule
        extends AbstractMatchingRule
        implements MatchingRule
{
  /**
   * Normalizes the provided value fragment into a form that can be
@@ -174,36 +176,5 @@
    return true;
  }
  /**
   * Indicates whether the provided attribute value should be
   * considered a match for the given assertion value.  This will only
   * be used for the purpose of extensible matching.
   * <BR><BR>
   * Note that substring matching rules by default do not support
   * extensible matching, and therefore this method will always return
   * {@code UNDEFINED}.  If a substring matching rule does support
   * extensible matching operations, then it should override this
   * method and provide an appropriate implementation.
   *
   * @param  attributeValue  The attribute value in a form that has
   *                         been normalized according to this
   *                         matching rule.
   * @param  assertionValue  The assertion value in a form that has
   *                         been normalized according to this
   *                         matching rule.
   *
   * @return  {@code true} if the attribute value should be considered
   *          a match for the provided assertion value, or
   *          {@code false} if not.
   */
  @Override
  public ConditionResult valuesMatch(ByteSequence attributeValue,
                                     ByteSequence assertionValue)
  {
    return ConditionResult.UNDEFINED;
  }
}
opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java
@@ -22,12 +22,13 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.replication.plugin;
import java.util.Collection;
import java.util.Collections;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteSequence;
@@ -36,7 +37,8 @@
 * Used to establish an order between historical information and index them.
 */
public class HistoricalCsnOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -63,7 +65,6 @@
   * @param value2 second value to compare
   * @return 0 when equals, -1 or 1 to establish order
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    String[] token1 = value1.toString().split(":", 3);
opends/src/server/org/opends/server/schema/CaseExactOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -33,6 +33,7 @@
import java.util.Collection;
import java.util.Collections;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.types.ByteSequence;
import org.opends.server.types.ByteString;
@@ -47,7 +48,8 @@
 * and referenced in RFC 4519.
 */
class CaseExactOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -201,10 +203,9 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    return StaticUtils.compare(value1, value2);
    return value1.compareTo(value2);
  }
opends/src/server/org/opends/server/schema/CaseIgnoreOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -34,6 +34,7 @@
import java.util.Collection;
import java.util.Collections;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.types.ByteSequence;
import org.opends.server.types.ByteString;
@@ -48,7 +49,8 @@
 * and referenced in RFC 2252.
 */
public class CaseIgnoreOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -202,10 +204,9 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    return StaticUtils.compare(value1, value2);
    return value1.compareTo(value2);
  }
opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
@@ -58,11 +58,13 @@
import org.opends.server.admin.std.meta.
  CollationMatchingRuleCfgDefn.MatchingRuleType;
import org.opends.server.admin.std.server.CollationMatchingRuleCfg;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.ExtensibleIndexer;
import org.opends.server.api.ExtensibleMatchingRule;
import org.opends.server.api.IndexQueryFactory;
import org.opends.server.api.MatchingRule;
import org.opends.server.api.MatchingRuleFactory;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.backends.jeb.AttributeIndex;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
@@ -75,6 +77,7 @@
import org.opends.server.types.IndexConfig;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import org.opends.server.util.StaticUtils;
@@ -721,8 +724,9 @@
  /**
   * Collation Extensible matching rule.
   */
  private abstract class CollationMatchingRule extends
      ExtensibleMatchingRule
  private abstract class CollationMatchingRule
          extends AbstractMatchingRule
          implements ExtensibleMatchingRule
  {
    // Names for this class.
    private final Collection<String> names;
@@ -857,7 +861,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<ExtensibleIndexer> getIndexers(IndexConfig config)
    {
      if (indexer == null)
@@ -873,9 +876,21 @@
  /**
   * Collation rule for Equality matching rule.
   */
  private final class CollationEqualityMatchingRule extends
      CollationMatchingRule
  private final class CollationEqualityMatchingRule
          extends CollationMatchingRule
          implements OrderingMatchingRule
  {
    /**
     * The serial version identifier required to satisfy the compiler because
     * this class implements the <CODE>java.io.Serializable</CODE> interface.
     * This value was generated using the <CODE>serialver</CODE> command-line
     * utility included with the Java SDK.
     */
    private static final long serialVersionUID = 3990778178484159862L;
    /**
     * Constructs a new CollationEqualityMatchingRule.
     *
@@ -929,7 +944,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T createIndexQuery(ByteSequence assertionValue,
        IndexQueryFactory<T> factory) throws DirectoryException
    {
@@ -937,6 +951,26 @@
      return factory.createExactMatchQuery(indexer
          .getExtensibleIndexID(), normalizeValue(assertionValue));
    }
    /**
     * {@inheritDoc}
     */
    public int compare(byte[] arg0, byte[] arg1)
    {
      return StaticUtils.compare(arg0, arg1);
    }
    /**
     * {@inheritDoc}
     */
    public int compareValues(ByteSequence value1, ByteSequence value2)
    {
      return value1.compareTo(value2);
    }
  }
  /**
@@ -1645,7 +1679,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T createIndexQuery(ByteSequence assertionValue,
        IndexQueryFactory<T> factory) throws DirectoryException
    {
@@ -1690,9 +1723,21 @@
  /**
   * An abstract Collation rule for Ordering matching rule.
   */
  private abstract class CollationOrderingMatchingRule extends
      CollationMatchingRule
  private abstract class CollationOrderingMatchingRule
          extends CollationMatchingRule
          implements OrderingMatchingRule
  {
    /**
     * The serial version identifier required to satisfy the compiler because
     * this class implements the <CODE>java.io.Serializable</CODE> interface.
     * This value was generated using the <CODE>serialver</CODE> command-line
     * utility included with the Java SDK.
     */
    private static final long serialVersionUID = 7354051060508436941L;
    /**
     * Constructs a new CollationOrderingMatchingRule.
     *
@@ -1721,6 +1766,26 @@
      CollationKey key = collator.getCollationKey(value.toString());
      return ByteString.wrap(key.toByteArray());
    }
    /**
     * {@inheritDoc}
     */
    public int compare(byte[] arg0, byte[] arg1)
    {
      return StaticUtils.compare(arg0, arg1);
    }
    /**
     * {@inheritDoc}
     */
    public int compareValues(ByteSequence value1, ByteSequence value2)
    {
      return value1.compareTo(value2);
    }
  }
  /**
@@ -1729,6 +1794,15 @@
  private final class CollationLessThanMatchingRule extends
      CollationOrderingMatchingRule
  {
    /**
     * The serial version identifier required to satisfy the compiler because
     * this class implements the <CODE>java.io.Serializable</CODE> interface.
     * This value was generated using the <CODE>serialver</CODE> command-line
     * utility included with the Java SDK.
     */
    private static final long serialVersionUID = -7578406829946732713L;
    /**
     * Constructs a new CollationLessThanMatchingRule.
@@ -1772,7 +1846,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T createIndexQuery(ByteSequence assertionValue,
        IndexQueryFactory<T> factory) throws DirectoryException
    {
@@ -1788,6 +1861,15 @@
  private final class CollationLessThanOrEqualToMatchingRule extends
      CollationOrderingMatchingRule
  {
    /**
     * The serial version identifier required to satisfy the compiler because
     * this class implements the <CODE>java.io.Serializable</CODE> interface.
     * This value was generated using the <CODE>serialver</CODE> command-line
     * utility included with the Java SDK.
     */
    private static final long serialVersionUID = 7222067708233629974L;
    /**
     * Constructs a new CollationLessThanOrEqualToMatchingRule.
@@ -1831,7 +1913,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T createIndexQuery(ByteSequence assertionValue,
        IndexQueryFactory<T> factory) throws DirectoryException
    {
@@ -1848,6 +1929,15 @@
  private final class CollationGreaterThanMatchingRule extends
      CollationOrderingMatchingRule
  {
    /**
     * The serial version identifier required to satisfy the compiler because
     * this class implements the <CODE>java.io.Serializable</CODE> interface.
     * This value was generated using the <CODE>serialver</CODE> command-line
     * utility included with the Java SDK.
     */
    private static final long serialVersionUID = 1204368277332957024L;
    /**
     * Constructs a new CollationGreaterThanMatchingRule.
@@ -1891,7 +1981,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T createIndexQuery(ByteSequence assertionValue,
        IndexQueryFactory<T> factory) throws DirectoryException
    {
@@ -1907,6 +1996,15 @@
  private final class CollationGreaterThanOrEqualToMatchingRule extends
      CollationOrderingMatchingRule
  {
    /**
     * The serial version identifier required to satisfy the compiler because
     * this class implements the <CODE>java.io.Serializable</CODE> interface.
     * This value was generated using the <CODE>serialver</CODE> command-line
     * utility included with the Java SDK.
     */
    private static final long serialVersionUID = -5212358378014047933L;
    /**
     * Constructs a new CollationGreaterThanOrEqualToMatchingRule.
@@ -1950,7 +2048,6 @@
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T createIndexQuery(ByteSequence assertionValue,
        IndexQueryFactory<T> factory) throws DirectoryException
    {
opends/src/server/org/opends/server/schema/GeneralizedTimeOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -35,6 +35,7 @@
import java.util.Collection;
import java.util.Collections;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.debug.DebugTracer;
@@ -50,7 +51,8 @@
 * X.520 and referenced in RFC 2252.
 */
class GeneralizedTimeOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The tracer object for the debug logger.
@@ -203,7 +205,6 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    try
@@ -253,6 +254,6 @@
  public int compare(byte[] b1, byte[] b2)
  {
    return compareValues(ByteString.wrap(b1), ByteString.wrap(b2));
  }
}
}
opends/src/server/org/opends/server/schema/IntegerOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -36,6 +36,7 @@
import java.util.Collections;
import org.opends.messages.Message;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ByteSequence;
@@ -50,7 +51,8 @@
 * and referenced in RFC 4519.
 */
class IntegerOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -374,7 +376,6 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    int b1Length = value1.length();
opends/src/server/org/opends/server/schema/NumericStringOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -36,6 +36,7 @@
import java.util.Collections;
import org.opends.messages.Message;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
@@ -52,7 +53,8 @@
 * in X.520 and referenced in RFC 2252.
 */
class NumericStringOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -208,10 +210,9 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    return StaticUtils.compare(value1, value2);
    return value1.compareTo(value2);
  }
@@ -232,6 +233,6 @@
  public int compare(byte[] b1, byte[] b2)
  {
    return StaticUtils.compare(b1, b2);
  }
}
}
opends/src/server/org/opends/server/schema/OctetStringOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -33,6 +33,7 @@
import java.util.Collection;
import java.util.Collections;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.types.ByteSequence;
import org.opends.server.types.ByteString;
@@ -47,7 +48,8 @@
 * octet string syntaxes.
 */
class OctetStringOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -169,10 +171,9 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    return StaticUtils.compare(value1, value2);
    return value1.compareTo(value2);
  }
@@ -193,6 +194,6 @@
  public int compare(byte[] b1, byte[] b2)
  {
    return StaticUtils.compare(b1, b2);
  }
}
}
opends/src/server/org/opends/server/schema/UUIDOrderingMatchingRule.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
@@ -35,6 +35,7 @@
import java.util.Collections;
import org.opends.messages.Message;
import org.opends.server.api.AbstractMatchingRule;
import org.opends.server.api.OrderingMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
@@ -51,7 +52,8 @@
 * This will be the default ordering matching rule for the UUID syntax.
 */
class UUIDOrderingMatchingRule
       extends OrderingMatchingRule
       extends AbstractMatchingRule
       implements OrderingMatchingRule
{
  /**
   * The serial version identifier required to satisfy the compiler because this
@@ -279,10 +281,9 @@
   *          ascending order, or zero if there is no difference between the
   *          values with regard to ordering.
   */
  @Override
  public int compareValues(ByteSequence value1, ByteSequence value2)
  {
    return StaticUtils.compare(value1, value2);
    return value1.compareTo(value2);
  }
@@ -303,6 +304,6 @@
  public int compare(byte[] b1, byte[] b2)
  {
    return StaticUtils.compare(b1, b2);
  }
}
}
opends/src/server/org/opends/server/types/Schema.java
@@ -1876,7 +1876,13 @@
  public ExtensibleMatchingRule getExtensibleMatchingRule(
                                      String lowerName)
  {
    return extensibleMatchingRules.get(lowerName);
    //An ExtensibleMatchingRule can be of multiple types.
    MatchingRule rule = matchingRules.get(lowerName);
    if(rule instanceof ExtensibleMatchingRule)
    {
      return (ExtensibleMatchingRule)rule;
    }
    return null;
  }
opends/src/server/org/opends/server/util/StaticUtils.java
@@ -1415,6 +1415,7 @@
   *         if the first byte array is less than, equal to, or greater
   *         than the second.
   */
  @Deprecated
  public static int compare(ByteSequence a, ByteSequence a2) {
    if (a == a2) {
      return 0;
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/CollationMatchingRuleTest.java
@@ -22,24 +22,31 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
import java.util.ArrayList;
import static org.testng.Assert.*;
import java.util.List;
import org.opends.server.TestCaseUtils;
import org.opends.server.controls.ServerSideSortRequestControl;
import org.opends.server.controls.VLVRequestControl;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.tools.LDAPModify;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.Entry;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchScope;
import org.testng.annotations.BeforeClass;
@@ -65,6 +72,10 @@
  {
    TestCaseUtils.startServer();
    TestCaseUtils.initializeTestBackend(true);
    user1 = DN.decode("cn=user1,dc=example,dc=com");
    user2 = DN.decode("cn=user2,dc=example,dc=com");
    user3 = DN.decode("cn=user3,dc=example,dc=com");
    user4 = DN.decode("cn=user4,dc=example,dc=com");
  }
@@ -363,4 +374,161 @@
    //An entry must be returned for sn=quebec.
    assertNotNull(e);
  }
  private DN user1;
  private DN user2 ;
  private DN user3;
  private DN user4;
  /**
   * Test to verify the Sort control works well with the Collation
   * Less-than-equal-to matching rule and French Locale.
   */
  @Test()
  public void testSortControlLTERule() throws Exception
  {
    ArrayList<DN> expectedDNOrder = new ArrayList<DN>();
    expectedDNOrder.add(user4);
    expectedDNOrder.add(user3);
    expectedDNOrder.add(user2);
    expectedDNOrder.add(user1);
    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("displayname:fr"));
    ValidateSortControl(expectedDNOrder,
            requestControls,
            "displayname:fr-FR.6:=A*");
  }
  /**
   * Test to verify the Sort control works with Collation equality
   * matching rule and Spanish locale.
   */
  @Test()
  public void testSortControlEQRule() throws Exception
  {
    ArrayList<DN> expectedDNOrder = new ArrayList<DN>();
    expectedDNOrder.add(user4);
    expectedDNOrder.add(user3);
    expectedDNOrder.add(user2);
    expectedDNOrder.add(user1);
    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("displayname:es"));
    ValidateSortControl(expectedDNOrder,
            requestControls,
            "displayname:es.6:=A*");
  }
  /**
   * Test to verify the Sort control works with Collation greater
   * than matching rule and English locale in a descending order.
   */
  @Test()
  public void testSortControlGTRule() throws Exception
  {
    ArrayList<DN> expectedDNOrder = new ArrayList<DN>();
    expectedDNOrder.add(user1);
    expectedDNOrder.add(user2);
    expectedDNOrder.add(user3);
    expectedDNOrder.add(user4);
    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("-displayname:en"));
    ValidateSortControl(expectedDNOrder,
            requestControls,
            "displayname:en-US.6:=A*");
  }
  /**
   * Tests the Sort control with the VLV control using a collation equality
   * matching rule.
   */
  @Test()
  public void testVLVSortControl() throws Exception
  {
    ArrayList<DN> expectedDNOrder = new ArrayList<DN>();
    expectedDNOrder.add(user4);
    expectedDNOrder.add(user3);
    expectedDNOrder.add(user2);
    expectedDNOrder.add(user1);
    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("displayname:fr"));
    requestControls.add(new VLVRequestControl(0, 4, 1, 0));
    ValidateSortControl(expectedDNOrder,
            requestControls,
            "objectclass=inetOrgPerson");
  }
  private void ValidateSortControl(ArrayList<DN> expectedDNOrder,
          ArrayList<Control> requestControls,
          String searchFilter) throws Exception
  {
    try
    {
      populateEntriesForControl();
      InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
      InternalSearchOperation internalSearch =
         new InternalSearchOperation(conn, InternalClientConnection.nextOperationID(),
                  InternalClientConnection.nextMessageID(), requestControls,
                  DN.decode("dc=example,dc=com"), SearchScope.WHOLE_SUBTREE,
                  DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false,
                  SearchFilter.createFilterFromString(searchFilter),
                  null, null);
      internalSearch.run();
      assertEquals(internalSearch.getResultCode(), ResultCode.SUCCESS);
      ArrayList<DN> returnedDNOrder = new ArrayList<DN>();
      for (Entry e : internalSearch.getSearchEntries())
      {
        returnedDNOrder.add(e.getDN());
      }
     assertEquals(returnedDNOrder, expectedDNOrder);
    }
    finally
    {
      TestCaseUtils.clearJEBackend(false, "userRoot", "dc=example,dc=com");
    }
  }
  private void populateEntriesForControl() throws Exception
  {
    TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com");
    TestCaseUtils.addEntries(
      "dn: cn=user1,dc=example,dc=com",
      "objectclass: inetorgperson",
      "cn: user1",
      "sn: user1",
      "uid: user1",
      "displayname:: QXVy4oiawqlsaWVuNA==",
      "",
      "dn: cn=user2,dc=example,dc=com",
      "objectclass: inetorgperson",
      "cn: user2",
      "sn: user2",
      "uid: user2",
      "displayname:: QXVy4oiawqlsaWVuMw==",
      "",
      "dn: cn=user3,dc=example,dc=com",
      "objectclass: inetorgperson",
      "cn: user3",
      "sn: user3",
      "uid: user3",
      "displayname:: QXVy4oiawqlsaWVuMg==",
      "",
      "dn: cn=user4,dc=example,dc=com",
      "objectclass: inetorgperson",
      "cn: user4",
      "sn: user4",
      "uid: user4",
      "displayname:: QXVy4oiawqlsaWVuMQ=="
    );
  }
}