All Downloads are FREE. Search and download functionalities are using the official Maven repository.

delight.async.flow.CallbackAggregator Maven / Gradle / Ivy

Go to download

Asynchronous utilities for Java and GWT applications. Includes a simple promise implementation for Java.

There is a newer version: 0.1.5
Show newest version
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;
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy