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 2024/08/27 16:39:21 UTC
(tinkerpop) branch gvalue-3.7 updated: wip - removed admin interface methods - doesn't work nice
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch gvalue-3.7
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/gvalue-3.7 by this push:
new c6abf2a789 wip - removed admin interface methods - doesn't work nice
c6abf2a789 is described below
commit c6abf2a789359e782147ffecdbd5a6b83b1c49aa
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Tue Aug 27 12:38:32 2024 -0400
wip - removed admin interface methods - doesn't work nice
---
.../traversal/dsl/graph/GraphTraversal.java | 750 +++++++++++----------
.../traversal/dsl/graph/GraphTraversalSource.java | 72 +-
.../gremlin/process/traversal/dsl/graph/__.java | 113 ++++
.../gremlin/process/traversal/step/GValue.java | 42 ++
.../process/traversal/step/map/GraphStep.java | 10 +-
.../process/traversal/step/map/VertexStep.java | 16 +-
.../traversal/step/sideEffect/InjectStep.java | 10 +-
.../process/traversal/step/util/AbstractStep.java | 44 --
.../optimization/InlineFilterStrategy.java | 2 +-
.../tinkerpop/gremlin/util/CollectionUtil.java | 21 +
.../traversal/translator/DotNetTranslatorTest.java | 2 +-
11 files changed, 598 insertions(+), 484 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 9e38327b86..b64f379d76 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -203,8 +203,10 @@ import org.apache.tinkerpop.gremlin.structure.PropertyType;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.util.CollectionUtil;
import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
+import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -241,346 +243,6 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
*/
public interface Admin<S, E> extends Traversal.Admin<S, E>, GraphTraversal<S, E> {
- /**
- * Filter the <code>E</code> object given a biased coin toss. For internal use for parameterization features.
- *
- * @param probability the probability that the object will pass through the filter
- * @return the traversal with an appended {@link CoinStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#coin-step" target="_blank">Reference Documentation - Coin Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, E> coin(final GValue<Double> probability) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.coin, probability);
- return this.asAdmin().addStep(new CoinStep<>(this.asAdmin(), probability));
- }
-
- /**
- * Map any object to a fixed <code>E</code> value. For internal use for parameterization features.
- *
- * @return the traversal with an appended {@link ConstantStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#constant-step" target="_blank">Reference Documentation - Constant Step</a>
- * @since 3.7.3
- */
- public default <E2> GraphTraversal<S, E2> constant(final GValue<E2> e) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.constant, e);
- return this.asAdmin().addStep(new ConstantStep<E, E2>(this.asAdmin(), e));
- }
-
- /**
- * Map the {@link Vertex} to its adjacent vertices given a direction and edge labels. The arguments for the
- * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param direction the direction to traverse from the current vertex
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Vertex> to(final Direction direction, final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.to, direction, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, direction, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its outgoing adjacent vertices given the edge labels. The arguments for the
- * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Vertex> out(final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.out, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.OUT, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its incoming adjacent vertices given the edge labels. The arguments for the
- * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Vertex> in(final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.in, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.IN, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its adjacent vertices given the edge labels. The arguments for the labels must be
- * either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Vertex> both(final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.both, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.BOTH, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its incident edges given the direction and edge labels. The arguments for the
- * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param direction the direction to traverse from the current vertex
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Edge> toE(final Direction direction, final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.toE, direction, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, direction, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its outgoing incident edges given the edge labels. The arguments for the labels
- * must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Edge> outE(final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.outE, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.OUT, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its incoming incident edges given the edge labels. The arguments for the labels
- * must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Edge> inE(final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.inE, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.IN, edgeLabels));
- }
-
- /**
- * Map the {@link Vertex} to its incident edges given the edge labels. The arguments for the labels must be
- * either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
- *
- * @param edgeLabels the edge labels to traverse
- * @return the traversal with an appended {@link VertexStep}.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Edge> bothE(final Object... edgeLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.bothE, edgeLabels);
- return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.BOTH, edgeLabels));
- }
-
- /**
- * Adds a {@link Vertex}.
- *
- * @param vertexLabel the label of the {@link Vertex} to add
- * @return the traversal with the {@link AddVertexStep} added
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addvertex-step" target="_blank">Reference Documentation - AddVertex Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Vertex> addV(final GValue<String> vertexLabel) {
- if (null == vertexLabel || null == vertexLabel.get()) throw new IllegalArgumentException("vertexLabel cannot be null");
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.addV, vertexLabel);
- return this.asAdmin().addStep(new AddVertexStep<>(this.asAdmin(), vertexLabel));
- }
-
- /**
- * Performs a merge (i.e. upsert) style operation for an {@link Vertex} using a {@code Map} as an argument.
- * The {@code Map} represents search criteria and will match each of the supplied key/value pairs where the keys
- * may be {@code String} property values or a value of {@link T}. If a match is not made it will use that search
- * criteria to create the new {@link Vertex}.
- *
- * @param searchCreate This {@code Map} can have a key of {@link T} or a {@code String}.
- * @since 3.7.3
- */
- public default GraphTraversal<S, Vertex> mergeV(final GValue<Map<Object, Object>> searchCreate) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.mergeV, searchCreate);
- final MergeVertexStep<S> step = new MergeVertexStep(this.asAdmin(), false, null == searchCreate ? GValue.ofMap(null) : searchCreate);
- return this.asAdmin().addStep(step);
- }
-
- /**
- * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using a
- * {@code Map} as an argument.
- *
- * @param searchCreate This {@code Map} can have a key of {@link T} {@link Direction} or a {@code String}.
- * @since 3.7.3
- */
- public default GraphTraversal<S, Edge> mergeE(final GValue<Map<Object, Object>> searchCreate) {
- // get a construction time exception if the Map is bad
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.mergeE, searchCreate);
- final MergeEdgeStep<S> step = new MergeEdgeStep(this.asAdmin(), false, null == searchCreate ? GValue.ofMap(null) : searchCreate);
- return this.asAdmin().addStep(step);
- }
-
- /**
- * Adds an {@link Edge} with the specified edge label.
- *
- * @param edgeLabel the label of the newly added edge
- * @return the traversal with the {@link AddEdgeStep} added
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - AddEdge Step</a>
- * @since 3.7.3
- */
- public default GraphTraversal<S, Edge> addE(final GValue<String> edgeLabel) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.addE, edgeLabel);
- return this.asAdmin().addStep(new AddEdgeStep<>(this.asAdmin(), edgeLabel));
- }
-
- /**
- * Filters vertices, edges and vertex properties based on their label.
- *
- * @param label the label of the {@link Element}
- * @param otherLabels additional labels of the {@link Element}
- * @return the traversal with an appended {@link HasStep}
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a>
- * @since 3.2.2
- */
- public default GraphTraversal<S, E> hasLabel(final GValue<String> label, final GValue<String>... otherLabels) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.hasLabel, label, otherLabels);
-
- // groovy evaluation seems to do strange things with varargs given hasLabel(null, null). odd someone would
- // do this but the failure is ugly if not handled.
- final int otherLabelsLength = null == otherLabels ? 0 : otherLabels.length;
- final Object[] labels = new Object[otherLabelsLength + 1];
- labels[0] = label;
- if (otherLabelsLength > 0)
- System.arraycopy(otherLabels, 0, labels, 1, otherLabelsLength);
- return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.label.getAccessor(), labels.length == 1 ? P.eq(labels[0]) : P.within(labels)));
- }
-
- /**
- * This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
- * provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
- * the documentation of such steps to understand the usage context.
- *
- * @param token the token that would trigger this option which may be a {@link Pick}, {@link Merge},
- * a {@link Traversal}, {@link Predicate}, or object depending on the step being modulated.
- * @param traversalOption the option as a traversal
- * @return the traversal with the modulated step
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#choose-step" target="_blank">Reference Documentation - Choose Step</a>
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
- * @since 3.0.0-incubating
- */
- public default <M, E2> GraphTraversal<S, E> option(final GValue<M> token, final Traversal<?, E2> traversalOption) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, token, traversalOption);
-
- // handle null similar to how option() with Map handles it, otherwise we get a NPE if this one gets used
- final Traversal.Admin<E,E2> t = null == traversalOption ?
- new ConstantTraversal<>(null) : (Traversal.Admin<E, E2>) traversalOption.asAdmin();
- ((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption(token.get(), t);
- return this;
- }
-
- /**
- * This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
- * provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
- * the documentation of such steps to understand the usage context.
- *
- * @param m Provides a {@code Map} as the option which is the same as doing {@code constant(m)}.
- * @return the traversal with the modulated step
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
- * @since 3.7.3
- */
- public default <M, E2> GraphTraversal<S, E> option(final M token, final GValue<Map<Object, Object>> m) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, token, m);
- ((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption(token, (Traversal.Admin<E, E2>) new ConstantTraversal<>(m).asAdmin());
- return this;
- }
-
- /**
- * This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
- * provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
- * the documentation of such steps to understand the usage context.
- *
- * @param m Provides a {@code Map} as the option which is the same as doing {@code constant(m)}.
- * @return the traversal with the modulated step
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
- * @since 3.7.3
- */
- public default <M, E2> GraphTraversal<S, E> option(final Merge merge, final GValue<Map<Object, Object>> m, final VertexProperty.Cardinality cardinality) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, merge, m, cardinality);
-
- final Map<Object, Object> map = m.get();
-
- // do explicit cardinality for every single pair in the map
- for (Object k : map.keySet()) {
- final Object o = map.get(k);
- if (!(o instanceof CardinalityValueTraversal))
- map.put(k, new CardinalityValueTraversal(cardinality, o));
- }
- ((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption((M) merge, (Traversal.Admin<E, E2>) new ConstantTraversal<>(m).asAdmin());
- return this;
- }
-
- /**
- * When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
- * incoming vertex of the newly added {@link Edge}.
- *
- * @param toVertex the vertex for selecting the incoming vertex
- * @return the traversal with the modified {@link AddEdgeStep}
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
- * @since 4.0.0
- */
- public default GraphTraversal<S, E> to(final GValue<Vertex> toVertex) {
- final Step<?,?> prev = this.asAdmin().getEndStep();
- if (!(prev instanceof FromToModulating))
- throw new IllegalArgumentException(String.format(
- "The to() step cannot follow %s", prev.getClass().getSimpleName()));
-
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.to, toVertex);
- ((FromToModulating) prev).addTo(__.constant(toVertex).asAdmin());
- return this;
- }
-
- /**
- * When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
- * outgoing vertex of the newly added {@link Edge}.
- *
- * @param fromVertex the vertex for selecting the outgoing vertex
- * @return the traversal with the modified {@link AddEdgeStep}
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
- * @since 4.0.0
- */
- public default GraphTraversal<S, E> from(final GValue<Vertex> fromVertex) {
- final Step<?,?> prev = this.asAdmin().getEndStep();
- if (!(prev instanceof FromToModulating))
- throw new IllegalArgumentException(String.format(
- "The from() step cannot follow %s", prev.getClass().getSimpleName()));
-
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.from, fromVertex);
- ((FromToModulating) prev).addFrom(__.constant(fromVertex).asAdmin());
- return this;
- }
-
- /**
- * Filters vertices, edges and vertex properties based on their properties.
- *
- * @param label the label of the {@link Element}
- * @param propertyKey the key of the property to filter on
- * @param value the value to compare the accessor value to for equality
- * @return the traversal with an appended {@link HasStep}
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a>
- * @since 4.0.0
- */
- public default GraphTraversal<S, E> has(final GValue<String> label, final String propertyKey, final Object value) {
- this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.has, label.get(), propertyKey, value);
- TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.label.getAccessor(), P.eq(label)));
- return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(propertyKey, value instanceof P ? (P) value : P.eq(value)));
- }
-
@Override
public default <E2> GraphTraversal.Admin<S, E2> addStep(final Step<?, E2> step) {
return (GraphTraversal.Admin<S, E2>) Traversal.Admin.super.addStep((Step) step);
@@ -705,6 +367,18 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new ConstantStep<E, E2>(this.asAdmin(), e));
}
+ /**
+ * Map any object to a fixed <code>E</code> value. For internal use for parameterization features.
+ *
+ * @return the traversal with an appended {@link ConstantStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#constant-step" target="_blank">Reference Documentation - Constant Step</a>
+ * @since 4.0.0
+ */
+ public default <E2> GraphTraversal<S, E2> constant(final GValue<E2> e) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.constant, e);
+ return this.asAdmin().addStep(new ConstantStep<E, E2>(this.asAdmin(), e));
+ }
+
/**
* A {@code V} step is usually used to start a traversal but it may also be used mid-traversal.
*
@@ -749,6 +423,22 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, direction, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its adjacent vertices given a direction and edge labels. The arguments for the
+ * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param direction the direction to traverse from the current vertex
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Vertex> to(final Direction direction, final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.to, direction, edgeLabel, edgeLabels);
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, edgeLabel, GValue.class);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, direction, labels));
+ }
+
/**
* Map the {@link Vertex} to its outgoing adjacent vertices given the edge labels.
*
@@ -762,6 +452,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.OUT, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its outgoing adjacent vertices given the edge labels. The arguments for the
+ * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 3.7.3
+ */
+ public default GraphTraversal<S, Vertex> out(final GValue<String> label, final GValue<String>... edgeLabels) {
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, label, GValue.class);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.out, label, edgeLabels);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.OUT, labels));
+ }
+
/**
* Map the {@link Vertex} to its incoming adjacent vertices given the edge labels.
*
@@ -775,6 +480,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.IN, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its incoming adjacent vertices given the edge labels. The arguments for the
+ * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Vertex> in(final GValue<String> label, final GValue<String>... edgeLabels) {
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, label, GValue.class);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.in, label, edgeLabels);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.IN, labels));
+ }
+
/**
* Map the {@link Vertex} to its adjacent vertices given the edge labels.
*
@@ -788,6 +508,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.BOTH, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its adjacent vertices given the edge labels. The arguments for the labels must be
+ * either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Vertex> both(final GValue<String> label, final GValue<String>... edgeLabels) {
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, label, GValue.class);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.both, label, edgeLabels);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Vertex.class, Direction.BOTH, labels));
+ }
+
/**
* Map the {@link Vertex} to its incident edges given the direction and edge labels.
*
@@ -802,6 +537,23 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, direction, edgeLabels));
}
+
+ /**
+ * Map the {@link Vertex} to its incident edges given the direction and edge labels. The arguments for the
+ * labels must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param direction the direction to traverse from the current vertex
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Edge> toE(final Direction direction, final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.toE, direction, edgeLabel, edgeLabels);
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, edgeLabel, GValue.class);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, direction, labels));
+ }
+
/**
* Map the {@link Vertex} to its outgoing incident edges given the edge labels.
*
@@ -815,6 +567,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.OUT, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its outgoing incident edges given the edge labels. The arguments for the labels
+ * must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Edge> outE(final GValue<String> label, final GValue<String>... edgeLabels) {
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, label, GValue.class);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.outE, label, edgeLabels);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.OUT, labels));
+ }
+
/**
* Map the {@link Vertex} to its incoming incident edges given the edge labels.
*
@@ -828,6 +595,22 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.IN, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its incoming incident edges given the edge labels. The arguments for the labels
+ * must be either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Edge> inE(final GValue<String> label, final GValue<String>... edgeLabels) {
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, label, GValue.class);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.inE, label, edgeLabels);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.IN, labels));
+ }
+
+
/**
* Map the {@link Vertex} to its incident edges given the edge labels.
*
@@ -841,6 +624,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.BOTH, edgeLabels));
}
+ /**
+ * Map the {@link Vertex} to its incident edges given the edge labels. The arguments for the labels must be
+ * either a {@code String} or a {@link GValue<String>}. For internal use for parameterization.
+ *
+ * @param edgeLabels the edge labels to traverse
+ * @return the traversal with an appended {@link VertexStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#vertex-steps" target="_blank">Reference Documentation - Vertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Edge> bothE(final GValue<String> label, final GValue<String>... edgeLabels) {
+ final GValue<String>[] labels = CollectionUtil.addFirst(edgeLabels, label, GValue.class);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.bothE, label, edgeLabels);
+ return this.asAdmin().addStep(new VertexStep<>(this.asAdmin(), Edge.class, Direction.BOTH, labels));
+ }
+
/**
* Map the {@link Edge} to its incident vertices given the direction.
*
@@ -1470,6 +1268,20 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new AddVertexStep<>(this.asAdmin(), vertexLabelTraversal.asAdmin()));
}
+ /**
+ * Adds a {@link Vertex}.
+ *
+ * @param vertexLabel the label of the {@link Vertex} to add
+ * @return the traversal with the {@link AddVertexStep} added
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addvertex-step" target="_blank">Reference Documentation - AddVertex Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Vertex> addV(final GValue<String> vertexLabel) {
+ if (null == vertexLabel || null == vertexLabel.get()) throw new IllegalArgumentException("vertexLabel cannot be null");
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.addV, vertexLabel);
+ return this.asAdmin().addStep(new AddVertexStep<>(this.asAdmin(), vertexLabel));
+ }
+
/**
* Adds a {@link Vertex} with a default vertex label.
*
@@ -1528,6 +1340,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(step);
}
+ /**
+ * Performs a merge (i.e. upsert) style operation for an {@link Vertex} using a {@code Map} as an argument.
+ * The {@code Map} represents search criteria and will match each of the supplied key/value pairs where the keys
+ * may be {@code String} property values or a value of {@link T}. If a match is not made it will use that search
+ * criteria to create the new {@link Vertex}.
+ *
+ * @param searchCreate This {@code Map} can have a key of {@link T} or a {@code String}.
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Vertex> mergeV(final GValue<Map<Object, Object>> searchCreate) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.mergeV, searchCreate);
+ final MergeVertexStep<S> step = new MergeVertexStep(this.asAdmin(), false, null == searchCreate ? GValue.ofMap(null) : searchCreate);
+ return this.asAdmin().addStep(step);
+ }
+
/**
* Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using an
* incoming {@code Map} as an argument.
@@ -1569,6 +1396,20 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(step);
}
+ /**
+ * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using a
+ * {@code Map} as an argument.
+ *
+ * @param searchCreate This {@code Map} can have a key of {@link T} {@link Direction} or a {@code String}.
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Edge> mergeE(final GValue<Map<Object, Object>> searchCreate) {
+ // get a construction time exception if the Map is bad
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.mergeE, searchCreate);
+ final MergeEdgeStep<S> step = new MergeEdgeStep(this.asAdmin(), false, null == searchCreate ? GValue.ofMap(null) : searchCreate);
+ return this.asAdmin().addStep(step);
+ }
+
/**
* Adds an {@link Edge} with the specified edge label.
*
@@ -1595,21 +1436,35 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
/**
- * Provide {@code to()}-modulation to respective steps.
+ * Adds an {@link Edge} with the specified edge label.
*
- * @param toStepLabel the step label to modulate to.
- * @return the traversal with the modified {@link FromToModulating} step.
- * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#to-step" target="_blank">Reference Documentation - To Step</a>
+ * @param edgeLabel the label of the newly added edge
+ * @return the traversal with the {@link AddEdgeStep} added
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - AddEdge Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, Edge> addE(final GValue<String> edgeLabel) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.addE, edgeLabel);
+ return this.asAdmin().addStep(new AddEdgeStep<>(this.asAdmin(), edgeLabel));
+ }
+
+ /**
+ * When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
+ * outgoing vertex of the newly added {@link Edge}.
+ *
+ * @param fromVertex the traversal for selecting the outgoing vertex
+ * @return the traversal with the modified {@link AddEdgeStep}
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
* @since 3.1.0-incubating
*/
- public default GraphTraversal<S, E> to(final String toStepLabel) {
+ public default GraphTraversal<S, E> from(final Traversal<?, Vertex> fromVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
- "The to() step cannot follow %s", prev.getClass().getSimpleName()));
+ "The from() step cannot follow %s", prev.getClass().getSimpleName()));
- this.asAdmin().getBytecode().addStep(Symbols.to, toStepLabel);
- ((FromToModulating) prev).addTo(toStepLabel);
+ this.asAdmin().getBytecode().addStep(Symbols.from, fromVertex);
+ ((FromToModulating) prev).addFrom(fromVertex.asAdmin());
return this;
}
@@ -1634,21 +1489,21 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
/**
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
- * incoming vertex of the newly added {@link Edge}.
+ * outgoing vertex of the newly added {@link Edge}.
*
- * @param toVertex the traversal for selecting the incoming vertex
+ * @param fromVertex the vertex for selecting the outgoing vertex
* @return the traversal with the modified {@link AddEdgeStep}
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
- * @since 3.1.0-incubating
+ * @since 4.0.0
*/
- public default GraphTraversal<S, E> to(final Traversal<?, Vertex> toVertex) {
+ public default GraphTraversal<S, E> from(final GValue<Vertex> fromVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
- "The to() step cannot follow %s", prev.getClass().getSimpleName()));
+ "The from() step cannot follow %s", prev.getClass().getSimpleName()));
- this.asAdmin().getBytecode().addStep(Symbols.to, toVertex);
- ((FromToModulating) prev).addTo(toVertex.asAdmin());
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.from, fromVertex);
+ ((FromToModulating) prev).addFrom(__.constant(fromVertex).asAdmin());
return this;
}
@@ -1656,19 +1511,38 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
* outgoing vertex of the newly added {@link Edge}.
*
- * @param fromVertex the traversal for selecting the outgoing vertex
+ * @param fromVertex the vertex for selecting the outgoing vertex
* @return the traversal with the modified {@link AddEdgeStep}
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
- * @since 3.1.0-incubating
+ * @since 3.3.0
*/
- public default GraphTraversal<S, E> from(final Traversal<?, Vertex> fromVertex) {
+ public default GraphTraversal<S, E> from(final Vertex fromVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
"The from() step cannot follow %s", prev.getClass().getSimpleName()));
this.asAdmin().getBytecode().addStep(Symbols.from, fromVertex);
- ((FromToModulating) prev).addFrom(fromVertex.asAdmin());
+ ((FromToModulating) prev).addFrom(__.constant(fromVertex).asAdmin());
+ return this;
+ }
+
+ /**
+ * Provide {@code to()}-modulation to respective steps.
+ *
+ * @param toStepLabel the step label to modulate to.
+ * @return the traversal with the modified {@link FromToModulating} step.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#to-step" target="_blank">Reference Documentation - To Step</a>
+ * @since 3.1.0-incubating
+ */
+ public default GraphTraversal<S, E> to(final String toStepLabel) {
+ final Step<?,?> prev = this.asAdmin().getEndStep();
+ if (!(prev instanceof FromToModulating))
+ throw new IllegalArgumentException(String.format(
+ "The to() step cannot follow %s", prev.getClass().getSimpleName()));
+
+ this.asAdmin().getBytecode().addStep(Symbols.to, toStepLabel);
+ ((FromToModulating) prev).addTo(toStepLabel);
return this;
}
@@ -1679,36 +1553,56 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
* @param toVertex the vertex for selecting the incoming vertex
* @return the traversal with the modified {@link AddEdgeStep}
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
- * @since 3.3.0
+ * @since 4.0.0
*/
- public default GraphTraversal<S, E> to(final Vertex toVertex) {
+ public default GraphTraversal<S, E> to(final GValue<Vertex> toVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
"The to() step cannot follow %s", prev.getClass().getSimpleName()));
- this.asAdmin().getBytecode().addStep(Symbols.to, toVertex);
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.to, toVertex);
((FromToModulating) prev).addTo(__.constant(toVertex).asAdmin());
return this;
}
/**
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
- * outgoing vertex of the newly added {@link Edge}.
+ * incoming vertex of the newly added {@link Edge}.
*
- * @param fromVertex the vertex for selecting the outgoing vertex
+ * @param toVertex the traversal for selecting the incoming vertex
+ * @return the traversal with the modified {@link AddEdgeStep}
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
+ * @since 3.1.0-incubating
+ */
+ public default GraphTraversal<S, E> to(final Traversal<?, Vertex> toVertex) {
+ final Step<?,?> prev = this.asAdmin().getEndStep();
+ if (!(prev instanceof FromToModulating))
+ throw new IllegalArgumentException(String.format(
+ "The to() step cannot follow %s", prev.getClass().getSimpleName()));
+
+ this.asAdmin().getBytecode().addStep(Symbols.to, toVertex);
+ ((FromToModulating) prev).addTo(toVertex.asAdmin());
+ return this;
+ }
+
+ /**
+ * When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
+ * incoming vertex of the newly added {@link Edge}.
+ *
+ * @param toVertex the vertex for selecting the incoming vertex
* @return the traversal with the modified {@link AddEdgeStep}
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
* @since 3.3.0
*/
- public default GraphTraversal<S, E> from(final Vertex fromVertex) {
+ public default GraphTraversal<S, E> to(final Vertex toVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
- "The from() step cannot follow %s", prev.getClass().getSimpleName()));
+ "The to() step cannot follow %s", prev.getClass().getSimpleName()));
- this.asAdmin().getBytecode().addStep(Symbols.from, fromVertex);
- ((FromToModulating) prev).addFrom(__.constant(fromVertex).asAdmin());
+ this.asAdmin().getBytecode().addStep(Symbols.to, toVertex);
+ ((FromToModulating) prev).addTo(__.constant(toVertex).asAdmin());
return this;
}
@@ -2666,6 +2560,22 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new TraversalFilterStep(this.asAdmin(), __.values(propertyKey)));
}
+ /**
+ * Filters vertices, edges and vertex properties based on their properties.
+ *
+ * @param label the label of the {@link Element}
+ * @param propertyKey the key of the property to filter on
+ * @param value the value to compare the accessor value to for equality
+ * @return the traversal with an appended {@link HasStep}
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, E> has(final GValue<String> label, final String propertyKey, final Object value) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.has, label.get(), propertyKey, value);
+ TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.label.getAccessor(), P.eq(label)));
+ return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(propertyKey, value instanceof P ? (P) value : P.eq(value)));
+ }
+
/**
* Filters vertices, edges and vertex properties based on the non-existence of properties.
*
@@ -2693,11 +2603,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
// groovy evaluation seems to do strange things with varargs given hasLabel(null, null). odd someone would
// do this but the failure is ugly if not handled.
- final int otherLabelsLength = null == otherLabels ? 0 : otherLabels.length;
- final String[] labels = new String[otherLabelsLength + 1];
- labels[0] = label;
- if (otherLabelsLength > 0)
- System.arraycopy(otherLabels, 0, labels, 1, otherLabelsLength);
+ final String[] labels = CollectionUtil.addFirst(otherLabels, label, String.class);
return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.label.getAccessor(), labels.length == 1 ? P.eq(labels[0]) : P.within(labels)));
}
@@ -2720,6 +2626,24 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
}
+ /**
+ * Filters vertices, edges and vertex properties based on their label.
+ *
+ * @param label the label of the {@link Element}
+ * @param otherLabels additional labels of the {@link Element}
+ * @return the traversal with an appended {@link HasStep}
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, E> hasLabel(final GValue<String> label, final GValue<String>... otherLabels) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.hasLabel, label, otherLabels);
+
+ // groovy evaluation seems to do strange things with varargs given hasLabel(null, null). odd someone would
+ // do this but the failure is ugly if not handled.
+ final Object[] labels = CollectionUtil.addFirst(otherLabels, label, GValue.class);
+ return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.label.getAccessor(), labels.length == 1 ? P.eq(labels[0]) : P.within(labels)));
+ }
+
/**
* Filters vertices, edges and vertex properties based on their identifier.
*
@@ -2931,6 +2855,19 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new CoinStep<>(this.asAdmin(), probability));
}
+ /**
+ * Filter the <code>E</code> object given a biased coin toss. For internal use for parameterization features.
+ *
+ * @param probability the probability that the object will pass through the filter
+ * @return the traversal with an appended {@link CoinStep}.
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#coin-step" target="_blank">Reference Documentation - Coin Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, E> coin(final GValue<Double> probability) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.coin, probability);
+ return this.asAdmin().addStep(new CoinStep<>(this.asAdmin(), probability));
+ }
+
/**
* Filter the objects in the traversal by the number of them to pass through the stream. Those before the value
* of {@code low} do not pass through and those that exceed the value of {@code high} will end the iteration.
@@ -4295,6 +4232,73 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this;
}
+ /**
+ * This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
+ * provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
+ * the documentation of such steps to understand the usage context.
+ *
+ * @param token the token that would trigger this option which may be a {@link Pick}, {@link Merge},
+ * a {@link Traversal}, {@link Predicate}, or object depending on the step being modulated.
+ * @param traversalOption the option as a traversal
+ * @return the traversal with the modulated step
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#choose-step" target="_blank">Reference Documentation - Choose Step</a>
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
+ * @since 3.0.0-incubating
+ */
+ public default <M, E2> GraphTraversal<S, E> option(final GValue<M> token, final Traversal<?, E2> traversalOption) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, token, traversalOption);
+
+ // handle null similar to how option() with Map handles it, otherwise we get a NPE if this one gets used
+ final Traversal.Admin<E,E2> t = null == traversalOption ?
+ new ConstantTraversal<>(null) : (Traversal.Admin<E, E2>) traversalOption.asAdmin();
+ ((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption(token.get(), t);
+ return this;
+ }
+
+ /**
+ * This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
+ * provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
+ * the documentation of such steps to understand the usage context.
+ *
+ * @param m Provides a {@code Map} as the option which is the same as doing {@code constant(m)}.
+ * @return the traversal with the modulated step
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
+ * @since 3.7.3
+ */
+ public default <M, E2> GraphTraversal<S, E> option(final M token, final GValue<Map<Object, Object>> m) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, token, m);
+ ((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption(token, (Traversal.Admin<E, E2>) new ConstantTraversal<>(m).asAdmin());
+ return this;
+ }
+
+ /**
+ * This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
+ * provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
+ * the documentation of such steps to understand the usage context.
+ *
+ * @param m Provides a {@code Map} as the option which is the same as doing {@code constant(m)}.
+ * @return the traversal with the modulated step
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
+ * @since 3.7.3
+ */
+ public default <M, E2> GraphTraversal<S, E> option(final Merge merge, final GValue<Map<Object, Object>> m, final VertexProperty.Cardinality cardinality) {
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, merge, m, cardinality);
+
+ final Map<Object, Object> map = m.get();
+
+ // do explicit cardinality for every single pair in the map
+ for (Object k : map.keySet()) {
+ final Object o = map.get(k);
+ if (!(o instanceof CardinalityValueTraversal))
+ map.put(k, new CardinalityValueTraversal(cardinality, o));
+ }
+ ((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption((M) merge, (Traversal.Admin<E, E2>) new ConstantTraversal<>(m).asAdmin());
+ return this;
+ }
+
////
///////////////////// IO STEPS /////////////////////
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
index 961ba8c59c..6197ce751f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
@@ -69,7 +69,6 @@ public class GraphTraversalSource implements TraversalSource {
protected final Graph graph;
protected TraversalStrategies strategies;
protected Bytecode bytecode = new Bytecode();
- protected Admin admin;
////////////////
@@ -102,12 +101,6 @@ public class GraphTraversalSource implements TraversalSource {
this.strategies.addStrategies(new RemoteStrategy(connection));
}
- public GraphTraversalSource.Admin asAdmin() {
- if (null == this.admin)
- this.admin = new Admin();
- return this.admin;
- }
-
@Override
public Optional<Class<?>> getAnonymousTraversalClass() {
return Optional.of(__.class);
@@ -414,6 +407,22 @@ public class GraphTraversalSource implements TraversalSource {
return traversal.addStep(step);
}
+ /**
+ * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Vertex} using a
+ * {@code Map} as an argument. The {@code Map} represents search criteria and will match each of the supplied
+ * key/value pairs where the keys may be {@code String} property values or a value of {@link T}. If a match is not
+ * made it will use that search criteria to create the new {@link Vertex}.
+ *
+ * @param searchCreate This {@code Map} can have a key of {@link T} or a {@code String}.
+ * @since 4.0.0
+ */
+ public GraphTraversal<Vertex, Vertex> mergeV(final GValue<Map<Object, Object>> searchCreate) {
+ final GraphTraversalSource clone = GraphTraversalSource.this.clone();
+ clone.bytecode.addStep(GraphTraversal.Symbols.mergeV, searchCreate);
+ final GraphTraversal.Admin<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(clone);
+ return traversal.addStep(new MergeVertexStep(traversal, true, searchCreate));
+ }
+
/**
* Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using a
* {@code Map} as an argument.
@@ -446,6 +455,20 @@ public class GraphTraversalSource implements TraversalSource {
return traversal.addStep(step);
}
+ /**
+ * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using a
+ * {@code Map} as an argument.
+ *
+ * @param searchCreate This {@code Map} can have a key of {@link T} {@link Direction} or a {@code String}.
+ * @since 4.0.0
+ */
+ public GraphTraversal<Edge, Edge> mergeE(final GValue<Map<?, Object>> searchCreate) {
+ final GraphTraversalSource clone = GraphTraversalSource.this.clone();
+ clone.bytecode.addStep(GraphTraversal.Symbols.mergeE, searchCreate);
+ final GraphTraversal.Admin<Edge, Edge> traversal = new DefaultGraphTraversal<>(clone);
+ return traversal.addStep(new MergeEdgeStep(traversal, true, searchCreate));
+ }
+
/**
* Spawns a {@link GraphTraversal} starting it with arbitrary values.
*/
@@ -632,39 +655,4 @@ public class GraphTraversalSource implements TraversalSource {
return StringFactory.traversalSourceString(this);
}
- /**
- * This class masks spawn steps that are more reserved for advanced usage.
- */
- public class Admin {
-
- /**
- * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Vertex} using a
- * {@code Map} as an argument. The {@code Map} represents search criteria and will match each of the supplied
- * key/value pairs where the keys may be {@code String} property values or a value of {@link T}. If a match is not
- * made it will use that search criteria to create the new {@link Vertex}.
- *
- * @param searchCreate This {@code Map} can have a key of {@link T} or a {@code String}.
- * @since 4.0.0
- */
- public GraphTraversal<Vertex, Vertex> mergeV(final GValue<Map<Object, Object>> searchCreate) {
- final GraphTraversalSource clone = GraphTraversalSource.this.clone();
- clone.bytecode.addStep(GraphTraversal.Symbols.mergeV, searchCreate);
- final GraphTraversal.Admin<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(clone);
- return traversal.addStep(new MergeVertexStep(traversal, true, searchCreate));
- }
-
- /**
- * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using a
- * {@code Map} as an argument.
- *
- * @param searchCreate This {@code Map} can have a key of {@link T} {@link Direction} or a {@code String}.
- * @since 4.0.0
- */
- public GraphTraversal<Edge, Edge> mergeE(final GValue<Map<?, Object>> searchCreate) {
- final GraphTraversalSource clone = GraphTraversalSource.this.clone();
- clone.bytecode.addStep(GraphTraversal.Symbols.mergeE, searchCreate);
- final GraphTraversal.Admin<Edge, Edge> traversal = new DefaultGraphTraversal<>(clone);
- return traversal.addStep(new MergeEdgeStep(traversal, true, searchCreate));
- }
- }
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index d6cdc1ef7f..009f67be38 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Scope;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.FormatStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
@@ -110,6 +111,13 @@ public class __ {
return __.<A>start().constant(a);
}
+ /**
+ * @see GraphTraversal#constant(GValue)
+ */
+ public static <A> GraphTraversal<A, A> constant(final GValue<A> a) {
+ return __.<A>start().constant(a);
+ }
+
/**
* @see GraphTraversal#label()
*/
@@ -145,6 +153,13 @@ public class __ {
return __.<Vertex>start().to(direction, edgeLabels);
}
+ /**
+ * @see GraphTraversal#to(Direction, GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Vertex> to(final Direction direction, final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().to(direction, edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#out(String...)
*/
@@ -152,6 +167,13 @@ public class __ {
return __.<Vertex>start().out(edgeLabels);
}
+ /**
+ * @see GraphTraversal#out(GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Vertex> out(final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().out(edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#in(String...)
*/
@@ -159,6 +181,13 @@ public class __ {
return __.<Vertex>start().in(edgeLabels);
}
+ /**
+ * @see GraphTraversal#in(String...)
+ */
+ public static GraphTraversal<Vertex, Vertex> in(final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().in(edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#both(String...)
*/
@@ -166,6 +195,13 @@ public class __ {
return __.<Vertex>start().both(edgeLabels);
}
+ /**
+ * @see GraphTraversal#both(GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Vertex> both(final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().both(edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#toE(Direction, String...)
*/
@@ -173,6 +209,13 @@ public class __ {
return __.<Vertex>start().toE(direction, edgeLabels);
}
+ /**
+ * @see GraphTraversal#toE(Direction, GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Edge> toE(final Direction direction, final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().toE(direction, edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#outE(String...)
*/
@@ -180,6 +223,13 @@ public class __ {
return __.<Vertex>start().outE(edgeLabels);
}
+ /**
+ * @see GraphTraversal#outE(GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Edge> outE(final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().outE(edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#inE(String...)
*/
@@ -187,6 +237,13 @@ public class __ {
return __.<Vertex>start().inE(edgeLabels);
}
+ /**
+ * @see GraphTraversal#inE(GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Edge> inE(final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().inE(edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#bothE(String...)
*/
@@ -194,6 +251,13 @@ public class __ {
return __.<Vertex>start().bothE(edgeLabels);
}
+ /**
+ * @see GraphTraversal#bothE(GValue, GValue...)
+ */
+ public static GraphTraversal<Vertex, Edge> bothE(final GValue<String> edgeLabel, final GValue<String>... edgeLabels) {
+ return __.<Vertex>start().bothE(edgeLabel, edgeLabels);
+ }
+
/**
* @see GraphTraversal#toV(Direction)
*/
@@ -512,6 +576,13 @@ public class __ {
return __.<A>start().addV(vertexLabel);
}
+ /**
+ * @see GraphTraversal#addV(GValue)
+ */
+ public static <A> GraphTraversal<A, Vertex> addV(final GValue<String> vertexLabel) {
+ return __.<A>start().addV(vertexLabel);
+ }
+
/**
* @see GraphTraversal#addV(org.apache.tinkerpop.gremlin.process.traversal.Traversal)
*/
@@ -540,6 +611,13 @@ public class __ {
return __.<A>start().mergeV(searchCreate);
}
+ /**
+ * @see GraphTraversal#mergeV(GValue)
+ */
+ public static <A> GraphTraversal<A, Vertex> mergeV(final GValue<Map<Object, Object>> searchCreate) {
+ return __.<A>start().mergeV(searchCreate);
+ }
+
/**
* @see GraphTraversal#mergeV(Traversal)
*/
@@ -554,6 +632,13 @@ public class __ {
return __.<A>start().addE(edgeLabel);
}
+ /**
+ * @see GraphTraversal#addE(GValue)
+ */
+ public static <A> GraphTraversal<A, Edge> addE(final GValue<String> edgeLabel) {
+ return __.<A>start().addE(edgeLabel);
+ }
+
/**
* @see GraphTraversal#addE(Traversal)
*/
@@ -575,6 +660,13 @@ public class __ {
return __.<A>start().mergeE(searchCreate);
}
+ /**
+ * @see GraphTraversal#mergeE(GValue)
+ */
+ public static <A> GraphTraversal<A, Edge> mergeE(final GValue<Map<Object, Object>> searchCreate) {
+ return __.<A>start().mergeE(searchCreate);
+ }
+
/**
* @see GraphTraversal#mergeE(Traversal)
*/
@@ -934,6 +1026,13 @@ public class __ {
return __.<A>start().has(label, propertyKey, value);
}
+ /**
+ * @see GraphTraversal#has(GValue, String, Object)
+ */
+ public static <A> GraphTraversal<A, A> has(final GValue<String> label, final String propertyKey, final Object value) {
+ return __.<A>start().has(label, propertyKey, value);
+ }
+
/**
* @see GraphTraversal#has(String, String, P)
*/
@@ -976,6 +1075,13 @@ public class __ {
return __.<A>start().hasLabel(label, otherLabels);
}
+ /**
+ * @see GraphTraversal#hasLabel(GValue, GValue...)
+ */
+ public static <A> GraphTraversal<A, A> hasLabel(final GValue<String> label, GValue<String>... otherLabels) {
+ return __.<A>start().hasLabel(label, otherLabels);
+ }
+
/**
* @see GraphTraversal#hasLabel(P)
*/
@@ -1074,6 +1180,13 @@ public class __ {
return __.<A>start().coin(probability);
}
+ /**
+ * @see GraphTraversal#coin(GValue)
+ */
+ public static <A> GraphTraversal<A, A> coin(final GValue<Double> probability) {
+ return __.<A>start().coin(probability);
+ }
+
/**
* @see GraphTraversal#range(long, long)
*/
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
index 5af5109ac6..5b50c64cad 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
@@ -34,6 +34,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Stream;
/**
* A {@code GValue} is a variable or literal value that is used in a {@link Traversal}. It is composed of a key-value
@@ -57,6 +58,47 @@ public class GValue<V> implements Cloneable, Serializable {
this.value = value;
}
+ /**
+ * The elements in object array argument are examined to see if they are {@link GValue} objects. If they are, they
+ * are preserved as is. If they are not then they are wrapped in a {@link GValue} object.
+ */
+ public static <T> GValue<T>[] convertToGValues(final Object[] args) {
+ return Stream.of(args).map(id -> {
+ if (id instanceof GValue)
+ return (GValue<?>) id;
+ else
+ return of(id);
+ }).toArray(GValue[]::new);
+ }
+
+ /**
+ * Converts {@link GValue} objects arguments to their values to prevent them from leaking to the Graph API.
+ * Providers extending from this step should use this method to get actual values to prevent any {@link GValue}
+ * objects from leaking to the Graph API.
+ */
+ public static Object[] resolveToValues(final List<GValue<?>> gvalues) {
+ // convert gvalues to array
+ final Object[] newIds = new Object[gvalues.size()];
+ int i = 0;
+ for (final GValue<?> gvalue : gvalues) {
+ newIds[i++] = gvalue.get();
+ }
+ return newIds;
+ }
+
+ /**
+ * Converts {@link GValue} objects argument array to their values to prevent them from leaking to the Graph API.
+ * Providers extending from this step should use this method to get actual values to prevent any {@link GValue}
+ * objects from leaking to the Graph API.
+ */
+ public static Object[] resolveToValues(final GValue<?>[] gvalues) {
+ final Object[] newIds = new Object[gvalues.length];
+ for (int i = 0; i < gvalues.length; i++) {
+ newIds[i] = gvalues[i].get();
+ }
+ return newIds;
+ }
+
/**
* Determines if the value held by this object was defined as a variable or a literal value. Literal values simply
* have no name.
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStep.java
index f22683fd14..d6f66f20f4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStep.java
@@ -70,13 +70,13 @@ public class GraphStep<S, E extends Element> extends AbstractStep<S, E> implemen
this.returnClass = returnClass;
// if ids is a single collection like g.V(['a','b','c']), then unroll it into an array of ids
- this.ids = convertToGValues(tryUnrollSingleCollectionArgument(ids));
+ this.ids = GValue.convertToGValues(tryUnrollSingleCollectionArgument(ids));
this.isStart = isStart;
this.iteratorSupplier = () -> (Iterator<E>) (Vertex.class.isAssignableFrom(this.returnClass) ?
- this.getTraversal().getGraph().get().vertices(resolveToValues(this.ids)) :
- this.getTraversal().getGraph().get().edges(resolveToValues(this.ids)));
+ this.getTraversal().getGraph().get().vertices(GValue.resolveToValues(this.ids)) :
+ this.getTraversal().getGraph().get().edges(GValue.resolveToValues(this.ids)));
}
/**
@@ -148,7 +148,7 @@ public class GraphStep<S, E extends Element> extends AbstractStep<S, E> implemen
public Object[] getIds() {
if (legacyLogicForPassingNoIds) return null;
- return resolveToValues(this.ids);
+ return GValue.resolveToValues(this.ids);
}
public void addIds(final Object... newIds) {
@@ -162,7 +162,7 @@ public class GraphStep<S, E extends Element> extends AbstractStep<S, E> implemen
this.legacyLogicForPassingNoIds = newIds.length == 1 && ((newIds[0] instanceof List && ((List) newIds[0]).isEmpty()) ||
(newIds[0] instanceof GValue && ((GValue) newIds[0]).getType().isCollection() && ((List) ((GValue) newIds[0]).get()).isEmpty()));
- final GValue[] gvalues = convertToGValues(tryUnrollSingleCollectionArgument(newIds));
+ final GValue[] gvalues = GValue.convertToGValues(tryUnrollSingleCollectionArgument(newIds));
this.ids = ArrayUtils.addAll(this.ids, gvalues);
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
index e27fbb3802..896934668d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
@@ -54,24 +54,14 @@ public class VertexStep<E extends Element> extends FlatMapStep<Vertex, E> implem
private final Class<E> returnClass;
public VertexStep(final Traversal.Admin traversal, final Class<E> returnClass, final Direction direction, final String... edgeLabels) {
- this(traversal, returnClass, direction, (Object[]) edgeLabels);
+ this(traversal, returnClass, direction, GValue.convertToGValues(edgeLabels));
}
- public VertexStep(final Traversal.Admin traversal, final Class<E> returnClass, final Direction direction, final Object... edgeLabels) {
+ public VertexStep(final Traversal.Admin traversal, final Class<E> returnClass, final Direction direction, final GValue<String>... edgeLabels) {
super(traversal);
this.direction = direction;
this.returnClass = returnClass;
-
- // check each edgeLabel to ensure it is a string or a GValue with a GType.STRING in it. if it is just a string
- // then convert edgeLabels to a GValue<String> or otherwise throw an exception
- this.edgeLabelsGValue = Arrays.stream(edgeLabels).map(edgeLabel -> {
- if (edgeLabel instanceof String)
- return GValue.ofString((String) edgeLabel);
- else if (edgeLabel instanceof GValue && ((GValue<String>) edgeLabel).get().getClass().equals(String.class))
- return (GValue<String>) edgeLabel;
- else
- throw new IllegalArgumentException("All edge labels must be strings");
- }).toArray(GValue[]::new);
+ this.edgeLabelsGValue = edgeLabels;
// convert the GValue<String> to a String[] for the edgeLabels field to cache the values
this.edgeLabels = Arrays.stream(this.edgeLabelsGValue).map(GValue::get).toArray(String[]::new);
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
index 627f0f7b79..f3cdcdafbc 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
@@ -32,28 +32,28 @@ public final class InjectStep<S> extends StartStep<S> {
@SafeVarargs
public InjectStep(final Traversal.Admin traversal, final S... injections) {
super(traversal);
- this.injections = convertToGValues(injections);
- this.start = new ArrayIterator<>(resolveToValues(this.injections));
+ this.injections = GValue.convertToGValues(injections);
+ this.start = new ArrayIterator<>(GValue.resolveToValues(this.injections));
}
@Override
public InjectStep<S> clone() {
final InjectStep<S> clone = (InjectStep<S>) super.clone();
- clone.start = new ArrayIterator<>(resolveToValues(clone.injections));
+ clone.start = new ArrayIterator<>(GValue.resolveToValues(clone.injections));
return clone;
}
@Override
public void reset() {
super.reset();
- this.start = new ArrayIterator<>(resolveToValues(this.injections));
+ this.start = new ArrayIterator<>(GValue.resolveToValues(this.injections));
}
/**
* Get the injections of the step.
*/
public S[] getInjections() {
- return (S[]) resolveToValues(injections);
+ return (S[]) GValue.resolveToValues(injections);
}
public GValue<S>[] getInjectionsGValue() {
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
index 94c5866b14..72f03b5a95 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
@@ -21,7 +21,6 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.util;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
@@ -31,11 +30,9 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
-import java.util.stream.Stream;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -231,45 +228,4 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
}
return traverser;
}
-
- /**
- * The elements in object array argument are examined to see if they are {@link GValue} objects. If they are, they
- * are preserved as is. If they are not then they are wrapped in a {@link GValue} object.
- */
- protected static <T> GValue<T>[] convertToGValues(final Object[] args) {
- return Stream.of(args).map(id -> {
- if (id instanceof GValue)
- return (GValue<?>) id;
- else
- return GValue.of(id);
- }).toArray(GValue[]::new);
- }
-
- /**
- * Converts {@link GValue} objects arguments to their values to prevent them from leaking to the Graph API.
- * Providers extending from this step should use this method to get actual values to prevent any {@link GValue}
- * objects from leaking to the Graph API.
- */
- protected Object[] resolveToValues(final List<GValue<?>> gvalues) {
- // convert gvalues to array
- final Object[] newIds = new Object[gvalues.size()];
- int i = 0;
- for (final GValue<?> gvalue : gvalues) {
- newIds[i++] = gvalue.get();
- }
- return newIds;
- }
-
- /**
- * Converts {@link GValue} objects argument array to their values to prevent them from leaking to the Graph API.
- * Providers extending from this step should use this method to get actual values to prevent any {@link GValue}
- * objects from leaking to the Graph API.
- */
- protected Object[] resolveToValues(final GValue<?>[] gvalues) {
- final Object[] newIds = new Object[gvalues.length];
- for (int i = 0; i < gvalues.length; i++) {
- newIds[i] = gvalues[i].get();
- }
- return newIds;
- }
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
index 5ff63b3e0f..c0903c0783 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
@@ -161,7 +161,7 @@ public final class InlineFilterStrategy extends AbstractTraversalStrategy<Traver
}
}
if (!edgeLabels.isEmpty()) {
- final VertexStep<Edge> newVertexStep = new VertexStep<>(traversal, Edge.class, previousStep.getDirection(), edgeLabels.toArray(new Object[edgeLabels.size()]));
+ final VertexStep<Edge> newVertexStep = new VertexStep<>(traversal, Edge.class, previousStep.getDirection(), GValue.convertToGValues(edgeLabels.toArray()));
TraversalHelper.replaceStep(previousStep, newVertexStep, traversal);
TraversalHelper.copyLabels(previousStep, newVertexStep, false);
if (step.getHasContainers().isEmpty()) {
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java
index 1242d16af7..61d9d7573d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java
@@ -19,6 +19,9 @@
package org.apache.tinkerpop.gremlin.util;
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -74,4 +77,22 @@ public final class CollectionUtil {
return result;
}
+
+ /**
+ * Adds the element argument to the start of the supplied array argument, but if the array is null then return the
+ * element as a new array with just that item in it.
+ */
+ public static <T> T[] addFirst(final T[] array, final T element, final Class<T> clazz) {
+ if (null == array && null == element) {
+ final T[] singleElementArray = (T[]) Array.newInstance(clazz, 1);
+ singleElementArray[0] = null;
+ return singleElementArray;
+ } else if (null == array) {
+ final T[] singleElementArray = (T[]) Array.newInstance(clazz, 1);
+ singleElementArray[0] = element;
+ return singleElementArray;
+ } else {
+ return ArrayUtils.addFirst(array, element);
+ }
+ }
}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java
index 21f8f2e457..05b0365ee4 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java
@@ -184,7 +184,7 @@ public class DotNetTranslatorTest {
public void shouldTranslateHasLabelNull() {
String script = translator.translate(g.V().hasLabel(null).asAdmin().getBytecode()).getScript();
assertEquals("g.V().HasLabel((string) null)", script);
- script = translator.translate(g.V().hasLabel(null, null).asAdmin().getBytecode()).getScript();
+ script = translator.translate(g.V().hasLabel((String) null, null).asAdmin().getBytecode()).getScript();
assertEquals("g.V().HasLabel(null,null)", script);
script = translator.translate(g.V().hasLabel(null, "person").asAdmin().getBytecode()).getScript();
assertEquals("g.V().HasLabel(null,\"person\")", script);