delight.async.flow.CallbackAggregator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of delight-async Show documentation
Show all versions of delight-async Show documentation
Asynchronous utilities for Java and GWT applications. Includes a simple promise implementation for Java.
package delight.async.flow;
import delight.async.Value;
import delight.async.callbacks.ValueCallback;
import delight.async.helper.Aggregator;
import delight.functional.collections.CollectionsUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class CallbackAggregator implements Aggregator {
final int expected;
final ValueCallback> callback;
Value callbacksDefined;
Map resultsMap;
List results;
Value exceptionReceived;
Throwable exception;
@Override
public final ValueCallback createCallback() {
synchronized (callbacksDefined) {
final int callbackIdx = callbacksDefined.get();
callbacksDefined.set(callbackIdx + 1);
if (callbackIdx > expected - 1) {
throw new IllegalStateException("Too many callbacks defined.");
}
return new ValueCallback() {
@Override
public void onFailure(final Throwable t) {
synchronized (exceptionReceived) {
// t.printStackTrace();
// only trigger onFailure for first exception received
if (exceptionReceived.get() != null) {
return;
// throw new RuntimeException(
// "Another exception already received. Cannot send
// exception to callback.\n Previous exception: ["
// + exceptionReceived.get() + "]\n This exception:
// [" + t + "]",
// exceptionReceived.get());
}
exceptionReceived.set(t);
callback.onFailure(t);
}
}
@Override
public void onSuccess(final V value) {
boolean callWithMap = false;
synchronized (resultsMap) {
resultsMap.put(callbackIdx, value);
if (CollectionsUtils.isMapComplete(resultsMap, expected)) {
callWithMap = true;
}
}
// so that it's out of the synchronized block.
if (callWithMap) {
callback.onSuccess(CollectionsUtils.toOrderedList(resultsMap));
return;
}
boolean callWithList = false;
synchronized (results) {
results.add(value);
if (results.size() == expected) {
callWithList = true;
}
}
if (callWithList) {
callback.onSuccess(results);
return;
}
}
};
}
}
public CallbackAggregator(final int expected, final ValueCallback> callback) {
super();
this.expected = expected;
this.callback = callback;
this.exceptionReceived = new Value(null);
this.callbacksDefined = new Value(0);
this.results = new ArrayList(expected);
this.resultsMap = new HashMap();
this.exception = null;
if (expected == 0) {
callback.onSuccess(new ArrayList(0));
return;
}
}
}