You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/10/31 19:06:20 UTC
[tinkerpop] branch TINKERPOP-2072 updated (b1998da -> 811915a)
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a change to branch TINKERPOP-2072
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.
discard b1998da TINKERPOP-2072 Refactored TypeTranslator for direction extension
discard 8a4c6ac wip
add 88c08b7 Bump to 3.3.5-SNAPSHOT CTR
add 84b419e Merge branch 'tp33'
add 6cadd07 typo, change plural to singular in MapReduce explanation
add b99338b Merge branch 'tp33'
add 68f069d repleaces EnumSet to HashSet
add 48cd7e2 Merge branch 'pr-951' into tp33
add cc50113 Merge branch 'tp33'
add 29eb3f0 TINKERPOP-2061 Added with() option for traversal configuration
add 11f9949 Merge pull request #961 from apache/TINKERPOP-2061
add 78e95b6 Fixed misspelling of javascript CTR
add b9aad1f Added docker hub info to release email template CTR
add a06ec1e Added (tm) in a few spots to docs CTR
add 92e0feb Added more (tm) to various docs CTR
add ff604e7 Fixed version in email template CTR
add a7ae62c Added a note for clarity for how the "release date" works CTR
add db429a8 Merge branch 'tp33'
add 759d1a7 TINKERPOP-2066 Bump to Groovy 2.5.3
add e145e54 Merge pull request #962 from apache/TINKERPOP-2066
add aef8437 TINKERPOP-2073 Generate tabs for static code blocks
add 51f75cc Merge pull request #965 from apache/TINKERPOP-2073
add f2e8bac Merge branch 'tp33'
add 7445d18 TINKERPOP-2074 Only push NuGet for current version CTR
add 971c348 Merge branch 'tp33'
add f603049 TINKERPOP-2062 added Traversal class to CoreImports
add 9a4dbe4 Merge pull request #971 from apache/TINKERPOP-2062
add e3d8946 Merge branch 'tp33'
add 4b635a4 Bump to 3.2.11-SNAPSHOT
add d5c4949 Merge branch 'tp32' into tp33
add ba6a19c Merge branch 'tp33'
add 5cc2536 TINKERPOP-2081: Fix PersistedOutputRDD to eager persist RDD
add ed2f061 Merge branch 'pr-973' into tp33
add c131918 Merge branch 'tp33'
add 767851f Backport 7445d18b05791e210c5d2682d7893ee4d47edb0a
add aacdf7a Merge branch 'tp32' into tp33
add 3bef734 Merge branch 'tp33'
add 4d2364c gremlin-python: g:Set graphson deserializer should return a python set
add 79cd801 Merge branch 'pr-964' into tp33
add 28a3d55 Merge branch 'tp33'
add 94d1e27 Change example to not mutate the graph.
add ddb2270 Merge branch 'tp32' into tp33
add 42371d8 Merge branch 'tp33'
add 9bda0fe Used regular ArrayList in assertion
add a9e0cc2 Merge branch 'tp33'
add c610a18 Add default create() method to VertexProgram.Builder and remove unnecessary methods from test VPs
add 717e29e ensure public
add 6dd4fed Merge pull request #967 from PBGraff/TINKERPOP-2077
add a224b07 Merge remote-tracking branch 'origin/tp33'
add cdd41da TINKERPOP-2068 bump jackson-databind to 2.9.7
add 82cd53d Merge branch 'TINKERPOP-2068-tp32' into TINKERPOP-2068-tp33
add eeed2c7 Merge branch 'TINKERPOP-2068-tp33' into TINKERPOP-2068-master
add 462079b Merge pull request #970 from apache/TINKERPOP-2068-master
new 811915a TINKERPOP-2072 Refactored TypeTranslator for direction extension
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (b1998da)
\
N -- N -- N refs/heads/TINKERPOP-2072 (811915a)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
CHANGELOG.asciidoc | 18 ++++++++++-
README.asciidoc | 2 +-
docs/preprocessor/awk/tabify.awk | 16 +++++++---
docs/src/dev/developer/release.asciidoc | 13 ++++++--
docs/src/dev/future/index.asciidoc | 8 ++---
docs/src/dev/io/index.asciidoc | 2 +-
docs/src/dev/provider/index.asciidoc | 8 ++---
docs/src/index.asciidoc | 2 +-
docs/src/recipes/index.asciidoc | 2 +-
docs/src/reference/gremlin-applications.asciidoc | 9 +++---
docs/src/reference/gremlin-variants.asciidoc | 7 +++--
docs/src/reference/intro.asciidoc | 12 ++++----
docs/src/reference/the-traversal.asciidoc | 2 +-
docs/src/tutorials/getting-started/index.asciidoc | 2 +-
.../tutorials/the-gremlin-console/index.asciidoc | 2 +-
docs/src/upgrade/index.asciidoc | 6 ++--
docs/src/upgrade/release-3.2.x-incubating.asciidoc | 7 +++++
docs/src/upgrade/release-3.3.x.asciidoc | 12 ++++++--
docs/src/upgrade/release-3.4.x.asciidoc | 12 ++++++--
gremlin-console/src/main/static/NOTICE | 2 +-
gremlin-core/pom.xml | 2 +-
.../tinkerpop/gremlin/jsr223/CoreImports.java | 2 ++
.../gremlin/process/computer/VertexProgram.java | 4 +++
.../gremlin/process/traversal/TraversalSource.java | 35 ++++++++++++++++++++++
.../traversal/dsl/graph/GraphTraversal.java | 1 +
.../traversal/dsl/graph/GraphTraversalSource.java | 17 +++++++++++
.../traversal/step/util/RequirementsStep.java | 11 +++++--
.../strategy/decoration/RequirementsStrategy.java | 4 +--
.../process/traversal/util/DefaultTraversal.java | 4 +--
.../process/traversal/util/TraversalHelper.java | 3 +-
.../Process/Traversal/GraphTraversalSource.cs | 16 ++++++++++
gremlin-dotnet/src/pom.xml | 4 +--
.../DriverRemoteConnection/GraphTraversalTests.cs | 6 ++--
.../lib/process/graph-traversal.js | 10 +++++++
.../gremlin_python/process/graph_traversal.py | 5 ++++
.../gremlin_python/structure/io/graphsonV3d0.py | 22 ++++++++++----
.../src/main/jython/tests/driver/test_client.py | 5 ++++
.../jython/tests/structure/io/test_graphsonV3d0.py | 11 ++++++-
.../gremlin/server/op/AbstractEvalOpProcessor.java | 6 ++--
gremlin-server/src/main/static/NOTICE | 2 +-
.../gremlin/server/GremlinServerIntegrateTest.java | 2 +-
gremlin-shaded/pom.xml | 2 +-
gremlin-test/features/map/Select.feature | 4 +--
.../process/computer/GraphComputerTest.java | 8 -----
.../process/traversal/step/branch/ChooseTest.java | 7 +++--
pom.xml | 2 +-
.../spark/structure/io/PersistedOutputRDD.java | 12 ++++++--
.../strategy/decoration/OptionsStrategyTest.java | 13 +++++++-
48 files changed, 278 insertions(+), 86 deletions(-)
[tinkerpop] 01/01: TINKERPOP-2072 Refactored TypeTranslator for
direction extension
Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch TINKERPOP-2072
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 811915a84651cf2fb6e11e99a8380a8d6713fbd5
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Fri Oct 19 11:42:58 2018 -0400
TINKERPOP-2072 Refactored TypeTranslator for direction extension
This approach makes it much easier to extend TypeTranslators as the core functionality of the GroovyTranslator is itself a TypeTranslator. Simply extend that and go. Probably should have been this way from the beginning.
---
CHANGELOG.asciidoc | 1 +
docs/src/upgrade/release-3.4.x.asciidoc | 16 ++
.../gremlin/process/traversal/Translator.java | 29 +-
.../groovy/jsr223/GremlinGroovyScriptEngine.java | 2 +-
.../gremlin/groovy/jsr223/GroovyTranslator.java | 294 +++++++++++----------
.../groovy/jsr223/GroovyTranslatorTest.java | 33 +--
6 files changed, 186 insertions(+), 189 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 402ed7c..34ba9d9 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -40,6 +40,7 @@ This release also includes changes from <<release-3-3-3, 3.3.3>>.
* Deprecated `Graph.io()` and related infrastructure.
* `GraphMLReader` better handles edge and vertex properties with the same name.
* Maintained order of annotations in metrics returned from `profile()`-step.
+* Refactored `TypeTranslator` to be directly extensible for `ScriptTranslator` functions.
* Bumped to Netty 4.1.25.
* Bumped to Spark 2.3.1.
* Bumped to Groovy 2.5.2.
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index d412fda..bc4b921 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -608,3 +608,19 @@ The extent to which TinkerPop tests "upsert" is fairly narrow. Graph providers t
should consider their own test suites carefully to ensure appropriate coverage.
See: link:https://issues.apache.org/jira/browse/TINKERPOP-1685[TINKERPOP-1685]
+
+==== TypeTranslator Changes
+
+The `TypeTranslator` experienced a change in its API and `GroovyTranslator` a change in expectations.
+
+`TypeTranslator` now implements `BiFunction` and takes the graph traversal source name as an argument along with the
+object to translate. This interface is implemented by default for Groovy with `GroovyTranslator.DefaultTypeTranslator`
+which encapsulates all the functionality of what `GroovyTranslator` formerly did by default. To provide customize
+translation, simply extend the `DefaultTypeTranslator` and override the methods.
+
+`GroovyTranslator` now expects that the `TypeTranslator` provide to it as part of its `of()` static method overload
+is "complete" - i.e. that it provides all the functionality to translate the types passed to it. Thus, a "complete"
+`TypeTranslator` is one that does everything that `DefaultTypeTranslator` does as a minimum requirement. Therefore,
+the extension model described above is the easiest way to get going with a custom `TypeTranslator` approach.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2072[TINKERPOP-2072]
\ No newline at end of file
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java
index 0346092..8cdd84d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java
@@ -19,7 +19,7 @@
package org.apache.tinkerpop.gremlin.process.traversal;
-import java.util.function.UnaryOperator;
+import java.util.function.BiFunction;
/**
* A Translator will translate {@link Bytecode} into another representation. That representation may be a
@@ -63,31 +63,10 @@ public interface Translator<S, T> {
public interface ScriptTranslator extends Translator<String, String> {
/**
- * Provides a way to customize and override the standard translation process. A {@link ScriptTranslator}
- * implementation can choose to expose a way to accept a {@code TypeTranslator} which will convert an incoming
- * object to a different form which will then be normally processed or can return a {@link Handled} object
- * with the already translated script.
+ * Provides a way for the {@link ScriptTranslator} to convert various data types to their string
+ * representations in their target language.
*/
- public interface TypeTranslator extends UnaryOperator<Object> {
- public static TypeTranslator identity() {
- return t -> t;
- }
- }
-
- /**
- * Contains a completed type translation from the {@link TypeTranslator}.
- */
- public class Handled {
- private final String translation;
-
- public Handled(final String translation) {
- this.translation = translation;
- }
-
- public String getTranslation() {
- return translation;
- }
- }
+ public interface TypeTranslator extends BiFunction<String, Object, Object> { }
}
/**
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
index dae427c..0cd55be 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
@@ -278,7 +278,7 @@ public class GremlinGroovyScriptEngine extends GroovyScriptEngineImpl implements
filter(p -> p instanceof TranslatorCustomizer).
map(p -> (TranslatorCustomizer) p).findFirst();
typeTranslator = translatorCustomizer.isPresent() ? translatorCustomizer.get().createTypeTranslator() :
- Translator.ScriptTranslator.TypeTranslator.identity();
+ new GroovyTranslator.DefaultTypeTranslator();
createClassLoader();
}
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 ae892f3..b961821 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
@@ -66,18 +66,19 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
}
public static final GroovyTranslator of(final String traversalSource) {
- return of(traversalSource, TypeTranslator.identity());
+ return of(traversalSource, null);
}
public static final GroovyTranslator of(final String traversalSource, final TypeTranslator typeTranslator) {
- return new GroovyTranslator(traversalSource, Optional.ofNullable(typeTranslator).orElse(TypeTranslator.identity()));
+ return new GroovyTranslator(traversalSource,
+ Optional.ofNullable(typeTranslator).orElseGet(DefaultTypeTranslator::new));
}
///////
@Override
public String translate(final Bytecode bytecode) {
- return this.internalTranslate(this.traversalSource, bytecode);
+ return typeTranslator.apply(traversalSource, bytecode).toString();
}
@Override
@@ -95,153 +96,158 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
return this.traversalSource;
}
- ///////
+ /**
+ * Performs standard type translation for the TinkerPop types to Groovy.
+ */
+ public static class DefaultTypeTranslator implements TypeTranslator {
- private String internalTranslate(final String start, final Bytecode bytecode) {
- final StringBuilder traversalScript = new StringBuilder(start);
- for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
- final String methodName = instruction.getOperator();
- if (0 == instruction.getArguments().length)
- traversalScript.append(".").append(methodName).append("()");
- else {
- traversalScript.append(".");
- String temp = methodName + "(";
- for (final Object object : instruction.getArguments()) {
- temp = temp + convertToString(object) + ",";
- }
- traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
- }
+ @Override
+ public Object apply(final String traversalSource, final Object o) {
+ if (o instanceof Bytecode)
+ return internalTranslate(traversalSource, (Bytecode) o);
+ else
+ return convertToString(o);
}
- return traversalScript.toString();
- }
- private String convertToString(final Object o) {
- // a TypeTranslator that returns Handled means that the typetranslator figure out how to convert the
- // object to a string and it should be used as-is, otherwise it gets passed down the line through the normal
- // process
- final Object object = typeTranslator.apply(o);
-
- if (object instanceof Handled)
- return ((Handled) object).getTranslation();
- else if (object instanceof Bytecode.Binding)
- return ((Bytecode.Binding) object).variable();
- else if (object instanceof Bytecode)
- return this.internalTranslate("__", (Bytecode) object);
- else if (object instanceof Traversal)
- return convertToString(((Traversal) object).asAdmin().getBytecode());
- else if (object instanceof String) {
- return (((String) object).contains("\"") ? "\"\"\"" + StringEscapeUtils.escapeJava((String) object) + "\"\"\"" : "\"" + StringEscapeUtils.escapeJava((String) object) + "\"")
- .replace("$", "\\$");
- } else if (object instanceof Set) {
- final Set<String> set = new HashSet<>(((Set) object).size());
- for (final Object item : (Set) object) {
- set.add(convertToString(item));
- }
- return set.toString() + " as Set";
- } else if (object instanceof List) {
- final List<String> list = new ArrayList<>(((List) object).size());
- for (final Object item : (List) object) {
- list.add(convertToString(item));
- }
- return list.toString();
- } else if (object instanceof Map) {
- final StringBuilder map = new StringBuilder("[");
- for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
- map.append("(").
- append(convertToString(entry.getKey())).
- append("):(").
- append(convertToString(entry.getValue())).
- append("),");
- }
+ protected String convertToString(final Object object) {
+ if (object instanceof Bytecode.Binding)
+ return ((Bytecode.Binding) object).variable();
+ else if (object instanceof Bytecode)
+ return internalTranslate("__", (Bytecode) object);
+ else if (object instanceof Traversal)
+ return convertToString(((Traversal) object).asAdmin().getBytecode());
+ else if (object instanceof String) {
+ return (((String) object).contains("\"") ? "\"\"\"" + StringEscapeUtils.escapeJava((String) object) + "\"\"\"" : "\"" + StringEscapeUtils.escapeJava((String) object) + "\"")
+ .replace("$", "\\$");
+ } else if (object instanceof Set) {
+ final Set<String> set = new HashSet<>(((Set) object).size());
+ for (final Object item : (Set) object) {
+ set.add(convertToString(item));
+ }
+ return set.toString() + " as Set";
+ } else if (object instanceof List) {
+ final List<String> list = new ArrayList<>(((List) object).size());
+ for (final Object item : (List) object) {
+ list.add(convertToString(item));
+ }
+ return list.toString();
+ } else if (object instanceof Map) {
+ final StringBuilder map = new StringBuilder("[");
+ for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
+ map.append("(").
+ append(convertToString(entry.getKey())).
+ append("):(").
+ append(convertToString(entry.getValue())).
+ append("),");
+ }
- // only need to remove this last bit if entries were added
- if (!((Map<?, ?>) object).isEmpty())
- map.deleteCharAt(map.length() - 1);
-
- return map.append("]").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 Timestamp)
- return "new java.sql.Timestamp(" + ((Timestamp) object).getTime() + ")";
- else if (object instanceof Date)
- return "new java.util.Date(" + ((Date) object).getTime() + ")";
- else if (object instanceof UUID)
- return "java.util.UUID.fromString('" + object.toString() + "')";
- else if (object instanceof P)
- return convertPToString((P) object, new StringBuilder()).toString();
- else if (object instanceof SackFunctions.Barrier)
- return "SackFunctions.Barrier." + object.toString();
- else if (object instanceof VertexProperty.Cardinality)
- return "VertexProperty.Cardinality." + object.toString();
- else if (object instanceof TraversalOptionParent.Pick)
- return "TraversalOptionParent.Pick." + object.toString();
- else if (object instanceof Enum)
- return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString();
- else if (object instanceof Element) {
- if (object instanceof Vertex) {
- final Vertex vertex = (Vertex) object;
- return "new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex(" +
- convertToString(vertex.id()) + "," +
- convertToString(vertex.label()) + ", Collections.emptyMap())";
- } else if (object instanceof Edge) {
- final Edge edge = (Edge) object;
- return "new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge(" +
- convertToString(edge.id()) + "," +
- convertToString(edge.label()) + "," +
- "Collections.emptyMap()," +
- convertToString(edge.outVertex().id()) + "," +
- convertToString(edge.outVertex().label()) + "," +
- convertToString(edge.inVertex().id()) + "," +
- convertToString(edge.inVertex().label()) + ")";
- } else {// VertexProperty
- final VertexProperty vertexProperty = (VertexProperty) object;
- return "new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty(" +
- convertToString(vertexProperty.id()) + "," +
- convertToString(vertexProperty.label()) + "," +
- convertToString(vertexProperty.value()) + "," +
- "Collections.emptyMap()," +
- convertToString(vertexProperty.element()) + ")";
- }
- } else if (object instanceof Lambda) {
- final String lambdaString = ((Lambda) object).getLambdaScript().trim();
- return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
- } else if (object instanceof TraversalStrategyProxy) {
- final TraversalStrategyProxy proxy = (TraversalStrategyProxy) object;
- if (proxy.getConfiguration().isEmpty())
- return proxy.getStrategyClass().getCanonicalName() + ".instance()";
- else
- return proxy.getStrategyClass().getCanonicalName() + ".create(new org.apache.commons.configuration.MapConfiguration(" + convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + "))";
- } else if (object instanceof TraversalStrategy) {
- return convertToString(new TraversalStrategyProxy(((TraversalStrategy) object)));
- } else
- return null == object ? "null" : object.toString();
- }
+ // only need to remove this last bit if entries were added
+ if (!((Map<?, ?>) object).isEmpty())
+ map.deleteCharAt(map.length() - 1);
+
+ return map.append("]").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 Timestamp)
+ return "new java.sql.Timestamp(" + ((Timestamp) object).getTime() + ")";
+ else if (object instanceof Date)
+ return "new java.util.Date(" + ((Date) object).getTime() + ")";
+ else if (object instanceof UUID)
+ return "java.util.UUID.fromString('" + object.toString() + "')";
+ else if (object instanceof P)
+ return convertPToString((P) object, new StringBuilder()).toString();
+ else if (object instanceof SackFunctions.Barrier)
+ return "SackFunctions.Barrier." + object.toString();
+ else if (object instanceof VertexProperty.Cardinality)
+ return "VertexProperty.Cardinality." + object.toString();
+ else if (object instanceof TraversalOptionParent.Pick)
+ return "TraversalOptionParent.Pick." + object.toString();
+ else if (object instanceof Enum)
+ return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString();
+ else if (object instanceof Element) {
+ if (object instanceof Vertex) {
+ final Vertex vertex = (Vertex) object;
+ return "new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex(" +
+ convertToString(vertex.id()) + "," +
+ convertToString(vertex.label()) + ", Collections.emptyMap())";
+ } else if (object instanceof Edge) {
+ final Edge edge = (Edge) object;
+ return "new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge(" +
+ convertToString(edge.id()) + "," +
+ convertToString(edge.label()) + "," +
+ "Collections.emptyMap()," +
+ convertToString(edge.outVertex().id()) + "," +
+ convertToString(edge.outVertex().label()) + "," +
+ convertToString(edge.inVertex().id()) + "," +
+ convertToString(edge.inVertex().label()) + ")";
+ } else {// VertexProperty
+ final VertexProperty vertexProperty = (VertexProperty) object;
+ return "new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty(" +
+ convertToString(vertexProperty.id()) + "," +
+ convertToString(vertexProperty.label()) + "," +
+ convertToString(vertexProperty.value()) + "," +
+ "Collections.emptyMap()," +
+ convertToString(vertexProperty.element()) + ")";
+ }
+ } else if (object instanceof Lambda) {
+ final String lambdaString = ((Lambda) object).getLambdaScript().trim();
+ return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
+ } else if (object instanceof TraversalStrategyProxy) {
+ final TraversalStrategyProxy proxy = (TraversalStrategyProxy) object;
+ if (proxy.getConfiguration().isEmpty())
+ return proxy.getStrategyClass().getCanonicalName() + ".instance()";
+ else
+ return proxy.getStrategyClass().getCanonicalName() + ".create(new org.apache.commons.configuration.MapConfiguration(" + convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + "))";
+ } else if (object instanceof TraversalStrategy) {
+ return convertToString(new TraversalStrategyProxy(((TraversalStrategy) object)));
+ } else
+ return null == object ? "null" : object.toString();
+ }
- private StringBuilder convertPToString(final P p, final StringBuilder current) {
- if (p instanceof TextP) return convertTextPToString((TextP) p, 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(");
+ protected String internalTranslate(final String start, final Bytecode bytecode) {
+ final StringBuilder traversalScript = new StringBuilder(start);
+ for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
+ final String methodName = instruction.getOperator();
+ if (0 == instruction.getArguments().length)
+ traversalScript.append(".").append(methodName).append("()");
+ else {
+ traversalScript.append(".");
+ String temp = methodName + "(";
+ for (final Object object : instruction.getArguments()) {
+ temp = temp + convertToString(object) + ",";
+ }
+ traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
+ }
}
- current.append(")");
- } else
- current.append("P.").append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
- return current;
- }
+ return traversalScript.toString();
+ }
- private StringBuilder convertTextPToString(final TextP p, final StringBuilder current) {
- current.append("TextP.").append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
- return current;
+ protected StringBuilder convertPToString(final P p, final StringBuilder current) {
+ if (p instanceof TextP) return convertTextPToString((TextP) p, 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;
+ }
+
+ protected StringBuilder convertTextPToString(final TextP p, final StringBuilder current) {
+ current.append("TextP.").append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
+ return current;
+ }
}
}
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java
index 2cbc962..e56b105 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java
@@ -20,7 +20,6 @@
package org.apache.tinkerpop.gremlin.groovy.jsr223;
import org.apache.commons.configuration.MapConfiguration;
-import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
import org.apache.tinkerpop.gremlin.jsr223.TranslatorCustomizer;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
@@ -225,17 +224,6 @@ public class GroovyTranslatorTest {
}
@Test
- public void shouldOverrideDefaultTypeTranslationWithSomethingBonkers() {
- final TinkerGraph graph = TinkerGraph.open();
- final GraphTraversalSource g = graph.traversal();
- final String thingToSuffixAllStringsWith = "-why-would-anyone-do-this";
- final String script = GroovyTranslator.of("g", x -> x instanceof String ? x + thingToSuffixAllStringsWith : x).
- translate(g.inject("yyy", "xxx").asAdmin().getBytecode());
- assertEquals(String.format("g.inject(\"yyy%s\",\"xxx%s\")", thingToSuffixAllStringsWith, thingToSuffixAllStringsWith), script);
- assertThatScriptOk(script, "g", g);
- }
-
- @Test
public void shouldIncludeCustomTypeTranslationForSomethingSilly() throws Exception {
final TinkerGraph graph = TinkerGraph.open();
final SillyClass notSillyEnough = SillyClass.from("not silly enough", 100);
@@ -247,10 +235,7 @@ public class GroovyTranslatorTest {
assertEquals(String.format("g.inject(%s)", "not silly enough:100"), scriptBad);
// with type translation we get valid gremlin
- final String scriptGood = GroovyTranslator.of("g",
- x -> x instanceof SillyClass ?
- new Translator.ScriptTranslator.Handled(String.format("org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslatorTest.SillyClass.from('%s', (int) %s)",
- ((SillyClass) x).getX(), ((SillyClass) x).getY())) : x).
+ final String scriptGood = GroovyTranslator.of("g", new SillyClassTranslator()).
translate(g.inject(notSillyEnough).asAdmin().getBytecode());
assertEquals(String.format("g.inject(org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslatorTest.SillyClass.from('%s', (int) %s))", notSillyEnough.getX(), notSillyEnough.getY()), scriptGood);
assertThatScriptOk(scriptGood, "g", g);
@@ -389,13 +374,23 @@ public class GroovyTranslatorTest {
}
}
+ public static class SillyClassTranslator extends GroovyTranslator.DefaultTypeTranslator {
+
+ @Override
+ protected String convertToString(final Object object) {
+ if (object instanceof SillyClass)
+ return String.format("org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslatorTest.SillyClass.from('%s', (int) %s)",
+ ((SillyClass) object).getX(), ((SillyClass) object).getY());
+ else
+ return super.convertToString(object);
+ }
+ }
+
public static class SillyClassTranslatorCustomizer implements TranslatorCustomizer {
@Override
public Translator.ScriptTranslator.TypeTranslator createTypeTranslator() {
- return x -> x instanceof SillyClass ?
- new Translator.ScriptTranslator.Handled(String.format("org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslatorTest.SillyClass.from('%s', (int) %s)",
- ((SillyClass) x).getX(), ((SillyClass) x).getY())) : x;
+ return new SillyClassTranslator();
}
}
}