From 48dfaad29e7758526f1c107ed7b7ee2a0697c0a5 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Thu, 24 Mar 2016 13:15:06 +0000
Subject: [PATCH] Replaced server's SortKey and SortOrder by SDK's SortKey + List<SortKey>

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java |  100 +++++++++++++++++++++++++++++--------------------
 1 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
index 145993c..499c063 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
+++ b/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);
   }

--
Gitblit v1.10.0