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

Jean-Noël Rouvignac
05.28.2016 48dfaad29e7758526f1c107ed7b7ee2a0697c0a5
Replaced server's SortKey and SortOrder by SDK's SortKey + List<SortKey>

Main changes are:
- SOrtOrder => List<SortKey>
- SortKey.ascending() => SortKey.isReverseOrder()
- SortKey now returns strings for attributeDescriptions and equality matching rules
instead of the full blown types
- We are now correctly using AttributeDescription instead of AttributeType
2 files deleted
5 files modified
780 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java 16 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java 100 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/controls/ServerSideSortRequestControl.java 85 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/SortKey.java 331 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/SortOrder.java 180 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java 25 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/controls/ServerSideSortControlTestCase.java 43 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -51,6 +51,7 @@
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.SortKey;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.util.Pair;
import org.opends.messages.CoreMessages;
@@ -97,7 +98,6 @@
import org.opends.server.types.Operation;
import org.opends.server.types.Privilege;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SortOrder;
import org.opends.server.types.VirtualAttributeRule;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.StaticUtils;
@@ -771,8 +771,8 @@
              // this sort key was not found in the user entry.
              try
              {
                SortOrder sortOrder = sortRequest.getSortOrder();
                reorderedCandidateEntryIDs = sort(txn, candidateEntryIDs, searchOperation, sortOrder, vlvRequest);
                List<SortKey> sortKeys = sortRequest.getSortKeys();
                reorderedCandidateEntryIDs = sort(txn, candidateEntryIDs, searchOperation, sortKeys, vlvRequest);
              }
              catch (DirectoryException de)
              {
@@ -2499,7 +2499,7 @@
  }
  private long[] sort(ReadableTransaction txn, EntryIDSet entryIDSet, SearchOperation searchOperation,
      SortOrder sortOrder, VLVRequestControl vlvRequest) throws DirectoryException
      List<SortKey> sortKeys, VLVRequestControl vlvRequest) throws DirectoryException
  {
    if (!entryIDSet.isDefined())
    {
@@ -2518,7 +2518,7 @@
        Entry e = getEntry(txn, id);
        if (e.matchesBaseAndScope(baseDN, scope) && filter.matchesEntry(e))
        {
          sortMap.put(encodeVLVKey(sortOrder, e, id.longValue()), id);
          sortMap.put(encodeVLVKey(sortKeys, e, id.longValue()), id);
        }
      }
      catch (Exception e)
@@ -2539,7 +2539,7 @@
    {
      return sortByOffset(searchOperation, vlvRequest, sortMap);
    }
    return sortByGreaterThanOrEqualAssertion(searchOperation, vlvRequest, sortOrder, sortMap);
    return sortByGreaterThanOrEqualAssertion(searchOperation, vlvRequest, sortKeys, sortMap);
  }
  private static final long[] toArray(Collection<EntryID> entryIDs)
@@ -2554,12 +2554,12 @@
  }
  private static final long[] sortByGreaterThanOrEqualAssertion(SearchOperation searchOperation,
      VLVRequestControl vlvRequest, SortOrder sortOrder, final TreeMap<ByteString, EntryID> sortMap)
      VLVRequestControl vlvRequest, List<SortKey> sortKeys, final TreeMap<ByteString, EntryID> sortMap)
      throws DirectoryException
  {
    ByteString assertionValue = vlvRequest.getGreaterThanOrEqualAssertion();
    ByteSequence encodedTargetAssertion =
        encodeTargetAssertion(sortOrder, assertionValue, searchOperation, sortMap.size());
        encodeTargetAssertion(sortKeys, assertionValue, searchOperation, sortMap.size());
    boolean targetFound = false;
    int index = 0;
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
@@ -20,9 +20,11 @@
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.backends.pluggable.EntryIDSet.*;
import static org.opends.server.backends.pluggable.IndexFilter.*;
import static org.opends.server.core.DirectoryServer.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
@@ -34,12 +36,15 @@
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigChangeResult;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.SortKey;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.util.Reject;
@@ -62,13 +67,10 @@
import org.opends.server.core.SearchOperation;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Attribute;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SortKey;
import org.opends.server.types.SortOrder;
import org.opends.server.util.StaticUtils;
/**
@@ -96,7 +98,7 @@
  private DN baseDN;
  private SearchScope scope;
  private SearchFilter filter;
  private SortOrder sortOrder;
  private List<SortKey> sortKeys;
  /** The storage associated with this index. */
  private final Storage storage;
@@ -120,7 +122,7 @@
    final ConfigChangeResult ccr = new ConfigChangeResult();
    this.filter = parseSearchFilter(config, getName().toString(), ccr);
    this.sortOrder = new SortOrder(parseSortKeys(config.getSortOrder(), ccr));
    this.sortKeys = parseSortKeys(config.getSortOrder(), ccr);
    if (!ccr.getMessages().isEmpty())
    {
      throw new ConfigException(ccr.getMessages().get(0));
@@ -263,7 +265,7 @@
    // Update the sort order only if changed
    if (!config.getSortOrder().equals(cfg.getSortOrder()))
    {
      this.sortOrder = new SortOrder(parseSortKeys(cfg.getSortOrder(), ccr));
      this.sortKeys = parseSortKeys(cfg.getSortOrder(), ccr);
      ccr.setAdminActionRequired(true);
    }
@@ -285,22 +287,21 @@
    this.config = cfg;
  }
  private SortKey[] parseSortKeys(final String sortOrder, ConfigChangeResult ccr)
  private List<SortKey> parseSortKeys(final String sortOrder, ConfigChangeResult ccr)
  {
    return parseSortKeys(sortOrder, ccr, getName().toString());
  }
  private static SortKey[] parseSortKeys(final String sortOrder, ConfigChangeResult ccr, String indexName)
  private static List<SortKey> parseSortKeys(final String sortOrder, ConfigChangeResult ccr, String indexName)
  {
    final String[] sortAttrs = sortOrder.split(" ");
    final SortKey[] sortKeys = new SortKey[sortAttrs.length];
    for (int i = 0; i < sortAttrs.length; i++)
    final List<SortKey> sortKeys = new ArrayList<>(sortAttrs.length);
    for (String sortAttr : sortAttrs)
    {
      String sortAttr = sortAttrs[i];
      final boolean ascending;
      final boolean isReverseOrder;
      try
      {
        ascending = !sortAttr.startsWith("-");
        isReverseOrder = sortAttr.startsWith("-");
        if (sortAttr.startsWith("-") || sortAttr.startsWith("+"))
        {
@@ -311,23 +312,24 @@
      {
        ccr.setResultCode(ResultCode.INVALID_ATTRIBUTE_SYNTAX);
        ccr.addMessage(ERR_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortAttr, indexName));
        return null;
        return Collections.emptyList();
      }
      final AttributeType attrType = DirectoryServer.getAttributeType(sortAttr);
      final AttributeDescription attrDesc = AttributeDescription.valueOf(sortAttr);
      final AttributeType attrType = attrDesc.getAttributeType();
      if (attrType.isPlaceHolder())
      {
        ccr.setResultCode(ResultCode.INVALID_ATTRIBUTE_SYNTAX);
        ccr.addMessage(ERR_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortAttr, indexName));
        return null;
        return Collections.emptyList();
      }
      if (attrType.getOrderingMatchingRule() == null)
      {
        ccr.setResultCode(ResultCode.CONSTRAINT_VIOLATION);
        ccr.addMessage(INFO_SORTREQ_CONTROL_NO_ORDERING_RULE_FOR_ATTR.get(attrType.getNameOrOID()));
        return null;
        return Collections.emptyList();
      }
      sortKeys[i] = new SortKey(attrType, ascending);
      sortKeys.add(new SortKey(sortAttr, isReverseOrder));
    }
    return sortKeys;
  }
@@ -411,9 +413,10 @@
  private boolean isSortAttributeModified(final List<Modification> mods)
  {
    for (final SortKey sortKey : sortOrder.getSortKeys())
    for (final SortKey sortKey : sortKeys)
    {
      final AttributeType attributeType = sortKey.getAttributeType();
      final AttributeDescription attrDesc = AttributeDescription.valueOf(sortKey.getAttributeDescription());
      final AttributeType attributeType = attrDesc.getAttributeType();
      final List<AttributeType> subTypes = DirectoryServer.getSchema().getSubTypes(attributeType);
      for (final Modification mod : mods)
      {
@@ -486,7 +489,7 @@
        !searchOperation.getBaseDN().equals(baseDN) ||
        !searchOperation.getScope().equals(scope) ||
        !searchOperation.getFilter().equals(filter) ||
        !sortControl.getSortOrder().equals(sortOrder))
        !sortControl.getSortKeys().equals(sortKeys))
    {
      return null;
    }
@@ -547,7 +550,7 @@
    final int afterCount = vlvRequest.getAfterCount();
    final ByteString assertion = vlvRequest.getGreaterThanOrEqualAssertion();
    final ByteSequence encodedTargetAssertion =
        encodeTargetAssertion(sortOrder, assertion, searchOperation, currentCount);
        encodeTargetAssertion(sortKeys, assertion, searchOperation, currentCount);
    try (Cursor<ByteString, ByteString> cursor = txn.openCursor(getName()))
    {
      final LinkedList<Long> selectedIDs = new LinkedList<>();
@@ -616,10 +619,10 @@
  }
  /** Normalize the assertion using the primary key's ordering matching rule. */
  static ByteSequence encodeTargetAssertion(final SortOrder sortOrder, final ByteString assertion,
  static ByteSequence encodeTargetAssertion(final List<SortKey> sortKeys, final ByteString assertion,
      final SearchOperation searchOperation, final int resultSetSize) throws DirectoryException
  {
    final SortKey primarySortKey = sortOrder.getSortKeys()[0];
    final SortKey primarySortKey = sortKeys.get(0);
    try
    {
      /*
@@ -628,16 +631,16 @@
       * include some escaped bytes as well. 10 extra bytes should accommodate most inputs.
       */
      final ByteStringBuilder encodedPrimaryKey = new ByteStringBuilder(assertion.length() + 10);
      final MatchingRule matchingRule = primarySortKey.getEffectiveOrderingRule();
      final MatchingRule matchingRule = getEffectiveOrderingRule(primarySortKey);
      final ByteString normalizedAttributeValue = matchingRule.normalizeAttributeValue(assertion);
      encodeVLVKeyValue(normalizedAttributeValue, encodedPrimaryKey, primarySortKey.ascending());
      encodeVLVKeyValue(normalizedAttributeValue, encodedPrimaryKey, primarySortKey.isReverseOrder());
      return encodedPrimaryKey;
    }
    catch (final DecodeException e)
    {
      addVLVResponseControl(searchOperation, 0, resultSetSize, LDAPResultCode.OFFSET_RANGE_ERROR);
      final String attributeName = primarySortKey.getAttributeType().getNameOrOID();
      throw new DirectoryException(ResultCode.VIRTUAL_LIST_VIEW_ERROR, ERR_VLV_BAD_ASSERTION.get(attributeName));
      final String attrDesc = primarySortKey.getAttributeDescription();
      throw new DirectoryException(ResultCode.VIRTUAL_LIST_VIEW_ERROR, ERR_VLV_BAD_ASSERTION.get(attrDesc));
    }
  }
@@ -779,23 +782,23 @@
  private ByteString encodeVLVKey(final Entry entry, final long entryID)
  {
    return encodeVLVKey(sortOrder, entry, entryID);
    return encodeVLVKey(sortKeys, entry, entryID);
  }
  static ByteString encodeVLVKey(final SortOrder sortOrder, final Entry entry, final long entryID)
  static ByteString encodeVLVKey(final List<SortKey> sortKeys, final Entry entry, final long entryID)
  {
    final ByteStringBuilder builder = new ByteStringBuilder();
    encodeVLVKey0(sortOrder, entry, builder);
    encodeVLVKey0(sortKeys, entry, builder);
    builder.appendLong(entryID);
    return builder.toByteString();
  }
  private static void encodeVLVKey0(final SortOrder sortOrder, final Entry entry, final ByteStringBuilder builder)
  private static void encodeVLVKey0(final List<SortKey> sortKeys, final Entry entry, final ByteStringBuilder builder)
  {
    for (final SortKey sortKey : sortOrder.getSortKeys())
    for (final SortKey sortKey : sortKeys)
    {
      ByteString sortValue = getLowestAttributeValue(entry, sortKey);
      encodeVLVKeyValue(sortValue, builder, sortKey.ascending());
      encodeVLVKeyValue(sortValue, builder, sortKey.isReverseOrder());
    }
  }
@@ -805,10 +808,10 @@
   */
  private static ByteString getLowestAttributeValue(final Entry entry, final SortKey sortKey)
  {
    final AttributeType attributeType = sortKey.getAttributeType();
    final MatchingRule matchingRule = sortKey.getEffectiveOrderingRule();
    final AttributeDescription attrDesc = AttributeDescription.valueOf(sortKey.getAttributeDescription());
    final MatchingRule matchingRule = getEffectiveOrderingRule(sortKey);
    ByteString sortValue = null;
    for (Attribute a : entry.getAttribute(attributeType))
    for (Attribute a : entry.getAttribute(attrDesc.getAttributeType()))
    {
      for (ByteString v : a)
      {
@@ -833,6 +836,21 @@
    return sortValue;
  }
  private static MatchingRule getEffectiveOrderingRule(SortKey sortKey)
  {
    String mrOid = sortKey.getOrderingMatchingRule();
    if (mrOid != null)
    {
      MatchingRule orderingRule = getMatchingRule(mrOid);
      if (orderingRule != null)
      {
        return orderingRule;
      }
    }
    AttributeDescription attrDesc = AttributeDescription.valueOf(sortKey.getAttributeDescription());
    return attrDesc.getAttributeType().getOrderingMatchingRule();
  }
  /**
   * Package private for testing.
   * <p>
@@ -853,12 +871,12 @@
   * </ul>
   */
  static void encodeVLVKeyValue(final ByteString keyBytes, final ByteStringBuilder builder,
      final boolean ascending)
      final boolean isReverseOrder)
  {
    final byte separator = ascending ? (byte) 0x00 : (byte) 0xff;
    final byte separator = !isReverseOrder ? (byte) 0x00 : (byte) 0xff;
    if (keyBytes != null)
    {
      final byte escape = ascending ? (byte) 0x01 : (byte) 0xfe;
      final byte escape = !isReverseOrder ? (byte) 0x01 : (byte) 0xfe;
      final byte sortOrderMask = separator;
      final int length = keyBytes.length();
      for (int i = 0; i < length; i++)
@@ -884,7 +902,7 @@
    else
    {
      // Ensure that null keys sort after (ascending) or before (descending) all other keys.
      builder.appendByte(ascending ? 0xFF : 0x00);
      builder.appendByte(!isReverseOrder ? 0xFF : 0x00);
    }
    builder.appendByte(separator);
  }
opendj-server-legacy/src/main/java/org/opends/server/controls/ServerSideSortRequestControl.java
@@ -16,25 +16,30 @@
 */
package org.opends.server.controls;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.io.ASN1;
import org.forgerock.opendj.io.ASN1Reader;
import org.forgerock.opendj.io.ASN1Writer;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SortKey;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.LDAPException;
/**
 * This class implements the server-side sort request control as defined in RFC
@@ -104,12 +109,11 @@
          {
            //This attribute is not defined in the schema. There is no point
            //iterating over the next attribute and return a partially sorted result.
            return new ServerSideSortRequestControl(isCritical,
            new SortOrder(sortKeys.toArray(new SortKey[0])));
            return new ServerSideSortRequestControl(isCritical, sortKeys);
          }
          MatchingRule orderingRule = null;
          boolean ascending = true;
          boolean isReverseOrder = false;
          if(reader.hasNextElement() &&
              reader.peekType() == TYPE_ORDERING_RULE_ID)
          {
@@ -129,7 +133,7 @@
          if(reader.hasNextElement() &&
              reader.peekType() == TYPE_REVERSE_ORDER)
          {
            ascending = ! reader.readBoolean();
            isReverseOrder = reader.readBoolean();
          }
          reader.readEndSequence();
@@ -140,12 +144,11 @@
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
          }
          sortKeys.add(new SortKey(attrType, ascending, orderingRule));
          sortKeys.add(new SortKey(AttributeDescription.create(attrType), isReverseOrder, orderingRule));
        }
        reader.readEndSequence();
        return new ServerSideSortRequestControl(isCritical,
            new SortOrder(sortKeys.toArray(new SortKey[0])));
        return new ServerSideSortRequestControl(isCritical, sortKeys);
      }
      catch (DirectoryException de)
      {
@@ -175,10 +178,9 @@
      new Decoder();
  /** The sort order associated with this control represented by strings. */
  private ArrayList<String[]> decodedKeyList;
  private List<String[]> decodedKeyList;
  /** The sort order associated with this control. */
  private SortOrder sortOrder;
  private List<SortKey> sortKeys;
  /**
   * Creates a new server-side sort request control based on the definition in
@@ -289,11 +291,11 @@
   * Creates a new server-side sort request control based on the provided sort
   * order.
   *
   * @param  sortOrder  The sort order to use for this control.
   * @param  sortKeys  The sort order to use for this control.
   */
  public ServerSideSortRequestControl(SortOrder sortOrder)
  public ServerSideSortRequestControl(List<SortKey> sortKeys)
  {
    this(false, sortOrder);
    this(false, sortKeys);
  }
  /**
@@ -302,14 +304,14 @@
   *
   * @param  isCritical    Indicates whether support for this control should be
   *                       considered a critical part of the server processing.
   * @param  sortOrder     sort order associated with this server-side sort
   * @param  sortKeys     sort order associated with this server-side sort
   *                       control.
   */
  public ServerSideSortRequestControl(boolean isCritical, SortOrder sortOrder)
  public ServerSideSortRequestControl(boolean isCritical, List<SortKey> sortKeys)
  {
    super(OID_SERVER_SIDE_SORT_REQUEST_CONTROL, isCritical);
    this.sortOrder = sortOrder;
    this.sortKeys = sortKeys;
  }
@@ -317,17 +319,15 @@
   * Retrieves the sort order for this server-side sort request control.
   *
   * @return  The sort order for this server-side sort request control.
   * @throws  DirectoryException if an error occurs while retriving the
   *          sort order.
   * @throws  DirectoryException if an error occurs while retrieving the sort order.
   */
  public SortOrder getSortOrder() throws DirectoryException
  public List<SortKey> getSortKeys() throws DirectoryException
  {
    if(sortOrder == null)
    if (sortKeys == null)
    {
      sortOrder = decodeSortOrderFromString();
      sortKeys = decodeSortKeysFromString();
    }
    return sortOrder;
    return sortKeys;
  }
  /**
@@ -344,7 +344,7 @@
   */
  public boolean  containsSortKeys() throws DirectoryException
  {
    return getSortOrder().getSortKeys().length!=0;
    return !getSortKeys().isEmpty();
  }
  /**
@@ -381,7 +381,7 @@
  public void toString(StringBuilder buffer)
  {
    buffer.append("ServerSideSortRequestControl(");
    if(sortOrder == null)
    if (sortKeys == null)
    {
      buffer.append("SortOrder(");
@@ -399,7 +399,7 @@
    }
    else
    {
      buffer.append(sortOrder);
      buffer.append(sortKeys);
    }
    buffer.append(")");
  }
@@ -426,9 +426,9 @@
    buffer.append(")");
  }
  private SortOrder decodeSortOrderFromString() throws DirectoryException
  private List<SortKey> decodeSortKeysFromString() throws DirectoryException
  {
    ArrayList<SortKey> sortKeys = new ArrayList<>();
    List<SortKey> sortKeys = new ArrayList<>();
    for(String[] decodedKey : decodedKeyList)
    {
      AttributeType attrType = DirectoryServer.getAttributeType(decodedKey[0]);
@@ -436,7 +436,7 @@
      {
        //This attribute is not defined in the schema. There is no point
        //iterating over the next attribute and return a partially sorted result.
        return new SortOrder(sortKeys.toArray(new SortKey[0]));
        return sortKeys;
      }
      MatchingRule orderingRule = null;
@@ -451,7 +451,7 @@
      }
      String decodedKey2 = decodedKey[2];
      boolean ascending = decodedKey2 == null || !decodedKey2.equals("r");
      boolean isReverseOrder = decodedKey2 != null && decodedKey2.equals("r");
      if (orderingRule == null
          && attrType.getOrderingMatchingRule() == null)
      {
@@ -459,10 +459,10 @@
            INFO_SORTREQ_CONTROL_NO_ORDERING_RULE_FOR_ATTR.get(decodedKey[0]));
      }
      sortKeys.add(new SortKey(attrType, ascending, orderingRule));
      sortKeys.add(new SortKey(AttributeDescription.create(attrType), isReverseOrder, orderingRule));
    }
    return new SortOrder(sortKeys.toArray(new SortKey[0]));
    return sortKeys;
  }
  private void writeValueFromString(ASN1Writer writer) throws IOException
@@ -497,18 +497,17 @@
    writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE);
    writer.writeStartSequence();
    for (SortKey sortKey : sortOrder.getSortKeys())
    for (SortKey sortKey : sortKeys)
    {
      writer.writeStartSequence();
      writer.writeOctetString(sortKey.getAttributeType().getNameOrOID());
      writer.writeOctetString(sortKey.getAttributeDescription());
      if (sortKey.getOrderingRule() != null)
      if (sortKey.getOrderingMatchingRule() != null)
      {
        writer.writeOctetString(TYPE_ORDERING_RULE_ID,
            sortKey.getOrderingRule().getNameOrOID());
        writer.writeOctetString(TYPE_ORDERING_RULE_ID, sortKey.getOrderingMatchingRule());
      }
      if (! sortKey.ascending())
      if (sortKey.isReverseOrder())
      {
        writer.writeBoolean(TYPE_REVERSE_ORDER, true);
      }
opendj-server-legacy/src/main/java/org/opends/server/types/SortKey.java
File was deleted
opendj-server-legacy/src/main/java/org/opends/server/types/SortOrder.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java
@@ -33,6 +33,7 @@
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
import org.opends.server.DirectoryServerTestCase;
@@ -52,7 +53,6 @@
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.types.Control;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.SearchResultEntry;
@@ -207,31 +207,28 @@
  @Test(dataProvider = "encodedKeyDataProvider")
  public void vlvKeyEncodingGenerateCorrectAscendingSortOrder(String key1, String key2, int expectedCompareResult)
  {
    ByteString bytes1 = key1 != null ? ByteString.valueOfHex(key1) : null;
    ByteStringBuilder encodedBytes1 = new ByteStringBuilder();
    VLVIndex.encodeVLVKeyValue(bytes1, encodedBytes1, true);
    ByteString bytes2 = key2 != null ? ByteString.valueOfHex(key2) : null;
    ByteStringBuilder encodedBytes2 = new ByteStringBuilder();
    VLVIndex.encodeVLVKeyValue(bytes2, encodedBytes2, true);
    int actualResult = Math.min(Math.max(encodedBytes1.compareTo(encodedBytes2), -1), 1);
    assertThat(actualResult).isEqualTo(expectedCompareResult);
    vlvKeyEncodingGenerateCorrectSortOrder(key1, key2, expectedCompareResult, false);
  }
  @Test(dataProvider = "encodedKeyDataProvider")
  public void vlvKeyEncodingGenerateCorrectDescendingSortOrder(String key1, String key2, int expectedCompareResult)
  {
    vlvKeyEncodingGenerateCorrectSortOrder(key1, key2, expectedCompareResult, true);
  }
  private void vlvKeyEncodingGenerateCorrectSortOrder(String key1, String key2, int expectedCompareResult,
      boolean isReverseOrder)
  {
    ByteString bytes1 = key1 != null ? ByteString.valueOfHex(key1) : null;
    ByteStringBuilder encodedBytes1 = new ByteStringBuilder();
    VLVIndex.encodeVLVKeyValue(bytes1, encodedBytes1, false);
    VLVIndex.encodeVLVKeyValue(bytes1, encodedBytes1, isReverseOrder);
    ByteString bytes2 = key2 != null ? ByteString.valueOfHex(key2) : null;
    ByteStringBuilder encodedBytes2 = new ByteStringBuilder();
    VLVIndex.encodeVLVKeyValue(bytes2, encodedBytes2, false);
    VLVIndex.encodeVLVKeyValue(bytes2, encodedBytes2, isReverseOrder);
    int actualResult = Math.min(Math.max(encodedBytes1.compareTo(encodedBytes2), -1), 1);
    assertThat(actualResult).isEqualTo(-expectedCompareResult);
    assertThat(actualResult).isEqualTo(isReverseOrder ? -expectedCompareResult : expectedCompareResult);
  }
  @DataProvider
opendj-server-legacy/src/test/java/org/opends/server/controls/ServerSideSortControlTestCase.java
@@ -21,21 +21,18 @@
import java.util.LinkedList;
import java.util.List;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.SortKey;
import org.opends.server.TestCaseUtils;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.internal.SearchRequest;
import org.opends.server.protocols.ldap.LDAPControl;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.opends.server.types.Control;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SortKey;
import org.opends.server.types.SortOrder;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -51,11 +48,6 @@
public class ServerSideSortControlTestCase
    extends ControlsTestCase
{
  /** The givenName attribute type. */
  private AttributeType givenNameType;
  /** The sn attribute type. */
  private AttributeType snType;
  /** The DN for "Aaccf Johnson". */
  DN aaccfJohnsonDN;
  /** The DN for "Aaron Zimmerman". */
@@ -87,12 +79,6 @@
  {
    TestCaseUtils.startServer();
    givenNameType = DirectoryServer.getAttributeType("givenname");
    assertNotNull(givenNameType);
    snType = DirectoryServer.getAttributeType("sn");
    assertNotNull(snType);
    aaccfJohnsonDN    = DN.valueOf("uid=aaccf.johnson,dc=example,dc=com");
    aaronZimmermanDN  = DN.valueOf("uid=aaron.zimmerman,dc=example,dc=com");
    albertSmithDN     = DN.valueOf("uid=albert.smith,dc=example,dc=com");
@@ -221,23 +207,18 @@
  @Test
  public void testRequestConstructor1() throws Exception
  {
    SortKey sortKey = new SortKey(givenNameType, true);
    SortOrder sortOrder = new SortOrder(sortKey);
    new ServerSideSortRequestControl(sortOrder).toString();
    sortKey.toString();
    sortOrder.toString();
    SortKey sortKey = new SortKey("givenName", false);
    List<SortKey> sortKeys = Arrays.asList(sortKey);
    new ServerSideSortRequestControl(sortKeys).toString();
    sortKey = new SortKey(givenNameType, false);
    sortOrder = new SortOrder(sortKey);
    new ServerSideSortRequestControl(sortOrder).toString();
    sortKey.toString();
    sortOrder.toString();
    sortKey = new SortKey("givenName", true);
    sortKeys = Arrays.asList(sortKey);
    new ServerSideSortRequestControl(sortKeys).toString();
    sortOrder = new SortOrder(
      new SortKey(snType, true),
      new SortKey(givenNameType, true));
    new ServerSideSortRequestControl(sortOrder).toString();
    sortOrder.toString();
    sortKeys = Arrays.asList(
      new SortKey("sn", false),
      new SortKey("givenName", false));
    new ServerSideSortRequestControl(sortKeys).toString();
  }