| File was renamed from sdk/src/com/sun/opends/sdk/util/ResultTransformer.java |
| | |
| | | |
| | | |
| | | |
| | | 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; |
| | | |
| | | |
| | | |
| | |
| | | * @param handler |
| | | * The outer result handler. |
| | | */ |
| | | protected ResultTransformer(ResultHandler<? super N> handler) |
| | | protected FutureResultTransformer(ResultHandler<? super N> handler) |
| | | { |
| | | this.handler = handler; |
| | | } |
| | |
| | | /** |
| | | * {@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); |
| | |
| | | * {@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(); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | 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(); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | 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; |
| | | |
| | | } |