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

com.englishtown.promises.internal.handlers.Handler Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
package com.englishtown.promises.internal.handlers;

import com.englishtown.promises.HandlerState;
import com.englishtown.promises.State;
import com.englishtown.promises.Thenable;
import com.englishtown.promises.internal.Continuation;
import com.englishtown.promises.internal.PromiseHelper;

import java.util.function.BiFunction;
import java.util.function.Consumer;

import static com.englishtown.promises.HandlerState.PENDING;

/**
 * Abstract promise handler
 */
public abstract class Handler {

    protected final PromiseHelper helper;
    protected Handler handler;
    public Object context;
    protected HandlerState _state;

    public Handler(PromiseHelper helper) {
        this.helper = helper;
        _state = PENDING;
    }

    public void when(Continuation continuation) {
    }

    public void resolve(T x) {
    }

    public void resolve(Thenable x) {
    }

    public void reject(Throwable cause) {
    }

//    public void _notify(Object x) {} // TODO: added "_" to notify()

    public void _fatal(Object context) {
    }

    protected void _unreport() {
    }

    protected void _report(Object context) {
    }

    public State inspect() {
        return toPendingState();
    }

    /**
     * Creates a pending state snapshot
     *
     * @return {{state:'pending'}}
     */
    protected State toPendingState() {
        return new State<>(PENDING);
    }

    public HandlerState state() {
        return this._state;
    }

    /**
     * Recursively collapse handler chain to find the handler
     * nearest to the fully resolved value.
     *
     * @return handler nearest the fully resolved value
     */
    public Handler join() {
        Handler h = this;
        while (h.handler != null) {
            h = h.handler;
        }
        return h;
    }

    public void chain(Consumer fulfilled, Consumer rejected) {

        Continuation cont = new Continuation<>();
        cont.resolve = (x) -> {
        };
        cont.context = null;
        cont.fulfilled = fulfilled == null ? null : (x) -> {
            fulfilled.accept(x);
            return null;
        };
        cont.rejected = rejected == null ? null : (x) -> {
            rejected.accept(x);
            return null;
        };

        this.when(cont);
    }

    public void map(Consumer f, Handler to) {
        this.chain(f, to::reject);
    }

    public void catchError(Consumer f, Handler to) {
        this.chain(to::resolve, f);
    }

    public  void fold(Handler to, BiFunction> f, Thenable z) {
        this.join().map((x) -> {
            helper.getHandler(z).map((z1) -> {
                to.resolve(helper.tryCatchReject2(f, z1, x));
            }, to);
        }, to);
    }

}