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/10/06 16:07:24 UTC
tinkerpop git commit: so many bug fixes in the GLV/Translator world.
So many more tests added. We are now testing translators against all the
strategies (save Evenstrategy cause it requires Java objects). This is really
becoming clean.
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1455 3e4075bd0 -> 894ff3dc0
so many bug fixes in the GLV/Translator world. So many more tests added. We are now testing translators against all the strategies (save Evenstrategy cause it requires Java objects). This is really becoming clean.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/894ff3dc
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/894ff3dc
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/894ff3dc
Branch: refs/heads/TINKERPOP-1455
Commit: 894ff3dc0ccae16dae2fa314684aff7bbbcc139a
Parents: 3e4075b
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Oct 6 10:07:15 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Oct 6 10:07:15 2016 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 11 +++-
.../upgrade/release-3.2.x-incubating.asciidoc | 63 +++++++++++++-----
.../gremlin/jsr223/JavaTranslator.java | 22 ++++++-
.../gremlin/process/computer/Computer.java | 22 ++++++-
.../gremlin/process/traversal/Bindings.java | 5 ++
.../gremlin/process/traversal/Bytecode.java | 69 +++++++++++++-------
.../process/traversal/TraversalStrategy.java | 12 ++++
.../strategy/decoration/ElementIdStrategy.java | 27 +++++---
.../decoration/HaltedTraverserStrategy.java | 12 ++++
.../strategy/decoration/PartitionStrategy.java | 18 ++++-
.../strategy/decoration/SubgraphStrategy.java | 27 ++++++--
.../finalization/MatchAlgorithmStrategy.java | 24 +++++++
.../StandardVerificationStrategy.java | 2 +-
.../gremlin/jsr223/JavaTranslatorTest.java | 68 +++++++++++++++++++
.../gremlin/process/traversal/BytecodeTest.java | 42 ++++++++++++
.../dsl/graph/GraphTraversalSourceTest.java | 2 +-
.../gremlin/groovy/jsr223/GroovyTranslator.java | 20 ++++--
.../python/TraversalSourceGenerator.groovy | 17 ++++-
.../gremlin/python/jsr223/PythonTranslator.java | 19 ++++--
.../jython/gremlin_python/process/traversal.py | 17 ++++-
.../gremlin_python/structure/io/graphson.py | 5 +-
.../TinkerGraphGroovyTranslatorProvider.java | 3 +
.../TinkerGraphJavaTranslatorProvider.java | 3 +
23 files changed, 429 insertions(+), 81 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index f25e095..7ec7d15 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,10 +26,15 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
TinkerPop 3.2.3 (Release Date: NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* Fixed a `String` bug in `GroovyTranslator` and `PythonTranslator` where if the string has double-quotes, use """ """.
-* Fixed a `List` and `Map` bug in `JavaTranslator` where such collections were not being internally translated.
+* Fixed a `Set`, `List`, `Map` bug in the various `Translators` where such collections were not being internally translated.
+* Fixed a `Bytecode` bug where nested structures (map, list, set) were not being analyzed for bindings and bytecode conversions.
+* Fixed a `String` bug in `GroovyTranslator` and `PythonTranslator` where if the string has double-quotes it now uses """ """.
+* Added a default `TraversalStrategy.getConfiguration()` which returns the configuration needed to construct the strategy.
+* Gremlin-Java `TraversalStrategy` and `Computer` instances are now converted to `Map`-representations in `Bytecode`.
+* `Computer` instances can be created with `Computer.create(Configuration)` and accessed via `Computer.getConf()`.
+* Every `TraversalStrategy` can be created via a `Configuration` and a static `MyStrategy.create(Configuration)`.
* Added `TraversalSource.withComputer(Map<String,Object>)` for better language variant support.
-* Added `TraversalSource.withStrategies(Map<String,Object>)`/`withoutStrategies(String...)` for better language variant support.
+* Added `TraversalSource.withStrategies(Map<String,Object>...)`/`withoutStrategies(String...)` for better language variant support.
* Added `PartitionStrategy.Builder.readPartitions()` and deprecated `PartitionStrategy.Builder.addPartition()`.
* `FilterRankStrategy` now propagates labels "right" over non-`Scoping` filters.
* Fixed a bug in `ConnectiveP` where nested equivalent connectives should be inlined.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 983c63e..5fbf4fe 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -163,7 +163,7 @@ Configurable Strategies
`TraversalSource.withStrategies()` and `TraversalSource.withoutStrategies()` use Java objects. In order to make strategy
manipulation possible from Gremlin language variants like Gremlin-Python, it is important to support non-JVM-based versions
-of these methods. As such, `TraversalSource.withStrategy(String,Object...)` and `TraversalSource.withoutStrategy(String)`
+of these methods. As such, `TraversalSource.withStrategies(Map<String,Object>...)` and `TraversalSource.withoutStrategies(String...)`
were added.
If the provider has non-configurable `TraversalStrategy` classes, those classes should expose a static `instance()`-method.
@@ -175,31 +175,60 @@ a `SubgraphStrategy`, it does the following:
[source,python]
----
g = Graph().traversal().withRemote(connection).
- withStrategy('org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy',
- 'vertices', __.hasLabel('person'),
- 'edges', __.has('weight',gt(0.5))
+ withStrategy({'strategy':'org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy',
+ 'vertices': __.hasLabel('person'),
+ 'edges': __.has('weight',gt(0.5))})
---
-`SubgraphStrategy.create(Configuration)`-method is defined as:
+The `SubgraphStrategy.create(Configuration)`-method is defined as:
[source,java]
----
public static SubgraphStrategy create(final Configuration configuration) {
final Builder builder = SubgraphStrategy.build();
- configuration.getKeys().forEachRemaining(key -> {
- if (key.equals("vertices") || key.equals("vertexCriterion"))
- builder.vertices((Traversal) configuration.getProperty(key));
- else if (key.equals("edges") || key.equals("edgeCriterion"))
- builder.edges((Traversal) configuration.getProperty(key));
- else if (key.equals("vertexProperties"))
- builder.vertexProperties((Traversal) configuration.getProperty(key));
- else
- throw new IllegalArgumentException("The following " + SubgraphStrategy.class.getSimpleName() + " configuration is unknown: " + key + ":" + configuration.getProperty(key));
- });
- return builder.create();
- }
+ if (configuration.containsKey(VERTICES))
+ builder.vertices((Traversal) configuration.getProperty(VERTICES));
+ if (configuration.containsKey(EDGES))
+ builder.edges((Traversal) configuration.getProperty(EDGES));
+ if (configuration.containsKey(VERTEX_PROPERTIES))
+ builder.vertexProperties((Traversal) configuration.getProperty(VERTEX_PROPERTIES));
+ return builder.create();
+}
+----
+
+Finally, in order to make serialization possible from JVM-based Gremlin language variants, all strategies have a
+`TraverserStrategy.getConfiguration()` method which returns a `Configuration` that can be used to `create()` the
+`TraversalStrategy`.
+
+The `SubgraphStrategy.getConfiguration()`-method is defined as:
+
+[source,java]
+----
+@Override
+public Configuration getConfiguration() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(STRATEGY, SubgraphStrategy.class.getCanonicalName());
+ if (null != this.vertexCriterion)
+ map.put(VERTICES, this.vertexCriterion);
+ if (null != this.edgeCriterion)
+ map.put(EDGES, this.edgeCriterion);
+ if (null != this.vertexPropertyCriterion)
+ map.put(VERTEX_PROPERTIES, this.vertexPropertyCriterion);
+ return new MapConfiguration(map);
+}
----
+The default implementation of `TraversalStrategy.getConfiguration()` is defined as:
+
+[source,java]
+----
+public default Configuration getConfiguration() {
+ return new MapConfiguration(Collections.singletonMap(STRATEGY, this.getClass().getCanonicalName()));
+}
+----
+
+Thus, if the provider does not have any "builder"-based strategies, then no updates to their strategies are required.
+
See: link:https://issues.apache.org/jira/browse/TINKERPOP-1455[TINKERPOP-1455]
Deprecated elementNotFound
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
index af245c5..d1e974d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
@@ -23,6 +23,7 @@ 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.TraversalStrategy;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import java.lang.reflect.Array;
@@ -31,8 +32,11 @@ import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -40,6 +44,8 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public final class JavaTranslator<S extends TraversalSource, T extends Traversal.Admin<?, ?>> implements Translator.StepTranslator<S, T> {
+ private static final boolean IS_TESTING = Boolean.valueOf(System.getProperty("is.testing", "false"));
+
private final S traversalSource;
private final Class anonymousTraversal;
private static final Map<Class<?>, Map<String, List<Method>>> GLOBAL_METHOD_CACHE = new ConcurrentHashMap<>();
@@ -64,6 +70,10 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
TraversalSource dynamicSource = this.traversalSource;
Traversal.Admin<?, ?> traversal = null;
for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
+ if (IS_TESTING &&
+ instruction.getOperator().equals(TraversalSource.Symbols.withStrategies) &&
+ ((Map) instruction.getArguments()[0]).get(TraversalStrategy.STRATEGY).toString().contains("TranslationStrategy"))
+ continue;
dynamicSource = (TraversalSource) invokeMethod(dynamicSource, TraversalSource.class, instruction.getOperator(), instruction.getArguments());
}
boolean spawned = false;
@@ -91,7 +101,7 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
private Object translateObject(final Object object) {
if (object instanceof Bytecode.Binding)
- return ((Bytecode.Binding) object).value();
+ return translateObject(((Bytecode.Binding) object).value());
else if (object instanceof Bytecode) {
try {
final Traversal.Admin<?, ?> traversal = (Traversal.Admin) this.anonymousTraversal.getMethod("start").invoke(null);
@@ -103,17 +113,23 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
throw new IllegalStateException(e.getMessage());
}
} else if (object instanceof Map) {
- final Map<Object, Object> map = new HashMap<>(((Map) object).size());
+ final Map<Object, Object> map = new LinkedHashMap<>(((Map) object).size());
for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
map.put(translateObject(entry.getKey()), translateObject(entry.getValue()));
}
return map;
} else if (object instanceof List) {
- final List<Object> list = new ArrayList<>();
+ final List<Object> list = new ArrayList<>(((List) object).size());
for (final Object o : (List) object) {
list.add(translateObject(o));
}
return list;
+ } else if (object instanceof Set) {
+ final Set<Object> set = new HashSet<>(((Set) object).size());
+ for (final Object o : (Set) object) {
+ set.add(translateObject(o));
+ }
+ return set;
} else
return object;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
index e06a62a..86e1a12 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
@@ -20,6 +20,7 @@
package org.apache.tinkerpop.gremlin.process.computer;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -65,7 +66,7 @@ public final class Computer implements Function<Graph, GraphComputer>, Serializa
final Computer computer = new Computer();
for (final String key : (List<String>) IteratorUtils.asList(configuration.getKeys())) {
if (key.equals(GRAPH_COMPUTER))
- computer.graphComputerClass = (Class) Class.forName(configuration.getString("graphComputer"));
+ computer.graphComputerClass = (Class) Class.forName(configuration.getString(key));
else if (key.equals(WORKERS))
computer.workers = configuration.getInt(key);
else if (key.equals(PERSIST))
@@ -198,4 +199,23 @@ public final class Computer implements Function<Graph, GraphComputer>, Serializa
public int getWorkers() {
return this.workers;
}
+
+ public Configuration getConf() {
+ final Map<String, Object> map = new HashMap<>();
+ if (-1 != this.workers)
+ map.put(WORKERS, this.workers);
+ if (null != this.persist)
+ map.put(PERSIST, this.persist.name());
+ if (null != this.resultGraph)
+ map.put(RESULT, this.resultGraph.name());
+ if (null != this.vertices)
+ map.put(RESULT, this.vertices);
+ if (null != this.edges)
+ map.put(EDGES, this.edges);
+ map.put(GRAPH_COMPUTER, this.graphComputerClass.getCanonicalName());
+ for (final Map.Entry<String, Object> entry : this.configuration.entrySet()) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ return new MapConfiguration(map);
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
index ca830f1..ba31e21 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
@@ -55,4 +55,9 @@ public final class Bindings {
protected void clear() {
this.map.clear();
}
+
+ @Override
+ public String toString() {
+ return this.map.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 9443064..f331d50 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
@@ -19,6 +19,8 @@
package org.apache.tinkerpop.gremlin.process.traversal;
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.apache.tinkerpop.gremlin.process.computer.Computer;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -44,6 +46,8 @@ import java.util.Map;
*/
public final class Bytecode implements Cloneable, Serializable {
+ private static final Object[] EMPTY_ARRAY = new Object[]{};
+
private List<Instruction> sourceInstructions = new ArrayList<>();
private List<Instruction> stepInstructions = new ArrayList<>();
private transient Bindings bindings = null;
@@ -111,21 +115,32 @@ public final class Bytecode implements Cloneable, Serializable {
public Map<String, Object> getBindings() {
final Map<String, Object> bindingsMap = new HashMap<>();
for (final Instruction instruction : this.sourceInstructions) {
- addInstructionBindings(bindingsMap, instruction);
+ for (final Object argument : instruction.getArguments()) {
+ addArgumentBinding(bindingsMap, argument);
+ }
}
for (final Instruction instruction : this.stepInstructions) {
- addInstructionBindings(bindingsMap, instruction);
+ for (final Object argument : instruction.getArguments()) {
+ addArgumentBinding(bindingsMap, argument);
+ }
}
return bindingsMap;
}
- private static final void addInstructionBindings(final Map<String, Object> bindingsMap, final Instruction instruction) {
- for (final Object argument : instruction.getArguments()) {
- if (argument instanceof Binding)
- bindingsMap.put(((Binding) argument).key, ((Binding) argument).value);
- else if (argument instanceof Bytecode)
- bindingsMap.putAll(((Bytecode) argument).getBindings());
- }
+ private static final void addArgumentBinding(final Map<String, Object> bindingsMap, final Object argument) {
+ if (argument instanceof Binding)
+ bindingsMap.put(((Binding) argument).key, ((Binding) argument).value);
+ else if (argument instanceof Map) {
+ for (final Map.Entry<?, ?> entry : ((Map<?, ?>) argument).entrySet()) {
+ addArgumentBinding(bindingsMap, entry.getKey());
+ addArgumentBinding(bindingsMap, entry.getValue());
+ }
+ } else if (argument instanceof List) {
+ for (final Object item : (List) argument) {
+ addArgumentBinding(bindingsMap, item);
+ }
+ } else if (argument instanceof Bytecode)
+ bindingsMap.putAll(((Bytecode) argument).getBindings());
}
@Override
@@ -234,35 +249,45 @@ public final class Bytecode implements Cloneable, Serializable {
private final Object[] flattenArguments(final Object... arguments) {
if (arguments.length == 0)
- return new Object[]{};
+ return EMPTY_ARRAY;
final List<Object> flatArguments = new ArrayList<>();
for (final Object object : arguments) {
if (object instanceof Object[]) {
for (final Object nestObject : (Object[]) object) {
- flatArguments.add(convertArgument(nestObject));
+ flatArguments.add(convertArgument(nestObject, true));
}
} else
- flatArguments.add(convertArgument(object));
+ flatArguments.add(convertArgument(object, true));
}
return flatArguments.toArray();
}
- private final Object convertArgument(final Object argument) {
+ private final Object convertArgument(final Object argument, final boolean searchBindings) {
+ if (searchBindings && null != this.bindings) {
+ final String variable = this.bindings.getBoundVariable(argument);
+ if (null != variable)
+ return new Binding<>(variable, convertArgument(argument, false));
+ }
+ //
if (argument instanceof Traversal)
return ((Traversal) argument).asAdmin().getBytecode();
+ else if (argument instanceof TraversalStrategy)
+ return convertArgument(ConfigurationConverter.getMap(((TraversalStrategy) argument).getConfiguration()), true);
+ else if (argument instanceof Computer)
+ return convertArgument(ConfigurationConverter.getMap(((Computer) argument).getConf()), true);
else if (argument instanceof Map) {
final Map<Object, Object> map = new LinkedHashMap<>(((Map) argument).size());
for (final Map.Entry<?, ?> entry : ((Map<?, ?>) argument).entrySet()) {
- map.put(convertArgument(entry.getKey()), convertArgument(entry.getValue()));
+ map.put(convertArgument(entry.getKey(), true), convertArgument(entry.getValue(), true));
}
return map;
- }
- if (null != this.bindings) {
- final String variable = this.bindings.getBoundVariable(argument);
- if (null != variable)
- return new Binding<>(variable, argument);
- }
-
- return argument;
+ } else if (argument instanceof List) {
+ final List<Object> list = new ArrayList<>(((List) argument).size());
+ for (final Object item : (List) argument) {
+ list.add(convertArgument(item, true));
+ }
+ return list;
+ } else
+ return argument;
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
index a04f304..7943624 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
@@ -18,6 +18,8 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.ProfileStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy;
@@ -76,6 +78,16 @@ public interface TraversalStrategy<S extends TraversalStrategy> extends Serializ
return (Class) TraversalStrategy.class;
}
+ /**
+ * Get the configuration representation of this strategy.
+ * This is useful for converting a strategy into a serialized form.
+ *
+ * @return the configuration used to create this strategy
+ */
+ public default Configuration getConfiguration() {
+ return new MapConfiguration(Collections.singletonMap(STRATEGY, this.getClass().getCanonicalName()));
+ }
+
@Override
public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
return 0;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
index 396de49..32437e1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
@@ -19,6 +19,7 @@
package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
@@ -40,6 +41,8 @@ import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
@@ -152,16 +155,24 @@ public final class ElementIdStrategy extends AbstractTraversalStrategy<Traversal
}
}
+ public static final String ID_PROPERTY_KEY = "idPropertyKey";
+ public static final String ID_MAKER = "idMaker";
+
public static ElementIdStrategy create(final Configuration configuration) {
final ElementIdStrategy.Builder builder = ElementIdStrategy.build();
- configuration.getKeys().forEachRemaining(key -> {
- if (key.equals("idPropertyKey"))
- builder.idPropertyKey((String) configuration.getProperty(key));
- else if (key.equals("idMaker"))
- builder.idMaker((Supplier) configuration.getProperty(key));
- else
- throw new IllegalArgumentException("The following " + ElementIdStrategy.class.getSimpleName() + " configuration is unknown: " + key + ":" + configuration.getProperty(key));
- });
+ if (configuration.containsKey(ID_MAKER))
+ builder.idMaker((Supplier) configuration.getProperty(ID_MAKER));
+ if (configuration.containsKey(ID_PROPERTY_KEY))
+ builder.idPropertyKey(configuration.getString(ID_PROPERTY_KEY));
return builder.create();
}
+
+ @Override
+ public Configuration getConfiguration() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(STRATEGY, ElementIdStrategy.class.getCanonicalName());
+ map.put(ID_PROPERTY_KEY, this.idPropertyKey);
+ map.put(ID_MAKER, this.idMaker);
+ return new MapConfiguration(map);
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
index ee1f017..3f02c40 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
@@ -20,6 +20,7 @@
package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
@@ -27,6 +28,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversal
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -69,6 +73,14 @@ public final class HaltedTraverserStrategy extends AbstractTraversalStrategy<Tra
}
}
+ @Override
+ public Configuration getConfiguration() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(STRATEGY, HaltedTraverserStrategy.class.getCanonicalName());
+ map.put(HALTED_TRAVERSER_FACTORY, this.haltedTraverserFactory.getCanonicalName());
+ return new MapConfiguration(map);
+ }
+
////////////
public static HaltedTraverserStrategy detached() {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
index 2ee4bf3..438d8b2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
@@ -19,6 +19,7 @@
package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
@@ -55,6 +56,7 @@ import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -324,6 +326,20 @@ public final class PartitionStrategy extends AbstractTraversalStrategy<Traversal
}
}
+ @Override
+ public Configuration getConfiguration() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(STRATEGY, PartitionStrategy.class.getCanonicalName());
+ map.put(INCLUDE_META_PROPERTIES, this.includeMetaProperties);
+ if (null != this.writePartition)
+ map.put(WRITE_PARTITION, this.writePartition);
+ if (null != this.readPartitions)
+ map.put(READ_PARTITIONS, this.readPartitions);
+ if (null != this.partitionKey)
+ map.put(PARTITION_KEY, this.partitionKey);
+ return new MapConfiguration(map);
+ }
+
public static final String INCLUDE_META_PROPERTIES = "includeMetaProperties";
public static final String WRITE_PARTITION = "writePartition";
public static final String PARTITION_KEY = "partitionKey";
@@ -338,7 +354,7 @@ public final class PartitionStrategy extends AbstractTraversalStrategy<Traversal
if (configuration.containsKey(PARTITION_KEY))
builder.partitionKey(configuration.getString(PARTITION_KEY));
if (configuration.containsKey(READ_PARTITIONS))
- builder.readPartitions((List) configuration.getList(READ_PARTITIONS));
+ builder.readPartitions(new ArrayList((Collection)configuration.getProperty(READ_PARTITIONS)));
return builder.create();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
index d7269aa..e612bee 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
@@ -19,6 +19,7 @@
package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
@@ -54,9 +55,10 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
-import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -78,15 +80,15 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
private static final Set<Class<? extends DecorationStrategy>> POSTS = Collections.singleton(ConnectiveStrategy.class);
- private final String MARKER = Graph.Hidden.hide(UUID.randomUUID().toString());
+ private final String MARKER = Graph.Hidden.hide("gremlin.subgraphStrategy");
private SubgraphStrategy(final Traversal<Vertex, ?> vertexCriterion, final Traversal<Edge, ?> edgeCriterion, final Traversal<VertexProperty, ?> vertexPropertyCriterion) {
- this.vertexCriterion = null == vertexCriterion ? null : vertexCriterion.asAdmin();
+ this.vertexCriterion = null == vertexCriterion ? null : vertexCriterion.asAdmin().clone();
// if there is no vertex predicate there is no need to test either side of the edge
if (null == this.vertexCriterion) {
- this.edgeCriterion = null == edgeCriterion ? null : edgeCriterion.asAdmin();
+ this.edgeCriterion = null == edgeCriterion ? null : edgeCriterion.asAdmin().clone();
} else {
final Traversal.Admin<Edge, ?> vertexPredicate;
vertexPredicate = __.<Edge>and(
@@ -97,10 +99,10 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
// edge predicate provided by the user.
this.edgeCriterion = null == edgeCriterion ?
vertexPredicate :
- edgeCriterion.asAdmin().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
+ edgeCriterion.asAdmin().clone().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
}
- this.vertexPropertyCriterion = null == vertexPropertyCriterion ? null : vertexPropertyCriterion.asAdmin();
+ this.vertexPropertyCriterion = null == vertexPropertyCriterion ? null : vertexPropertyCriterion.asAdmin().clone();
if (null != this.vertexCriterion)
this.addLabelMarker(this.vertexCriterion);
@@ -275,6 +277,19 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
}
@Override
+ public Configuration getConfiguration() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(STRATEGY, SubgraphStrategy.class.getCanonicalName());
+ if (null != this.vertexCriterion)
+ map.put(VERTICES, this.vertexCriterion);
+ if (null != this.edgeCriterion)
+ map.put(EDGES, this.edgeCriterion);
+ if (null != this.vertexPropertyCriterion)
+ map.put(VERTEX_PROPERTIES, this.vertexPropertyCriterion);
+ return new MapConfiguration(map);
+ }
+
+ @Override
public Set<Class<? extends DecorationStrategy>> applyPost() {
return POSTS;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
index be31575..7b78295 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
@@ -18,6 +18,8 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
@@ -25,11 +27,15 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
public final class MatchAlgorithmStrategy extends AbstractTraversalStrategy<TraversalStrategy.FinalizationStrategy> implements TraversalStrategy.FinalizationStrategy {
+ private static final String MATCH_ALGORITHM = "matchAlgorithm";
private final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass;
private MatchAlgorithmStrategy(final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass) {
@@ -45,6 +51,24 @@ public final class MatchAlgorithmStrategy extends AbstractTraversalStrategy<Trav
}
}
+ public static MatchAlgorithmStrategy create(final Configuration configuration) {
+ try {
+ return new MatchAlgorithmStrategy((Class) Class.forName(configuration.getString(MATCH_ALGORITHM)));
+ } catch (final ClassNotFoundException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public Configuration getConfiguration() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(STRATEGY, MatchAlgorithmStrategy.class.getCanonicalName());
+ map.put(MATCH_ALGORITHM, null != this.matchAlgorithmClass.getDeclaringClass() ?
+ this.matchAlgorithmClass.getCanonicalName().replace("." + this.matchAlgorithmClass.getSimpleName(), "$" + this.matchAlgorithmClass.getSimpleName()) :
+ this.matchAlgorithmClass.getCanonicalName());
+ return new MapConfiguration(map);
+ }
+
public static Builder build() {
return new Builder();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
index 9f7f516..f72de50 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
@@ -53,7 +53,7 @@ public final class StandardVerificationStrategy extends AbstractTraversalStrateg
}
for (final Step<?, ?> step : traversal.getSteps()) {
- for (String label : new ArrayList<>(step.getLabels())) {
+ for (String label : step.getLabels()) {
if (Graph.Hidden.isHidden(label))
step.removeLabel(label);
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java
new file mode 100644
index 0000000..ac8a645
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.jsr223;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Bindings;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+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.step.filter.TraversalFilterStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class JavaTranslatorTest {
+
+ @Test
+ public void shouldTranslateNestedBindings() {
+ final Bindings b = new Bindings();
+ final GraphTraversalSource g = EmptyGraph.instance().traversal().withBindings(b);
+
+ final Bytecode bytecode = g.withStrategies(new HashMap<String, Object>() {{
+ put(SubgraphStrategy.STRATEGY, SubgraphStrategy.class.getCanonicalName());
+ put(SubgraphStrategy.VERTICES, b.of("a", __.has("name", "marko")));
+ }}).V().out(b.of("b", "created")).asAdmin().getBytecode();
+
+ Traversal.Admin<?, ?> traversal = JavaTranslator.of(EmptyGraph.instance().traversal()).translate(bytecode);
+ assertFalse(traversal.isLocked());
+ assertEquals(2, traversal.getSteps().size());
+ // assertEquals(traversal.getBytecode(),bytecode); TODO: bindings are removed -- should translated bytecode be the same bytecode?!
+ traversal.applyStrategies();
+ assertEquals(5, TraversalHelper.getStepsOfAssignableClassRecursively(TraversalFilterStep.class, traversal).size());
+
+ // JavaTranslator should not mutate original bytecode
+ assertTrue(bytecode.getBindings().containsKey("a"));
+ assertTrue(bytecode.getBindings().containsKey("b"));
+ assertEquals(2, bytecode.getBindings().size());
+ assertEquals(__.has("name", "marko").asAdmin().getBytecode(), bytecode.getBindings().get("a"));
+ assertEquals("created", bytecode.getBindings().get("b"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
index 0b9c65a..6093dae 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
@@ -19,15 +19,24 @@
package org.apache.tinkerpop.gremlin.process.traversal;
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.apache.tinkerpop.gremlin.process.computer.Computer;
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.strategy.decoration.SubgraphStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
import org.apache.tinkerpop.gremlin.structure.Column;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import org.junit.Test;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -92,6 +101,39 @@ public class BytecodeTest {
assertEquals(1, bytecode1.getBindings().size());
assertEquals("created", bytecode1.getBindings().get("a"));
+ }
+
+ @Test
+ public void shouldSupportNestedBindings() {
+ final Bindings b = new Bindings();
+ final GraphTraversalSource g = EmptyGraph.instance().traversal().withBindings(b);
+ final Bytecode bytecode = g.withStrategies(new HashMap<String, Object>() {{
+ put(SubgraphStrategy.STRATEGY, SubgraphStrategy.class.getCanonicalName());
+ put(SubgraphStrategy.VERTICES, b.of("a", __.has("name", "marko")));
+ }}).V().out(b.of("b", "created")).asAdmin().getBytecode();
+
+ assertTrue(bytecode.getBindings().containsKey("a"));
+ assertTrue(bytecode.getBindings().containsKey("b"));
+ assertEquals(2, bytecode.getBindings().size());
+ assertEquals(__.has("name", "marko").asAdmin().getBytecode(), bytecode.getBindings().get("a"));
+ assertEquals("created", bytecode.getBindings().get("b"));
+ }
+
+ @Test
+ public void shouldConvertStrategies() {
+ final GraphTraversalSource g = EmptyGraph.instance().traversal();
+ Bytecode bytecode = g.withStrategies(ReadOnlyStrategy.instance()).getBytecode();
+ assertEquals(Collections.singletonMap(ReadOnlyStrategy.STRATEGY, ReadOnlyStrategy.class.getCanonicalName()), bytecode.getSourceInstructions().iterator().next().getArguments()[0]);
+ bytecode = g.withStrategies(SubgraphStrategy.build().edges(__.hasLabel("knows")).create()).getBytecode();
+ assertEquals(SubgraphStrategy.build().edges(__.hasLabel("knows")).create().getEdgeCriterion().asAdmin().getBytecode(),
+ ((Map) bytecode.getSourceInstructions().iterator().next().getArguments()[0]).get(SubgraphStrategy.EDGES));
+ }
+
+ @Test
+ public void shouldConvertComputer() {
+ final GraphTraversalSource g = EmptyGraph.instance().traversal();
+ Bytecode bytecode = g.withComputer(Computer.compute().workers(10)).getBytecode();
+ assertEquals(ConfigurationConverter.getMap(Computer.compute().workers(10).getConf()), bytecode.getSourceInstructions().iterator().next().getArguments()[0]);
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
index 6efa4b5..457747d 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
@@ -59,7 +59,7 @@ public class GraphTraversalSourceTest {
}
@Test
- public void shouldSupportStringBasedStrategies() throws Exception {
+ public void shouldSupportMapBasedStrategies() throws Exception {
GraphTraversalSource g = EmptyGraph.instance().traversal();
assertFalse(g.getStrategies().getStrategy(SubgraphStrategy.class).isPresent());
g = g.withStrategies(new HashMap<String, Object>() {{
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 59a07b3..154c4a1 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
@@ -24,8 +24,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
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.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
import org.apache.tinkerpop.gremlin.structure.Element;
@@ -34,8 +34,10 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -82,7 +84,9 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
final StringBuilder traversalScript = new StringBuilder(start);
for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
final String methodName = instruction.getOperator();
- if (IS_TESTING && methodName.equals(TraversalSource.Symbols.withStrategies))
+ if (IS_TESTING &&
+ instruction.getOperator().equals(TraversalSource.Symbols.withStrategies) &&
+ ((Map) instruction.getArguments()[0]).get(TraversalStrategy.STRATEGY).toString().contains("TranslationStrategy"))
continue;
if (0 == instruction.getArguments().length)
traversalScript.append(".").append(methodName).append("()");
@@ -103,7 +107,13 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
return ((Bytecode.Binding) object).variable();
else if (object instanceof String)
return ((String) object).contains("\"") ? "\"\"\"" + object + "\"\"\"" : "\"" + object + "\"";
- else if (object instanceof List) {
+ 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));
@@ -139,15 +149,11 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString();
else if (object instanceof Element)
return convertToString(((Element) object).id()); // hack
- else if (object instanceof Computer)
- return "";
else if (object instanceof Lambda) {
final String lambdaString = ((Lambda) object).getLambdaScript().trim();
return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
} else if (object instanceof Bytecode)
return this.internalTranslate("__", (Bytecode) object);
- else if (object instanceof Traversal)
- return this.internalTranslate("__", ((Traversal) object).asAdmin().getBytecode());
else
return null == object ? "null" : object.toString();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
index e12c2cd..fe62685 100644
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
+++ b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
@@ -254,9 +254,24 @@ class Bytecode(object):
if isinstance(arg, Traversal):
self.bindings.update(arg.bytecode.bindings)
return arg.bytecode
+ elif isinstance(arg, dict):
+ newDict = {}
+ for key in arg:
+ newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key])
+ return newDict
+ elif isinstance(arg, list):
+ newList = []
+ for item in arg:
+ newList.append(self.__convertArgument(item))
+ return newList
+ elif isinstance(arg, set):
+ newSet = set()
+ for item in arg:
+ newSet.add(self.__convertArgument(item))
+ return newSet
elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
self.bindings[arg[0]] = arg[1]
- return Binding(arg[0],arg[1])
+ return Binding(arg[0],self.__convertArgument(arg[1]))
else:
return arg
def __repr__(self):
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 65042ab..4bfdc45 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
@@ -19,7 +19,6 @@
package org.apache.tinkerpop.gremlin.python.jsr223;
-import org.apache.tinkerpop.gremlin.process.computer.Computer;
import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.Operator;
import org.apache.tinkerpop.gremlin.process.traversal.P;
@@ -27,6 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
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.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
@@ -42,6 +42,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -103,7 +104,9 @@ public class PythonTranslator implements Translator.ScriptTranslator {
for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
final String methodName = instruction.getOperator();
final Object[] arguments = instruction.getArguments();
- if (IS_TESTING && methodName.equals(TraversalSource.Symbols.withStrategies) && !(instruction.getArguments()[0] instanceof Map))
+ if (IS_TESTING &&
+ instruction.getOperator().equals(TraversalSource.Symbols.withStrategies) &&
+ ((Map) instruction.getArguments()[0]).get(TraversalStrategy.STRATEGY).toString().contains("TranslationStrategy"))
continue;
else if (0 == arguments.length)
traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
@@ -135,7 +138,13 @@ public class PythonTranslator implements Translator.ScriptTranslator {
return ((Bytecode.Binding) object).variable();
else if (object instanceof String)
return ((String) object).contains("\"") ? "\"\"\"" + object + "\"\"\"" : "\"" + object + "\"";
- else if (object instanceof List) {
+ else if (object instanceof Set) {
+ final Set<String> set = new LinkedHashSet<>(((Set) object).size());
+ for (final Object item : (Set) object) {
+ set.add(convertToString(item));
+ }
+ return "set(" + set.toString() + ")";
+ } else if (object instanceof List) {
final List<String> list = new ArrayList<>(((List) object).size());
for (final Object item : (List) object) {
list.add(convertToString(item));
@@ -168,10 +177,6 @@ public class PythonTranslator implements Translator.ScriptTranslator {
return convertToString(((Element) object).id()); // hack
else if (object instanceof Bytecode)
return this.internalTranslate("__", (Bytecode) object);
- else if (object instanceof Traversal)
- return this.internalTranslate("__", ((Traversal.Admin) object).asAdmin().getBytecode());
- else if (object instanceof Computer)
- return "";
else if (object instanceof Lambda)
return convertLambdaToString((Lambda) object);
else
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
index 4c2f3b9..aa36869 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
@@ -313,9 +313,24 @@ class Bytecode(object):
if isinstance(arg, Traversal):
self.bindings.update(arg.bytecode.bindings)
return arg.bytecode
+ elif isinstance(arg, dict):
+ newDict = {}
+ for key in arg:
+ newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key])
+ return newDict
+ elif isinstance(arg, list):
+ newList = []
+ for item in arg:
+ newList.append(self.__convertArgument(item))
+ return newList
+ elif isinstance(arg, set):
+ newSet = set()
+ for item in arg:
+ newSet.add(self.__convertArgument(item))
+ return newSet
elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
self.bindings[arg[0]] = arg[1]
- return Binding(arg[0],arg[1])
+ return Binding(arg[0],self.__convertArgument(arg[1]))
else:
return arg
def __repr__(self):
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
index a032032..7899925 100644
--- a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
@@ -47,7 +47,7 @@ class GraphSONWriter(object):
if isinstance(object, key):
return serializers[key]._dictify(object)
# list and map are treated as normal json objects (could be isolated serializers)
- if isinstance(object, list):
+ if isinstance(object, list) or isinstance(object, set):
newList = []
for item in object:
newList.append(GraphSONWriter._dictify(item))
@@ -181,7 +181,8 @@ class NumberSerializer(GraphSONSerializer):
def _dictify(self, number):
if isinstance(number, bool): # python thinks that 0/1 integers are booleans
return number
- elif isinstance(number, long) or (abs(number) > 2147483647): # in python all numbers are int unless specified otherwise
+ elif isinstance(number, long) or (
+ abs(number) > 2147483647): # in python all numbers are int unless specified otherwise
return _SymbolHelper.objectify("Int64", number)
elif isinstance(number, int):
return _SymbolHelper.objectify("Int32", number)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
index 7591bf0..c086c3a 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
@@ -27,6 +27,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
@@ -52,6 +54,7 @@ public class TinkerGraphGroovyTranslatorProvider extends TinkerGraphProvider {
ProgramTest.Traversals.class.getCanonicalName(),
TraversalInterruptionTest.class.getCanonicalName(),
TraversalInterruptionComputerTest.class.getCanonicalName(),
+ EventStrategyProcessTest.class.getCanonicalName(),
ElementIdStrategyProcessTest.class.getCanonicalName()));
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
index 1e6645b..f40a8c7 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSo
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
@@ -48,6 +49,8 @@ public class TinkerGraphJavaTranslatorProvider extends TinkerGraphProvider {
TraversalInterruptionComputerTest.class.getCanonicalName(),
"shouldNeverPropagateANoBulkTraverser",
"shouldNeverPropagateANullValuedTraverser",
+ ElementIdStrategyProcessTest.class.getCanonicalName(),
+ EventStrategyProcessTest.class.getCanonicalName(),
ProgramTest.Traversals.class.getCanonicalName()));