From b362d9da285a8dc1b86db29b945feb3bc245b03b Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 22 May 2012 16:28:29 +0000
Subject: [PATCH] Checkpoint basic GET functionality, including example gateway for testing.

---
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java |  169 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 143 insertions(+), 26 deletions(-)

diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
index 5b4e80d..b2ff886 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
@@ -18,50 +18,167 @@
 
 import java.util.Collection;
 
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.ConnectionFactory;
+import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.ErrorResultException;
+import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.ResultHandler;
 import org.forgerock.opendj.ldap.SearchResultHandler;
+import org.forgerock.opendj.ldap.SearchScope;
+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.ldap.responses.SearchResultReference;
 import org.forgerock.resource.provider.Context;
 
 /**
  *
  */
 public final class EntryContainer {
+    // FIXME: make this configurable, also allow use of DN.
+    private static final String UUID_ATTRIBUTE = "entryUUID";
 
-    /**
-     * @param entry
-     * @return
-     */
-    public String getIDFromEntry(final SearchResultEntry entry) {
-        // TODO Auto-generated method stub
-        return null;
+    // FIXME: make this configurable.
+    private static final String ETAG_ATTRIBUTE = "etag";
+
+    private final ConnectionFactory factory;
+    private final DN baseDN;
+
+    private abstract class AbstractRequestCompletionHandler<R, H extends ResultHandler<? super R>>
+            implements ResultHandler<R> {
+        final H resultHandler;
+        final Connection connection;
+
+        AbstractRequestCompletionHandler(final Connection connection, final H resultHandler) {
+            this.connection = connection;
+            this.resultHandler = resultHandler;
+        }
+
+        @Override
+        public final void handleErrorResult(final ErrorResultException error) {
+            connection.close();
+            resultHandler.handleErrorResult(error);
+        }
+
+        @Override
+        public final void handleResult(final R result) {
+            connection.close();
+            resultHandler.handleResult(result);
+        }
+
     }
 
-    /**
-     * @param context
-     * @param handler
-     */
+    private abstract class ConnectionCompletionHandler<R> implements ResultHandler<Connection> {
+        private final ResultHandler<? super R> resultHandler;
+
+        ConnectionCompletionHandler(final ResultHandler<? super R> resultHandler) {
+            this.resultHandler = resultHandler;
+        }
+
+        @Override
+        public final void handleErrorResult(final ErrorResultException error) {
+            resultHandler.handleErrorResult(error);
+        }
+
+        @Override
+        public abstract void handleResult(Connection connection);
+
+    }
+
+    private final class RequestCompletionHandler<R> extends
+            AbstractRequestCompletionHandler<R, ResultHandler<? super R>> {
+        RequestCompletionHandler(final Connection connection,
+                final ResultHandler<? super R> resultHandler) {
+            super(connection, resultHandler);
+        }
+    }
+
+    private final class SearchRequestCompletionHandler extends
+            AbstractRequestCompletionHandler<Result, SearchResultHandler> implements
+            SearchResultHandler {
+
+        SearchRequestCompletionHandler(final Connection connection,
+                final SearchResultHandler resultHandler) {
+            super(connection, resultHandler);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public final boolean handleEntry(final SearchResultEntry entry) {
+            return resultHandler.handleEntry(entry);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public final boolean handleReference(final SearchResultReference reference) {
+            return resultHandler.handleReference(reference);
+        }
+
+    }
+
+    public EntryContainer(DN baseDN, ConnectionFactory factory) {
+        this.baseDN = baseDN;
+        this.factory = factory;
+    }
+
     public void listEntries(final Context context, final SearchResultHandler handler) {
-        // TODO Auto-generated method stub
+        final ConnectionCompletionHandler<Result> outerHandler =
+                new ConnectionCompletionHandler<Result>(handler) {
 
+                    @Override
+                    public void handleResult(final Connection connection) {
+                        final SearchRequestCompletionHandler innerHandler =
+                                new SearchRequestCompletionHandler(connection, handler);
+                        SearchRequest request =
+                                Requests.newSearchRequest(baseDN, SearchScope.SINGLE_LEVEL, Filter
+                                        .objectClassPresent(), UUID_ATTRIBUTE, ETAG_ATTRIBUTE);
+                        connection.searchAsync(request, null, innerHandler);
+                    }
+
+                };
+
+        factory.getConnectionAsync(outerHandler);
     }
 
-    /**
-     * Reads the entry having the specified resource ID.
-     *
-     * @param c
-     *            The request context.
-     * @param id
-     *            The resource ID.
-     * @param attributes
-     *            The set of LDAP attributes to be read.
-     * @param h
-     *            The result handler.
-     */
     public void readEntry(final Context c, final String id, final Collection<String> attributes,
-            final ResultHandler<SearchResultEntry> h) {
-        // TODO Auto-generated method stub
+            final ResultHandler<SearchResultEntry> handler) {
+        final ConnectionCompletionHandler<SearchResultEntry> outerHandler =
+                new ConnectionCompletionHandler<SearchResultEntry>(handler) {
 
+                    @Override
+                    public void handleResult(final Connection connection) {
+                        final RequestCompletionHandler<SearchResultEntry> innerHandler =
+                                new RequestCompletionHandler<SearchResultEntry>(connection, handler);
+                        // FIXME: who is responsible for adding the UUID and
+                        // etag attributes to this search?
+                        String[] tmp = attributes.toArray(new String[attributes.size() + 2]);
+                        tmp[tmp.length - 2] = UUID_ATTRIBUTE;
+                        tmp[tmp.length - 1] = ETAG_ATTRIBUTE;
+
+                        SearchRequest request =
+                                Requests.newSearchRequest(baseDN, SearchScope.SINGLE_LEVEL, Filter
+                                        .equality(UUID_ATTRIBUTE, id), tmp);
+                        connection.searchSingleEntryAsync(request, innerHandler);
+                    }
+
+                };
+
+        factory.getConnectionAsync(outerHandler);
+    }
+
+    public String getIDFromEntry(final Entry entry) {
+        return entry.parseAttribute(UUID_ATTRIBUTE).asString();
+    }
+
+    public String getEtagFromEntry(final Entry entry) {
+        return entry.parseAttribute(ETAG_ATTRIBUTE).asString();
     }
 
 }

--
Gitblit v1.10.0