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 2017/05/26 12:55:57 UTC
[47/49] tinkerpop git commit: TINKERPOP-1618 Removed dependence on
groovy for gremlin-python
TINKERPOP-1618 Removed dependence on groovy for gremlin-python
Executed code generation with the gmaven plugin and the Groovy templating library. This approach also gets the files generated in a much earlier (and more correct) phase of the maven life cycle which may be important to other GLVs using this as a pattern.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/894fc805
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/894fc805
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/894fc805
Branch: refs/heads/TINKERPOP-1618
Commit: 894fc8051e6464fbbd94d05631ac5cf420683881
Parents: 1d97c3d
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri May 19 14:37:27 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri May 26 08:30:16 2017 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
gremlin-python/pom.xml | 120 +-
.../python/GraphTraversalSourceGenerator.groovy | 207 --
.../python/TraversalSourceGenerator.groovy | 356 ----
.../gremlin/python/GenerateGremlinPython.java | 32 -
.../gremlin_python/process/graph_traversal.py | 1764 ++++++++++--------
.../jython/gremlin_python/process/traversal.py | 192 +-
.../resources/GraphTraversalSource.template | 96 +
.../src/main/resources/TraversalSource.template | 282 +++
9 files changed, 1515 insertions(+), 1535 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894fc805/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index dd7616e..2067ea2 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -30,6 +30,7 @@ TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
* Reduced memory usage for TinkerGraph deserialization in GraphSON by streaming vertices and edges.
* Added the `gremlin-archetype-dsl` to demonstrate how to structure a Maven project for a DSL.
* Developed and documented patterns for Domain Specific Language implementations.
+* Removed the Groovy dependency from `gremlin-python` and used Groovy Templates and the `gmavenplus-plugin` to generate the python GLV classes.
* Now using Groovy `[...]` map notation in `GroovyTranslator` instead of `new LinkedHashMap(){{ }}`.
* Maintained type information on `Traversal.promise()`.
* Propagated exception to `Future` instead of calling thread in `RemoteConnection`.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894fc805/gremlin-python/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml
index 19d3041..96cbc51 100644
--- a/gremlin-python/pom.xml
+++ b/gremlin-python/pom.xml
@@ -32,12 +32,6 @@ limitations under the License.
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy</artifactId>
- <version>${groovy.version}</version>
- <classifier>indy</classifier>
- </dependency>
- <dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.1b2</version>
@@ -90,32 +84,6 @@ limitations under the License.
</testResources>
<plugins>
<plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <executions>
- <execution>
- <id>generate-python</id>
- <phase>generate-test-resources</phase>
- <goals>
- <goal>java</goal>
- </goals>
- <configuration>
- <mainClass>org.apache.tinkerpop.gremlin.python.GenerateGremlinPython</mainClass>
- <arguments>
- <argument>${basedir}/src/main/jython/gremlin_python/process/traversal.py</argument>
- <argument>${basedir}/src/main/jython/gremlin_python/process/graph_traversal.py
- </argument>
- </arguments>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.gmavenplus</groupId>
- <artifactId>gmavenplus-plugin</artifactId>
- </plugin>
- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
@@ -511,6 +479,94 @@ limitations under the License.
</dependencies>
<executions>
<execution>
+ <id>generate-dsl</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <scripts>
+ <script><![CDATA[
+import org.apache.tinkerpop.gremlin.jsr223.CoreImports
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
+import org.apache.tinkerpop.gremlin.process.traversal.P
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
+import java.lang.reflect.Modifier
+
+// this is a bit of a copy of what's in SymbolHelper - no way around it because this code generation task occurs
+// before the SymbolHelper is available to the plugin.
+def toPythonMap = ["global": "global_",
+ "as": "as_",
+ "in": "in_",
+ "and": "and_",
+ "or": "or_",
+ "is": "is_",
+ "not": "not_",
+ "from": "from_",
+ "list": "list_",
+ "set": "set_",
+ "all": "all_"]
+def toJavaMap = toPythonMap.collectEntries{k,v -> [(v):k]}
+
+def toPython = { symbol -> toPythonMap.getOrDefault(symbol, symbol) }
+def toJava = { symbol -> toJavaMap.getOrDefault(symbol, symbol) }
+
+def binding = ["enums": CoreImports.getClassImports()
+ .findAll { Enum.class.isAssignableFrom(it) }
+ .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() },
+ "pmethods": P.class.getMethods().
+ findAll { Modifier.isStatic(it.getModifiers()) }.
+ findAll { P.class.isAssignableFrom(it.returnType) }.
+ collect { toPython(it.name) }.
+ unique().
+ sort { a, b -> a <=> b },
+ "sourceStepMethods": GraphTraversalSource.getMethods(). // SOURCE STEPS
+ findAll { GraphTraversalSource.class.equals(it.returnType) }.
+ findAll {
+ !it.name.equals("clone") &&
+ !it.name.equals(TraversalSource.Symbols.withBindings) &&
+ !it.name.equals(TraversalSource.Symbols.withRemote) &&
+ !it.name.equals(TraversalSource.Symbols.withComputer)
+ }.
+ collect { toPython(it.name) }.
+ unique().
+ sort { a, b -> a <=> b },
+ "sourceSpawnMethods": GraphTraversalSource.getMethods(). // SPAWN STEPS
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ collect { toPython(it.name) }.
+ unique().
+ sort { a, b -> a <=> b },
+ "graphStepMethods": GraphTraversal.getMethods().
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ findAll { !it.name.equals("clone") && !it.name.equals("iterate") }.
+ collect { toPython(it.name) }.
+ unique().
+ sort { a, b -> a <=> b },
+ "anonStepMethods": __.class.getMethods().
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ findAll { Modifier.isStatic(it.getModifiers()) }.
+ findAll { !it.name.equals("__") && !it.name.equals("start") }.
+ collect { toPython(it.name) }.
+ unique().
+ sort { a, b -> a <=> b },
+ "toPython": toPython,
+ "toJava": toJava]
+
+def engine = new groovy.text.GStringTemplateEngine()
+def traversalTemplate = engine.createTemplate(new File('${project.basedir}/src/main/resources/TraversalSource.template')).make(binding)
+def traversalFile = new File('${project.basedir}/src/main/jython/gremlin_python/process/traversal.py')
+traversalFile.newWriter().withWriter{ it << traversalTemplate }
+
+def graphTraversalTemplate = engine.createTemplate(new File('${project.basedir}/src/main/resources/GraphTraversalSource.template')).make(binding)
+def graphTraversalFile = new File('${project.basedir}/src/main/jython/gremlin_python/process/graph_traversal.py')
+graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate }
+]]> </script>
+ </scripts>
+ </configuration>
+ </execution>
+ <execution>
<id>gremlin-server-start</id>
<phase>pre-integration-test</phase>
<goals>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894fc805/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
deleted file mode 100644
index 086b8ea..0000000
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.tinkerpop.gremlin.python
-
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
-import org.apache.tinkerpop.gremlin.python.jsr223.SymbolHelper
-
-import java.lang.reflect.Modifier
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-class GraphTraversalSourceGenerator {
-
- public static void create(final String graphTraversalSourceFile) {
-
- final StringBuilder pythonClass = new StringBuilder()
-
- pythonClass.append("""'''
-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.
-'''
-""")
- pythonClass.append("import sys\n")
- pythonClass.append("from .traversal import Traversal\n")
- pythonClass.append("from .traversal import TraversalStrategies\n")
- pythonClass.append("from .strategies import VertexProgramStrategy\n")
- pythonClass.append("from .traversal import Bytecode\n")
- pythonClass.append("from ..driver.remote_connection import RemoteStrategy\n")
- pythonClass.append("from .. import statics\n")
- pythonClass.append("from ..statics import long\n\n")
-
-//////////////////////////
-// GraphTraversalSource //
-//////////////////////////
- pythonClass.append(
- """class GraphTraversalSource(object):
- def __init__(self, graph, traversal_strategies, bytecode=None):
- self.graph = graph
- self.traversal_strategies = traversal_strategies
- if bytecode is None:
- bytecode = Bytecode()
- self.bytecode = bytecode
- self.graph_traversal = GraphTraversal
- def __repr__(self):
- return "graphtraversalsource[" + str(self.graph) + "]"
- def get_graph_traversal_source(self):
- return self.__class__(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
- def get_graph_traversal(self):
- return self.graph_traversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
-""")
- GraphTraversalSource.getMethods(). // SOURCE STEPS
- findAll { GraphTraversalSource.class.equals(it.returnType) }.
- findAll {
- !it.name.equals("clone") &&
- !it.name.equals(TraversalSource.Symbols.withBindings) &&
- !it.name.equals(TraversalSource.Symbols.withRemote) &&
- !it.name.equals(TraversalSource.Symbols.withComputer)
- }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- forEach { method ->
- pythonClass.append(
- """ def ${method}(self, *args):
- source = self.get_graph_traversal_source()
- source.bytecode.add_source("${SymbolHelper.toJava(method)}", *args)
- return source
-""")
- }
- pythonClass.append(
- """ def withRemote(self, remote_connection):
- source = self.get_graph_traversal_source()
- source.traversal_strategies.add_strategies([RemoteStrategy(remote_connection)])
- return source
- def withComputer(self,graph_computer=None, workers=None, result=None, persist=None, vertices=None, edges=None, configuration=None):
- return self.withStrategies(VertexProgramStrategy(graph_computer,workers,result,persist,vertices,edges,configuration))
-""")
- GraphTraversalSource.getMethods(). // SPAWN STEPS
- findAll { GraphTraversal.class.equals(it.returnType) }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- forEach { method ->
- pythonClass.append(
- """ def ${method}(self, *args):
- traversal = self.get_graph_traversal()
- traversal.bytecode.add_step("${SymbolHelper.toJava(method)}", *args)
- return traversal
-""")
- }
- pythonClass.append("\n\n")
-
-////////////////////
-// GraphTraversal //
-////////////////////
- pythonClass.append(
- """class GraphTraversal(Traversal):
- def __init__(self, graph, traversal_strategies, bytecode):
- super(GraphTraversal, self).__init__(graph, traversal_strategies, bytecode)
- def __getitem__(self, index):
- if isinstance(index, int):
- return self.range(long(index), long(index + 1))
- elif isinstance(index, slice):
- return self.range(long(0) if index.start is None else long(index.start), long(sys.maxsize) if index.stop is None else long(index.stop))
- else:
- raise TypeError("Index must be int or slice")
- def __getattr__(self, key):
- return self.values(key)
-""")
- GraphTraversal.getMethods().
- findAll { GraphTraversal.class.equals(it.returnType) }.
- findAll { !it.name.equals("clone") && !it.name.equals("iterate") }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- forEach { method ->
- pythonClass.append(
- """ def ${method}(self, *args):
- self.bytecode.add_step("${SymbolHelper.toJava(method)}", *args)
- return self
-""")
- };
- pythonClass.append("\n\n")
-
-////////////////////////
-// AnonymousTraversal //
-////////////////////////
- pythonClass.append(
- """class __(object):
- graph_traversal = GraphTraversal
- @classmethod
- def start(cls):
- return GraphTraversal(None, None, Bytecode())
- @classmethod
- def __(cls, *args):
- return __.inject(*args)
-""")
- __.class.getMethods().
- findAll { GraphTraversal.class.equals(it.returnType) }.
- findAll { Modifier.isStatic(it.getModifiers()) }.
- findAll { !it.name.equals("__") && !it.name.equals("start") }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- forEach { method ->
- pythonClass.append(
- """ @classmethod
- def ${method}(cls, *args):
- return cls.graph_traversal(None, None, Bytecode()).${method}(*args)
-""")
- };
- pythonClass.append("\n\n")
- // add to gremlin.python.statics
- __.class.getMethods().
- findAll { GraphTraversal.class.equals(it.returnType) }.
- findAll { Modifier.isStatic(it.getModifiers()) }.
- findAll { !it.name.equals("__") && !it.name.equals("start") }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- forEach {
- pythonClass.append("def ${it}(*args):\n").append(" return __.${it}(*args)\n\n")
- pythonClass.append("statics.add_static('${it}', ${it})\n\n")
- }
- pythonClass.append("\n\n")
-
-// save to a python file
- final File file = new File(graphTraversalSourceFile);
- file.delete()
- pythonClass.eachLine { file.append(it + "\n") }
- }
-}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894fc805/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
deleted file mode 100644
index 995fe80..0000000
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.tinkerpop.gremlin.python
-
-import org.apache.tinkerpop.gremlin.jsr223.CoreImports
-import org.apache.tinkerpop.gremlin.process.traversal.P
-import org.apache.tinkerpop.gremlin.python.jsr223.SymbolHelper
-
-import java.lang.reflect.Modifier
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-class TraversalSourceGenerator {
-
- public static void create(final String traversalSourceFile) {
-
- final StringBuilder pythonClass = new StringBuilder()
-
- pythonClass.append("""'''
-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.
-'''
-""")
- pythonClass.append("from aenum import Enum\n")
- pythonClass.append("from .. import statics\n")
- pythonClass.append("from ..statics import long\n\n")
-
- pythonClass.append("""
-class Traversal(object):
- def __init__(self, graph, traversal_strategies, bytecode):
- self.graph = graph
- self.traversal_strategies = traversal_strategies
- self.bytecode = bytecode
- self.side_effects = TraversalSideEffects()
- self.traversers = None
- self.last_traverser = None
- def __repr__(self):
- return str(self.bytecode)
- def __eq__(self, other):
- if isinstance(other, self.__class__):
- return self.bytecode == other.bytecode
- else:
- return False
- def __iter__(self):
- return self
- def __next__(self):
- if self.traversers is None:
- self.traversal_strategies.apply_strategies(self)
- if self.last_traverser is None:
- self.last_traverser = next(self.traversers)
- object = self.last_traverser.object
- self.last_traverser.bulk = self.last_traverser.bulk - 1
- if self.last_traverser.bulk <= 0:
- self.last_traverser = None
- return object
- def toList(self):
- return list(iter(self))
- def toSet(self):
- return set(iter(self))
- def iterate(self):
- while True:
- try: self.nextTraverser()
- except StopIteration: return self
- def nextTraverser(self):
- if self.traversers is None:
- self.traversal_strategies.apply_strategies(self)
- if self.last_traverser is None:
- return next(self.traversers)
- else:
- temp = self.last_traverser
- self.last_traverser = None
- return temp
- def next(self, amount=None):
- if amount is None:
- return self.__next__()
- else:
- count = 0
- tempList = []
- while count < amount:
- count = count + 1
- try: temp = self.__next__()
- except StopIteration: return tempList
- tempList.append(temp)
- return tempList
- def promise(self, cb=None):
- self.traversal_strategies.apply_async_strategies(self)
- future_traversal = self.remote_results
- future = type(future_traversal)()
- def process(f):
- try:
- traversal = f.result()
- except Exception as e:
- future.set_exception(e)
- else:
- self.traversers = iter(traversal.traversers)
- self.side_effects = traversal.side_effects
- if cb:
- try:
- result = cb(self)
- except Exception as e:
- future.set_exception(e)
- else:
- future.set_result(result)
- else:
- future.set_result(self)
- future_traversal.add_done_callback(process)
- return future
-
-
-""")
-
-///////////
-// Enums //
-///////////
- for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
- .findAll { Enum.class.isAssignableFrom(it) }
- .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
- .collect()) {
- pythonClass.append("${enumClass.getSimpleName()} = Enum('${enumClass.getSimpleName()}', '");
- enumClass.getEnumConstants()
- .sort { a, b -> a.name() <=> b.name() }
- .each { value -> pythonClass.append("${SymbolHelper.toPython(value.name())} "); }
- pythonClass.deleteCharAt(pythonClass.length() - 1).append("')\n")
- enumClass.getEnumConstants().each { value ->
- pythonClass.append("statics.add_static('${SymbolHelper.toPython(value.name())}', ${value.getDeclaringClass().getSimpleName()}.${SymbolHelper.toPython(value.name())})\n");
- }
- pythonClass.append("\n");
- }
- //////////////
-
- pythonClass.append("""class P(object):
- def __init__(self, operator, value, other=None):
- self.operator = operator
- self.value = value
- self.other = other
-""")
- P.class.getMethods().
- findAll { Modifier.isStatic(it.getModifiers()) }.
- findAll { P.class.isAssignableFrom(it.returnType) }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- each { method ->
- pythonClass.append(
- """ @staticmethod
- def ${method}(*args):
- return P("${SymbolHelper.toJava(method)}", *args)
-""")
- };
- pythonClass.append(""" def and_(self, arg):
- return P("and", self, arg)
- def or_(self, arg):
- return P("or", self, arg)
- def __eq__(self, other):
- return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other
- def __repr__(self):
- return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")"
-""")
- pythonClass.append("\n")
- P.class.getMethods().
- findAll { Modifier.isStatic(it.getModifiers()) }.
- findAll { !it.name.equals("clone") }.
- findAll { P.class.isAssignableFrom(it.getReturnType()) }.
- collect { SymbolHelper.toPython(it.name) }.
- unique().
- sort { a, b -> a <=> b }.
- forEach {
- pythonClass.append("def ${it}(*args):\n").append(" return P.${it}(*args)\n")
- pythonClass.append("statics.add_static('${it}',${it})\n\n")
- }
- pythonClass.append("\n")
- //////////////
-
- pythonClass.append("""
-'''
-TRAVERSER
-'''
-
-class Traverser(object):
- def __init__(self, object, bulk=None):
- if bulk is None:
- bulk = long(1)
- self.object = object
- self.bulk = bulk
- def __repr__(self):
- return str(self.object)
- def __eq__(self, other):
- return isinstance(other, self.__class__) and self.object == other.object
-
-'''
-TRAVERSAL SIDE-EFFECTS
-'''
-
-class TraversalSideEffects(object):
- def keys(self):
- return set()
- def get(self, key):
- raise KeyError(key)
- def __getitem__(self, key):
- return self.get(key)
- def __repr__(self):
- return "sideEffects[size:" + str(len(self.keys())) + "]"
-
-'''
-TRAVERSAL STRATEGIES
-'''
-
-class TraversalStrategies(object):
- global_cache = {}
- def __init__(self, traversal_strategies=None):
- self.traversal_strategies = traversal_strategies.traversal_strategies if traversal_strategies is not None else []
- def add_strategies(self, traversal_strategies):
- self.traversal_strategies = self.traversal_strategies + traversal_strategies
- def apply_strategies(self, traversal):
- for traversal_strategy in self.traversal_strategies:
- traversal_strategy.apply(traversal)
- def apply_async_strategies(self, traversal):
- for traversal_strategy in self.traversal_strategies:
- traversal_strategy.apply_async(traversal)
- def __repr__(self):
- return str(self.traversal_strategies)
-
-
-class TraversalStrategy(object):
- def __init__(self, strategy_name=None, configuration=None):
- self.strategy_name = type(self).__name__ if strategy_name is None else strategy_name
- self.configuration = {} if configuration is None else configuration
- def apply(self, traversal):
- return
- def apply_async(self, traversal):
- return
- def __eq__(self, other):
- return isinstance(other, self.__class__)
- def __hash__(self):
- return hash(self.strategy_name)
- def __repr__(self):
- return self.strategy_name
-
-'''
-BYTECODE
-'''
-
-class Bytecode(object):
- def __init__(self, bytecode=None):
- self.source_instructions = []
- self.step_instructions = []
- self.bindings = {}
- if bytecode is not None:
- self.source_instructions = list(bytecode.source_instructions)
- self.step_instructions = list(bytecode.step_instructions)
- def add_source(self, source_name, *args):
- instruction = [source_name]
- for arg in args:
- instruction.append(self.__convertArgument(arg))
- self.source_instructions.append(instruction)
- def add_step(self, step_name, *args):
- instruction = [step_name]
- for arg in args:
- instruction.append(self.__convertArgument(arg))
- self.step_instructions.append(instruction)
- def __eq__(self, other):
- if isinstance(other, self.__class__):
- return self.source_instructions == other.source_instructions and self.step_instructions == other.step_instructions
- else:
- return False
- def __convertArgument(self,arg):
- 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],self.__convertArgument(arg[1]))
- else:
- return arg
- def __repr__(self):
- return (str(self.source_instructions) if len(self.source_instructions) > 0 else "") + \\
- (str(self.step_instructions) if len(self.step_instructions) > 0 else "")
-
-
-'''
-BINDINGS
-'''
-
-class Bindings(object):
- def of(self,key,value):
- if not isinstance(key, str):
- raise TypeError("Key must be str")
- return (key,value)
-
-class Binding(object):
- def __init__(self,key,value):
- self.key = key
- self.value = value
- def __eq__(self, other):
- return isinstance(other, self.__class__) and self.key == other.key and self.value == other.value
- def __hash__(self):
- return hash(self.key) + hash(self.value)
- def __repr__(self):
- return "binding[" + self.key + "=" + str(self.value) + "]"
-
-""")
- //////////////
-
- // save to a python file
- final File file = new File(traversalSourceFile);
- file.delete()
- pythonClass.eachLine { file.append(it + "\n") }
- }
-}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894fc805/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
deleted file mode 100644
index 6d8f04d..0000000
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.tinkerpop.gremlin.python;
-
-public class GenerateGremlinPython {
-
- private GenerateGremlinPython() {
- // just need the main method
- }
-
- public static void main(String[] args) {
- TraversalSourceGenerator.create(args[0]);
- GraphTraversalSourceGenerator.create(args[1]);
- }
-}