package edu.uw.zookeeper.common; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import com.google.common.base.Optional; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import edu.uw.zookeeper.common.Promise; import edu.uw.zookeeper.common.PromiseTask; public class CallablePromiseTask<T extends Callable<Optional<V>>,V> extends PromiseTask<T,V> implements Runnable { public static <T extends Callable<Optional<V>>,V> CallablePromiseTask<T,V> run( T task, Promise<V> promise) { CallablePromiseTask<T,V> instance = create(task, promise); instance.run(); return instance; } public static <T extends Callable<Optional<V>>,V> CallablePromiseTask<T,V> create( T task, Promise<V> promise) { return new CallablePromiseTask<T,V>(task, promise); } public static <T extends Callable<Optional<V>> & ListenableFuture<?>,V> CallablePromiseTask<T,V> listen( T task, Promise<V> promise) { return listen(create(task, promise)); } public static <T extends Callable<Optional<V>> & ListenableFuture<?>,V> CallablePromiseTask<T,V> listenSynchronized( T task, Promise<V> promise) { return listen(createSynchronized(task, promise)); } public static <T extends Callable<Optional<V>> & ListenableFuture<?>,V> CallablePromiseTask<T,V> listen( CallablePromiseTask<T,V> task) { task.task().addListener(task, MoreExecutors.directExecutor()); return task; } public static <T extends Callable<Optional<V>>,V> SynchronizedCallablePromiseTask<T,V> runSynchronized( T task, Promise<V> promise) { SynchronizedCallablePromiseTask<T,V> instance = createSynchronized(task, promise); instance.run(); return instance; } public static <T extends Callable<Optional<V>>,V> SynchronizedCallablePromiseTask<T,V> createSynchronized( T task, Promise<V> promise) { return new SynchronizedCallablePromiseTask<T,V>(task, promise); } protected CallablePromiseTask( T task, Promise<V> promise) { super(task, promise); } @Override public void run() { try { if (!isDone()) { Optional<? extends V> result = task().call(); if (result.isPresent()) { set(result.get()); } } } catch (CancellationException e) { cancel(false); } catch (Throwable t) { setException(t); } } public static class SynchronizedCallablePromiseTask<T extends Callable<Optional<V>>,V> extends CallablePromiseTask<T,V> { protected SynchronizedCallablePromiseTask( T task, Promise<V> promise) { super(task, promise); } @Override public synchronized void run() { super.run(); } } }