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

com.github.rahulsom.grooves.queries.FunctionalTemporalQuery Maven / Gradle / Ivy

package com.github.rahulsom.grooves.queries;

import com.github.rahulsom.grooves.api.AggregateType;
import com.github.rahulsom.grooves.api.EventApplyOutcome;
import com.github.rahulsom.grooves.api.events.BaseEvent;
import com.github.rahulsom.grooves.api.snapshots.TemporalSnapshot;
import com.github.rahulsom.grooves.queries.internal.SimpleExecutor;
import com.github.rahulsom.grooves.queries.internal.SimpleQuery;
import org.jetbrains.annotations.NotNull;
import org.reactivestreams.Publisher;

import java.util.Date;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Util class to build Temporal Queries in a Functional Style.
 *
 * @param  The type of {@link AggregateT}'s id
 * @param    The aggregate over which the query executes
 * @param      The type of the {@link EventT}'s id field
 * @param        The type of the Event
 * @param   The type of the {@link SnapshotT}'s id field
 * @param     The type of the Snapshot
 * @param        A reference to the query type. Typically a self reference.
 *
 * @author Rahul Somasunderam
 */
public class FunctionalTemporalQuery<
        AggregateIdT,
        AggregateT extends AggregateType,
        EventIdT,
        EventT extends BaseEvent,
        SnapshotIdT,
        SnapshotT extends TemporalSnapshot,
        QueryT extends FunctionalTemporalQuery
        > implements
        TemporalQuerySupport,
        SimpleQuery {

    private BiFunction> snapshot;
    private Supplier emptySnapshot;
    private TriFunction> events;
    private Predicate applyEvents;
    private BiConsumer deprecator;
    private TriFunction> exceptionHandler;
    private BiFunction> eventHandler;

    @NotNull
    @Override
    public SimpleExecutor getExecutor() {
        return new SimpleExecutor();
    }

    @NotNull
    @Override
    public Publisher getSnapshot(Date maxTimestamp, @NotNull AggregateT aggregate) {
        return snapshot.apply(maxTimestamp, aggregate);
    }

    @NotNull
    @Override
    public SnapshotT createEmptySnapshot() {
        return emptySnapshot.get();
    }

    @Override
    public Publisher getUncomputedEvents(
            AggregateT aggregate, SnapshotT lastSnapshot, Date snapshotTime) {
        return events.apply(aggregate, lastSnapshot, snapshotTime);
    }

    @Override
    public boolean shouldEventsBeApplied(@NotNull SnapshotT snapshot) {
        return applyEvents.test(snapshot);
    }

    @Override
    public void addToDeprecates(
            @NotNull SnapshotT snapshot, @NotNull AggregateT deprecatedAggregate) {
        deprecator.accept(snapshot, deprecatedAggregate);
    }

    @NotNull
    @Override
    public Publisher onException(
            @NotNull Exception e, @NotNull SnapshotT snapshot, @NotNull EventT event) {
        return exceptionHandler.apply(e, snapshot, event);
    }

    @Override
    public Publisher applyEvent(EventT event, SnapshotT snapshot) {
        return eventHandler.apply(event, snapshot);
    }

    /**
     * Builder for {@link FunctionalTemporalQuery}.
     *
     * @param  The type of {@link AggregateT}'s id
     * @param    The aggregate over which the query executes
     * @param      The type of the {@link EventT}'s id field
     * @param        The type of the Event
     * @param   The type of the {@link SnapshotT}'s id field
     * @param     The type of the Snapshot
     * @param        A reference to the query type. Typically a self reference.
     */
    public static final class Builder<
            AggregateIdT,
            AggregateT extends AggregateType,
            EventIdT,
            EventT extends BaseEvent,
            SnapshotIdT,
            SnapshotT extends TemporalSnapshot,
            QueryT extends FunctionalTemporalQuery
            > {
        private BiFunction> snapshot;
        private Supplier emptySnapshot;
        private TriFunction> events;
        private Predicate applyEvents = snapshotT -> true;
        private BiConsumer deprecator;
        private TriFunction> exceptionHandler;
        private BiFunction> eventHandler;

        private Builder() {
        }

        public static <
                AggregateIdT,
                AggregateT extends AggregateType,
                EventIdT,
                EventT extends BaseEvent,
                SnapshotIdT,
                SnapshotT extends TemporalSnapshot,
                QueryT extends FunctionalTemporalQuery
                > Builder newBuilder() {
            return new Builder<>();
        }

        public Builder withSnapshot(BiFunction> snapshot) {
            this.snapshot = snapshot;
            return this;
        }

        public Builder withEmptySnapshot(Supplier emptySnapshot) {
            this.emptySnapshot = emptySnapshot;
            return this;
        }

        public Builder withEvents(TriFunction> events) {
            this.events = events;
            return this;
        }

        public Builder withApplyEvents(Predicate applyEvents) {
            this.applyEvents = applyEvents;
            return this;
        }

        public Builder withDeprecator(BiConsumer deprecator) {
            this.deprecator = deprecator;
            return this;
        }

        public Builder withExceptionHandler(
                        TriFunction> exceptionHandler) {
            this.exceptionHandler = exceptionHandler;
            return this;
        }

        public Builder withEventHandler(
                        BiFunction> eventHandler) {
            this.eventHandler = eventHandler;
            return this;
        }

        /**
         * Builds the Functional Temporal Query.
         */
        public TemporalQuery build() {
            FunctionalTemporalQuery functionalTemporalQuery = new FunctionalTemporalQuery<>();
            functionalTemporalQuery.deprecator = this.deprecator;
            functionalTemporalQuery.events = this.events;
            functionalTemporalQuery.exceptionHandler = this.exceptionHandler;
            functionalTemporalQuery.applyEvents = this.applyEvents;
            functionalTemporalQuery.snapshot = this.snapshot;
            functionalTemporalQuery.emptySnapshot = this.emptySnapshot;
            functionalTemporalQuery.eventHandler = this.eventHandler;
            return functionalTemporalQuery;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy