package com.tinkerpop.pipes.util;
import com.tinkerpop.pipes.FunctionPipe;
import com.tinkerpop.pipes.IdentityPipe;
import com.tinkerpop.pipes.Pipe;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.branch.CopySplitPipe;
import com.tinkerpop.pipes.branch.ExhaustMergePipe;
import com.tinkerpop.pipes.branch.FairMergePipe;
import com.tinkerpop.pipes.branch.IfThenElsePipe;
import com.tinkerpop.pipes.branch.LoopPipe;
import com.tinkerpop.pipes.filter.AndFilterPipe;
import com.tinkerpop.pipes.filter.BackFilterPipe;
import com.tinkerpop.pipes.filter.CyclicPathFilterPipe;
import com.tinkerpop.pipes.filter.DuplicateFilterPipe;
import com.tinkerpop.pipes.filter.ExceptFilterPipe;
import com.tinkerpop.pipes.filter.FilterFunctionPipe;
import com.tinkerpop.pipes.filter.OrFilterPipe;
import com.tinkerpop.pipes.filter.RandomFilterPipe;
import com.tinkerpop.pipes.filter.RangeFilterPipe;
import com.tinkerpop.pipes.filter.RetainFilterPipe;
import com.tinkerpop.pipes.sideeffect.AggregatePipe;
import com.tinkerpop.pipes.sideeffect.GroupByPipe;
import com.tinkerpop.pipes.sideeffect.GroupByReducePipe;
import com.tinkerpop.pipes.sideeffect.GroupCountFunctionPipe;
import com.tinkerpop.pipes.sideeffect.GroupCountPipe;
import com.tinkerpop.pipes.sideeffect.OptionalPipe;
import com.tinkerpop.pipes.sideeffect.SideEffectFunctionPipe;
import com.tinkerpop.pipes.sideeffect.SideEffectPipe;
import com.tinkerpop.pipes.sideeffect.StorePipe;
import com.tinkerpop.pipes.sideeffect.TablePipe;
import com.tinkerpop.pipes.sideeffect.TreePipe;
import com.tinkerpop.pipes.transform.GatherFunctionPipe;
import com.tinkerpop.pipes.transform.GatherPipe;
import com.tinkerpop.pipes.transform.MemoizePipe;
import com.tinkerpop.pipes.transform.OrderMapPipe;
import com.tinkerpop.pipes.transform.OrderPipe;
import com.tinkerpop.pipes.transform.PathPipe;
import com.tinkerpop.pipes.transform.ScatterPipe;
import com.tinkerpop.pipes.transform.SelectPipe;
import com.tinkerpop.pipes.transform.ShufflePipe;
import com.tinkerpop.pipes.transform.SideEffectCapPipe;
import com.tinkerpop.pipes.transform.TransformFunctionPipe;
import com.tinkerpop.pipes.transform.TransformPipe;
import com.tinkerpop.pipes.util.structures.AsMap;
import com.tinkerpop.pipes.util.structures.Pair;
import com.tinkerpop.pipes.util.structures.Row;
import com.tinkerpop.pipes.util.structures.Table;
import com.tinkerpop.pipes.util.structures.Tree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* PipesPipeline allows for the creation of a Pipeline using the fluent-pattern (http://en.wikipedia.org/wiki/Fluent_interface).
* Each Pipe in Pipes maintains a fluent method in PipesPipeline.
* Numerous method overloadings are provided in order to accommodate the various ways in which one logically thinks of a pipeline structure.
*
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@Deprecated
public class PipesPipeline<S, E> extends Pipeline<S, E> implements PipesFluentPipeline<S, E> {
private final AsMap asMap = new AsMap(this);
public PipesPipeline() {
super();
}
public PipesPipeline(final Object starts) {
super(new StartPipe(starts));
FluentUtility.setStarts(this, starts);
}
public <T> PipesPipeline<S, T> add(final Pipe<?, T> pipe) {
this.addPipe(pipe);
return (PipesPipeline<S, T>) this;
}
public PipesPipeline<S, ?> step(final PipeFunction function) {
return this.add(new FunctionPipe(function));
}
public <T> PipesPipeline<S, T> step(final Pipe<E, T> pipe) {
return this.add(pipe);
}
////////////////////
/// BRANCH PIPES ///
////////////////////
public PipesPipeline<S, ?> copySplit(final Pipe... pipes) {
return this.add(new CopySplitPipe(pipes));
}
public PipesPipeline<S, ?> exhaustMerge() {
return this.add(new ExhaustMergePipe((((MetaPipe) FluentUtility.getPreviousPipe(this)).getPipes())));
}
public PipesPipeline<S, ?> fairMerge() {
return this.add(new FairMergePipe((((MetaPipe) FluentUtility.getPreviousPipe(this)).getPipes())));
}
public PipesPipeline<S, ?> ifThenElse(final PipeFunction<E, Boolean> ifFunction, final PipeFunction<E, ?> thenFunction, final PipeFunction<E, ?> elseFunction) {
return this.add(new IfThenElsePipe(FluentUtility.prepareFunction(this.asMap, ifFunction), FluentUtility.prepareFunction(this.asMap, thenFunction), FluentUtility.prepareFunction(this.asMap, elseFunction)));
}
public PipesPipeline<S, E> loop(final int numberedStep, final PipeFunction<LoopPipe.LoopBundle<E>, Boolean> whileFunction) {
return this.add(new LoopPipe(new Pipeline(FluentUtility.removePreviousPipes(this, numberedStep)), FluentUtility.prepareFunction(this.asMap, whileFunction)));
}
public PipesPipeline<S, E> loop(final String namedStep, final PipeFunction<LoopPipe.LoopBundle<E>, Boolean> whileFunction) {
return this.add(new LoopPipe(new Pipeline(FluentUtility.removePreviousPipes(this, namedStep)), FluentUtility.prepareFunction(this.asMap, whileFunction)));
}
public PipesPipeline<S, E> loop(final int numberedStep, final PipeFunction<LoopPipe.LoopBundle<E>, Boolean> whileFunction, final PipeFunction<LoopPipe.LoopBundle<E>, Boolean> emitFunction) {
return this.add(new LoopPipe(new Pipeline(FluentUtility.removePreviousPipes(this, numberedStep)), FluentUtility.prepareFunction(this.asMap, whileFunction), FluentUtility.prepareFunction(this.asMap, emitFunction)));
}
public PipesPipeline<S, E> loop(final String namedStep, final PipeFunction<LoopPipe.LoopBundle<E>, Boolean> whileFunction, final PipeFunction<LoopPipe.LoopBundle<E>, Boolean> emitFunction) {
return this.add(new LoopPipe(new Pipeline(FluentUtility.removePreviousPipes(this, namedStep)), FluentUtility.prepareFunction(this.asMap, whileFunction), FluentUtility.prepareFunction(this.asMap, emitFunction)));
}
////////////////////
/// FILTER PIPES ///
////////////////////
public PipesPipeline<S, E> and(final Pipe<E, ?>... pipes) {
return this.add(new AndFilterPipe<E>(pipes));
}
public PipesPipeline<S, ?> back(final int numberedStep) {
return this.add(new BackFilterPipe(new Pipeline(FluentUtility.removePreviousPipes(this, numberedStep))));
}
public PipesPipeline<S, ?> back(final String namedStep) {
return this.add(new BackFilterPipe(new Pipeline(FluentUtility.removePreviousPipes(this, namedStep))));
}
public PipesPipeline<S, E> dedup() {
return this.add(new DuplicateFilterPipe<E>());
}
public PipesPipeline<S, E> dedup(final PipeFunction<E, ?> dedupFunction) {
return this.add(new DuplicateFilterPipe<E>(FluentUtility.prepareFunction(this.asMap, dedupFunction)));
}
public PipesPipeline<S, E> except(final Collection<E> collection) {
return this.add(new ExceptFilterPipe<E>(collection));
}
public PipesPipeline<S, E> except(final String... namedSteps) {
return this.add(new ExceptFilterPipe<E>(this.asMap, namedSteps));
}
public PipesPipeline<S, E> filter(final PipeFunction<E, Boolean> filterFunction) {
return this.add(new FilterFunctionPipe<E>(FluentUtility.prepareFunction(this.asMap, filterFunction)));
}
public PipesPipeline<S, E> or(final Pipe<E, ?>... pipes) {
return this.add(new OrFilterPipe<E>(pipes));
}
public PipesPipeline<S, E> random(final Double bias) {
return this.add(new RandomFilterPipe<E>(bias));
}
public PipesPipeline<S, E> range(final int low, final int high) {
return this.add(new RangeFilterPipe<E>(low, high));
}
public PipesPipeline<S, E> retain(final Collection<E> collection) {
return this.add(new RetainFilterPipe<E>(collection));
}
public PipesPipeline<S, E> retain(final String... namedSteps) {
return this.add(new RetainFilterPipe<E>(this.asMap, namedSteps));
}
public PipesPipeline<S, E> simplePath() {
return this.add(new CyclicPathFilterPipe<E>());
}
/////////////////////////
/// SIDE-EFFECT PIPES ///
/////////////////////////
public PipesPipeline<S, E> aggregate() {
return this.aggregate(new ArrayList<E>());
}
public PipesPipeline<S, E> aggregate(final Collection<E> aggregate) {
return this.add(new AggregatePipe<E>(aggregate));
}
public PipesPipeline<S, E> aggregate(final Collection aggregate, final PipeFunction<E, ?> aggregateFunction) {
return this.add(new AggregatePipe<E>(aggregate, FluentUtility.prepareFunction(this.asMap, aggregateFunction)));
}
public PipesPipeline<S, E> aggregate(final PipeFunction<E, ?> aggregateFunction) {
return this.aggregate(new ArrayList(), FluentUtility.prepareFunction(this.asMap, aggregateFunction));
}
public PipesPipeline<S, ?> optional(final int numberedStep) {
return this.add(new OptionalPipe(new Pipeline(FluentUtility.removePreviousPipes(this, numberedStep))));
}
public PipesPipeline<S, ?> optional(final String namedStep) {
return this.add(new OptionalPipe(new Pipeline(FluentUtility.removePreviousPipes(this, namedStep))));
}
public PipesPipeline<S, E> groupBy(final Map<?, List<?>> map, final PipeFunction keyFunction, final PipeFunction valueFunction) {
return this.add(new GroupByPipe(map, FluentUtility.prepareFunction(this.asMap, keyFunction), FluentUtility.prepareFunction(this.asMap, valueFunction)));
}
public PipesPipeline<S, E> groupBy(final PipeFunction keyFunction, final PipeFunction valueFunction) {
return this.add(new GroupByPipe(FluentUtility.prepareFunction(this.asMap, keyFunction), FluentUtility.prepareFunction(this.asMap, valueFunction)));
}
public PipesPipeline<S, E> groupBy(final Map reduceMap, final PipeFunction keyFunction, final PipeFunction valueFunction, final PipeFunction reduceFunction) {
return this.add(new GroupByReducePipe(reduceMap, FluentUtility.prepareFunction(this.asMap, keyFunction), FluentUtility.prepareFunction(this.asMap, valueFunction), FluentUtility.prepareFunction(this.asMap, reduceFunction)));
}
public PipesPipeline<S, E> groupBy(final PipeFunction keyFunction, final PipeFunction valueFunction, final PipeFunction reduceFunction) {
return this.add(new GroupByReducePipe(FluentUtility.prepareFunction(this.asMap, keyFunction), FluentUtility.prepareFunction(this.asMap, valueFunction), FluentUtility.prepareFunction(this.asMap, reduceFunction)));
}
public PipesPipeline<S, E> groupCount(final Map<?, Number> map, final PipeFunction keyFunction, final PipeFunction<Pair<?, Number>, Number> valueFunction) {
return this.add(new GroupCountFunctionPipe(map, FluentUtility.prepareFunction(this.asMap, keyFunction), FluentUtility.prepareFunction(this.asMap, valueFunction)));
}
public PipesPipeline<S, E> groupCount(final PipeFunction keyFunction, final PipeFunction<Pair<?, Number>, Number> valueFunction) {
return this.add(new GroupCountFunctionPipe(FluentUtility.prepareFunction(this.asMap, keyFunction), FluentUtility.prepareFunction(this.asMap, valueFunction)));
}
public PipesPipeline<S, E> groupCount(final Map<?, Number> map, final PipeFunction keyFunction) {
return this.add(new GroupCountFunctionPipe(map, FluentUtility.prepareFunction(this.asMap, keyFunction), null));
}
public PipesPipeline<S, E> groupCount(final PipeFunction keyFunction) {
return this.add(new GroupCountFunctionPipe(FluentUtility.prepareFunction(this.asMap, keyFunction), null));
}
public PipesPipeline<S, E> groupCount(final Map<?, Number> map) {
return this.add(new GroupCountPipe(map));
}
public PipesPipeline<S, E> groupCount() {
return this.add(new GroupCountPipe<E>());
}
public PipesPipeline<S, E> sideEffect(final PipeFunction<E, ?> sideEffectFunction) {
return this.add(new SideEffectFunctionPipe<E>(FluentUtility.prepareFunction(this.asMap, sideEffectFunction)));
}
public PipesPipeline<S, E> store(final Collection<E> storage) {
return this.add(new StorePipe<E>(storage));
}
public PipesPipeline<S, E> store(final Collection storage, final PipeFunction<E, ?> storageFunction) {
return this.add(new StorePipe<E>(storage, FluentUtility.prepareFunction(this.asMap, storageFunction)));
}
public PipesFluentPipeline<S, E> store(final PipeFunction<E, ?> storageFunction) {
return this.store(new ArrayList(), FluentUtility.prepareFunction(this.asMap, storageFunction));
}
public PipesPipeline<S, E> store() {
return this.store(new ArrayList<E>());
}
public PipesPipeline<S, E> table(final Table table, final Collection<String> stepNames, final PipeFunction... columnFunctions) {
return this.add(new TablePipe<E>(table, stepNames, FluentUtility.getAsPipes(this), FluentUtility.prepareFunctions(this.asMap, columnFunctions)));
}
public PipesPipeline<S, E> table(final Table table, final PipeFunction... columnFunctions) {
return this.add(new TablePipe<E>(table, null, FluentUtility.getAsPipes(this), FluentUtility.prepareFunctions(this.asMap, columnFunctions)));
}
public PipesPipeline<S, E> table(final PipeFunction... columnFunctions) {
return this.add(new TablePipe<E>(new Table(), null, FluentUtility.getAsPipes(this), FluentUtility.prepareFunctions(this.asMap, columnFunctions)));
}
public PipesPipeline<S, E> table(final Table table) {
return this.add(new TablePipe<E>(table, null, FluentUtility.getAsPipes(this)));
}
public PipesPipeline<S, E> table() {
return this.add(new TablePipe<E>(new Table(), null, FluentUtility.getAsPipes(this)));
}
public PipesPipeline<S, E> tree(final Tree tree, final PipeFunction... branchFunctions) {
return this.add(new TreePipe<E>(tree, FluentUtility.prepareFunctions(this.asMap, branchFunctions)));
}
public PipesPipeline<S, E> tree(final PipeFunction... branchFunctions) {
return this.add(new TreePipe<E>(FluentUtility.prepareFunctions(this.asMap, branchFunctions)));
}
///////////////////////
/// TRANSFORM PIPES ///
///////////////////////
public PipesPipeline<S, List> gather() {
return this.add(new GatherPipe());
}
public PipesPipeline<S, ?> gather(PipeFunction<List, ?> function) {
return this.add(new GatherFunctionPipe(FluentUtility.prepareFunction(this.asMap, function)));
}
public PipesPipeline<S, E> _() {
return this.add(new IdentityPipe<E>());
}
public PipesPipeline<S, E> memoize(final String namedStep) {
return this.add(new MemoizePipe(new Pipeline(FluentUtility.removePreviousPipes(this, namedStep))));
}
public PipesPipeline<S, E> memoize(final int numberedStep) {
return this.add(new MemoizePipe(new Pipeline(FluentUtility.removePreviousPipes(this, numberedStep))));
}
public PipesPipeline<S, E> memoize(final String namedStep, final Map map) {
return this.add(new MemoizePipe(new Pipeline(FluentUtility.removePreviousPipes(this, namedStep)), map));
}
public PipesPipeline<S, E> memoize(final int numberedStep, final Map map) {
return this.add(new MemoizePipe(new Pipeline(FluentUtility.removePreviousPipes(this, numberedStep)), map));
}
public PipesPipeline<S, E> order() {
return this.add(new OrderPipe());
}
public PipesPipeline<S, E> order(TransformPipe.Order order) {
return this.add(new OrderPipe(order));
}
public PipesPipeline<S, E> order(final PipeFunction<Pair<E, E>, Integer> compareFunction) {
return this.add(new OrderPipe(FluentUtility.prepareFunction(this.asMap, compareFunction)));
}
public PipesPipeline<S, List> path(final PipeFunction... pathFunctions) {
return this.add(new PathPipe<Object>(FluentUtility.prepareFunctions(this.asMap, pathFunctions)));
}
public PipesPipeline<S, Row> select(final Collection<String> stepNames, final PipeFunction... columnFunctions) {
return this.add(new SelectPipe(stepNames, FluentUtility.getAsPipes(this), FluentUtility.prepareFunctions(this.asMap, columnFunctions)));
}
public PipesPipeline<S, Row> select(final PipeFunction... columnFunctions) {
return this.add(new SelectPipe(null, FluentUtility.getAsPipes(this), FluentUtility.prepareFunctions(this.asMap, columnFunctions)));
}
public PipesPipeline<S, Row> select() {
return this.add(new SelectPipe(null, FluentUtility.getAsPipes(this)));
}
public PipesPipeline<S, ?> scatter() {
return this.add(new ScatterPipe());
}
public PipesPipeline<S, List> shuffle() {
return this.add(new ShufflePipe());
}
public PipesPipeline<S, ?> cap() {
return this.add(new SideEffectCapPipe((SideEffectPipe) FluentUtility.removePreviousPipes(this, 1).get(0)));
}
public PipesPipeline<S, ?> orderMap(final TransformPipe.Order order) {
return this.add(new OrderMapPipe<Object>(order));
}
public PipesPipeline<S, ?> orderMap(final PipeFunction<Pair<Map.Entry, Map.Entry>, Integer> compareFunction) {
return this.add(new OrderMapPipe(FluentUtility.prepareFunction(this.asMap, compareFunction)));
}
public <T> PipesPipeline<S, T> transform(final PipeFunction<E, T> function) {
return this.add(new TransformFunctionPipe(FluentUtility.prepareFunction(this.asMap, function)));
}
//////////////////////
/// UTILITY PIPES ///
//////////////////////
public PipesPipeline<S, E> as(final String name) {
final PipesPipeline<S, E> pipeline = this.add(new AsPipe(name, FluentUtility.removePreviousPipes(this, 1).get(0)));
this.asMap.refresh();
return pipeline;
}
public PipesPipeline<S, S> start(final S object) {
return this.add(new StartPipe<S>(object));
}
public PipesFluentPipeline<S, E> enablePath() {
this.enablePath(true);
return this;
}
/**
* Returns the current pipeline with a new end type.
* Useful if the end type of the pipeline cannot be implicitly derived.
*
* @return returns the current pipeline with the new end type.
*/
public <E> PipesPipeline<S, E> cast(Class<E> end) {
return (PipesPipeline<S, E>) this;
}
}