com.github.rahulsom.grooves.queries.internal.Utils Maven / Gradle / Ivy
package com.github.rahulsom.grooves.queries.internal;
import com.github.rahulsom.grooves.api.AggregateType;
import com.github.rahulsom.grooves.api.events.BaseEvent;
import com.github.rahulsom.grooves.api.events.DeprecatedBy;
import com.github.rahulsom.grooves.api.snapshots.internal.BaseSnapshot;
import io.reactivex.Flowable;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import static io.reactivex.Flowable.*;
/**
* Utility objects and methods to help with Queries.
*
* @author Rahul Somasunderam
*/
public class Utils {
private static final Collector JOIN_EVENT_IDS =
Collectors.joining(", ");
private static final Collector JOIN_EVENTS =
Collectors.joining(",\n ", "[\n ", "\n]");
private Utils() {
}
/**
* Returns a snapshot or redirects to its deprecator.
*
* @param redirect Whether a redirect is desirable
* @param events The sequence of events
* @param it The snapshot
* @param redirectedSnapshot A computation for the redirected snapshot
* @param The type of the snapshot
* @param The type of the event
*
* @return An observable of a snapshot.
*/
@NotNull public static <
AggregateIdT,
AggregateT extends AggregateType,
EventIdT,
EventT extends BaseEvent,
SnapshotIdT,
SnapshotT extends BaseSnapshot
> Flowable returnOrRedirect(
boolean redirect,
@NotNull List events,
@NotNull SnapshotT it,
@NotNull Supplier> redirectedSnapshot) {
final EventT lastEvent =
events.isEmpty() ? null : events.get(events.size() - 1);
final boolean redirectToDeprecator =
lastEvent != null
&& lastEvent instanceof DeprecatedBy
&& redirect;
return fromPublisher(it.getDeprecatedByObservable())
.flatMap(deprecatedBy -> redirectToDeprecator ? redirectedSnapshot.get() : just(it))
.defaultIfEmpty(it);
}
/**
* Computes forward only events. This could mean cancelling out events with their reverts
* within a list, or sometimes, invoking the supplier of fallback events to get events.
*
* @param events The sequence of events
* @param executor The executor to use for processing events
* @param fallbackSnapshotAndEvents The fallback supplier
* @param The type of {@link AggregateT}'s id
* @param The type of Aggregate
* @param The type of {@link EventT}'s id
* @param The type of Event
* @param The type of {@link SnapshotT}'s id
* @param The type of Snapshot
* @param The type of Query
*
* @return an observable of forward only events
*/
@NotNull public static <
AggregateIdT,
AggregateT extends AggregateType,
EventIdT,
EventT extends BaseEvent,
SnapshotIdT,
SnapshotT extends BaseSnapshot,
QueryT extends BaseQuery
> Flowable getForwardOnlyEvents(
@NotNull List events,
@NotNull Executor executor,
@NotNull Supplier>>>
fallbackSnapshotAndEvents) {
return executor.applyReverts(fromIterable(events))
.toList()
.map(Flowable::just)
.onErrorReturn(throwable -> executor
.applyReverts(
fallbackSnapshotAndEvents.get()
.flatMap(it -> fromIterable(it.getSecond()))
)
.toList().toFlowable()
)
.toFlowable()
.flatMap(it -> it)
.flatMap(Flowable::fromIterable);
}
/**
* Turns a list of events into a readable log style string.
*
* @param events The list of events
* @param The type of events
*
* @return A String representation of events
*/
@NotNull public static String stringify(
@NotNull List events) {
return events.stream()
.map(EventT::toString)
.collect(JOIN_EVENTS);
}
/**
* Turns a list of events into a readable list of ids.
*
* @param events The list of events
* @param The type of events
*
* @return A String representation of events
*/
@NotNull static String ids(
@NotNull List events) {
return events.stream()
.map(i -> String.valueOf(i.getId()))
.collect(JOIN_EVENT_IDS);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy