added Graph.traversal(Translator). A translator is able to translate a Java traversal into any other language -- for example -- gremlin-python. Moreover, for doing scripts to RemoteGraph, we can simply do graph.traversal(GroovyTranslator.of('g')) and the Java API will generate a Groovy string in the backend and then RemoteStrategy will send it as a ScriptTraversal which can contain lambdas (as they are still strings at this point). This translator work is now in gremlin-core as it use to be in gremlin-variant test/. Its generally useful beyond variants so its got center stage.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/47e71228 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/47e71228 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/47e71228 Branch: refs/heads/TINKERPOP-1278 Commit: 47e71228f3b13c8e409f838f22fbd6a61098460a Parents: d175894 Author: Marko A. Rodriguez <okramma...@gmail.com> Authored: Wed Jun 8 15:27:04 2016 -0600 Committer: Marko A. Rodriguez <okramma...@gmail.com> Committed: Wed Jun 8 15:27:04 2016 -0600 ---------------------------------------------------------------------- .../dsl/graph/GraphTraversalSource.java | 4 +- .../gremlin/process/traversal/dsl/graph/__.java | 9 +- .../dsl/graph/script/ScriptGraphTraversal.java | 957 ++++++++++++++++++ .../script/ScriptGraphTraversalSource.java | 239 +++++ .../process/traversal/util/Translator.java | 44 + .../tinkerpop/gremlin/structure/Graph.java | 7 + .../script/ScriptGraphTraversalSourceTest.java | 58 ++ .../graph/script/ScriptGraphTraversalTest.java | 57 ++ .../AbstractImportCustomizerProvider.java | 2 + .../traversal/dsl/graph/GroovyTranslator.java | 153 +++ .../variant/python/PythonTranslator.java | 258 +++++ .../process/variant/VariantConverter.java | 32 - .../process/variant/VariantGraphTraversal.java | 968 ------------------- .../variant/VariantGraphTraversalSource.java | 219 ----- .../VariantGraphTraversalSourceTest.java | 56 -- .../variant/VariantGraphTraversalTest.java | 56 -- .../process/variant/python/PythonProvider.java | 4 +- .../variant/python/PythonVariantConverter.java | 206 ---- 18 files changed, 1785 insertions(+), 1544 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java ---------------------------------------------------------------------- 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 ad33bf8..720d529 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 @@ -51,8 +51,8 @@ import java.util.function.UnaryOperator; */ public class GraphTraversalSource implements TraversalSource { - private final Graph graph; - private TraversalStrategies strategies; + protected final Graph graph; + protected TraversalStrategies strategies; public GraphTraversalSource(final Graph graph, final TraversalStrategies traversalStrategies) { this.graph = graph; http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java ---------------------------------------------------------------------- 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 21352cb..c4f83da 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 @@ -51,16 +51,19 @@ import java.util.function.Supplier; */ public class __ { - private static final boolean isTesting = Boolean.valueOf(System.getProperty("is.testing", "false")); - public static Supplier<GraphTraversal> EMPTY_GRAPH_TRAVERSAL = () -> new DefaultGraphTraversal<>(); + private static Supplier<GraphTraversal> ANONYMOUS_GRAPH_TRAVERSAL = null; protected __() { } ////////////////////////////////////////////////////////////////////// + public static void setAnonymousGraphTraversalSupplier(final Supplier<GraphTraversal> anonymousGraphTraversalSupplier) { + ANONYMOUS_GRAPH_TRAVERSAL = anonymousGraphTraversalSupplier; + } + public static <A> GraphTraversal<A, A> start() { - return isTesting ? EMPTY_GRAPH_TRAVERSAL.get() : new DefaultGraphTraversal<>(); + return null == ANONYMOUS_GRAPH_TRAVERSAL ? new DefaultGraphTraversal<>() : ANONYMOUS_GRAPH_TRAVERSAL.get(); } public static <A> GraphTraversal<A, A> __(final A... starts) { http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversal.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversal.java new file mode 100644 index 0000000..3b890e5 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversal.java @@ -0,0 +1,957 @@ +/* + * 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 org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script; + +import org.apache.tinkerpop.gremlin.process.computer.VertexProgram; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.P; +import org.apache.tinkerpop.gremlin.process.traversal.Path; +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.dsl.graph.DefaultGraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.process.traversal.util.Translator; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; +import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet; +import org.apache.tinkerpop.gremlin.structure.Column; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.Property; +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.ScriptEngineCache; + +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.SimpleBindings; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class ScriptGraphTraversal<S, E> extends DefaultGraphTraversal<S, E> { + + protected Translator translator; + + public ScriptGraphTraversal(final Graph graph, final Translator translator) { + super(graph); + this.translator = translator; + } + + public String getTraversalScript() { + return this.translator.getTraversalScript(); + } + + @Override + public void applyStrategies() { + if (!(this.getParent() instanceof EmptyStep)) { + return; + } + try { + final String traversalScriptString = this.getTraversalScript(); + __.setAnonymousGraphTraversalSupplier(null); + ScriptEngine engine = ScriptEngineCache.get(this.translator.getScriptEngine()); + final Bindings bindings = new SimpleBindings(); + bindings.put(this.translator.getAlias(), new GraphTraversalSource(this.getGraph().get(), this.getStrategies())); + Traversal.Admin<S, E> traversal = (Traversal.Admin<S, E>) engine.eval(traversalScriptString, bindings); + assert !traversal.isLocked(); + this.sideEffects = traversal.getSideEffects(); + this.strategies = traversal.getStrategies(); + traversal.getSteps().forEach(step -> this.addStep(step)); + super.applyStrategies(); + } catch (final Exception e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } + + private static String getMethodName() { + return Thread.currentThread().getStackTrace()[2].getMethodName(); + } + + ////////////////////////// + + public <E2> GraphTraversal<S, E2> map(final Function<Traverser<E>, E2> function) { + this.translator.addStep(getMethodName(), function); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> map(final Traversal<?, E2> mapTraversal) { + this.translator.addStep(getMethodName(), mapTraversal); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> flatMap(final Function<Traverser<E>, Iterator<E2>> function) { + this.translator.addStep(getMethodName(), function); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> flatMap(final Traversal<?, E2> flatMapTraversal) { + this.translator.addStep(getMethodName(), flatMapTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Object> id() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, String> label() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> identity() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> constant(final E2 e) { + this.translator.addStep(getMethodName(), e); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> V(final Object... vertexIdsOrElements) { + this.translator.addStep(getMethodName(), vertexIdsOrElements); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> to(final Direction direction, final String... edgeLabels) { + this.translator.addStep(getMethodName(), direction, edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> out(final String... edgeLabels) { + this.translator.addStep(getMethodName(), edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> in(final String... edgeLabels) { + this.translator.addStep(getMethodName(), edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> both(final String... edgeLabels) { + this.translator.addStep(getMethodName(), edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Edge> toE(final Direction direction, final String... edgeLabels) { + this.translator.addStep(getMethodName(), direction, edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Edge> outE(final String... edgeLabels) { + this.translator.addStep(getMethodName(), edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Edge> inE(final String... edgeLabels) { + this.translator.addStep(getMethodName(), edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Edge> bothE(final String... edgeLabels) { + this.translator.addStep(getMethodName(), edgeLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> toV(final Direction direction) { + this.translator.addStep(getMethodName(), direction); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> inV() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> outV() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> bothV() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> otherV() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> order() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> order(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, ? extends Property<E2>> properties(final String... propertyKeys) { + this.translator.addStep(getMethodName(), propertyKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> values(final String... propertyKeys) { + this.translator.addStep(getMethodName(), propertyKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> propertyMap(final String... propertyKeys) { + this.translator.addStep(getMethodName(), propertyKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> valueMap(final String... propertyKeys) { + this.translator.addStep(getMethodName(), propertyKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> valueMap(final boolean includeTokens, final String... propertyKeys) { + this.translator.addStep(getMethodName(), includeTokens, propertyKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Collection<E2>> select(final Column column) { + this.translator.addStep(getMethodName(), column); + return (GraphTraversal) this; + } + + @Deprecated + public <E2> GraphTraversal<S, E2> mapValues() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + @Deprecated + public <E2> GraphTraversal<S, E2> mapKeys() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, String> key() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> value() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Path> path() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> match(final Traversal<?, ?>... matchTraversals) { + this.translator.addStep(getMethodName(), matchTraversals); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> sack() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Integer> loops() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> project(final String projectKey, final String... otherProjectKeys) { + this.translator.addStep(getMethodName(), projectKey, otherProjectKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> select(final Pop pop, final String selectKey1, final String selectKey2, String... otherSelectKeys) { + this.translator.addStep(getMethodName(), pop, selectKey1, selectKey2, otherSelectKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, Map<String, E2>> select(final String selectKey1, final String selectKey2, String... otherSelectKeys) { + this.translator.addStep(getMethodName(), selectKey1, selectKey2, otherSelectKeys); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> select(final Pop pop, final String selectKey) { + this.translator.addStep(getMethodName(), pop, selectKey); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> select(final String selectKey) { + this.translator.addStep(getMethodName(), selectKey); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> unfold() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, List<E>> fold() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> fold(final E2 seed, final BiFunction<E2, E, E2> foldFunction) { + this.translator.addStep(getMethodName(), seed, foldFunction); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Long> count() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Long> count(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> sum() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> sum(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> max() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> max(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> min() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> min(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> mean() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <E2 extends Number> GraphTraversal<S, E2> mean(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <K, V> GraphTraversal<S, Map<K, V>> group() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + @Deprecated + public <K, V> GraphTraversal<S, Map<K, V>> groupV3d0() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public <K> GraphTraversal<S, Map<K, Long>> groupCount() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Tree> tree() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> addV(final String vertexLabel) { + this.translator.addStep(getMethodName(), vertexLabel); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Vertex> addV() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + @Deprecated + public GraphTraversal<S, Vertex> addV(final Object... propertyKeyValues) { + this.translator.addStep(getMethodName(), propertyKeyValues); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Edge> addE(final String edgeLabel) { + this.translator.addStep(getMethodName(), edgeLabel); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> to(final String toStepLabel) { + this.translator.addStep(getMethodName(), toStepLabel); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> from(final String fromStepLabel) { + this.translator.addStep(getMethodName(), fromStepLabel); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> to(final Traversal<E, Vertex> toVertex) { + this.translator.addStep(getMethodName(), toVertex); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> from(final Traversal<E, Vertex> fromVertex) { + this.translator.addStep(getMethodName(), fromVertex); + return (GraphTraversal) this; + } + + @Deprecated + public GraphTraversal<S, Edge> addE(final Direction direction, final String firstVertexKeyOrEdgeLabel, final String edgeLabelOrSecondVertexKey, final Object... propertyKeyValues) { + this.translator.addStep(getMethodName(), direction, firstVertexKeyOrEdgeLabel, edgeLabelOrSecondVertexKey, propertyKeyValues); + return (GraphTraversal) this; + } + + @Deprecated + public GraphTraversal<S, Edge> addOutE(final String firstVertexKeyOrEdgeLabel, final String edgeLabelOrSecondVertexKey, final Object... propertyKeyValues) { + this.translator.addStep(getMethodName(), firstVertexKeyOrEdgeLabel, edgeLabelOrSecondVertexKey, propertyKeyValues); + return (GraphTraversal) this; + } + + @Deprecated + public GraphTraversal<S, Edge> addInE(final String firstVertexKeyOrEdgeLabel, final String edgeLabelOrSecondVertexKey, final Object... propertyKeyValues) { + this.translator.addStep(getMethodName(), firstVertexKeyOrEdgeLabel, edgeLabelOrSecondVertexKey, propertyKeyValues); + return (GraphTraversal) this; + } + + ///////////////////// FILTER STEPS ///////////////////// + + public GraphTraversal<S, E> filter(final Predicate<Traverser<E>> predicate) { + this.translator.addStep(getMethodName(), predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> filter(final Traversal<?, ?> filterTraversal) { + this.translator.addStep(getMethodName(), filterTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> or(final Traversal<?, ?>... orTraversals) { + this.translator.addStep(getMethodName(), orTraversals); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> and(final Traversal<?, ?>... andTraversals) { + this.translator.addStep(getMethodName(), andTraversals); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> inject(final E... injections) { + this.translator.addStep(getMethodName(), injections); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> dedup(final Scope scope, final String... dedupLabels) { + this.translator.addStep(getMethodName(), scope, dedupLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> dedup(final String... dedupLabels) { + this.translator.addStep(getMethodName(), dedupLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> where(final String startKey, final P<String> predicate) { + this.translator.addStep(getMethodName(), startKey, predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> where(final P<String> predicate) { + this.translator.addStep(getMethodName(), predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> where(final Traversal<?, ?> whereTraversal) { + this.translator.addStep(getMethodName(), whereTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final String propertyKey, final P<?> predicate) { + this.translator.addStep(getMethodName(), propertyKey, predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final T accessor, final P<?> predicate) { + this.translator.addStep(getMethodName(), accessor, predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final String propertyKey, final Object value) { + this.translator.addStep(getMethodName(), propertyKey, value); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final T accessor, final Object value) { + this.translator.addStep(getMethodName(), accessor, value); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final String label, final String propertyKey, final P<?> predicate) { + this.translator.addStep(getMethodName(), label, propertyKey, predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final String label, final String propertyKey, final Object value) { + this.translator.addStep(getMethodName(), label, propertyKey, value); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final T accessor, final Traversal<?, ?> propertyTraversal) { + this.translator.addStep(getMethodName(), accessor, propertyTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final String propertyKey, final Traversal<?, ?> propertyTraversal) { + this.translator.addStep(getMethodName(), propertyKey, propertyTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> has(final String propertyKey) { + this.translator.addStep(getMethodName(), propertyKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> hasNot(final String propertyKey) { + this.translator.addStep(getMethodName(), propertyKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> hasLabel(final String... labels) { + this.translator.addStep(getMethodName(), labels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> hasId(final Object... ids) { + this.translator.addStep(getMethodName(), ids); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> hasKey(final String... keys) { + this.translator.addStep(getMethodName(), keys); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> hasValue(final Object... values) { + this.translator.addStep(getMethodName(), values); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> is(final P<E> predicate) { + this.translator.addStep(getMethodName(), predicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> is(final Object value) { + this.translator.addStep(getMethodName(), value); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> not(final Traversal<?, ?> notTraversal) { + this.translator.addStep(getMethodName(), notTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> coin(final double probability) { + this.translator.addStep(getMethodName(), probability); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> range(final long low, final long high) { + this.translator.addStep(getMethodName(), low, high); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> range(final Scope scope, final long low, final long high) { + this.translator.addStep(getMethodName(), scope, low, high); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> limit(final long limit) { + this.translator.addStep(getMethodName(), limit); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> limit(final Scope scope, final long limit) { + this.translator.addStep(getMethodName(), scope, limit); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> tail() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> tail(final long limit) { + this.translator.addStep(getMethodName(), limit); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> tail(final Scope scope) { + this.translator.addStep(getMethodName(), scope); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> tail(final Scope scope, final long limit) { + this.translator.addStep(getMethodName(), scope, limit); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> timeLimit(final long timeLimit) { + this.translator.addStep(getMethodName(), timeLimit); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> simplePath() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> cyclicPath() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> sample(final int amountToSample) { + this.translator.addStep(getMethodName(), amountToSample); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> sample(final Scope scope, final int amountToSample) { + this.translator.addStep(getMethodName(), scope, amountToSample); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> drop() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + ///////////////////// SIDE-EFFECT STEPS ///////////////////// + + public GraphTraversal<S, E> sideEffect(final Consumer<Traverser<E>> consumer) { + this.translator.addStep(getMethodName(), consumer); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> sideEffect(final Traversal<?, ?> sideEffectTraversal) { + this.translator.addStep(getMethodName(), sideEffectTraversal); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> cap(final String sideEffectKey, final String... sideEffectKeys) { + this.translator.addStep(getMethodName(), sideEffectKey, sideEffectKeys); + return (GraphTraversal) this; + } + + public GraphTraversal<S, Edge> subgraph(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> aggregate(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> group(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> groupV3d0(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> groupCount(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> tree(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public <V, U> GraphTraversal<S, E> sack(final BiFunction<V, U, V> sackOperator) { + this.translator.addStep(getMethodName(), sackOperator); + return (GraphTraversal) this; + } + + + @Deprecated + public <V, U> GraphTraversal<S, E> sack(final BiFunction<V, U, V> sackOperator, final String elementPropertyKey) { + this.translator.addStep(getMethodName(), sackOperator, elementPropertyKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> store(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> profile(final String sideEffectKey) { + this.translator.addStep(getMethodName(), sideEffectKey); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> property(final VertexProperty.Cardinality cardinality, final Object key, final Object value, final Object... keyValues) { + this.translator.addStep(getMethodName(), cardinality, key, value, keyValues); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> property(final Object key, final Object value, final Object... keyValues) { + this.translator.addStep(getMethodName(), key, value, keyValues); + return (GraphTraversal) this; + } + + ///////////////////// BRANCH STEPS ///////////////////// + + public <M, E2> GraphTraversal<S, E2> branch(final Traversal<?, M> branchTraversal) { + this.translator.addStep(getMethodName(), branchTraversal); + return (GraphTraversal) this; + } + + public <M, E2> GraphTraversal<S, E2> branch(final Function<Traverser<E>, M> function) { + this.translator.addStep(getMethodName(), function); + return (GraphTraversal) this; + } + + public <M, E2> GraphTraversal<S, E2> choose(final Traversal<?, M> choiceTraversal) { + this.translator.addStep(getMethodName(), choiceTraversal); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> choose(final Traversal<?, ?> traversalPredicate, + final Traversal<?, E2> trueChoice, final Traversal<?, E2> falseChoice) { + this.translator.addStep(getMethodName(), traversalPredicate, trueChoice, falseChoice); + return (GraphTraversal) this; + } + + public <M, E2> GraphTraversal<S, E2> choose(final Function<E, M> choiceFunction) { + this.translator.addStep(getMethodName(), choiceFunction); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> choose(final Predicate<E> choosePredicate, + final Traversal<?, E2> trueChoice, final Traversal<?, E2> falseChoice) { + this.translator.addStep(getMethodName(), choosePredicate, trueChoice, falseChoice); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> optional(final Traversal<?, E2> optionalTraversal) { + this.translator.addStep(getMethodName(), optionalTraversal); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> union(final Traversal<?, E2>... unionTraversals) { + this.translator.addStep(getMethodName(), unionTraversals); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> coalesce(final Traversal<?, E2>... coalesceTraversals) { + this.translator.addStep(getMethodName(), coalesceTraversals); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> repeat(final Traversal<?, E> repeatTraversal) { + this.translator.addStep(getMethodName(), repeatTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> emit(final Traversal<?, ?> emitTraversal) { + this.translator.addStep(getMethodName(), emitTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> emit(final Predicate<Traverser<E>> emitPredicate) { + this.translator.addStep(getMethodName(), emitPredicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> emit() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> until(final Traversal<?, ?> untilTraversal) { + this.translator.addStep(getMethodName(), untilTraversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> until(final Predicate<Traverser<E>> untilPredicate) { + this.translator.addStep(getMethodName(), untilPredicate); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> times(final int maxLoops) { + this.translator.addStep(getMethodName(), maxLoops); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E2> local(final Traversal<?, E2> localTraversal) { + this.translator.addStep(getMethodName(), localTraversal); + return (GraphTraversal) this; + } + + /////////////////// VERTEX PROGRAM STEPS //////////////// + + public GraphTraversal<S, E> pageRank() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> pageRank(final double alpha) { + this.translator.addStep(getMethodName(), alpha); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> peerPressure() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> program(final VertexProgram<?> vertexProgram) { + this.translator.addStep(getMethodName(), vertexProgram); + return (GraphTraversal) this; + } + + ///////////////////// UTILITY STEPS ///////////////////// + + public GraphTraversal<S, E> as(final String stepLabel, final String... stepLabels) { + this.translator.addStep(getMethodName(), stepLabel, stepLabels); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> barrier() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> barrier(final int maxBarrierSize) { + this.translator.addStep(getMethodName(), maxBarrierSize); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> barrier(final Consumer<TraverserSet<Object>> barrierConsumer) { + this.translator.addStep(getMethodName(), barrierConsumer); + return (GraphTraversal) this; + } + + + //// BY-MODULATORS + + public GraphTraversal<S, E> by() { + this.translator.addStep(getMethodName()); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> by(final Traversal<?, ?> traversal) { + this.translator.addStep(getMethodName(), traversal); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> by(final T token) { + this.translator.addStep(getMethodName(), token); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> by(final String key) { + this.translator.addStep(getMethodName(), key); + return (GraphTraversal) this; + } + + public <V> GraphTraversal<S, E> by(final Function<V, Object> function) { + this.translator.addStep(getMethodName(), function); + return (GraphTraversal) this; + } + + //// COMPARATOR BY-MODULATORS + + public <V> GraphTraversal<S, E> by(final Traversal<?, ?> traversal, final Comparator<V> comparator) { + this.translator.addStep(getMethodName(), traversal, comparator); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> by(final Comparator<E> comparator) { + this.translator.addStep(getMethodName(), comparator); + return (GraphTraversal) this; + } + + public GraphTraversal<S, E> by(final Order order) { + this.translator.addStep(getMethodName(), order); + return (GraphTraversal) this; + } + + public <V> GraphTraversal<S, E> by(final String key, final Comparator<V> comparator) { + this.translator.addStep(getMethodName(), key, comparator); + return (GraphTraversal) this; + } + + public <U> GraphTraversal<S, E> by(final Function<U, Object> function, final Comparator comparator) { + this.translator.addStep(getMethodName(), function, comparator); + return (GraphTraversal) this; + } + + //// + + public <M, E2> GraphTraversal<S, E> option(final M pickToken, final Traversal<E, E2> traversalOption) { + this.translator.addStep(getMethodName(), pickToken, traversalOption); + return (GraphTraversal) this; + } + + public <E2> GraphTraversal<S, E> option(final Traversal<E, E2> traversalOption) { + this.translator.addStep(getMethodName(), traversalOption); + return (GraphTraversal) this; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSource.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSource.java new file mode 100644 index 0000000..9e0db74 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSource.java @@ -0,0 +1,239 @@ +/* + * 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 org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script; + +import org.apache.tinkerpop.gremlin.process.computer.Computer; +import org.apache.tinkerpop.gremlin.process.computer.GraphComputer; +import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies; +import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.process.traversal.util.Translator; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.Transaction; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.StringFactory; + +import java.util.function.BinaryOperator; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class ScriptGraphTraversalSource extends GraphTraversalSource { + + private final Translator<GraphTraversal> translator; + + public ScriptGraphTraversalSource(final Graph graph, final TraversalStrategies traversalStrategies, final Translator<GraphTraversal> translator) { + super(graph, traversalStrategies); + this.translator = translator; + } + + public ScriptGraphTraversalSource(final Graph graph, final Translator<GraphTraversal> translator) { + super(graph); + this.translator = translator; + } + + @Override + public TraversalStrategies getStrategies() { + return this.strategies; + } + + @Override + public Graph getGraph() { + return this.graph; + } + + @Override + public GraphTraversalSource clone() { + final ScriptGraphTraversalSource clone = (ScriptGraphTraversalSource) super.clone(); + clone.strategies = this.strategies.clone(); + return clone; + } + + + //// CONFIGURATIONS + + @Override + public GraphTraversalSource withComputer(final Computer computer) { + this.translator.addStrategy("withComputer", computer); + return this; + } + + @Override + public GraphTraversalSource withComputer(final Class<? extends GraphComputer> graphComputerClass) { + this.translator.addStrategy("withComputer", graphComputerClass); + return this; + } + + @Override + public GraphTraversalSource withComputer() { + this.translator.addStrategy("withComputer"); + return this; + } + + @Override + public GraphTraversalSource withStrategies(final TraversalStrategy... traversalStrategies) { + return super.withStrategies(traversalStrategies); + //this.translator.addStep("withStrategies", traversalStrategies); + } + + @Override + @SuppressWarnings({"unchecked", "varargs"}) + public GraphTraversalSource withoutStrategies(final Class<? extends TraversalStrategy>... traversalStrategyClasses) { + this.translator.addStrategy("withoutStrategies", traversalStrategyClasses); + return this; + } + + @Override + public <A> GraphTraversalSource withSideEffect(final String key, final Supplier<A> initialValue, final BinaryOperator<A> reducer) { + this.translator.addStrategy("withSideEffect", key, initialValue, reducer); + return this; + } + + @Override + public <A> GraphTraversalSource withSideEffect(final String key, final A initialValue, final BinaryOperator<A> reducer) { + this.translator.addStrategy("withSideEffect", key, initialValue, reducer); + return this; + } + + @Override + public <A> GraphTraversalSource withSideEffect(final String key, final A initialValue) { + this.translator.addStrategy("withSideEffect", key, initialValue); + return this; + } + + @Override + public <A> GraphTraversalSource withSideEffect(final String key, final Supplier<A> initialValue) { + this.translator.addStrategy("withSideEffect", key, initialValue); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) { + this.translator.addStrategy("withSack", initialValue, splitOperator, mergeOperator); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) { + this.translator.addStrategy("withSack", initialValue, splitOperator, mergeOperator); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final A initialValue) { + this.translator.addStrategy("withSack", initialValue); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final Supplier<A> initialValue) { + this.translator.addStrategy("withSack", initialValue); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator) { + this.translator.addStrategy("withSack", initialValue, splitOperator); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator) { + this.translator.addStrategy("withSack", initialValue, splitOperator); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final Supplier<A> initialValue, final BinaryOperator<A> mergeOperator) { + this.translator.addStrategy("withSack", initialValue, mergeOperator); + return this; + } + + @Override + public <A> GraphTraversalSource withSack(final A initialValue, final BinaryOperator<A> mergeOperator) { + this.translator.addStrategy("withSack", initialValue, mergeOperator); + return this; + } + + public GraphTraversalSource withBulk(final boolean useBulk) { + this.translator.addStrategy("withBulk", useBulk); + return this; + } + + public GraphTraversalSource withPath() { + this.translator.addStrategy("withPath"); + return this; + } + + //// SPAWNS + + /** + * @deprecated As of release 3.1.0, replaced by {@link #addV()} + */ + @Deprecated + public GraphTraversal<Vertex, Vertex> addV(final Object... keyValues) { + return this.generateTraversal("addV", keyValues); + } + + public GraphTraversal<Vertex, Vertex> addV(final String label) { + return this.generateTraversal("addV", label); + } + + public GraphTraversal<Vertex, Vertex> addV() { + return this.generateTraversal("addV"); + } + + public <S> GraphTraversal<S, S> inject(S... starts) { + return this.generateTraversal("inject", starts); + } + + public GraphTraversal<Vertex, Vertex> V(final Object... vertexIds) { + return this.generateTraversal("V", vertexIds); + } + + public GraphTraversal<Edge, Edge> E(final Object... edgesIds) { + return this.generateTraversal("E", edgesIds); + } + + private GraphTraversal generateTraversal(final String stepName, final Object... arguments) { + __.setAnonymousGraphTraversalSupplier(this.translator::__); + final Translator clone = this.translator.clone(); + clone.addStep(stepName, arguments); + final GraphTraversal traversal = new ScriptGraphTraversal(this.graph, clone); + traversal.asAdmin().setStrategies(this.strategies); + return traversal; + } + + + public Transaction tx() { + return this.graph.tx(); + } + + + @Override + public String toString() { + return StringFactory.traversalSourceString(this); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/Translator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/Translator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/Translator.java new file mode 100644 index 0000000..e3438cb --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/Translator.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 org.apache.tinkerpop.gremlin.process.traversal.util; + +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public interface Translator<V extends Traversal> extends Cloneable { + + public String getScriptEngine(); + + public String getAlias(); + + public void addStep(final String stepName, final Object... arguments); + + public default void addStrategy(final String strategyName, final Object... arguments) { + this.addStep(strategyName, arguments); + } + + public V __(); + + public String getTraversalScript(); + + public Translator<V> clone(); +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java index 455b1a4..0e95d29 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java @@ -23,7 +23,10 @@ import org.apache.tinkerpop.gremlin.process.computer.GraphComputer; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script.ScriptGraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.util.Translator; import org.apache.tinkerpop.gremlin.structure.io.Io; import org.apache.tinkerpop.gremlin.structure.io.IoRegistry; import org.apache.tinkerpop.gremlin.structure.util.FeatureDescriptor; @@ -183,6 +186,10 @@ public interface Graph extends AutoCloseable, Host { return new GraphTraversalSource(this); } + public default GraphTraversalSource traversal(final Translator<GraphTraversal> translator) { + return new ScriptGraphTraversalSource(this, translator); + } + /** * Get the {@link Vertex} objects in this graph with the provided vertex ids. If no ids are provided, get all * vertices. Note that a vertex identifier does not need to correspond to the actual id used in the graph. It http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSourceTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSourceTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSourceTest.java new file mode 100644 index 0000000..fe7ad1f --- /dev/null +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalSourceTest.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 org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script.ScriptGraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script.ScriptGraphTraversalSource; +import org.junit.Test; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class ScriptGraphTraversalSourceTest { + + private static Set<String> NO_GRAPH = new HashSet<>(Arrays.asList("clone", "iterate")); + + @Test + public void scriptGraphTraversalSourceShouldHaveMethodsOfGraphTraversalSource() { + for (Method methodA : GraphTraversalSource.class.getMethods()) { + if ((GraphTraversal.class.isAssignableFrom(methodA.getReturnType()) || GraphTraversalSource.class.isAssignableFrom(methodA.getReturnType())) && !NO_GRAPH.contains(methodA.getName())) { + boolean found = false; + final String methodAName = methodA.getName(); + final String methodAParameters = Arrays.asList(methodA.getParameterTypes()).toString(); + for (final Method methodB : ScriptGraphTraversalSource.class.getDeclaredMethods()) { + final String methodBName = methodB.getName(); + final String methodBParameters = Arrays.asList(methodB.getParameterTypes()).toString(); + if (methodAName.equals(methodBName) && methodAParameters.equals(methodBParameters)) + found = true; + } + if (!found) + throw new IllegalStateException(ScriptGraphTraversal.class.getSimpleName() + " is missing the following method: " + methodAName + ":" + methodAParameters); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalTest.java new file mode 100644 index 0000000..8ce7f23 --- /dev/null +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/script/ScriptGraphTraversalTest.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 org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script.ScriptGraphTraversal; +import org.junit.Test; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class ScriptGraphTraversalTest { + + private static Set<String> NO_GRAPH = new HashSet<>(Arrays.asList("asAdmin","iterate")); + + @Test + public void scriptGraphTraversalShouldHaveMethodsOfGraphTraversal() { + for (Method methodA : GraphTraversal.class.getMethods()) { + if (GraphTraversal.class.isAssignableFrom(methodA.getReturnType()) && !NO_GRAPH.contains(methodA.getName())) { + boolean found = false; + final String methodAName = methodA.getName(); + final String methodAParameters = Arrays.asList(methodA.getParameterTypes()).toString(); + for (final Method methodB : ScriptGraphTraversal.class.getDeclaredMethods()) { + final String methodBName = methodB.getName(); + final String methodBParameters = Arrays.asList(methodB.getParameterTypes()).toString(); + if (methodAName.equals(methodBName) && methodAParameters.equals(methodBParameters)) + found = true; + } + if (!found) + throw new IllegalStateException(ScriptGraphTraversal.class.getSimpleName() + " is missing the following method: " + methodAName + ":" + methodAParameters); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java index a6d3609..11400ba 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java @@ -23,6 +23,7 @@ import groovy.json.JsonBuilder; import org.apache.commons.configuration.Configuration; import org.apache.tinkerpop.gremlin.groovy.function.GFunction; import org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader; +import org.apache.tinkerpop.gremlin.groovy.process.traversal.dsl.graph.GroovyTranslator; import org.apache.tinkerpop.gremlin.process.computer.Computer; import org.apache.tinkerpop.gremlin.process.computer.GraphComputer; import org.apache.tinkerpop.gremlin.process.computer.bulkdumping.BulkDumperVertexProgram; @@ -108,6 +109,7 @@ public abstract class AbstractImportCustomizerProvider implements ImportCustomiz imports.add(VertexProgramStrategy.class.getPackage().getName() + DOT_STAR); // computer decoration strategies imports.add(GraphFilterStrategy.class.getPackage().getName() + DOT_STAR); // computer optimization strategies imports.add(Event.class.getPackage().getName() + DOT_STAR); // eventing + imports.add(GroovyTranslator.class.getPackage().getName() + DOT_STAR); // groovy translator staticImports.add(P.class.getCanonicalName() + DOT_STAR); staticImports.add(Order.class.getCanonicalName() + DOT_STAR); http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/process/traversal/dsl/graph/GroovyTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/process/traversal/dsl/graph/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/process/traversal/dsl/graph/GroovyTranslator.java new file mode 100644 index 0000000..639fa04 --- /dev/null +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/process/traversal/dsl/graph/GroovyTranslator.java @@ -0,0 +1,153 @@ +/* + * 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 org.apache.tinkerpop.gremlin.groovy.process.traversal.dsl.graph; + +import org.apache.tinkerpop.gremlin.process.traversal.P; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script.ScriptGraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; +import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; +import org.apache.tinkerpop.gremlin.process.traversal.util.Translator; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; +import org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator; +import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class GroovyTranslator implements Translator<GraphTraversal> { + + private StringBuilder traversalScript; + private final String alias; + + public GroovyTranslator(final String alias) { + this.alias = alias; + this.traversalScript = new StringBuilder(this.alias); + + } + + @Override + public String getScriptEngine() { + return "gremlin-groovy"; + } + + @Override + public String getAlias() { + return this.alias; + } + + @Override + public void addStep(final String stepName, final Object... arguments) { + // flatten the arguments into a single array + final Object[] objects = Stream.of(arguments) + .flatMap(arg -> + IteratorUtils.stream(arg instanceof Object[] ? + new ArrayIterator<>((Object[]) arg) : + IteratorUtils.of(arg))) + .toArray(); + if (objects.length == 0) + this.traversalScript.append(".").append(stepName).append("()"); + else { + this.traversalScript.append("."); + String temp = stepName + "("; + for (final Object object : objects) { + temp = temp + convertToString(object) + ","; + } + this.traversalScript.append(temp.substring(0, temp.length() - 1) + ")"); + } + } + + @Override + public GraphTraversal __() { + return new ScriptGraphTraversal(EmptyGraph.instance(), new GroovyTranslator("__")); + } + + @Override + public String getTraversalScript() { + return this.traversalScript.toString(); + } + + @Override + public GroovyTranslator clone() { + try { + final GroovyTranslator clone = (GroovyTranslator) super.clone(); + clone.traversalScript = new StringBuilder(this.traversalScript); + return clone; + } catch (final CloneNotSupportedException e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + + public static final GroovyTranslator of(final String alias) { + return new GroovyTranslator(alias); + } + + /////// + + private static String convertToString(final Object object) { + if (object instanceof String) + return "\"" + object + "\""; + else if (object instanceof List) { + final List list = new ArrayList<>(((List) object).size()); + for (final Object item : (List) object) { + list.add(item instanceof String ? "'" + item + "'" : convertToString(item)); // hack + } + return list.toString(); + } else if (object instanceof Long) + return object + "L"; + else if (object instanceof Double) + return object + "d"; + else if (object instanceof Float) + return object + "f"; + else if (object instanceof Integer) + return "(int) " + object; + else if (object instanceof Class) + return ((Class) object).getCanonicalName(); + else if (object instanceof P) + return convertPToString((P) object, new StringBuilder()).toString(); + else if (object instanceof Enum) + return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString(); + else if (object instanceof Element) + return convertToString(((Element) object).id()); // hack + else if (object instanceof ScriptGraphTraversal) + return ((ScriptGraphTraversal) object).getTraversalScript(); + else + return null == object ? "null" : object.toString(); + } + + private static StringBuilder convertPToString(final P p, final StringBuilder current) { + if (p instanceof ConnectiveP) { + final List<P<?>> list = ((ConnectiveP) p).getPredicates(); + for (int i = 0; i < list.size(); i++) { + convertPToString(list.get(i), current); + if (i < list.size() - 1) + current.append(p instanceof OrP ? "._or(" : "._and("); + } + current.append(")"); + } else + current.append("P.").append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")"); + return current; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/process/variant/python/PythonTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/process/variant/python/PythonTranslator.java b/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/process/variant/python/PythonTranslator.java new file mode 100644 index 0000000..3a0dbee --- /dev/null +++ b/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/process/variant/python/PythonTranslator.java @@ -0,0 +1,258 @@ +/* + * 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 org.apache.tinkerpop.gremlin.process.variant.python; + +import org.apache.tinkerpop.gremlin.process.traversal.Operator; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.P; +import org.apache.tinkerpop.gremlin.process.traversal.Pop; +import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions; +import org.apache.tinkerpop.gremlin.process.traversal.Scope; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.script.ScriptGraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException; +import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; +import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; +import org.apache.tinkerpop.gremlin.process.traversal.util.Translator; +import org.apache.tinkerpop.gremlin.structure.Column; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph; +import org.apache.tinkerpop.gremlin.util.ScriptEngineCache; +import org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator; +import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; + +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import javax.script.SimpleBindings; +import java.io.File; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class PythonTranslator implements Translator<GraphTraversal> { + + private static boolean isTesting = Boolean.valueOf(System.getProperty("is.testing", "false")); + private static ScriptEngine JYTHON_ENGINE; + private static boolean IMPORT_STATICS = false; + //// + private static final Set<String> STEP_NAMES = Stream.of(GraphTraversal.class.getMethods()).filter(method -> Traversal.class.isAssignableFrom(method.getReturnType())).map(Method::getName).collect(Collectors.toSet()); + private static final Set<String> PREFIX_NAMES = new HashSet<>(Arrays.asList("as", "in", "and", "or", "is", "not", "from", "global")); + private static final Set<String> NO_STATIC = Stream.of(T.values(), Operator.values()) + .flatMap(arg -> IteratorUtils.stream(new ArrayIterator<>(arg))) + .map(arg -> ((Enum) arg).name()) + .collect(Collectors.toCollection(() -> new HashSet<>(Arrays.asList("not")))); + + static { + if (isTesting) { + IMPORT_STATICS = new Random().nextBoolean(); + try { + final String rootPackageName = (new File("gremlin-variant").exists() ? "gremlin-variant/" : "") + "src/main/jython/"; + final String gremlinPythonPackageName = rootPackageName + "/gremlin_python"; + final String gremlinDriverPackageName = rootPackageName + "/gremlin_driver"; + final String gremlinPythonModuleName = gremlinPythonPackageName + "/gremlin_python.py"; + GremlinPythonGenerator.create(gremlinPythonModuleName); + JYTHON_ENGINE = ScriptEngineCache.get("jython"); + JYTHON_ENGINE.eval("import sys"); + JYTHON_ENGINE.eval("sys.path.append('" + gremlinPythonPackageName + "')"); + JYTHON_ENGINE.eval("sys.path.append('" + gremlinDriverPackageName + "')"); + JYTHON_ENGINE.eval("from gremlin_python import *"); + JYTHON_ENGINE.eval("from gremlin_python import __"); + if (IMPORT_STATICS) + JYTHON_ENGINE.eval("for k in statics:\n globals()[k] = statics[k]"); + } catch (final ScriptException e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + } + + private StringBuilder traversalScript; + private final String alias; + private final String scriptEngine; + + public PythonTranslator(final String scriptEngine, final String alias) { + this.scriptEngine = scriptEngine; + this.alias = alias; + this.traversalScript = new StringBuilder(this.alias); + } + + @Override + public String getAlias() { + return this.alias; + } + + @Override + public String getScriptEngine() { + return this.scriptEngine; + } + + @Override + public GraphTraversal __() { + return new ScriptGraphTraversal(EmptyGraph.instance(), new PythonTranslator(this.scriptEngine, "__")); + } + + @Override + public String getTraversalScript() { + if (isTesting && !this.alias.equals("__")) { + try { + if (traversalScript.toString().contains("$")) + throw new VerificationException("Lambdas are currently not supported: " + this.traversalScript.toString(), EmptyTraversal.instance()); + + final Bindings jythonBindings = new SimpleBindings(); + jythonBindings.put(this.alias, JYTHON_ENGINE.eval("PythonGraphTraversalSource(\"" + this.alias + "\", None)")); + JYTHON_ENGINE.getContext().setBindings(jythonBindings, ScriptContext.GLOBAL_SCOPE); + return JYTHON_ENGINE.eval(this.traversalScript.toString()).toString(); + } catch (final ScriptException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } else { + return this.traversalScript.toString(); + } + } + + @Override + public void addStep(final String stepName, final Object... arguments) { + // flatten the arguments into a single array + final Object[] objects = Stream.of(arguments) + .flatMap(arg -> + IteratorUtils.stream(arg instanceof Object[] ? + new ArrayIterator<>((Object[]) arg) : + IteratorUtils.of(arg))) + .toArray(); + if (objects.length == 0) + this.traversalScript.append(".").append(convertStepName(stepName)).append("()"); + else if (stepName.equals("range") && 2 == objects.length) + this.traversalScript.append("[").append(objects[0]).append(":").append(objects[1]).append("]"); + else if (stepName.equals("limit") && 1 == objects.length) + this.traversalScript.append("[0:").append(objects[0]).append("]"); + else if (stepName.equals("values") && 1 == objects.length && !traversalScript.toString().equals("__") && !STEP_NAMES.contains(objects[0].toString())) + this.traversalScript.append(".").append(objects[0]); + else { + this.traversalScript.append("."); + String temp = convertStepName(stepName) + "("; + for (final Object object : objects) { + temp = temp + convertToString(object) + ","; + } + this.traversalScript.append(temp.substring(0, temp.length() - 1)).append(")"); + } + if (IMPORT_STATICS && this.traversalScript.toString().startsWith("__.") + && !NO_STATIC.stream().filter(name -> this.traversalScript.toString().contains(name)).findAny().isPresent()) + traversalScript.delete(0, 3); + if (isTesting && !IMPORT_STATICS) + assert this.traversalScript.toString().startsWith(this.alias + "."); + } + + @Override + public PythonTranslator clone() { + try { + final PythonTranslator clone = (PythonTranslator) super.clone(); + clone.traversalScript = new StringBuilder(this.traversalScript); + return clone; + } catch (final CloneNotSupportedException e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + + /////// + + private static String convertToString(final Object object) { + if (object instanceof String) + return "\"" + object + "\""; + else if (object instanceof List) { + final List list = new ArrayList<>(((List) object).size()); + for (final Object item : (List) object) { + list.add(item instanceof String ? "'" + item + "'" : convertToString(item)); // hack + } + return list.toString(); + } else if (object instanceof Long) + return object + "L"; + else if (object instanceof Class) + return ((Class) object).getCanonicalName(); + else if (object instanceof SackFunctions.Barrier) + return convertStatic("Barrier.") + object.toString(); + else if (object instanceof VertexProperty.Cardinality) + return "Cardinality." + object.toString(); + else if (object instanceof Direction) + return convertStatic("Direction.") + object.toString(); + else if (object instanceof Operator) + return convertStatic("Operator.") + convertStepName(object.toString()); // to catch and/or + else if (object instanceof Pop) + return convertStatic("Pop.") + object.toString(); + else if (object instanceof Column) + return convertStatic("Column.") + object.toString(); + else if (object instanceof P) + return convertPToString((P) object, new StringBuilder()).toString(); + else if (object instanceof T) + return convertStatic("T.") + object.toString(); + else if (object instanceof Order) + return convertStatic("Order.") + object.toString(); + else if (object instanceof Scope) + return convertStatic("Scope.") + convertStepName(object.toString()); // to catch global + else if (object instanceof Element) + return convertToString(((Element) object).id()); // hack + else if (object instanceof ScriptGraphTraversal) + return ((ScriptGraphTraversal) object).getTraversalScript().toString(); + else if (object instanceof Boolean) + return object.equals(Boolean.TRUE) ? "True" : "False"; + else + return null == object ? "" : object.toString(); + } + + private static String convertStatic(final String name) { + return IMPORT_STATICS ? "" : name; + } + + private static String convertStepName(final String stepName) { + if (PREFIX_NAMES.contains(stepName)) + return "_" + stepName; + else + return stepName; + } + + private static StringBuilder convertPToString(final P p, final StringBuilder current) { + if (p instanceof ConnectiveP) { + final List<P<?>> list = ((ConnectiveP) p).getPredicates(); + for (int i = 0; i < list.size(); i++) { + convertPToString(list.get(i), current); + if (i < list.size() - 1) + current.append(p instanceof OrP ? "._or(" : "._and("); + } + current.append(")"); + } else + current.append(convertStatic("P.")).append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")"); + return current; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/47e71228/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/process/variant/VariantConverter.java ---------------------------------------------------------------------- diff --git a/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/process/variant/VariantConverter.java b/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/process/variant/VariantConverter.java deleted file mode 100644 index 110a1ef..0000000 --- a/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/process/variant/VariantConverter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 org.apache.tinkerpop.gremlin.process.variant; - -import javax.script.ScriptException; - -/** - * @author Marko A. Rodriguez (http://markorodriguez.com) - */ -public interface VariantConverter { - - public void addStep(final StringBuilder currentTraversal, final String stepName, final Object... arguments); - - public String generateGremlinGroovy(final StringBuilder currentTraversal) throws ScriptException; -}