mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
15.58.2009 388f25a9dc58704ea19a333ba9a28054d48590b1
sdk/src/com/sun/opends/sdk/util/FutureResultTransformer.java
File was renamed from sdk/src/com/sun/opends/sdk/util/ResultTransformer.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;
}