From b4d0bd8bb05e4c16392f1ac1a1c97236048fbc98 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 15 May 2012 13:27:10 +0000
Subject: [PATCH] Fix OPENDJ-496: Add support for creating lessThan and greaterThan filters

---
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Filter.java         |   95 +++++++++++++++++++++++++++++++
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java |   51 ++++++++++++++++
 2 files changed, 145 insertions(+), 1 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Filter.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Filter.java
index 45b14c8..1d500ef 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Filter.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Filter.java
@@ -652,6 +652,54 @@
     }
 
     /**
+     * Creates a new {@code greater than} filter using the provided attribute
+     * description and assertion value.
+     * <p>
+     * <b>NOTE:</b> since LDAP does not support {@code greater than}
+     * comparisons, this method returns a filter of the form
+     * {@code (&(type>=value)(!(type=value)))}. An alternative is to return a
+     * filter of the form {@code (!(type<=value))} , however the outer
+     * {@code not} filter will often prevent directory servers from optimizing
+     * the search using indexes.
+     *
+     * @param attributeDescription
+     *            The attribute description.
+     * @param assertionValue
+     *            The assertion value.
+     * @return The newly created {@code greater than} filter.
+     */
+    public static Filter greaterThan(final String attributeDescription,
+            final ByteString assertionValue) {
+        return and(greaterOrEqual(attributeDescription, assertionValue), not(equality(
+                attributeDescription, assertionValue)));
+    }
+
+    /**
+     * Creates a new {@code greater than} filter using the provided
+     * attribute description and assertion value.
+     * <p>
+     * If {@code assertionValue} is not an instance of {@code ByteString} then
+     * it will be converted using the {@link ByteString#valueOf(Object)} method.
+     * <p>
+     * <b>NOTE:</b> since LDAP does not support {@code greater than}
+     * comparisons, this method returns a filter of the form
+     * {@code (&(type>=value)(!(type=value)))}. An alternative is to return a
+     * filter of the form {@code (!(type<=value))} , however the outer
+     * {@code not} filter will often prevent directory servers from optimizing
+     * the search using indexes.
+     *
+     * @param attributeDescription
+     *            The attribute description.
+     * @param assertionValue
+     *            The assertion value.
+     * @return The newly created {@code greater than} filter.
+     */
+    public static Filter greaterThan(final String attributeDescription,
+            final Object assertionValue) {
+        return greaterThan(attributeDescription, ByteString.valueOf(assertionValue));
+    }
+
+    /**
      * Creates a new {@code less or equal} filter using the provided attribute
      * description and assertion value.
      *
@@ -685,6 +733,53 @@
     }
 
     /**
+     * Creates a new {@code less than} filter using the provided attribute
+     * description and assertion value.
+     * <p>
+     * <b>NOTE:</b> since LDAP does not support {@code less than} comparisons,
+     * this method returns a filter of the form
+     * {@code (&(type<=value)(!(type=value)))}. An alternative is to return a
+     * filter of the form {@code (!(type>=value))} , however the outer
+     * {@code not} filter will often prevent directory servers from optimizing
+     * the search using indexes.
+     *
+     * @param attributeDescription
+     *            The attribute description.
+     * @param assertionValue
+     *            The assertion value.
+     * @return The newly created {@code less than} filter.
+     */
+    public static Filter lessThan(final String attributeDescription,
+            final ByteString assertionValue) {
+        return and(lessOrEqual(attributeDescription, assertionValue), not(equality(
+                attributeDescription, assertionValue)));
+    }
+
+    /**
+     * Creates a new {@code less than} filter using the provided attribute
+     * description and assertion value.
+     * <p>
+     * If {@code assertionValue} is not an instance of {@code ByteString} then
+     * it will be converted using the {@link ByteString#valueOf(Object)} method.
+     * <p>
+     * <b>NOTE:</b> since LDAP does not support {@code less than} comparisons,
+     * this method returns a filter of the form
+     * {@code (&(type<=value)(!(type=value)))}. An alternative is to return a
+     * filter of the form {@code (!(type>=value))} , however the outer
+     * {@code not} filter will often prevent directory servers from optimizing
+     * the search using indexes.
+     *
+     * @param attributeDescription
+     *            The attribute description.
+     * @param assertionValue
+     *            The assertion value.
+     * @return The newly created {@code less than} filter.
+     */
+    public static Filter lessThan(final String attributeDescription, final Object assertionValue) {
+        return lessThan(attributeDescription, ByteString.valueOf(assertionValue));
+    }
+
+    /**
      * Creates a new {@code not} filter using the provided sub-filter.
      *
      * @param subFilter
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java
index 1a82065..20d35f2 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/FilterTestCase.java
@@ -22,12 +22,13 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
+ *      Portions copyright 2011-2012 ForgeRock AS
  */
 
 package org.forgerock.opendj.ldap;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 import java.util.ArrayList;
@@ -199,6 +200,54 @@
         Filter.valueOf(filterStr);
     }
 
+    @Test
+    public void testGreaterThanFalse1() throws Exception {
+        final Filter filter = Filter.greaterThan("cn", "bbb");
+        final Entry entry = new LinkedHashMapEntry("dn: cn=bbb", "objectclass: top", "cn: bbb");
+        final Matcher matcher = filter.matcher();
+        assertFalse(matcher.matches(entry).toBoolean());
+    }
+
+    @Test
+    public void testGreaterThanFalse2() throws Exception {
+        final Filter filter = Filter.greaterThan("cn", "bbb");
+        final Entry entry = new LinkedHashMapEntry("dn: cn=aaa", "objectclass: top", "cn: aaa");
+        final Matcher matcher = filter.matcher();
+        assertFalse(matcher.matches(entry).toBoolean());
+    }
+
+    @Test
+    public void testGreaterThanTrue() throws Exception {
+        final Filter filter = Filter.greaterThan("cn", "bbb");
+        final Entry entry = new LinkedHashMapEntry("dn: cn=ccc", "objectclass: top", "cn: ccc");
+        final Matcher matcher = filter.matcher();
+        assertTrue(matcher.matches(entry).toBoolean());
+    }
+
+    @Test
+    public void testLessThanFalse1() throws Exception {
+        final Filter filter = Filter.lessThan("cn", "bbb");
+        final Entry entry = new LinkedHashMapEntry("dn: cn=bbb", "objectclass: top", "cn: bbb");
+        final Matcher matcher = filter.matcher();
+        assertFalse(matcher.matches(entry).toBoolean());
+    }
+
+    @Test
+    public void testLessThanFalse2() throws Exception {
+        final Filter filter = Filter.lessThan("cn", "bbb");
+        final Entry entry = new LinkedHashMapEntry("dn: cn=ccc", "objectclass: top", "cn: ccc");
+        final Matcher matcher = filter.matcher();
+        assertFalse(matcher.matches(entry).toBoolean());
+    }
+
+    @Test
+    public void testLessThanTrue() throws Exception {
+        final Filter filter = Filter.lessThan("cn", "bbb");
+        final Entry entry = new LinkedHashMapEntry("dn: cn=aaa", "objectclass: top", "cn: aaa");
+        final Matcher matcher = filter.matcher();
+        assertTrue(matcher.matches(entry).toBoolean());
+    }
+
     /**
      * Tests the matcher.
      *

--
Gitblit v1.10.0