From 54ddfdbd4532e496dc75432e87f4c348a3fac0fa Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 17 Oct 2013 12:48:05 +0000
Subject: [PATCH] Preliminary work for OPENDJ-701: Implement paged results support

---
 opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java     |   10 +++++
 opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java          |    9 ++++
 opendj-sdk/opendj3/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java |   86 ++++++++++++++++++++++++++++++++++++++++++-
 opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java            |    5 ++
 4 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java b/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
index 63d8453..62fc32a 100755
--- a/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
+++ b/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
- *      Portions copyright 2011-2012 ForgeRock AS
+ *      Portions copyright 2011-2013 ForgeRock AS
  */
 package org.forgerock.opendj.ldap;
 
@@ -229,6 +229,13 @@
     int hashCode();
 
     /**
+     * Returns {@code true} if this byte sequence has a length of zero.
+     *
+     * @return {@code true} if this byte sequence has a length of zero.
+     */
+    boolean isEmpty();
+
+    /**
      * Returns the length of this byte sequence.
      *
      * @return The length of this byte sequence.
diff --git a/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java b/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java
index e2b350e..2623377 100755
--- a/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java
+++ b/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteString.java
@@ -525,6 +525,11 @@
         return hashCode(buffer, offset, length);
     }
 
+    @Override
+    public boolean isEmpty() {
+        return length == 0;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java b/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
index 6ee1c5b..d99f241 100755
--- a/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
+++ b/opendj-sdk/opendj3/opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
@@ -180,6 +180,11 @@
             return ByteString.hashCode(buffer, subOffset, subLength);
         }
 
+        @Override
+        public boolean isEmpty() {
+            return length == 0;
+        }
+
         /**
          * {@inheritDoc}
          */
@@ -826,6 +831,11 @@
         return ByteString.hashCode(buffer, 0, length);
     }
 
+    @Override
+    public boolean isEmpty() {
+        return length == 0;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/opendj-sdk/opendj3/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java b/opendj-sdk/opendj3/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java
index c30e392..e7cb053 100644
--- a/opendj-sdk/opendj3/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java
+++ b/opendj-sdk/opendj3/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java
@@ -37,6 +37,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 
 import org.forgerock.opendj.ldap.controls.AssertionRequestControl;
 import org.forgerock.opendj.ldap.controls.PermissiveModifyRequestControl;
@@ -44,7 +45,10 @@
 import org.forgerock.opendj.ldap.controls.PostReadResponseControl;
 import org.forgerock.opendj.ldap.controls.PreReadRequestControl;
 import org.forgerock.opendj.ldap.controls.PreReadResponseControl;
+import org.forgerock.opendj.ldap.controls.SimplePagedResultsControl;
 import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.requests.SearchRequest;
+import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 import org.forgerock.opendj.ldif.LDIFEntryReader;
@@ -55,8 +59,7 @@
  */
 @SuppressWarnings("javadoc")
 public class MemoryBackendTestCase extends SdkTestCase {
-
-    int numberOfEntriesInBackend;
+    private int numberOfEntriesInBackend;
 
     @Test
     public void testAdd() throws Exception {
@@ -469,6 +472,61 @@
     }
 
     @Test
+    public void testSearchPagedResults() throws Exception {
+        final Connection connection = getConnection();
+        final List<SearchResultEntry> entries = new ArrayList<SearchResultEntry>();
+        final SearchRequest search =
+                Requests.newSearchRequest("ou=people,dc=example,dc=com", SearchScope.WHOLE_SUBTREE,
+                        "(uid=*)");
+        final DecodeOptions dc = new DecodeOptions();
+
+        // First page.
+        search.addControl(SimplePagedResultsControl.newControl(true, 2, ByteString.empty()));
+        Result result = connection.search(search, entries);
+        assertThat(entries).hasSize(2);
+        assertThat(entries.get(0).getName().toString()).isEqualTo(
+                "uid=test1,ou=People,dc=example,dc=com");
+        assertThat(entries.get(1).getName().toString()).isEqualTo(
+                "uid=test2,ou=People,dc=example,dc=com");
+        SimplePagedResultsControl control =
+                result.getControl(SimplePagedResultsControl.DECODER, dc);
+        assertThat(control).isNotNull();
+        ByteString cookie = control.getCookie();
+        assertThat(cookie).isNotNull();
+        assertThat(cookie.isEmpty()).isFalse();
+        entries.clear();
+        search.getControls().clear();
+
+        // Second page.
+        search.addControl(SimplePagedResultsControl.newControl(true, 2, cookie));
+        result = connection.search(search, entries);
+        assertThat(entries).hasSize(2);
+        assertThat(entries.get(0).getName().toString()).isEqualTo(
+                "uid=test3,ou=People,dc=example,dc=com");
+        assertThat(entries.get(1).getName().toString()).isEqualTo(
+                "uid=test4,ou=People,dc=example,dc=com");
+        control = result.getControl(SimplePagedResultsControl.DECODER, dc);
+        assertThat(control).isNotNull();
+        cookie = control.getCookie();
+        assertThat(cookie).isNotNull();
+        assertThat(cookie.isEmpty()).isFalse();
+        entries.clear();
+        search.getControls().clear();
+
+        // Final page.
+        search.addControl(SimplePagedResultsControl.newControl(true, 2, cookie));
+        result = connection.search(search, entries);
+        assertThat(entries).hasSize(1);
+        assertThat(entries.get(0).getName().toString()).isEqualTo(
+                "uid=test5,ou=People,dc=example,dc=com");
+        control = result.getControl(SimplePagedResultsControl.DECODER, dc);
+        assertThat(control).isNotNull();
+        cookie = control.getCookie();
+        assertThat(cookie).isNotNull();
+        assertThat(cookie.isEmpty()).isTrue();
+    }
+
+    @Test
     public void testSimpleBind() throws Exception {
         final Connection connection = getConnection();
         connection.bind("uid=test1,ou=people,dc=example,dc=com", "password".toCharArray());
@@ -548,6 +606,30 @@
             "cn: test user 2",
             "sn: user 2",
             "",
+            "dn: uid=test3,ou=People,dc=example,dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "uid: test3",
+            "userpassword: password",
+            "cn: test user 3",
+            "sn: user 3",
+            "",
+            "dn: uid=test4,ou=People,dc=example,dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "uid: test4",
+            "userpassword: password",
+            "cn: test user 4",
+            "sn: user 4",
+            "",
+            "dn: uid=test5,ou=People,dc=example,dc=com",
+            "objectClass: top",
+            "objectClass: person",
+            "uid: test5",
+            "userpassword: password",
+            "cn: test user 5",
+            "sn: user 5",
+            "",
             "dn: dc=xxx,dc=com",
             "objectClass: domain",
             "objectClass: top",

--
Gitblit v1.10.0