package com.buddy.sdk; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; class BuddyFuture<V> implements Future<V> { private boolean done; private V value; private Object SyncObj = new Object(); private class CallbackWrapper { public BuddyFutureCallback callback; public BuddyFuture<V> handle; } private List<CallbackWrapper> callbacks; public BuddyFuture() { } public BuddyFuture<V> continueWith(final BuddyFutureCallback<V> callback) { if (!done) { if (callbacks == null) { callbacks = new ArrayList<CallbackWrapper>(); } CallbackWrapper wrapper = new CallbackWrapper(); wrapper.callback = callback; wrapper.handle = new BuddyFuture<V>(); callbacks.add(wrapper); return wrapper.handle; } else { callback.completed(this); } return this; } public void setValue(V val) { synchronized (SyncObj) { value = val; if (!done) { done = true; if (callbacks != null) { for (CallbackWrapper cb : callbacks) { cb.handle.setValue(val); } } SyncObj.notify(); } } } @Override public boolean cancel(boolean mayInterruptIfRunning) { return false; } @Override public boolean isCancelled() { return false; } @Override public boolean isDone() { return done; } @Override public V get() throws InterruptedException, ExecutionException { synchronized (SyncObj) { if (!done) { SyncObj.wait(); } } return value; } @Override public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { if (!done) { synchronized (SyncObj) { SyncObj.wait(TimeUnit.MILLISECONDS.convert(timeout, unit)); } } return value; } }