package com.zillabyte.motherbrain.flow; import java.util.Collection; import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; import com.zillabyte.motherbrain.flow.components.ComponentInput; import com.zillabyte.motherbrain.flow.components.ComponentOutput; import com.zillabyte.motherbrain.flow.config.OperationConfig; import com.zillabyte.motherbrain.flow.graph.FlowGraph; import com.zillabyte.motherbrain.flow.operations.AggregationOperation; import com.zillabyte.motherbrain.flow.operations.Function; import com.zillabyte.motherbrain.flow.operations.GroupBy; import com.zillabyte.motherbrain.flow.operations.Join; import com.zillabyte.motherbrain.flow.operations.JoinType; import com.zillabyte.motherbrain.flow.operations.Operation; import com.zillabyte.motherbrain.flow.operations.Sink; import com.zillabyte.motherbrain.flow.operations.Source; import com.zillabyte.motherbrain.flow.operations.decorators.RemoveFields; import com.zillabyte.motherbrain.flow.operations.decorators.RenameFields; import com.zillabyte.motherbrain.flow.operations.decorators.RetainFields; @NonNullByDefault public abstract class StreamBuilder { /**** * * @author jake * */ public final static class AppStreamBuilder extends StreamBuilder { AppStreamBuilder(App flow, final Operation last, final String streamName) { super(flow, last, streamName); } public StreamBuilder sink(Sink fn) throws FlowCompilationException { _graph.connect(_last, fn, _streamName); _last = fn; fn.setContainerFlow(_flow); return this; } @Override public AppStreamBuilder extend(String streamName) { return new AppStreamBuilder((App)_flow, this._last, streamName); } } /**** * * @author jake * */ public final static class ComponentStreamBuilder extends StreamBuilder { public ComponentStreamBuilder(Component flow, final Operation last, final String streamName) { super(flow, last, streamName); } public StreamBuilder outputs(ComponentOutput fn) throws FlowCompilationException { _graph.connect(_last, fn, _streamName); _last = fn; fn.setContainerFlow(_flow); return this; } @Override public StreamBuilder.ComponentStreamBuilder extend(String streamName) { return new ComponentStreamBuilder((Component)this._flow, this._last, streamName); } } public static final AppStreamBuilder makeAppStreamBuilder(final App flow, final Source source, final String streamName) { return new AppStreamBuilder(flow, source, streamName); } public static final AppStreamBuilder makeAppStreamBuilder(final App flow, final ComponentOutput source, final String streamName) { return new AppStreamBuilder(flow, source, streamName); } public static final ComponentStreamBuilder makeComponentStreamBuilder(final Component flow, final ComponentInput consumer, final String streamName) { return new ComponentStreamBuilder(flow, consumer, streamName); } public static final ComponentStreamBuilder makeComponentStreamBuilder(final Component flow, final ComponentOutput source, final String streamName) { return new ComponentStreamBuilder(flow, source, streamName); } protected FlowGraph _graph; protected Operation _last; protected String _streamName; protected Flow _flow; public StreamBuilder(Flow flow, Operation source, String streamName) { _graph = flow.graph(); _flow = flow; _last = source; _streamName = streamName; source.setContainerFlow(flow); if (_flow == null) throw new NullPointerException("flow has not been set"); } public StreamBuilder each(Function fn) throws FlowCompilationException { _graph.connect(_last, fn, _streamName); _last = fn; fn.setContainerFlow(_flow); return this; } public StreamBuilder each(Function fn, Boolean loopBack, Integer maxIter) throws FlowCompilationException { _graph.connect(_last, fn, _streamName, loopBack, maxIter); _last = fn; fn.setContainerFlow(_flow); return this; } public StreamBuilder renameFields(Map<String, String> rename) { _last.addEmitDecorator(_streamName, new RenameFields(rename)); return this; } public StreamBuilder removeFields(Collection<String> remove) { _last.addEmitDecorator(_streamName, new RemoveFields(remove)); return this; } public StreamBuilder retainFields(Collection<String> retain) { _last.addEmitDecorator(_streamName, new RetainFields(retain)); return this; } public StreamBuilder aggregate(AggregationOperation fn) throws FlowCompilationException { _graph.connect(_last, fn, _streamName); _last = fn; fn.setContainerFlow(_flow); return this; } public StreamBuilder groupBy(GroupBy fn) throws FlowCompilationException { return aggregate(fn); } public StreamBuilder joinWith(StreamBuilder rawRhs, Join join) throws FlowCompilationException { StreamBuilder rhs = rawRhs; _graph.connect(_last, join, _streamName); _graph.connect(rhs._last, join, rhs._streamName); _last = join; join.setContainerFlow(_flow); return this; } public StreamBuilder joinWith(StreamBuilder rhs, Fields lhsJoinFields, Fields rhsJoinFields, JoinType joinType, OperationConfig config) throws FlowCompilationException { return joinWith(rhs, new Join("join." + this._streamName + "-" + rhs._streamName, this._streamName, lhsJoinFields, rhs.streamName(), rhsJoinFields, joinType, config)); } private String streamName() { return this._streamName; } public StreamBuilder joinWith(StreamBuilder rhs, Fields lhsJoinFields, Fields rhsJoinFields) throws FlowCompilationException { return joinWith(rhs, lhsJoinFields, rhsJoinFields, JoinType.INNER, OperationConfig.createEmpty()); } public StreamBuilder joinWith(StreamBuilder rhs, Fields joinFields) throws FlowCompilationException { return joinWith(rhs, joinFields, joinFields); } public StreamBuilder joinWith(StreamBuilder rhs, Fields fields, JoinType type) throws FlowCompilationException { return joinWith(rhs, fields, fields, type, OperationConfig.createEmpty()); } public String name() { return this._streamName; } public Operation last() { return this._last; } public abstract StreamBuilder extend(String streamName); }