You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/08/10 14:54:48 UTC
tinkerpop git commit: Added the much needed
Bytecode.getInstructions() method. Was able to really make GroovyTranslator
and PythonTranslator more compact and easy to reason about. Optimized a few
things in those respective translators. TranslationStrateg
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1278 c3ec2f09a -> b11bf2077
Added the much needed Bytecode.getInstructions() method. Was able to really make GroovyTranslator and PythonTranslator more compact and easy to reason about. Optimized a few things in those respective translators. TranslationStrategy (used in testing) inserts bindings for various arguments like knows/created so we know that bindings in the various translations are working as expected. Bytecode.getStep/SourceInstructions() now returns Iterable, not List.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/b11bf207
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/b11bf207
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/b11bf207
Branch: refs/heads/TINKERPOP-1278
Commit: b11bf2077036a7d0b4b7e7d06b2cfe870122e1a1
Parents: c3ec2f0
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Aug 10 08:53:57 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Aug 10 08:54:37 2016 -0600
----------------------------------------------------------------------
.../gremlin/process/traversal/Bytecode.java | 61 ++++++++++++++++----
.../process/traversal/util/BytecodeHelper.java | 13 +----
.../graphson/GraphSONTraversalSerializers.java | 4 +-
.../gremlin/groovy/jsr223/GroovyTranslator.java | 39 +++++--------
.../jsr223/GremlinJythonScriptEngine.java | 2 +-
.../gremlin/python/jsr223/PythonTranslator.java | 41 +++++--------
.../jsr223/PythonGraphSONJavaTranslator.java | 12 +---
.../gremlin/python/jsr223/PythonProvider.java | 2 +-
.../decoration/TranslationStrategy.java | 32 +++++++++-
9 files changed, 114 insertions(+), 92 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
index 0be140c..ef82d8e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
@@ -20,21 +20,24 @@
package org.apache.tinkerpop.gremlin.process.traversal;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
- * When a {@link TraversalSource} is manipulated, a {@link Traversal} is spawned and then mutated, a language
- * agnostic representation of those mutations is recorded in a byte code instance. Byte code is simply a list
- * of ordered instructions where an instruction is a string operator and an array of arguments. Byte code is used by
- * {@link Translator} instances which translate a traversal to another language by analyzing the
- * byte code as opposed to the Java traversal object representation on heap.
+ * When a {@link TraversalSource} is manipulated and then a {@link Traversal} is spawned and mutated, a language
+ * agnostic representation of those mutations is recorded in a bytecode instance. Bytecode is simply a list
+ * of ordered instructions where an instruction is a string operator and a (flattened) array of arguments.
+ * Bytecode is used by {@link Translator} instances which are able to translate a traversal in one language to another
+ * by analyzing the bytecode as opposed to the Java traversal object representation on heap.
+ * <p>
+ * Bytecode can be serialized between environments and machines by way of a GraphSON representation.
+ * Thus, Gremlin-Python can create bytecode in Python and ship it to Gremlin-Java for evaluation in Java.
*
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -42,9 +45,14 @@ public final class Bytecode implements Cloneable, Serializable {
private List<Instruction> sourceInstructions = new ArrayList<>();
private List<Instruction> stepInstructions = new ArrayList<>();
- // required for Gremlin-Java
private transient Bindings bindings = null;
+ /**
+ * Add a {@link TraversalSource} instruction to the bytecode.
+ *
+ * @param sourceName the traversal source method name (e.g. withSack())
+ * @param arguments the traversal source method arguments
+ */
public void addSource(final String sourceName, final Object... arguments) {
if (sourceName.equals(TraversalSource.Symbols.withBindings)) {
this.bindings = (Bindings) arguments[0];
@@ -55,19 +63,50 @@ public final class Bytecode implements Cloneable, Serializable {
}
}
+ /**
+ * Add a {@link Traversal} instruction to the bytecode.
+ *
+ * @param stepName the traversal method name (e.g. out())
+ * @param arguments the traversal method arguments
+ */
public void addStep(final String stepName, final Object... arguments) {
this.stepInstructions.add(new Instruction(stepName, flattenArguments(arguments)));
if (null != this.bindings) this.bindings.clear();
}
- public List<Instruction> getSourceInstructions() {
- return Collections.unmodifiableList(this.sourceInstructions);
+ /**
+ * Get the {@link TraversalSource} instructions associated with this bytecode.
+ *
+ * @return an iterable of instructions
+ */
+ public Iterable<Instruction> getSourceInstructions() {
+ return this.sourceInstructions;
}
- public List<Instruction> getStepInstructions() {
- return Collections.unmodifiableList(this.stepInstructions);
+ /**
+ * Get the {@link Traversal} instructions associated with this bytecode.
+ *
+ * @return an iterable of instructions
+ */
+ public Iterable<Instruction> getStepInstructions() {
+ return this.stepInstructions;
}
+ /**
+ * Get both the {@link TraversalSource} and {@link Traversal} instructions of this bytecode.
+ * The traversal source instructions are provided prior to the traversal instructions.
+ *
+ * @return an interable of all the instructions in this bytecode
+ */
+ public Iterable<Instruction> getInstructions() {
+ return () -> IteratorUtils.concat(this.sourceInstructions.iterator(), this.stepInstructions.iterator());
+ }
+
+ /**
+ * Get all the bindings (in a nested, recurssive manner) from all the arguments of all the instructions of this bytecode.
+ *
+ * @return a map of string variable and object value bindings
+ */
public Map<String, Object> getBindings() {
final Map<String, Object> bindingsMap = new HashMap<>();
for (final Instruction instruction : this.sourceInstructions) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
index 43f3828..dc611d6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
@@ -48,18 +48,7 @@ public final class BytecodeHelper {
}
public static Optional<String> getLambdaLanguage(final Bytecode bytecode) {
- for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
- for (Object object : instruction.getArguments()) {
- if (object instanceof Lambda)
- return Optional.of(((Lambda) object).getLambdaLanguage());
- else if (object instanceof Bytecode) {
- final Optional<String> temp = BytecodeHelper.getLambdaLanguage((Bytecode) object);
- if (temp.isPresent())
- return temp;
- }
- }
- }
- for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
+ for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
for (Object object : instruction.getArguments()) {
if (object instanceof Lambda)
return Optional.of(((Lambda) object).getLambdaLanguage());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
index 037ce96..89f0b42 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
@@ -88,7 +88,7 @@ public final class GraphSONTraversalSerializers {
throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("@type", "Bytecode");
- if (!bytecode.getSourceInstructions().isEmpty()) {
+ if (bytecode.getSourceInstructions().iterator().hasNext()) {
jsonGenerator.writeArrayFieldStart("source");
for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
jsonGenerator.writeStartArray();
@@ -100,7 +100,7 @@ public final class GraphSONTraversalSerializers {
}
jsonGenerator.writeEndArray();
}
- if (!bytecode.getStepInstructions().isEmpty()) {
+ if (bytecode.getStepInstructions().iterator().hasNext()) {
jsonGenerator.writeArrayFieldStart("step");
for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
jsonGenerator.writeStartArray();
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
index fdb3ece..9349c90 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
@@ -33,7 +33,6 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -88,31 +87,23 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
private String internalTranslate(final String start, final Bytecode bytecode) {
final StringBuilder traversalScript = new StringBuilder(start);
- for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
- processInstruction(traversalScript, instruction);
- }
- for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
- processInstruction(traversalScript, instruction);
- }
- return traversalScript.toString();
- }
-
- private void processInstruction(final StringBuilder traversalScript, final Bytecode.Instruction instruction) {
- final String methodName = instruction.getOperator();
- if (methodName.equals(TraversalSource.Symbols.withStrategies))
- return;
- final Object[] arguments = instruction.getArguments();
- final List<Object> objects = Arrays.asList(arguments);
- if (objects.isEmpty())
- traversalScript.append(".").append(methodName).append("()");
- else {
- traversalScript.append(".");
- String temp = methodName + "(";
- for (final Object object : objects) {
- temp = temp + convertToString(object) + ",";
+ for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
+ final String methodName = instruction.getOperator();
+ if (methodName.equals(TraversalSource.Symbols.withStrategies))
+ continue;
+ final Object[] arguments = instruction.getArguments();
+ if (0 == arguments.length)
+ traversalScript.append(".").append(methodName).append("()");
+ else {
+ traversalScript.append(".");
+ String temp = methodName + "(";
+ for (final Object object : arguments) {
+ temp = temp + convertToString(object) + ",";
+ }
+ traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
}
- traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
}
+ return traversalScript.toString();
}
private String convertToString(final Object object) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
index 3ea21e4..a10cb3f 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
@@ -119,7 +119,7 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
public Traversal.Admin eval(final Bytecode bytecode, final Bindings bindings) throws ScriptException {
bindings.putAll(bytecode.getBindings());
// TODO: this is kinda bad because it makes the assumption that we will always alias to "g" (which is generally true, but maybe better to not hardcode?)
- return (Traversal.Admin) this.eval(new PythonTranslator("g", "__").translate(bytecode), bindings);
+ return (Traversal.Admin) this.eval(PythonTranslator.of("g", "__").translate(bytecode), bindings);
}
@Override
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
index 70bb38b..20cc21b 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
@@ -62,14 +62,22 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
private String anonymousTraversal;
private final boolean importStatics;
- public PythonTranslator(final String traversalSource, final String anonymousTraversal, final boolean importStatics) {
+ private PythonTranslator(final String traversalSource, final String anonymousTraversal, final boolean importStatics) {
this.traversalSource = traversalSource;
this.anonymousTraversal = anonymousTraversal;
this.importStatics = importStatics;
}
- public PythonTranslator(final String traversalSource, final String anonymousTraversal) {
- this(traversalSource, anonymousTraversal, false);
+ public static final PythonTranslator of(final String traversalSource, final String anonymousTraversal, final boolean importStatics) {
+ return new PythonTranslator(traversalSource, anonymousTraversal, importStatics);
+ }
+
+ public static final PythonTranslator of(final String traversalSource, final String anonymousTraversal) {
+ return new PythonTranslator(traversalSource, anonymousTraversal, false);
+ }
+
+ public static final PythonTranslator of(final String traversalSource) {
+ return new PythonTranslator(traversalSource, "__", false);
}
@Override
@@ -104,32 +112,12 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
private String internalTranslate(final String start, final Bytecode bytecode) {
final StringBuilder traversalScript = new StringBuilder(start);
- for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
+ for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
final String methodName = instruction.getOperator();
+ final Object[] arguments = instruction.getArguments();
if (methodName.equals(TraversalSource.Symbols.withStrategies))
continue;
- final Object[] arguments = instruction.getArguments();
- if (0 == arguments.length)
- traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
- else {
- traversalScript.append(".");
- String temp = SymbolHelper.toPython(methodName) + "(";
- for (final Object object : arguments) {
- temp = temp + convertToString(object) + ",";
- }
- traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
- }
-
- // clip off __.
- if (this.importStatics && traversalScript.substring(0, 3).startsWith(this.anonymousTraversal + ".")
- && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(SymbolHelper.toPython(name))).findAny().isPresent()) {
- traversalScript.delete(0, 3);
- }
- }
- for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
- final String methodName = instruction.getOperator();
- final Object[] arguments = instruction.getArguments();
- if (0 == arguments.length)
+ else if (0 == arguments.length)
traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
else if (methodName.equals("range") && 2 == arguments.length)
traversalScript.append("[").append(arguments[0]).append(":").append(arguments[1]).append("]");
@@ -145,7 +133,6 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
}
traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
}
-
// clip off __.
if (this.importStatics && traversalScript.substring(0, 3).startsWith(this.anonymousTraversal + ".")
&& !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(SymbolHelper.toPython(name))).findAny().isPresent()) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
index 2a55228..f4e5cc7 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
@@ -24,8 +24,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.Translator;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
-import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
@@ -37,7 +35,7 @@ import java.io.ByteArrayInputStream;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends Traversal.Admin<?, ?>> implements Translator.StepTranslator<S, T> {
+final class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends Traversal.Admin<?, ?>> implements Translator.StepTranslator<S, T> {
private final PythonTranslator pythonTranslator;
private final JavaTranslator<S, T> javaTranslator;
@@ -65,14 +63,6 @@ public class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends T
@Override
public T translate(final Bytecode bytecode) {
-
- for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
- for (final Object argument : instruction.getArguments()) {
- if (argument.toString().contains("$"))
- throw new VerificationException("Lambdas are currently not supported: " + bytecode, EmptyTraversal.instance());
- }
- }
-
try {
final ScriptEngine jythonEngine = ScriptEngineCache.get("jython");
final Bindings bindings = jythonEngine.createBindings();
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
index 56b0963..1414f8b 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
@@ -157,7 +157,7 @@ public class PythonProvider extends AbstractGraphProvider {
throw new IllegalStateException(e.getMessage(), e);
}
final GraphTraversalSource g = graph.traversal();
- return g.withStrategies(new TranslationStrategy(g, new PythonGraphSONJavaTranslator<>(new PythonTranslator("g", "__", IMPORT_STATICS), JavaTranslator.of(g))));
+ return g.withStrategies(new TranslationStrategy(g, new PythonGraphSONJavaTranslator<>(PythonTranslator.of("g", "__", IMPORT_STATICS), JavaTranslator.of(g))));
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
index 5ad7401..92c9483 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
@@ -22,6 +22,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngine;
import org.apache.tinkerpop.gremlin.jsr223.SingleGremlinScriptEngineManager;
import org.apache.tinkerpop.gremlin.process.remote.traversal.strategy.decoration.RemoteStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Translator;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
@@ -71,13 +72,16 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers
// verifications to ensure unsupported steps do not exist in the traversal
if (Boolean.valueOf(System.getProperty("is.testing", "false")) &&
(traversal.getBytecode().toString().contains("$") || traversal.getBytecode().toString().contains("HashSetSupplier")))
- throw new VerificationException("Test suite does not support profiling nor lambdas", traversal);
+ throw new VerificationException("Test suite does not support lambdas", traversal);
final Traversal.Admin<?, ?> translatedTraversal;
+ final Bytecode bytecode = Boolean.valueOf(System.getProperty("is.testing", "false")) ?
+ insertBindingsForTesting(traversal.getBytecode()) :
+ traversal.getBytecode();
////////////////
if (this.translator instanceof Translator.StepTranslator) {
// reflection based translation
- translatedTraversal = (Traversal.Admin<?, ?>) this.translator.translate(traversal.getBytecode());
+ translatedTraversal = (Traversal.Admin<?, ?>) this.translator.translate(bytecode);
} else if (this.translator instanceof Translator.ScriptTranslator) {
try {
// script based translation
@@ -85,7 +89,7 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers
final Bindings bindings = scriptEngine.createBindings();
bindings.putAll(scriptEngine.getContext().getBindings(ScriptContext.ENGINE_SCOPE));
bindings.put(this.translator.getTraversalSource().toString(), this.traversalSource);
- translatedTraversal = (Traversal.Admin<?, ?>) scriptEngine.eval(traversal.getBytecode(), bindings);
+ translatedTraversal = (Traversal.Admin<?, ?>) scriptEngine.eval(bytecode, bindings);
} catch (final Exception e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
@@ -106,4 +110,26 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers
return POSTS;
}
+ private static final Bytecode insertBindingsForTesting(final Bytecode bytecode) {
+ final Bytecode newBytecode = new Bytecode();
+ bytecode.getSourceInstructions().forEach(instruction -> newBytecode.addSource(instruction.getOperator(), instruction.getArguments()));
+ for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
+ final Object[] args = instruction.getArguments();
+ final Object[] newArgs = new Object[args.length];
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("knows"))
+ newArgs[i] = new Bytecode.Binding<>("a", "knows");
+ else if (args[i].equals("created"))
+ newArgs[i] = new Bytecode.Binding<>("b", "created");
+ else if (args[i].equals(10))
+ newArgs[i] = new Bytecode.Binding<>("c", 10);
+ else
+ newArgs[i] = args[i];
+ }
+ newBytecode.addStep(instruction.getOperator(), newArgs);
+ }
+ return newBytecode;
+ }
+
}