/** * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.eventsourcing; import lombok.Getter; import java.util.stream.Stream; /** * EventStream is a wrapper around <code>Event<Stream></code> that holds * a typed state. * * It is used for event generation and passing of state from {@link Command#events(Repository, LockProvider)} * to {@link Command#result(Object, Repository, LockProvider)} * * @param <S> state type */ public class EventStream<S> { @Getter private Stream<? extends Event> stream; @Getter private S state; EventStream(S state, Stream<? extends Event> stream) { this.state = state; this.stream = stream; } public static class Builder<S> { private final S state; private final Stream.Builder<Event> builder = Stream.builder(); public Builder(S state) { this.state = state; } public void accept(Event event) { builder.accept(event); } public Builder<S> add(Event event) { accept(event); return this; } public EventStream<S> build() { return new EventStream<>(state, builder.build()); } } /** * EventStream builder * * @param state state * @param <S> state type * @return */ public static <S> Builder<S> builder(S state) { return new Builder<>(state); } /** * EventStream builder with state set to <code>null</code> * * @param <S> state type * @return */ public static <S> Builder<S> builder() { return new Builder<>(null); } /** * @param <S> state type * @return empty event stream with state set to <code>null</code> */ public static <S> EventStream<S> empty() { return new EventStream<>(null, Stream.empty()); } /** * @param state state * @param <S> state type * @return empty event stream with a state */ public static <S> EventStream<S> empty(S state) { return new EventStream<>(state, Stream.empty()); } /** * @param state state * @param stream stream of events * @param <S> state type * @return event stream with a state and a stream */ public static <S> EventStream<S> ofWithState(S state, Stream<? extends Event> stream) { return new EventStream<>(state, stream); } /** * @param stream stream of events * @param <S> state type * @return event stream with a state set to <code>null</code> and a stream */ public static <S> EventStream<S> of(Stream<? extends Event> stream) { return new EventStream<>(null, stream); } /** * @param state state * @param event event * @param <S> state type * @return event stream with a state and a stream of one event */ public static <S> EventStream<S> ofWithState(S state, Event event) { return new EventStream<>(state, Stream.of(event)); } /** * @param event event * @param <S> state type * @return event stream with a state set to <code>null</code> and a stream of one event */ public static <S> EventStream<S> of(Event event) { return new EventStream<>(null, Stream.of(event)); } /** * @param state state * @param events events * @param <S> state type * @return event stream with a state and a stream of multiple events */ public static <S> EventStream<S> ofWithState(S state, Event ...events) { return new EventStream<>(state, Stream.of(events)); } /** * * @param events events * @param <S> state type * @return event stream with a state set to <code>null</code> and a stream of multiple events */ public static <S> EventStream<S> of(Event ...events) { return new EventStream<>(null, Stream.of(events)); } }