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