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

com.github.rahulsom.grooves.queries.internal.JoinExecutor Maven / Gradle / Ivy

package com.github.rahulsom.grooves.queries.internal;

import com.github.rahulsom.grooves.api.AggregateType;
import com.github.rahulsom.grooves.api.events.*;
import com.github.rahulsom.grooves.api.snapshots.internal.BaseJoin;
import rx.Observable;

import java.util.List;

import static rx.Observable.just;

/**
 * Executes a query as a Join.
 *
 * @param          The Aggregate this join represents
 * @param            The type for the {@link EventT}'s id field
 * @param              The base type for events that apply to {@link AggregateT}
 * @param         The type for the join's id field
 * @param  The type for the id of the other aggregate that {@link AggregateT}
 *                             joins to
 * @param    The type for the other aggregate that {@link AggregateT} joins to
 * @param           The type of Snapshot that is computed
 * @param          The type of the Join Event
 * @param       The type of the disjoin event
 *
 * @author Rahul Somasunderam
 */
public class JoinExecutor<
        AggregateIdT,
        AggregateT extends AggregateType,
        EventIdT,
        EventT extends BaseEvent,
        JoinedAggregateIdT,
        JoinedAggregateT extends AggregateType,
        SnapshotIdT,
        SnapshotT extends BaseJoin,
        JoinEventT extends JoinEvent,
        DisjoinEventT extends DisjoinEvent,
        QueryT extends BaseQuery
        >
        extends
        QueryExecutor {

    private final Class classJoinE;
    private final Class classDisjoinE;

    public JoinExecutor(Class classJoinE, Class classDisjoinE) {
        this.classJoinE = classJoinE;
        this.classDisjoinE = classDisjoinE;
    }

    @Override
    public Observable applyEvents(
            QueryT query,
            SnapshotT initialSnapshot,
            Observable events,
            List> deprecatesList,
            AggregateT aggregate) {


        // s -> snapshotObservable
        return events.reduce(just(initialSnapshot), (s, event) -> s.flatMap(snapshot -> {
            if (!query.shouldEventsBeApplied(snapshot)) {
                return just(snapshot);
            } else {
                log.debug("     -> Applying Event: {}", event);

                if (event instanceof Deprecates) {
                    Deprecates deprecatesEvent =
                            (Deprecates) event;
                    return applyDeprecates(
                            deprecatesEvent, query, events, deprecatesList, aggregate);
                } else if (event instanceof DeprecatedBy) {
                    DeprecatedBy deprecatedByEvent =
                            (DeprecatedBy) event;
                    return applyDeprecatedBy(deprecatedByEvent, initialSnapshot);
                } else if (classJoinE.isAssignableFrom(event.getClass())) {
                    JoinEventT joinEvent = (JoinEventT) event;
                    return joinEvent
                            .getJoinAggregateObservable()
                            .map(joinedAggregate -> {
                                initialSnapshot.getJoinedIds().add(joinedAggregate.getId());
                                return initialSnapshot;
                            });
                } else if (classDisjoinE.isAssignableFrom(event.getClass())) {
                    DisjoinEventT disjoinEvent = (DisjoinEventT) event;
                    return disjoinEvent
                            .getJoinAggregateObservable()
                            .map(joinedAggregate -> {
                                initialSnapshot.getJoinedIds().remove(joinedAggregate.getId());
                                return initialSnapshot;
                            });
                } else {
                    return just(initialSnapshot);
                }
            }
        })).flatMap(it -> it);

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy