From 688ad011aac30561e68c16fcc26d05bcaf6a742f Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 13 Feb 2013 10:28:47 +0000
Subject: [PATCH] Refactoring work for OPENDJ-687: Implement REST to LDAP adapter for SDK

---
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java                  |   25 ++++++
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPCollectionResourceProvider.java |   18 ---
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java                           |   50 ++++++++++++
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java                  |   16 +++
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java                   |   97 ++++++++++++++++++++++++
 5 files changed, 188 insertions(+), 18 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
index 28bfeed..88ea33e 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2012 ForgeRock AS
+ *      Portions copyright 2011-2013 ForgeRock AS
  */
 
 package com.forgerock.opendj.util;
@@ -57,6 +57,7 @@
 import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.responses.SearchResultReference;
+import org.forgerock.opendj.ldif.ChangeRecord;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
 /**
@@ -139,6 +140,28 @@
      * The default implementation is to delegate.
      */
     @Override
+    public Result applyChange(ChangeRecord request) throws ErrorResultException {
+        return connection.applyChange(request);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default implementation is to delegate.
+     */
+    @Override
+    public FutureResult<Result> applyChangeAsync(final ChangeRecord request,
+            final IntermediateResponseHandler intermediateResponseHandler,
+            final ResultHandler<? super Result> resultHandler) {
+        return connection.applyChangeAsync(request, intermediateResponseHandler, resultHandler);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default implementation is to delegate.
+     */
+    @Override
     public void addConnectionEventListener(final ConnectionEventListener listener) {
         connection.addConnectionEventListener(listener);
     }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
index 09c44b5..e898072 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
@@ -36,7 +36,11 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+import org.forgerock.opendj.ldap.requests.AddRequest;
+import org.forgerock.opendj.ldap.requests.DeleteRequest;
 import org.forgerock.opendj.ldap.requests.ExtendedRequest;
+import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
+import org.forgerock.opendj.ldap.requests.ModifyRequest;
 import org.forgerock.opendj.ldap.requests.Requests;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
 import org.forgerock.opendj.ldap.responses.BindResult;
@@ -46,6 +50,8 @@
 import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.responses.SearchResultReference;
+import org.forgerock.opendj.ldif.ChangeRecord;
+import org.forgerock.opendj.ldif.ChangeRecordVisitor;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
 import com.forgerock.opendj.util.Validator;
@@ -206,6 +212,47 @@
 
     }
 
+    // Visitor used for processing synchronous change requests.
+    private static final ChangeRecordVisitor<Object, Connection> SYNC_VISITOR =
+            new ChangeRecordVisitor<Object, Connection>() {
+
+                @Override
+                public Object visitChangeRecord(final Connection p, final AddRequest change) {
+                    try {
+                        return p.add(change);
+                    } catch (final ErrorResultException e) {
+                        return e;
+                    }
+                }
+
+                @Override
+                public Object visitChangeRecord(final Connection p, final DeleteRequest change) {
+                    try {
+                        return p.delete(change);
+                    } catch (final ErrorResultException e) {
+                        return e;
+                    }
+                }
+
+                @Override
+                public Object visitChangeRecord(final Connection p, final ModifyRequest change) {
+                    try {
+                        return p.modify(change);
+                    } catch (final ErrorResultException e) {
+                        return e;
+                    }
+                }
+
+                @Override
+                public Object visitChangeRecord(final Connection p, final ModifyDNRequest change) {
+                    try {
+                        return p.modifyDN(change);
+                    } catch (final ErrorResultException e) {
+                        return e;
+                    }
+                }
+            };
+
     /**
      * Creates a new abstract connection.
      */
@@ -233,6 +280,56 @@
      * {@inheritDoc}
      */
     @Override
+    public Result applyChange(final ChangeRecord request) throws ErrorResultException {
+        final Object result = request.accept(SYNC_VISITOR, this);
+        if (result instanceof Result) {
+            return (Result) result;
+        } else {
+            throw (ErrorResultException) result;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FutureResult<Result> applyChangeAsync(final ChangeRecord request,
+            final IntermediateResponseHandler intermediateResponseHandler,
+            final ResultHandler<? super Result> resultHandler) {
+        final ChangeRecordVisitor<FutureResult<Result>, Connection> visitor =
+                new ChangeRecordVisitor<FutureResult<Result>, Connection>() {
+
+                    @Override
+                    public FutureResult<Result> visitChangeRecord(final Connection p,
+                            final AddRequest change) {
+                        return p.addAsync(change, intermediateResponseHandler, resultHandler);
+                    }
+
+                    @Override
+                    public FutureResult<Result> visitChangeRecord(final Connection p,
+                            final DeleteRequest change) {
+                        return p.deleteAsync(change, intermediateResponseHandler, resultHandler);
+                    }
+
+                    @Override
+                    public FutureResult<Result> visitChangeRecord(final Connection p,
+                            final ModifyRequest change) {
+                        return p.modifyAsync(change, intermediateResponseHandler, resultHandler);
+                    }
+
+                    @Override
+                    public FutureResult<Result> visitChangeRecord(final Connection p,
+                            final ModifyDNRequest change) {
+                        return p.modifyDNAsync(change, intermediateResponseHandler, resultHandler);
+                    }
+                };
+        return request.accept(visitor, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public BindResult bind(final String name, final char[] password) throws ErrorResultException {
         return bind(Requests.newSimpleBindRequest(name, password));
     }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
index 6a727a2..64c3c35 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2012 ForgeRock AS
+ *      Portions copyright 2011-2013 ForgeRock AS
  */
 
 package org.forgerock.opendj.ldap;
@@ -48,6 +48,7 @@
 import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.responses.SearchResultReference;
+import org.forgerock.opendj.ldif.ChangeRecord;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
 /**
@@ -294,6 +295,53 @@
     void addConnectionEventListener(ConnectionEventListener listener);
 
     /**
+     * Applies the provided change request to the Directory Server.
+     *
+     * @param request
+     *            The change request.
+     * @return The result of the operation.
+     * @throws ErrorResultException
+     *             If the result code indicates that the request failed for some
+     *             reason.
+     * @throws UnsupportedOperationException
+     *             If this connection does not support the provided change
+     *             request.
+     * @throws IllegalStateException
+     *             If this connection has already been closed, i.e. if
+     *             {@code isClosed() == true}.
+     * @throws NullPointerException
+     *             If {@code request} was {@code null}.
+     */
+    Result applyChange(ChangeRecord request) throws ErrorResultException;
+
+    /**
+     * Asynchronously applies the provided change request to the Directory
+     * Server.
+     *
+     * @param request
+     *            The change request.
+     * @param intermediateResponseHandler
+     *            An intermediate response handler which can be used to process
+     *            any intermediate responses as they are received, may be
+     *            {@code null}.
+     * @param resultHandler
+     *            A result handler which can be used to asynchronously process
+     *            the operation result when it is received, may be {@code null}.
+     * @return A future representing the result of the operation.
+     * @throws UnsupportedOperationException
+     *             If this connection does not support the provided change
+     *             request.
+     * @throws IllegalStateException
+     *             If this connection has already been closed, i.e. if
+     *             {@code isClosed() == true}.
+     * @throws NullPointerException
+     *             If {@code request} was {@code null}.
+     */
+    FutureResult<Result> applyChangeAsync(ChangeRecord request,
+            IntermediateResponseHandler intermediateResponseHandler,
+            ResultHandler<? super Result> resultHandler);
+
+    /**
      * Authenticates to the Directory Server using the provided bind request.
      *
      * @param request
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
index 2104786..df6795b 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2012 ForgeRock AS
+ *      Portions copyright 2011-2013 ForgeRock AS
  */
 
 package org.forgerock.opendj.ldap;
@@ -56,6 +56,7 @@
 import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.responses.SearchResultReference;
+import org.forgerock.opendj.ldif.ChangeRecord;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
 import com.forgerock.opendj.util.AsynchronousFutureResult;
@@ -192,6 +193,19 @@
         }
 
         @Override
+        public Result applyChange(ChangeRecord request) throws ErrorResultException {
+            return checkState().applyChange(request);
+        }
+
+        @Override
+        public FutureResult<Result> applyChangeAsync(final ChangeRecord request,
+                final IntermediateResponseHandler intermediateResponseHandler,
+                final ResultHandler<? super Result> resultHandler) {
+            return checkState().applyChangeAsync(request, intermediateResponseHandler,
+                    resultHandler);
+        }
+
+        @Override
         public BindResult bind(final BindRequest request) throws ErrorResultException {
             return checkState().bind(request);
         }
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 1c6b825..c0c4cd2 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
@@ -72,13 +72,12 @@
 import org.forgerock.opendj.ldap.controls.PostReadResponseControl;
 import org.forgerock.opendj.ldap.controls.PreReadResponseControl;
 import org.forgerock.opendj.ldap.requests.AddRequest;
-import org.forgerock.opendj.ldap.requests.ModifyRequest;
-import org.forgerock.opendj.ldap.requests.Request;
 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.opendj.ldif.ChangeRecord;
 
 /**
  * A {@code CollectionResourceProvider} implementation which maps a JSON
@@ -727,7 +726,7 @@
         return resultHandler;
     }
 
-    private void applyUpdate(final Context c, final Request request,
+    private void applyUpdate(final Context c, final ChangeRecord request,
             final ResultHandler<Resource> handler) {
         final org.forgerock.opendj.ldap.ResultHandler<Result> resultHandler =
                 postUpdateHandler(c, handler);
@@ -738,18 +737,7 @@
                     public void handleResult(final Connection connection) {
                         final RequestCompletionHandler<Result> innerHandler =
                                 new RequestCompletionHandler<Result>(connection, resultHandler);
-                        // FIXME: simplify this once we have Connection#applyChange()
-                        if (request instanceof AddRequest) {
-                            connection.addAsync((AddRequest) request, null, innerHandler);
-                        } else if (request instanceof org.forgerock.opendj.ldap.requests.DeleteRequest) {
-                            connection.deleteAsync(
-                                    (org.forgerock.opendj.ldap.requests.DeleteRequest) request,
-                                    null, innerHandler);
-                        } else if (request instanceof ModifyRequest) {
-                            connection.modifyAsync((ModifyRequest) request, null, innerHandler);
-                        } else {
-                            throw new IllegalStateException();
-                        }
+                        connection.applyChangeAsync(request, null, innerHandler);
                     }
                 };
         factory.getConnectionAsync(outerHandler);

--
Gitblit v1.10.0