You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/02/12 14:01:41 UTC
[15/77] [partial] incubator-tinkerpop git commit: moved com/tinkerpop
directories to org/apache/tinkerpop
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/RangeByIsCountStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/RangeByIsCountStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/RangeByIsCountStrategy.java
new file mode 100644
index 0000000..7a4af41
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/RangeByIsCountStrategy.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.traversal.strategy;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.TraversalStrategy;
+import com.tinkerpop.gremlin.process.graph.traversal.step.filter.IsStep;
+import com.tinkerpop.gremlin.process.graph.traversal.step.filter.RangeStep;
+import com.tinkerpop.gremlin.process.graph.traversal.step.map.CountStep;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import com.tinkerpop.gremlin.structure.Compare;
+import com.tinkerpop.gremlin.structure.Contains;
+
+import java.util.*;
+import java.util.function.BiPredicate;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class RangeByIsCountStrategy extends AbstractTraversalStrategy implements TraversalStrategy {
+
+ private static final Map<BiPredicate, Long> RANGE_PREDICATES = new HashMap<BiPredicate, Long>() {{
+ put(Compare.inside, 0L);
+ put(Compare.outside, 1L);
+ put(Contains.within, 1L);
+ put(Contains.without, 0L);
+ }};
+ private static final Set<Compare> INCREASED_OFFSET_SCALAR_PREDICATES =
+ EnumSet.of(Compare.eq, Compare.neq, Compare.lte, Compare.gt);
+
+ private static final RangeByIsCountStrategy INSTANCE = new RangeByIsCountStrategy();
+
+ private RangeByIsCountStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal, final TraversalEngine engine) {
+ final int size = traversal.getSteps().size();
+ Step prev = null;
+ for (int i = 0; i < size; i++) {
+ final Step curr = traversal.getSteps().get(i);
+ if (curr instanceof CountStep && i < size - 1) {
+ final Step next = traversal.getSteps().get(i + 1);
+ if (next instanceof IsStep && !(prev instanceof RangeStep)) { // if a RangeStep was provided, assume that the user knows what he's doing
+ final IsStep isStep = (IsStep) next;
+ final Object value = isStep.getValue();
+ final BiPredicate predicate = isStep.getPredicate();
+ if (value instanceof Number) {
+ final long highRangeOffset = INCREASED_OFFSET_SCALAR_PREDICATES.contains(predicate) ? 1L : 0L;
+ final long highRange = ((Number) value).longValue() + highRangeOffset;
+ TraversalHelper.insertBeforeStep(new RangeStep<>(traversal, 0L, highRange), curr, traversal);
+ i++;
+ } else {
+ final Long highRangeOffset = RANGE_PREDICATES.get(predicate);
+ if (value instanceof Collection && highRangeOffset != null) {
+ final Object high = Collections.max((Collection) value);
+ if (high instanceof Number) {
+ final long highRange = ((Number) high).longValue() + highRangeOffset;
+ TraversalHelper.insertBeforeStep(new RangeStep<>(traversal, 0L, highRange), curr, traversal);
+ i++;
+ }
+ }
+ }
+ }
+ }
+ prev = curr;
+ }
+ }
+
+ public static RangeByIsCountStrategy instance() {
+ return INSTANCE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/ReducingStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/ReducingStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/ReducingStrategy.java
new file mode 100644
index 0000000..86db4f5
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/ReducingStrategy.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.traversal.strategy;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.Traverser;
+import com.tinkerpop.gremlin.process.traversal.step.Reducing;
+import com.tinkerpop.gremlin.process.traversal.step.AbstractStep;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class ReducingStrategy extends AbstractTraversalStrategy {
+
+ private static final ReducingStrategy INSTANCE = new ReducingStrategy();
+
+ private ReducingStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal, final TraversalEngine engine) {
+ if (engine.equals(TraversalEngine.STANDARD))
+ return;
+
+ final Step endStep = traversal.getEndStep();
+ if (endStep instanceof Reducing)
+ TraversalHelper.replaceStep(endStep, new ReducingIdentity(traversal, (Reducing) endStep), traversal);
+ }
+
+ public static ReducingStrategy instance() {
+ return INSTANCE;
+ }
+
+ private static class ReducingIdentity extends AbstractStep implements Reducing {
+
+ private final Reducer reducer;
+ private String reducingStepString;
+
+ public ReducingIdentity(final Traversal.Admin traversal, final Reducing reducingStep) {
+ super(traversal);
+ this.reducer = reducingStep.getReducer();
+ this.reducingStepString = reducingStep.toString();
+ }
+
+ @Override
+ public String toString() {
+ return TraversalHelper.makeStepString(this, this.reducingStepString);
+ }
+
+ public Reducer getReducer() {
+ return this.reducer;
+ }
+
+ public Traverser processNextStart() {
+ return this.starts.next();
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectCapStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectCapStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectCapStrategy.java
new file mode 100644
index 0000000..cd6f786
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectCapStrategy.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.traversal.strategy;
+
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.TraversalStrategy;
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.process.graph.traversal.step.SideEffectCapable;
+import com.tinkerpop.gremlin.process.traversal.step.EmptyStep;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+
+public final class SideEffectCapStrategy extends AbstractTraversalStrategy implements TraversalStrategy {
+
+ private static final SideEffectCapStrategy INSTANCE = new SideEffectCapStrategy();
+ private static final Set<Class<? extends TraversalStrategy>> POSTS = Collections.singleton(LabeledEndStepStrategy.class);
+
+ private SideEffectCapStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal, final TraversalEngine engine) {
+ if (traversal.getEndStep() instanceof SideEffectCapable && traversal.getParent() instanceof EmptyStep) {
+ ((GraphTraversal) traversal).cap();
+ }
+ }
+
+ @Override
+ public Set<Class<? extends TraversalStrategy>> applyPost() {
+ return POSTS;
+ }
+
+ public static SideEffectCapStrategy instance() {
+ return INSTANCE;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectRegistrationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectRegistrationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectRegistrationStrategy.java
new file mode 100644
index 0000000..12fea4d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/SideEffectRegistrationStrategy.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.traversal.strategy;
+
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.TraversalStrategy;
+import com.tinkerpop.gremlin.process.traversal.step.SideEffectRegistrar;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class SideEffectRegistrationStrategy extends AbstractTraversalStrategy implements TraversalStrategy {
+
+ private static final SideEffectRegistrationStrategy INSTANCE = new SideEffectRegistrationStrategy();
+
+ private static final Set<Class<? extends TraversalStrategy>> PRIORS = Collections.singleton(SideEffectCapStrategy.class);
+
+ private SideEffectRegistrationStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal, final TraversalEngine engine) {
+ TraversalHelper.getStepsOfAssignableClass(SideEffectRegistrar.class, traversal).forEach(SideEffectRegistrar::registerSideEffects);
+ }
+
+ @Override
+ public Set<Class<? extends TraversalStrategy>> applyPrior() {
+ return PRIORS;
+ }
+
+ public static SideEffectRegistrationStrategy instance() {
+ return INSTANCE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/TraversalVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/TraversalVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/TraversalVerificationStrategy.java
new file mode 100644
index 0000000..6ea8957
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/strategy/TraversalVerificationStrategy.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.traversal.strategy;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import com.tinkerpop.gremlin.process.graph.traversal.step.util.ComputerAwareStep;
+import com.tinkerpop.gremlin.process.graph.traversal.step.util.ReducingBarrierStep;
+import com.tinkerpop.gremlin.process.graph.traversal.step.util.SupplyingBarrierStep;
+import com.tinkerpop.gremlin.process.traversal.step.EmptyStep;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.Optional;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class TraversalVerificationStrategy extends AbstractTraversalStrategy {
+
+ private static final TraversalVerificationStrategy INSTANCE = new TraversalVerificationStrategy();
+
+ private TraversalVerificationStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal, final TraversalEngine engine) {
+ if (engine.equals(TraversalEngine.STANDARD))
+ return;
+
+ final Step<?, ?> endStep = traversal.getEndStep() instanceof ComputerAwareStep.EndStep ?
+ ((ComputerAwareStep.EndStep) traversal.getEndStep()).getPreviousStep() :
+ traversal.getEndStep();
+
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ if ((step instanceof ReducingBarrierStep || step instanceof SupplyingBarrierStep) && (step != endStep || !(traversal.getParent() instanceof EmptyStep))) {
+ throw new IllegalStateException("Global traversals on GraphComputer may not contain mid-traversal barriers: " + step);
+ }
+ if (step instanceof TraversalParent) {
+ final Optional<Traversal.Admin<Object, Object>> traversalOptional = ((TraversalParent) step).getLocalChildren().stream()
+ .filter(t -> !TraversalHelper.isLocalStarGraph(t.asAdmin()))
+ .findAny();
+ if (traversalOptional.isPresent())
+ throw new IllegalStateException("Local traversals on GraphComputer may not traverse past the local star-graph: " + traversalOptional.get());
+ }
+ }
+ }
+
+ public static TraversalVerificationStrategy instance() {
+ return INSTANCE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/util/EmptyGraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/util/EmptyGraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/util/EmptyGraphTraversal.java
new file mode 100644
index 0000000..88018f4
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/util/EmptyGraphTraversal.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.traversal.util;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.computer.GraphComputer;
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class EmptyGraphTraversal<S, E> extends EmptyTraversal<S, E> implements GraphTraversal.Admin<S, E>, GraphTraversal<S, E> {
+
+ private static final EmptyGraphTraversal INSTANCE = new EmptyGraphTraversal<>();
+
+ public static <A, B> EmptyGraphTraversal<A, B> instance() {
+ return INSTANCE;
+ }
+
+ private EmptyGraphTraversal() {
+
+ }
+
+ @Override
+ public GraphTraversal.Admin<S, E> asAdmin() {
+ return this;
+ }
+
+ @Override
+ public <E2> GraphTraversal.Admin<S, E2> addStep(final Step<?, E2> step) {
+ return instance();
+ }
+
+ @Override
+ public GraphTraversal<S, E> withPath() {
+ return instance();
+ }
+
+ @Override
+ public GraphTraversal<S, E> submit(final GraphComputer computer) {
+ return instance();
+ }
+
+ @Override
+ public GraphTraversal<S, E> iterate() {
+ return this;
+ }
+
+ @Override
+ public EmptyGraphTraversal<S, E> clone() throws CloneNotSupportedException {
+ return instance();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/HasContainer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/HasContainer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/HasContainer.java
new file mode 100644
index 0000000..468b4fd
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/HasContainer.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.util;
+
+import com.tinkerpop.gremlin.process.T;
+import com.tinkerpop.gremlin.structure.Contains;
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.BiPredicate;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class HasContainer implements Serializable {
+
+ public String key;
+ public BiPredicate predicate;
+ public Object value;
+
+ public HasContainer(final String key, final BiPredicate predicate, final Object value) {
+ this.key = key;
+ this.predicate = predicate;
+ this.value = value;
+ if (null == this.value && !(this.predicate instanceof Contains)) {
+ throw new IllegalArgumentException("For determining the existence of a property, use the Contains predicate");
+ }
+ }
+
+ public HasContainer(final String key, final Contains contains) {
+ this(key, contains, null);
+ }
+
+ public HasContainer(final T accessor, final BiPredicate predicate, final Object value) {
+ this(accessor.getAccessor(), predicate, value);
+ }
+
+ public HasContainer(final T accessor, final Contains contains) {
+ this(accessor.getAccessor(), contains, null);
+ }
+
+ public boolean test(final Element element) {
+ if (null != this.value) {
+ if (this.key.equals(T.id.getAccessor()))
+ return this.predicate.test(element.id(), this.value);
+ else if (this.key.equals(T.label.getAccessor()))
+ return this.predicate.test(element.label(), this.value);
+ else if (element instanceof VertexProperty && this.key.equals(T.value.getAccessor()))
+ return this.predicate.test(((VertexProperty) element).value(), this.value);
+ else if (element instanceof VertexProperty && this.key.equals(T.key.getAccessor()))
+ return this.predicate.test(((VertexProperty) element).key(), this.value);
+ else {
+ if (element instanceof Vertex) {
+ final Iterator<? extends Property> itty = element.iterators().propertyIterator(this.key);
+ while (itty.hasNext()) {
+ if (this.predicate.test(itty.next().value(), this.value))
+ return true;
+ }
+ return false;
+ } else {
+ final Property property = element.property(this.key);
+ return property.isPresent() && this.predicate.test(property.value(), this.value);
+ }
+ }
+ } else {
+ return Contains.within.equals(this.predicate) ?
+ element.property(this.key).isPresent() :
+ !element.property(this.key).isPresent();
+ }
+ }
+
+ public static boolean testAll(final Element element, final List<HasContainer> hasContainers) {
+ if (hasContainers.size() == 0)
+ return true;
+ else {
+ for (final HasContainer hasContainer : hasContainers) {
+ if (!hasContainer.test(element))
+ return false;
+ }
+ return true;
+ }
+ }
+
+ // note that if the user is looking for a label property key (e.g.), then it will look the same as looking for the label of the element.
+ public String toString() {
+ return this.value == null ?
+ (this.predicate == Contains.within ?
+ '[' + this.key + ']' :
+ "[!" + this.key + ']') :
+ '[' + this.key + ',' + this.predicate + ',' + this.value + ']';
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/Tree.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/Tree.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/Tree.java
new file mode 100644
index 0000000..04d0584
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/util/Tree.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.graph.util;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class Tree<T> extends HashMap<T, Tree<T>> implements Serializable {
+
+ public Tree() {
+ super();
+ }
+
+ @SafeVarargs
+ public Tree(final T... children) {
+ this();
+ for (final T t : children) {
+ this.put(t, new Tree<>());
+ }
+ }
+
+ @SafeVarargs
+ public Tree(final Map.Entry<T, Tree<T>>... children) {
+ this();
+ for (final Map.Entry<T, Tree<T>> entry : children) {
+ this.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+
+ public List<Tree<T>> getTreesAtDepth(final int depth) {
+ List<Tree<T>> currentDepth = Collections.singletonList(this);
+ for (int i = 0; i < depth; i++) {
+ if (i == depth - 1) {
+ return currentDepth;
+ } else {
+ final List<Tree<T>> temp = new ArrayList<Tree<T>>();
+ for (final Tree<T> t : currentDepth) {
+ temp.addAll(t.values());
+ }
+ currentDepth = temp;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ public List<T> getObjectsAtDepth(final int depth) {
+ final List<T> list = new ArrayList<T>();
+ for (final Tree<T> t : this.getTreesAtDepth(depth)) {
+ list.addAll(t.keySet());
+ }
+ return list;
+ }
+
+ public List<Tree<T>> getLeafTrees() {
+ final List<Tree<T>> leaves = new ArrayList<>();
+ List<Tree<T>> currentDepth = Collections.singletonList(this);
+ boolean allLeaves = false;
+ while (!allLeaves) {
+ allLeaves = true;
+ final List<Tree<T>> temp = new ArrayList<>();
+ for (final Tree<T> t : currentDepth) {
+ if (t.isLeaf()) {
+ for (Map.Entry<T, Tree<T>> t2 : t.entrySet()) {
+ leaves.add(new Tree<T>(t2));
+ }
+ } else {
+ allLeaves = false;
+ temp.addAll(t.values());
+ }
+ }
+ currentDepth = temp;
+
+ }
+ return leaves;
+ }
+
+ public List<T> getLeafObjects() {
+ final List<T> leaves = new ArrayList<T>();
+ for (final Tree<T> t : this.getLeafTrees()) {
+ leaves.addAll(t.keySet());
+ }
+ return leaves;
+ }
+
+ public boolean isLeaf() {
+ final Collection<Tree<T>> values = this.values();
+ return values.iterator().next().isEmpty();
+
+ }
+
+ public void addTree(final Tree<T> tree) {
+ tree.forEach((k, t) -> {
+ if (this.containsKey(k)) {
+ this.get(k).addTree(t);
+ } else {
+ this.put(k, t);
+ }
+ });
+ }
+
+ public List<Tree<T>> splitParents() {
+ if (this.keySet().size() == 1) {
+ return Collections.singletonList(this);
+ } else {
+ final List<Tree<T>> parents = new ArrayList<>();
+ this.forEach((k, t) -> {
+ final Tree<T> parentTree = new Tree<>();
+ parentTree.put(k, t);
+ parents.add(parentTree);
+ });
+ return parents;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversal.java
new file mode 100644
index 0000000..c2e93c8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversal.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal;
+
+import com.tinkerpop.gremlin.process.*;
+import com.tinkerpop.gremlin.process.traversal.step.EmptyStep;
+import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.*;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class DefaultTraversal<S, E> implements Traversal.Admin<S, E> {
+
+ private E lastEnd = null;
+ private long lastEndCount = 0l;
+ private Step<?, E> finalEndStep = EmptyStep.instance();
+ private final StepPosition stepPosition = new StepPosition();
+
+ protected List<Step> steps = new ArrayList<>();
+ protected TraversalStrategies strategies;
+ protected TraversalSideEffects sideEffects = new DefaultTraversalSideEffects();
+ protected TraversalEngine traversalEngine = null;
+
+ protected TraversalParent traversalParent = (TraversalParent) EmptyStep.instance();
+
+ public DefaultTraversal(final Class emanatingClass) {
+ this.setStrategies(TraversalStrategies.GlobalCache.getStrategies(emanatingClass));
+ }
+
+ @Override
+ public Traversal.Admin<S, E> asAdmin() {
+ return this;
+ }
+
+ @Override
+ public void applyStrategies(final TraversalEngine engine) throws IllegalStateException {
+ if (null != this.traversalEngine) throw Traversal.Exceptions.traversalIsLocked();
+
+ TraversalHelper.reIdSteps(this.stepPosition, this);
+ this.strategies.applyStrategies(this, engine);
+ for (final Step<?, ?> step : this.getSteps()) {
+ if (step instanceof TraversalParent) {
+ ((TraversalParent) step).setChildStrategies(this.strategies); // TODO: should we clone?
+ for (final Traversal.Admin<?, ?> globalChild : ((TraversalParent) step).getGlobalChildren()) {
+ globalChild.applyStrategies(engine);
+ }
+ for (final Traversal.Admin<?, ?> localChild : ((TraversalParent) step).getLocalChildren()) {
+ localChild.applyStrategies(TraversalEngine.STANDARD);
+ }
+ }
+ }
+ this.traversalEngine = engine;
+ this.finalEndStep = this.getEndStep();
+ }
+
+ @Override
+ public Optional<TraversalEngine> getEngine() {
+ return Optional.ofNullable(this.traversalEngine);
+ }
+
+ @Override
+ public List<Step> getSteps() {
+ return Collections.unmodifiableList(this.steps);
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (null == this.traversalEngine) this.applyStrategies(TraversalEngine.STANDARD);
+ return this.lastEndCount > 0l || this.finalEndStep.hasNext();
+ }
+
+ @Override
+ public E next() {
+ if (null == this.traversalEngine) this.applyStrategies(TraversalEngine.STANDARD);
+ if (this.lastEndCount > 0l) {
+ this.lastEndCount--;
+ return this.lastEnd;
+ } else {
+ final Traverser<E> next = this.finalEndStep.next();
+ final long nextBulk = next.bulk();
+ if (nextBulk == 1) {
+ return next.get();
+ } else {
+ this.lastEndCount = nextBulk - 1;
+ this.lastEnd = next.get();
+ return this.lastEnd;
+ }
+ }
+ }
+
+ @Override
+ public void reset() {
+ this.steps.forEach(Step::reset);
+ this.lastEndCount = 0l;
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ if (null == this.traversalEngine) this.applyStrategies(TraversalEngine.STANDARD);
+ if (!this.steps.isEmpty()) this.steps.get(0).addStart(start);
+ }
+
+ @Override
+ public void addStarts(final Iterator<Traverser<S>> starts) {
+ if (null == this.traversalEngine) this.applyStrategies(TraversalEngine.STANDARD);
+ if (!this.steps.isEmpty()) this.steps.get(0).addStarts(starts);
+ }
+
+ @Override
+ public String toString() {
+ return TraversalHelper.makeTraversalString(this);
+ }
+
+ @Override
+ public Step<S, ?> getStartStep() {
+ return this.steps.isEmpty() ? EmptyStep.instance() : this.steps.get(0);
+ }
+
+ @Override
+ public Step<?, E> getEndStep() {
+ return this.steps.isEmpty() ? EmptyStep.instance() : this.steps.get(this.steps.size() - 1);
+ }
+
+ @Override
+ public DefaultTraversal<S, E> clone() throws CloneNotSupportedException {
+ final DefaultTraversal<S, E> clone = (DefaultTraversal<S, E>) super.clone();
+ clone.steps = new ArrayList<>();
+ clone.sideEffects = this.sideEffects.clone();
+ clone.strategies = this.strategies.clone(); // TODO: does this need to be cloned?
+ clone.lastEnd = null;
+ clone.lastEndCount = 0l;
+ for (final Step<?, ?> step : this.steps) {
+ final Step<?, ?> clonedStep = step.clone();
+ clonedStep.setTraversal(clone);
+ final Step previousStep = clone.steps.isEmpty() ? EmptyStep.instance() : clone.steps.get(clone.steps.size() - 1);
+ clonedStep.setPreviousStep(previousStep);
+ previousStep.setNextStep(clonedStep);
+ clone.steps.add(clonedStep);
+ }
+ clone.finalEndStep = clone.getEndStep();
+ return clone;
+ }
+
+ @Override
+ public void setSideEffects(final TraversalSideEffects sideEffects) {
+ this.sideEffects = sideEffects;
+ }
+
+ @Override
+ public TraversalSideEffects getSideEffects() {
+ return this.sideEffects;
+ }
+
+ @Override
+ public void setStrategies(final TraversalStrategies strategies) {
+ try {
+ this.strategies = strategies.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public TraversalStrategies getStrategies() {
+ return this.strategies;
+ }
+
+ @Override
+ public <S2, E2> Traversal.Admin<S2, E2> addStep(final int index, final Step<?, ?> step) throws IllegalStateException {
+ if (null != this.traversalEngine) throw Exceptions.traversalIsLocked();
+ step.setId(this.stepPosition.nextXId());
+ this.steps.add(index, step);
+ final Step previousStep = this.steps.size() > 0 && index != 0 ? steps.get(index - 1) : null;
+ final Step nextStep = this.steps.size() > index + 1 ? steps.get(index + 1) : null;
+ step.setPreviousStep(null != previousStep ? previousStep : EmptyStep.instance());
+ step.setNextStep(null != nextStep ? nextStep : EmptyStep.instance());
+ if (null != previousStep) previousStep.setNextStep(step);
+ if (null != nextStep) nextStep.setPreviousStep(step);
+ return (Traversal.Admin<S2, E2>) this;
+ }
+
+ @Override
+ public <S2, E2> Traversal.Admin<S2, E2> removeStep(final int index) throws IllegalStateException {
+ if (null != this.traversalEngine) throw Exceptions.traversalIsLocked();
+ final Step previousStep = this.steps.size() > 0 && index != 0 ? steps.get(index - 1) : null;
+ final Step nextStep = this.steps.size() > index + 1 ? steps.get(index + 1) : null;
+ this.steps.remove(index);
+ if (null != previousStep) previousStep.setNextStep(null == nextStep ? EmptyStep.instance() : nextStep);
+ if (null != nextStep) nextStep.setPreviousStep(null == previousStep ? EmptyStep.instance() : previousStep);
+ return (Traversal.Admin<S2, E2>) this;
+ }
+
+ @Override
+ public void setParent(final TraversalParent step) {
+ this.traversalParent = step;
+ }
+
+ @Override
+ public TraversalParent getParent() {
+ return this.traversalParent;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalSideEffects.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalSideEffects.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalSideEffects.java
new file mode 100644
index 0000000..e467bf2
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalSideEffects.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal;
+
+import com.tinkerpop.gremlin.process.TraversalSideEffects;
+import com.tinkerpop.gremlin.process.traversal.util.SideEffectHelper;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class DefaultTraversalSideEffects implements TraversalSideEffects {
+
+ protected Map<String, Object> objectMap = new HashMap<>();
+ protected Map<String, Supplier> supplierMap = new HashMap<>();
+ protected UnaryOperator sackSplitOperator = null;
+ protected Supplier sackInitialValue = null;
+
+ public DefaultTraversalSideEffects() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void registerSupplier(final String key, final Supplier supplier) {
+ this.supplierMap.put(key, supplier);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <V> Optional<Supplier<V>> getRegisteredSupplier(final String key) {
+ return Optional.ofNullable(this.supplierMap.get(key));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void registerSupplierIfAbsent(final String key, final Supplier supplier) {
+ if (!this.supplierMap.containsKey(key))
+ this.supplierMap.put(key, supplier);
+ }
+
+ @Override
+ public <S> void setSack(final Supplier<S> initialValue, final Optional<UnaryOperator<S>> splitOperator) {
+ this.sackInitialValue = initialValue;
+ this.sackSplitOperator = splitOperator.orElse(null);
+ }
+
+ @Override
+ public <S> Optional<Supplier<S>> getSackInitialValue() {
+ return Optional.ofNullable(this.sackInitialValue);
+ }
+
+ @Override
+ public <S> Optional<UnaryOperator<S>> getSackSplitOperator() {
+ return Optional.ofNullable(this.sackSplitOperator);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean exists(final String key) {
+ return this.objectMap.containsKey(key) || this.supplierMap.containsKey(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void set(final String key, final Object value) {
+ SideEffectHelper.validateSideEffect(key, value);
+ this.objectMap.put(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <V> V get(final String key) throws IllegalArgumentException {
+ final V value = (V) this.objectMap.get(key);
+ if (null != value)
+ return value;
+ else {
+ if (this.supplierMap.containsKey(key)) {
+ final V v = (V) this.supplierMap.get(key).get();
+ this.objectMap.put(key, v);
+ return v;
+ } else {
+ throw TraversalSideEffects.Exceptions.sideEffectDoesNotExist(key);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <V> V getOrCreate(final String key, final Supplier<V> orCreate) {
+ if (this.objectMap.containsKey(key))
+ return (V) this.objectMap.get(key);
+ else if (this.supplierMap.containsKey(key)) {
+ final V value = (V) this.supplierMap.get(key).get();
+ this.objectMap.put(key, value);
+ return value;
+ } else {
+ final V value = orCreate.get();
+ this.objectMap.put(key, value);
+ return value;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void remove(final String key) {
+ this.objectMap.remove(key);
+ this.supplierMap.remove(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<String> keys() {
+ final Set<String> keys = new HashSet<>();
+ keys.addAll(this.objectMap.keySet());
+ keys.addAll(this.supplierMap.keySet());
+ return Collections.unmodifiableSet(keys);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setLocalVertex(final Vertex vertex) {
+ final Property<Map<String, Object>> property = vertex.property(SIDE_EFFECTS);
+ if (property.isPresent()) {
+ this.objectMap = property.value();
+ } else {
+ this.objectMap = new HashMap<>();
+ vertex.property(SIDE_EFFECTS, this.objectMap);
+ }
+ }
+
+ @Override
+ public void mergeInto(final TraversalSideEffects sideEffects) {
+ this.objectMap.forEach(sideEffects::set);
+ this.supplierMap.forEach(sideEffects::registerSupplierIfAbsent);
+ // TODO: add sack information?
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.traversalSideEffectsString(this);
+ }
+
+ @Override
+ public DefaultTraversalSideEffects clone() throws CloneNotSupportedException {
+ final DefaultTraversalSideEffects sideEffects = (DefaultTraversalSideEffects) super.clone();
+ sideEffects.objectMap = new HashMap<>(this.objectMap);
+ sideEffects.supplierMap = new HashMap<>(this.supplierMap);
+ return sideEffects;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalStrategies.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalStrategies.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalStrategies.java
new file mode 100644
index 0000000..c6fa9f0
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/DefaultTraversalStrategies.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal;
+
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.TraversalStrategies;
+import com.tinkerpop.gremlin.process.TraversalStrategy;
+import com.tinkerpop.gremlin.process.traverser.TraverserGeneratorFactory;
+import com.tinkerpop.gremlin.process.traverser.util.DefaultTraverserGeneratorFactory;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class DefaultTraversalStrategies implements TraversalStrategies {
+
+ protected List<TraversalStrategy> traversalStrategies = new ArrayList<>();
+ protected TraverserGeneratorFactory traverserGeneratorFactory = DefaultTraverserGeneratorFactory.instance();
+
+ @Override
+ public TraversalStrategies addStrategies(final TraversalStrategy... strategies) {
+ boolean added = false;
+ for (final TraversalStrategy strategy : strategies) {
+ if (!this.traversalStrategies.contains(strategy)) {
+ this.traversalStrategies.add(strategy);
+ added = true;
+ }
+ }
+ if (added) TraversalStrategies.sortStrategies(this.traversalStrategies);
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public TraversalStrategies removeStrategies(final Class<? extends TraversalStrategy>... strategyClasses) {
+ boolean removed = false;
+ for (final Class<? extends TraversalStrategy> strategyClass : strategyClasses) {
+ final Optional<TraversalStrategy> strategy = this.traversalStrategies.stream().filter(s -> s.getClass().equals(strategyClass)).findAny();
+ if (strategy.isPresent()) {
+ this.traversalStrategies.remove(strategy.get());
+ removed = true;
+ }
+ }
+ if (removed) TraversalStrategies.sortStrategies(this.traversalStrategies);
+ return this;
+ }
+
+ @Override
+ public List<TraversalStrategy> toList() {
+ return Collections.unmodifiableList(this.traversalStrategies);
+ }
+
+ @Override
+ public void applyStrategies(final Traversal.Admin<?, ?> traversal, final TraversalEngine engine) {
+ this.traversalStrategies.forEach(ts -> ts.apply(traversal, engine));
+ }
+
+ @Override
+ public TraverserGeneratorFactory getTraverserGeneratorFactory() {
+ return this.traverserGeneratorFactory;
+ }
+
+ @Override
+ public void setTraverserGeneratorFactory(final TraverserGeneratorFactory traverserGeneratorFactory) {
+ this.traverserGeneratorFactory = traverserGeneratorFactory;
+ }
+
+ @Override
+ public DefaultTraversalStrategies clone() throws CloneNotSupportedException {
+ final DefaultTraversalStrategies clone = (DefaultTraversalStrategies) super.clone();
+ clone.traversalStrategies = new ArrayList<>();
+ clone.traversalStrategies.addAll(this.traversalStrategies);
+ return clone;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.traversalStrategiesString(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/StepPosition.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/StepPosition.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/StepPosition.java
new file mode 100644
index 0000000..6c6675d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/StepPosition.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal;
+
+import java.io.Serializable;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class StepPosition implements Serializable {
+
+ public int x; // step in traversal length
+ public int y; // depth in traversal nested tree
+ public int z; // breadth in traversal siblings
+ public String parentId; // the traversal holder id
+
+ private static final String DOT = ".";
+ private static final String LEFT_PARENTHESES = "(";
+ private static final String RIGHT_PARENTHESES = ")";
+ private static final String EMPTY_STRING = "";
+
+ private StepPosition(final int x, final int y, final int z, final String parentId) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.parentId = parentId;
+ }
+
+ public StepPosition() {
+ this(0, 0, 0, EMPTY_STRING);
+ }
+
+ public String nextXId() {
+ return this.x++ + DOT + this.y + DOT + this.z + LEFT_PARENTHESES + this.parentId + RIGHT_PARENTHESES;
+ }
+
+ @Override
+ public String toString() {
+ return this.x + DOT + this.y + DOT + this.z + LEFT_PARENTHESES + this.parentId + RIGHT_PARENTHESES;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalMatrix.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalMatrix.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalMatrix.java
new file mode 100644
index 0000000..90d84ad
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalMatrix.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A TraversalMatrix provides random, non-linear access to the steps of a traversal by their step id.
+ * This is useful in situations where traversers becomes detached from their traversal (and step) and later need to be re-attached.
+ * A classic use case is {@link com.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram} on {@link com.tinkerpop.gremlin.process.computer.GraphComputer}.
+ *
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class TraversalMatrix<S, E> {
+
+ private final Map<String, Step<?, ?>> matrix = new HashMap<>();
+ private final Traversal.Admin<S, E> traversal;
+
+ public TraversalMatrix(final Traversal.Admin<S, E> traversal) {
+ this.harvestSteps(this.traversal = traversal);
+ }
+
+ public <A, B, C extends Step<A, B>> C getStepById(final String stepId) {
+ return (C) this.matrix.get(stepId);
+ }
+
+ public Traversal.Admin<S, E> getTraversal() {
+ return this.traversal;
+ }
+
+ private final void harvestSteps(final Traversal.Admin<?, ?> traversal) {
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ this.matrix.put(step.getId(), step);
+ if (step instanceof TraversalParent) {
+ for (final Traversal.Admin<?, ?> globalChild : ((TraversalParent) step).getGlobalChildren()) {
+ this.harvestSteps(globalChild);
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
new file mode 100644
index 0000000..d2b230d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/AbstractLambdaTraversal.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.TraversalSideEffects;
+import com.tinkerpop.gremlin.process.TraversalStrategies;
+import com.tinkerpop.gremlin.process.Traverser;
+import com.tinkerpop.gremlin.process.TraverserGenerator;
+import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import com.tinkerpop.gremlin.process.traverser.O_TraverserGenerator;
+import com.tinkerpop.gremlin.process.traversal.step.EmptyStep;
+import com.tinkerpop.gremlin.process.traversal.util.EmptyTraversalSideEffects;
+import com.tinkerpop.gremlin.process.traversal.util.EmptyTraversalStrategies;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class AbstractLambdaTraversal<S, E> implements Traversal.Admin<S, E> {
+
+ @Override
+ public List<Step> getSteps() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void reset() {
+
+ }
+
+ @Override
+ public <S2, E2> Traversal.Admin<S2, E2> addStep(final int index, final Step<?, ?> step) throws IllegalStateException {
+ return (Traversal.Admin<S2, E2>) this;
+ }
+
+ @Override
+ public <S2, E2> Traversal.Admin<S2, E2> removeStep(final int index) throws IllegalStateException {
+ return (Traversal.Admin<S2, E2>) this;
+ }
+
+ @Override
+ public void applyStrategies(final TraversalEngine engine) throws IllegalStateException {
+
+ }
+
+ @Override
+ public Optional<TraversalEngine> getEngine() {
+ return Optional.of(TraversalEngine.STANDARD);
+ }
+
+ @Override
+ public TraverserGenerator getTraverserGenerator() {
+ return O_TraverserGenerator.instance();
+ }
+
+ @Override
+ public void setSideEffects(final TraversalSideEffects sideEffects) {
+
+ }
+
+ @Override
+ public TraversalSideEffects getSideEffects() {
+ return EmptyTraversalSideEffects.instance();
+ }
+
+ @Override
+ public void setStrategies(final TraversalStrategies strategies) {
+
+ }
+
+ @Override
+ public TraversalStrategies getStrategies() {
+ return EmptyTraversalStrategies.instance();
+ }
+
+ @Override
+ public void setParent(final TraversalParent step) {
+
+ }
+
+ @Override
+ public TraversalParent getParent() {
+ return (TraversalParent) EmptyStep.instance();
+ }
+
+ @Override
+ public Traversal.Admin<S, E> clone() throws CloneNotSupportedException {
+ return (AbstractLambdaTraversal<S, E>) super.clone();
+ }
+
+ @Override
+ public E next() {
+ throw new UnsupportedOperationException("The " + this.getClass().getSimpleName() + " can only be used as a predicate traversal");
+ }
+
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
+
+ public void addStart(final Traverser<S> start) {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
new file mode 100644
index 0000000..6ddb9bb
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ConstantTraversal.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class ConstantTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private final E end;
+
+ public ConstantTraversal(final E end) {
+ this.end = end;
+ }
+
+ @Override
+ public E next() {
+ return this.end;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + this.end.toString() + ")";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
new file mode 100644
index 0000000..285018e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ElementValueTraversal.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Traverser;
+import com.tinkerpop.gremlin.structure.Element;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class ElementValueTraversal<V> extends AbstractLambdaTraversal<Element, V> {
+
+ private final String propertyKey;
+ private V value;
+
+ public ElementValueTraversal(final String propertyKey) {
+ this.propertyKey = propertyKey;
+ }
+
+ @Override
+ public V next() {
+ return this.value;
+ }
+
+ @Override
+ public void addStart(final Traverser<Element> start) {
+ this.value = start.get().value(this.propertyKey);
+ }
+
+ public String getPropertyKey() {
+ return this.propertyKey;
+ }
+
+ @Override
+ public String toString() {
+ return "value(" + this.propertyKey + ')';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraversal.java
new file mode 100644
index 0000000..61bc598
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraversal.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Traverser;
+
+import java.util.function.Predicate;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class FilterTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private boolean filter = true;
+ private final Predicate<S> predicate;
+
+ public FilterTraversal(final Predicate<S> predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.filter;
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ this.filter = this.predicate.test(start.get());
+ }
+
+ @Override
+ public String toString() {
+ return this.predicate.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraverserTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraverserTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraverserTraversal.java
new file mode 100644
index 0000000..39f75b9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/FilterTraverserTraversal.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Traverser;
+
+import java.util.function.Predicate;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class FilterTraverserTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private boolean filter = true;
+ private final Predicate<Traverser<S>> predicate;
+
+ public FilterTraverserTraversal(final Predicate<Traverser<S>> predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.filter;
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ this.filter = this.predicate.test(start);
+ }
+
+ @Override
+ public String toString() {
+ return this.predicate.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/HasNextTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/HasNextTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/HasNextTraversal.java
new file mode 100644
index 0000000..830fb1e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/HasNextTraversal.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.TraversalEngine;
+import com.tinkerpop.gremlin.process.TraversalSideEffects;
+import com.tinkerpop.gremlin.process.TraversalStrategies;
+import com.tinkerpop.gremlin.process.Traverser;
+import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class HasNextTraversal<S> implements Traversal.Admin<S, Boolean> {
+
+ private Traversal.Admin<S, ?> hasNextTraversal;
+
+ public HasNextTraversal(final Admin<S, ?> hasNextTraversal) {
+ this.hasNextTraversal = hasNextTraversal;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
+
+ @Override
+ public Boolean next() {
+ return this.hasNextTraversal.hasNext();
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ this.hasNextTraversal.addStart(start);
+ }
+
+ @Override
+ public String toString() {
+ return "(hasNext)";
+ }
+
+ @Override
+ public void setStrategies(final TraversalStrategies strategies) {
+ this.hasNextTraversal.setStrategies(strategies);
+ }
+
+ @Override
+ public TraversalStrategies getStrategies() {
+ return null;
+ }
+
+ @Override
+ public void setSideEffects(final TraversalSideEffects sideEffects) {
+ this.hasNextTraversal.setSideEffects(sideEffects);
+ }
+
+ @Override
+ public TraversalSideEffects getSideEffects() {
+ return this.hasNextTraversal.getSideEffects();
+ }
+
+ @Override
+ public void setParent(final TraversalParent holder) {
+ this.hasNextTraversal.setParent(holder);
+ }
+
+ @Override
+ public TraversalParent getParent() {
+ return this.hasNextTraversal.getParent();
+ }
+
+ @Override
+ public Set<TraverserRequirement> getTraverserRequirements() {
+ return this.hasNextTraversal.getTraverserRequirements();
+ }
+
+ @Override
+ public List<Step> getSteps() {
+ return this.hasNextTraversal.getSteps();
+ }
+
+ @Override
+ public <S2, E2> Traversal.Admin<S2, E2> addStep(final int index, final Step<?, ?> step) throws IllegalStateException {
+ return this.hasNextTraversal.addStep(index, step);
+ }
+
+ @Override
+ public <S2, E2> Traversal.Admin<S2, E2> removeStep(int index) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public HasNextTraversal<S> clone() throws CloneNotSupportedException {
+ final HasNextTraversal<S> clone = (HasNextTraversal<S>) super.clone();
+ clone.hasNextTraversal = this.hasNextTraversal.clone();
+ return clone;
+ }
+
+ @Override
+ public void applyStrategies(final TraversalEngine engine) throws IllegalStateException {
+ this.hasNextTraversal.applyStrategies(engine);
+ }
+
+ @Override
+ public Optional<TraversalEngine> getEngine() {
+ return this.hasNextTraversal.getEngine();
+ }
+
+ @Override
+ public void reset() {
+ this.hasNextTraversal.reset();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
new file mode 100644
index 0000000..b251685
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/IdentityTraversal.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Traverser;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class IdentityTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private S s;
+
+ @Override
+ public E next() {
+ return (E) this.s;
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ this.s = start.get();
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraversal.java
new file mode 100644
index 0000000..82625ac
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraversal.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Traverser;
+
+import java.util.function.Function;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class MapTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private E e;
+ private final Function<S, E> function;
+
+ public MapTraversal(final Function<S, E> function) {
+ this.function = function;
+ }
+
+ @Override
+ public E next() {
+ return this.e;
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ this.e = this.function.apply(start.get());
+ }
+
+ @Override
+ public String toString() {
+ return this.function.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraverserTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraverserTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraverserTraversal.java
new file mode 100644
index 0000000..a459f1a
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/MapTraverserTraversal.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+import com.tinkerpop.gremlin.process.Traverser;
+
+import java.util.function.Function;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class MapTraverserTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private E e;
+ private final Function<Traverser<S>, E> function;
+
+ public MapTraverserTraversal(final Function<Traverser<S>, E> function) {
+ this.function = function;
+ }
+
+ @Override
+ public E next() {
+ return this.e;
+ }
+
+ @Override
+ public void addStart(final Traverser<S> start) {
+ this.e = this.function.apply(start);
+ }
+
+ @Override
+ public String toString() {
+ return this.function.toString();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
new file mode 100644
index 0000000..da1b40e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/TrueTraversal.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.process.traversal.lambda;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class TrueTraversal<S, E> extends AbstractLambdaTraversal<S, E> {
+
+ private static final TrueTraversal INSTANCE = new TrueTraversal<>();
+
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "true";
+ }
+
+ @Override
+ public TrueTraversal<S, E> clone() throws CloneNotSupportedException {
+ return INSTANCE;
+ }
+
+ public static <A, B> TrueTraversal<A, B> instance() {
+ return INSTANCE;
+ }
+
+
+}