From 59562a8ce354ec5217bfd52ad930d80a618f0aed Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 15 Feb 2013 22:45:58 +0000
Subject: [PATCH] OPENDJ-757: Add Rest2LDAP gateway Servlet

---
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java          |    2 
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java                      |   41 +------------
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java                          |    6 +
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java          |    3 
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java    |   31 ++++------
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java |   45 ++++++--------
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java                         |   44 --------------
 7 files changed, 44 insertions(+), 128 deletions(-)

diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java
index e5a8b1b..ca0e939 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Config.java
@@ -16,24 +16,17 @@
 package org.forgerock.opendj.rest2ldap;
 
 import org.forgerock.opendj.ldap.DecodeOptions;
-import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.schema.Schema;
 
 /**
  * Common configuration options.
  */
 final class Config {
-
-    private final Filter falseFilter;
     private final DecodeOptions options;
     private final ReadOnUpdatePolicy readOnUpdatePolicy;
     private final Schema schema;
-    private final Filter trueFilter;
 
-    Config(final Filter trueFilter, final Filter falseFilter,
-            final ReadOnUpdatePolicy readOnUpdatePolicy, final Schema schema) {
-        this.trueFilter = trueFilter;
-        this.falseFilter = falseFilter;
+    Config(final ReadOnUpdatePolicy readOnUpdatePolicy, final Schema schema) {
         this.readOnUpdatePolicy = readOnUpdatePolicy;
         this.schema = schema;
         this.options = new DecodeOptions().setSchema(schema);
@@ -51,16 +44,6 @@
     }
 
     /**
-     * Returns the absolute false filter which should be used when querying the
-     * LDAP server.
-     *
-     * @return The absolute false filter.
-     */
-    public Filter falseFilter() {
-        return falseFilter;
-    }
-
-    /**
      * Returns the policy which should be used in order to read an entry before
      * it is deleted, or after it is added or modified.
      *
@@ -81,29 +64,4 @@
     public Schema schema() {
         return schema;
     }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("trueFilter=");
-        builder.append(trueFilter);
-        builder.append(", falseFilter=");
-        builder.append(falseFilter);
-        builder.append(", readOnUpdatePolicy=");
-        builder.append(readOnUpdatePolicy);
-        return builder.toString();
-    }
-
-    /**
-     * Returns the absolute true filter which should be used when querying the
-     * LDAP server.
-     *
-     * @return The absolute true filter.
-     */
-    public Filter trueFilter() {
-        return trueFilter;
-    }
 }
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java
index 8c0c88d..7f3354b 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/JSONConstantAttributeMapper.java
@@ -15,6 +15,7 @@
  */
 package org.forgerock.opendj.rest2ldap;
 
+import static org.forgerock.opendj.rest2ldap.Utils.toFilter;
 import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
 
 import java.util.Collections;
@@ -50,20 +51,18 @@
         final Filter filter;
         final JsonValue subValue = value.get(jsonAttribute);
         if (subValue == null) {
-            filter = c.getConfig().falseFilter();
+            filter = toFilter(false);
         } else if (type == FilterType.PRESENT) {
-            filter = c.getConfig().trueFilter();
+            filter = toFilter(true);
         } else if (value.isString() && valueAssertion instanceof String) {
             final String v1 = toLowerCase(value.asString());
             final String v2 = toLowerCase((String) valueAssertion);
             switch (type) {
             case CONTAINS:
-                filter = v1.contains(v2) ? c.getConfig().trueFilter() : c.getConfig().falseFilter();
+                filter = toFilter(v1.contains(v2));
                 break;
             case STARTS_WITH:
-                filter =
-                        v1.startsWith(v2) ? c.getConfig().trueFilter() : c.getConfig()
-                                .falseFilter();
+                filter = toFilter(v1.startsWith(v2));
                 break;
             default:
                 filter = compare(c, type, v1, v2);
@@ -79,7 +78,7 @@
             filter = compare(c, type, v1, v2);
         } else {
             // This attribute mapper is a candidate but it does not match.
-            filter = c.getConfig().falseFilter();
+            filter = toFilter(false);
         }
         h.handleResult(filter);
     }
@@ -100,28 +99,22 @@
         final Filter filter;
         switch (type) {
         case EQUAL_TO:
-            filter = v1.equals(v2) ? c.getConfig().trueFilter() : c.getConfig().falseFilter();
+            filter = toFilter(v1.equals(v2));
             break;
         case GREATER_THAN:
-            filter =
-                    v1.compareTo(v2) > 0 ? c.getConfig().trueFilter() : c.getConfig().falseFilter();
+            filter = toFilter(v1.compareTo(v2) > 0);
             break;
         case GREATER_THAN_OR_EQUAL_TO:
-            filter =
-                    v1.compareTo(v2) >= 0 ? c.getConfig().trueFilter() : c.getConfig()
-                            .falseFilter();
+            filter = toFilter(v1.compareTo(v2) >= 0);
             break;
         case LESS_THAN:
-            filter =
-                    v1.compareTo(v2) < 0 ? c.getConfig().trueFilter() : c.getConfig().falseFilter();
+            filter = toFilter(v1.compareTo(v2) < 0);
             break;
         case LESS_THAN_OR_EQUAL_TO:
-            filter =
-                    v1.compareTo(v2) <= 0 ? c.getConfig().trueFilter() : c.getConfig()
-                            .falseFilter();
+            filter = toFilter(v1.compareTo(v2) <= 0);
             break;
         default:
-            filter = c.getConfig().falseFilter(); // Not supported.
+            filter = toFilter(false); // Not supported.
             break;
         }
         return filter;
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java
index 284ce2b..4c55d64 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java
@@ -15,8 +15,11 @@
  */
 package org.forgerock.opendj.rest2ldap;
 
+import static org.forgerock.opendj.ldap.Filter.alwaysFalse;
+import static org.forgerock.opendj.ldap.Filter.alwaysTrue;
 import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.USE_READ_ENTRY_CONTROLS;
 import static org.forgerock.opendj.rest2ldap.Utils.accumulate;
+import static org.forgerock.opendj.rest2ldap.Utils.toFilter;
 import static org.forgerock.opendj.rest2ldap.Utils.transform;
 
 import java.util.Collection;
@@ -335,7 +338,7 @@
             @Override
             public void handleResult(final Filter ldapFilter) {
                 // Avoid performing a search if the filter could not be mapped or if it will never match.
-                if (ldapFilter == null || ldapFilter == c.getConfig().falseFilter()) {
+                if (ldapFilter == null || ldapFilter == alwaysFalse()) {
                     handler.handleResult(new QueryResult());
                 } else {
                     final ConnectionCompletionHandler<Result> outerHandler =
@@ -350,7 +353,9 @@
                                             getLDAPAttributes(c, request.getFieldFilters());
                                     final SearchRequest request =
                                             Requests.newSearchRequest(getBaseDN(c),
-                                                    SearchScope.SINGLE_LEVEL, ldapFilter,
+                                                    SearchScope.SINGLE_LEVEL, ldapFilter == Filter
+                                                            .alwaysTrue() ? Filter
+                                                            .objectClassPresent() : ldapFilter,
                                                     attributes);
                                     connection.searchAsync(request, null, innerHandler);
                                 }
@@ -531,18 +536,15 @@
                                                 final Iterator<Filter> i = value.iterator();
                                                 while (i.hasNext()) {
                                                     final Filter f = i.next();
-                                                    if (f == null) {
-                                                        // Filter component did not match any attribute mappers.
-                                                        return c.getConfig().falseFilter();
-                                                    } else if (f == c.getConfig().falseFilter()) {
-                                                        return c.getConfig().falseFilter();
-                                                    } else if (f == c.getConfig().trueFilter()) {
+                                                    if (f == null || f == alwaysFalse()) {
+                                                        return alwaysFalse();
+                                                    } else if (f == alwaysTrue()) {
                                                         i.remove();
                                                     }
                                                 }
                                                 switch (value.size()) {
                                                 case 0:
-                                                    return c.getConfig().trueFilter();
+                                                    return alwaysTrue();
                                                 case 1:
                                                     return value.get(0);
                                                 default:
@@ -559,8 +561,7 @@
                     @Override
                     public Void visitBooleanLiteralFilter(final ResultHandler<Filter> p,
                             final boolean value) {
-                        p.handleResult(value ? c.getConfig().trueFilter() : c.getConfig()
-                                .falseFilter());
+                        p.handleResult(toFilter(value));
                         return null;
                     }
 
@@ -627,13 +628,10 @@
                         subFilter.accept(this, transform(new Function<Filter, Filter, Void>() {
                             @Override
                             public Filter apply(final Filter value, final Void p) {
-                                if (value == null) {
-                                    // Filter component did not match any attribute mappers.
-                                    return c.getConfig().trueFilter();
-                                } else if (value == c.getConfig().falseFilter()) {
-                                    return c.getConfig().trueFilter();
-                                } else if (value == c.getConfig().trueFilter()) {
-                                    return c.getConfig().falseFilter();
+                                if (value == null || value == alwaysFalse()) {
+                                    return alwaysTrue();
+                                } else if (value == alwaysTrue()) {
+                                    return alwaysFalse();
                                 } else {
                                     return Filter.not(value);
                                 }
@@ -655,18 +653,15 @@
                                                 final Iterator<Filter> i = value.iterator();
                                                 while (i.hasNext()) {
                                                     final Filter f = i.next();
-                                                    if (f == null) {
-                                                        // Filter component did not match any attribute mappers.
+                                                    if (f == null || f == alwaysFalse()) {
                                                         i.remove();
-                                                    } else if (f == c.getConfig().falseFilter()) {
-                                                        i.remove();
-                                                    } else if (f == c.getConfig().trueFilter()) {
-                                                        return c.getConfig().trueFilter();
+                                                    } else if (f == alwaysTrue()) {
+                                                        return alwaysTrue();
                                                     }
                                                 }
                                                 switch (value.size()) {
                                                 case 0:
-                                                    return c.getConfig().falseFilter();
+                                                    return alwaysFalse();
                                                 case 1:
                                                     return value.get(0);
                                                 default:
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java
index 69d421e..d611b3c 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ObjectAttributeMapper.java
@@ -16,6 +16,7 @@
 package org.forgerock.opendj.rest2ldap;
 
 import static org.forgerock.opendj.rest2ldap.Utils.accumulate;
+import static org.forgerock.opendj.rest2ldap.Utils.toFilter;
 import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
 import static org.forgerock.opendj.rest2ldap.Utils.transform;
 
@@ -101,7 +102,7 @@
             // Either the filter targeted the entire object (i.e. it was "/"), or it targeted
             // an unrecognized attribute within the object. Either way, the filter will
             // never match.
-            h.handleResult(c.getConfig().falseFilter());
+            h.handleResult(toFilter(false));
         }
     }
 
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
index 909830d..29a091f 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
@@ -57,13 +57,11 @@
         private final List<Attribute> additionalLDAPAttributes = new LinkedList<Attribute>();
         private DN baseDN; // TODO: support template variables.
         private ConnectionFactory factory;
-        private Filter falseFilter = Filter.present("1.1");
         private MVCCStrategy mvccStrategy;
         private NameStrategy nameStrategy;
         private ReadOnUpdatePolicy readOnUpdatePolicy = USE_READ_ENTRY_CONTROLS;
         private final ObjectAttributeMapper rootMapper = new ObjectAttributeMapper();
         private Schema schema = Schema.getDefaultSchema();
-        private Filter trueFilter = Filter.objectClassPresent();
 
         Builder() {
             useEtagAttribute();
@@ -114,8 +112,7 @@
                 throw new IllegalStateException("No mappings provided");
             }
             return new LDAPCollectionResourceProvider(baseDN, rootMapper, factory, nameStrategy,
-                    mvccStrategy, new Config(trueFilter, falseFilter, readOnUpdatePolicy, schema),
-                    additionalLDAPAttributes);
+                    mvccStrategy, new Config(readOnUpdatePolicy, schema), additionalLDAPAttributes);
         }
 
         public Builder factory(final ConnectionFactory factory) {
@@ -125,19 +122,6 @@
         }
 
         /**
-         * Sets the absolute false filter which should be used when querying the
-         * LDAP server.
-         *
-         * @param filter
-         *            The absolute false filter.
-         * @return A reference to this builder.
-         */
-        public Builder falseFilter(final Filter filter) {
-            this.falseFilter = ensureNotNull(filter);
-            return this;
-        }
-
-        /**
          * Sets the policy which should be used in order to read an entry before
          * it is deleted, or after it is added or modified.
          *
@@ -165,19 +149,6 @@
             return this;
         }
 
-        /**
-         * Sets the absolute true filter which should be used when querying the
-         * LDAP server.
-         *
-         * @param filter
-         *            The absolute true filter.
-         * @return A reference to this builder.
-         */
-        public Builder trueFilter(final Filter filter) {
-            this.trueFilter = ensureNotNull(filter);
-            return this;
-        }
-
         public Builder useClientDNNaming(final AttributeType attribute) {
             this.nameStrategy = new DNNameStrategy(attribute);
             return this;
@@ -308,8 +279,8 @@
 
         @Override
         SearchRequest createSearchRequest(final Context c, final DN baseDN, final String resourceId) {
-            return newSearchRequest(baseDN.child(rdn(resourceId)), SearchScope.BASE_OBJECT, c
-                    .getConfig().trueFilter());
+            return newSearchRequest(baseDN.child(rdn(resourceId)), SearchScope.BASE_OBJECT, Filter
+                    .objectClassPresent());
         }
 
         @Override
@@ -406,12 +377,6 @@
      *         ...
      *     },
      *
-     *     // Additional options (all are optional).
-     *     "options" : {
-     *         "trueFilter" : "(objectClass=*)",
-     *         "falseFilter" : "(1.1=*)",
-     *     },
-     *
      *     // The base DN beneath which LDAP entries are to be found.
      *     "baseDN" : "ou=people,dc=example,dc=com",
      *
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
index 9360506..266f8e1 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
@@ -183,7 +183,7 @@
             h.handleResult(toFilter(c, type, ldapAttributeName.toString(), valueAssertion));
         } else {
             // This attribute mapper does not support partial filtering.
-            h.handleResult(c.getConfig().falseFilter());
+            h.handleResult(toFilter(false));
         }
     }
 
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
index 19d9a38..2f6cc94 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -214,6 +214,10 @@
         return JSON_TO_BYTESTRING;
     }
 
+    static Filter toFilter(final boolean value) {
+        return value ? Filter.alwaysTrue() : Filter.alwaysFalse();
+    }
+
     static Filter toFilter(final Context c, final FilterType type, final String ldapAttribute,
             final Object valueAssertion) {
         final String v = String.valueOf(valueAssertion);
@@ -245,7 +249,7 @@
             break;
         case EXTENDED:
         default:
-            filter = c.getConfig().falseFilter(); // Not supported.
+            filter = toFilter(false); // Not supported.
             break;
         }
         return filter;

--
Gitblit v1.10.0