From 47e492a9ccde3af37512cdde9cd13d3c388f4ebe Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 15 Dec 2009 21:58:47 +0000
Subject: [PATCH] Various changes:

---
 opendj-sdk/sdk/src/com/sun/opends/sdk/util/FutureResultTransformer.java |  199 +++++++++++++++++++++++++++++++------------------
 1 files changed, 124 insertions(+), 75 deletions(-)

diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/util/ResultTransformer.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/util/FutureResultTransformer.java
similarity index 60%
rename from opendj-sdk/sdk/src/com/sun/opends/sdk/util/ResultTransformer.java
rename to opendj-sdk/sdk/src/com/sun/opends/sdk/util/FutureResultTransformer.java
index 80dc5fa..04eb558 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/util/ResultTransformer.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/util/FutureResultTransformer.java
@@ -29,62 +29,39 @@
 
 
 
-import java.util.concurrent.CancellationException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 import org.opends.sdk.ErrorResultException;
-import org.opends.sdk.ResultFuture;
+import org.opends.sdk.FutureResult;
 import org.opends.sdk.ResultHandler;
 
 
 
 /**
- * A base class which can be used to transform the result of an inner
- * asynchronous request to another result type.
+ * An implementation of the {@code FutureResult} interface which
+ * transforms the result of an asynchronous operation from one type to
+ * another. The implementation ensures that the transformed is computed
+ * only once.
  *
  * @param <M>
  *          The type of the inner result.
  * @param <N>
  *          The type of the outer result.
  */
-public abstract class ResultTransformer<M, N> implements
-    ResultFuture<N>, ResultHandler<M>
+public abstract class FutureResultTransformer<M, N> implements
+    FutureResult<N>, ResultHandler<M>
 {
 
   private final ResultHandler<? super N> handler;
 
-  private volatile ResultFuture<M> future = null;
+  private volatile FutureResult<M> future = null;
 
+  // These do not need to be volatile since the future acts as a memory
+  // barrier.
+  private N transformedResult = null;
 
-
-  /**
-   * Sets the inner future for this result transformer. This must be
-   * done before this future is published.
-   *
-   * @param future
-   *          The inner future.
-   */
-  public final void setResultFuture(ResultFuture<M> future)
-  {
-    this.future = future;
-  }
-
-
-
-  /**
-   * Transforms the inner result to an outer result, possibly throwing
-   * an {@code ErrorResultException} if the transformation fails for
-   * some reason.
-   *
-   * @param result
-   *          The inner result.
-   * @return The outer result.
-   * @throws ErrorResultException
-   *           If the transformation fails for some reason.
-   */
-  protected abstract N transformResult(M result)
-      throws ErrorResultException;
+  private ErrorResultException transformedErrorResult = null;
 
 
 
@@ -95,7 +72,7 @@
    * @param handler
    *          The outer result handler.
    */
-  protected ResultTransformer(ResultHandler<? super N> handler)
+  protected FutureResultTransformer(ResultHandler<? super N> handler)
   {
     this.handler = handler;
   }
@@ -105,39 +82,6 @@
   /**
    * {@inheritDoc}
    */
-  public final void handleErrorResult(ErrorResultException error)
-  {
-    if (handler != null)
-    {
-      handler.handleErrorResult(error);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public final void handleResult(M result)
-  {
-    if (handler != null)
-    {
-      try
-      {
-        handler.handleResult(transformResult(result));
-      }
-      catch (ErrorResultException e)
-      {
-        handler.handleErrorResult(e);
-      }
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
   public final boolean cancel(boolean mayInterruptIfRunning)
   {
     return future.cancel(mayInterruptIfRunning);
@@ -149,9 +93,12 @@
    * {@inheritDoc}
    */
   public final N get() throws ErrorResultException,
-      CancellationException, InterruptedException
+      InterruptedException
   {
-    return transformResult(future.get());
+    future.get();
+
+    // The handlers are guaranteed to have been invoked at this point.
+    return get0();
   }
 
 
@@ -161,9 +108,12 @@
    */
   public final N get(long timeout, TimeUnit unit)
       throws ErrorResultException, TimeoutException,
-      CancellationException, InterruptedException
+      InterruptedException
   {
-    return transformResult(future.get(timeout, unit));
+    future.get(timeout, unit);
+
+    // The handlers are guaranteed to have been invoked at this point.
+    return get0();
   }
 
 
@@ -171,9 +121,48 @@
   /**
    * {@inheritDoc}
    */
-  public final int getMessageID()
+  public final int getRequestID()
   {
-    return future.getMessageID();
+    return future.getRequestID();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public final void handleErrorResult(ErrorResultException error)
+  {
+    transformedErrorResult = transformErrorResult(error);
+    if (handler != null)
+    {
+      handler.handleErrorResult(transformedErrorResult);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public final void handleResult(M result)
+  {
+    try
+    {
+      transformedResult = transformResult(result);
+      if (handler != null)
+      {
+        handler.handleResult(transformedResult);
+      }
+    }
+    catch (final ErrorResultException e)
+    {
+      transformedErrorResult = e;
+      if (handler != null)
+      {
+        handler.handleErrorResult(transformedErrorResult);
+      }
+    }
   }
 
 
@@ -196,4 +185,64 @@
     return future.isDone();
   }
 
+
+
+  /**
+   * Sets the inner future for this result transformer. This must be
+   * done before this future is published.
+   *
+   * @param future
+   *          The inner future.
+   */
+  public final void setFutureResult(FutureResult<M> future)
+  {
+    this.future = future;
+  }
+
+
+
+  private N get0() throws ErrorResultException
+  {
+    if (transformedErrorResult != null)
+    {
+      throw transformedErrorResult;
+    }
+    else
+    {
+      return transformedResult;
+    }
+  }
+
+
+
+  /**
+   * Transforms the inner error result to an outer error result. The
+   * default implementation is to return the inner error result.
+   *
+   * @param errorResult
+   *          The inner error result.
+   * @return The outer error result.
+   */
+  protected ErrorResultException transformErrorResult(
+      ErrorResultException errorResult)
+  {
+    return errorResult;
+  }
+
+
+
+  /**
+   * Transforms the inner result to an outer result, possibly throwing
+   * an {@code ErrorResultException} if the transformation fails for
+   * some reason.
+   *
+   * @param result
+   *          The inner result.
+   * @return The outer result.
+   * @throws ErrorResultException
+   *           If the transformation fails for some reason.
+   */
+  protected abstract N transformResult(M result)
+      throws ErrorResultException;
+
 }

--
Gitblit v1.10.0