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/05/31 15:17:08 UTC

incubator-tinkerpop git commit: started a gremlin-variant/ package with Gremlin-Python as the first language.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1278 [created] 6ed7edc0b


started a gremlin-variant/ package with Gremlin-Python as the first language.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/6ed7edc0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/6ed7edc0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/6ed7edc0

Branch: refs/heads/TINKERPOP-1278
Commit: 6ed7edc0b4ad2abf933e917812d49ad92230c8d1
Parents: 670bc69
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue May 31 09:16:57 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue May 31 09:16:57 2016 -0600

----------------------------------------------------------------------
 gremlin-variant/pom.xml                         | 114 +++++++++++++
 .../python/GremlinPythonGenerator.groovy        | 161 +++++++++++++++++++
 .../tinkerpop/gremlin/python/GremlinPython.java |  28 ++++
 .../apache/tinkerpop/gremlin/python/Test.java   |  38 +++++
 pom.xml                                         |   1 +
 5 files changed, 342 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/6ed7edc0/gremlin-variant/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-variant/pom.xml b/gremlin-variant/pom.xml
new file mode 100644
index 0000000..4061684
--- /dev/null
+++ b/gremlin-variant/pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tinkerpop</groupId>
+        <artifactId>tinkerpop</artifactId>
+        <version>3.2.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>gremlin-variants</artifactId>
+    <name>Apache TinkerPop :: Gremlin Language Variants</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-core</artifactId>
+            <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>
+        </dependency>
+        <!-- TESTING -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <directory>${basedir}/target</directory>
+        <finalName>${project.artifactId}-${project.version}</finalName>
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources
+                </directory>
+            </resource>
+        </resources>
+        <testResources>
+            <testResource>
+                <directory>${basedir}/src/test/resources
+                </directory>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.gmavenplus</groupId>
+                <artifactId>gmavenplus-plugin</artifactId>
+                <version>1.2</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>addSources</goal>
+                            <goal>addTestSources</goal>
+                            <goal>generateStubs</goal>
+                            <goal>compile</goal>
+                            <goal>testGenerateStubs</goal>
+                            <goal>testCompile</goal>
+                            <goal>removeStubs</goal>
+                            <goal>removeTestStubs</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <invokeDynamic>true</invokeDynamic>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>net.sf.mavenjython</groupId>
+                <artifactId>jython-compile-maven-plugin</artifactId>
+                <version>1.4</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jython</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <libraries>
+                        <param>nose</param>
+                    </libraries>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/6ed7edc0/gremlin-variant/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-variant/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonGenerator.groovy b/gremlin-variant/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonGenerator.groovy
new file mode 100644
index 0000000..e810572
--- /dev/null
+++ b/gremlin-variant/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonGenerator.groovy
@@ -0,0 +1,161 @@
+/*
+ * 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.Traversal
+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.util.Gremlin
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+class GremlinPythonGenerator {
+
+    public static void create(final String outputFileLocation) {
+        final StringBuilder pythonClass = new StringBuilder()
+        pythonClass.append("""
+class Helper(object):
+  @staticmethod
+  def stringOrObject(arg):
+    if (type(arg) is str and
+       not(arg.startswith("P.")) and
+       not(arg.startswith("Order.")) and
+       not(arg.startswith("T.")) and
+       not(arg.startswith("Pop.")) and
+       not(arg.startswith("Column."))):
+      return "\\"" + arg + "\\""
+    elif type(arg) is bool:
+      return str(arg).lower()
+    else:
+      return str(arg)
+  @staticmethod
+  def stringify(*args):
+    if len(args) == 0:
+      return ""
+    elif len(args) == 1:
+      return Helper.stringOrObject(args[0])
+    else:
+      return ", ".join(Helper.stringOrObject(i) for i in args)
+""");
+
+//////////////////////////
+// GraphTraversalSource //
+//////////////////////////
+        Set<String> methods = GraphTraversalSource.getMethods().collect { it.name } as Set;
+        pythonClass.append(
+                """class PythonGraphTraversalSource(object):
+  def __init__(self, gremlinServerURI, traversalSourceString):
+    self.gremlinServerURI = gremlinServerURI
+    self.traversalSourceString = traversalSourceString
+  def __repr__(self):
+    return "graphtraversalsource[" + self.gremlinServerURI + ", " + self.traversalSourceString + "]"
+""")
+        methods.each { method ->
+            final Class<?> returnType = (GraphTraversalSource.getMethods() as Set).findAll {
+                it.name.equals(method)
+            }.collect {
+                it.returnType
+            }[0]
+            if (null != returnType && Traversal.isAssignableFrom(returnType)) {
+                pythonClass.append(
+                        """  def ${method}(self, *args):
+    return PythonGraphTraversal(self.traversalSourceString + ".${method}(" + Helper.stringify(*args) + ")", self.gremlinServerURI)
+""")
+            } else {
+                pythonClass.append(
+                        """  def ${method}(self, *args):
+    return PythonGraphTraversalSource(self.gremlinServerURI, self.traversalSourceString + ".${method}(" + Helper.stringify(*args) + ")")
+""")
+            }
+        }; []
+        pythonClass.append("\n\n")
+
+////////////////////
+// GraphTraversal //
+////////////////////
+        final Map<String, String> methodMap = [as: "_as", in: "_in", and: "_and", or: "_or", is: "_is", not: "_not", from: "_from"].withDefault {
+            it
+        }
+        final Map<String, String> invertedMethodMap = [_as: "as", _in: "in", _and: "and", _or: "or", _is: "is", _not: "not", _from: "from"].withDefault {
+            it
+        }
+        methods = GraphTraversal.getMethods().collect { methodMap[it.name] } as Set;
+        methods.remove("toList")
+        pythonClass.append(
+                """class PythonGraphTraversal(object):
+  def __init__(self, traversalString, gremlinServerURI=None):
+    self.traversalString = traversalString
+    self.gremlinServerURI = gremlinServerURI
+  def __repr__(self):
+    return self.traversalString;
+  def __getitem__(self,index):
+    if type(index) is int:
+      return self.range(index,index+1)
+    elif type(index) is slice:
+      return self.range(index.start,index.stop)
+    else:
+      raise TypeError("index must be int or slice")
+  def __getattr__(self,key):
+    return self.values(key)
+  def toList(self):
+    return IOLoop.current().run_sync(lambda: Helper.submit(self.gremlinServerURI, self.traversalString))
+""")
+        methods.each { method ->
+            final Class<?> returnType = (GraphTraversal.getMethods() as Set).findAll {
+                it.name.equals(invertedMethodMap[method])
+            }.collect { it.returnType }[0]
+            if (null != returnType && Traversal.isAssignableFrom(returnType)) {
+                pythonClass.append(
+                        """  def ${method}(self, *args):
+    self.traversalString = self.traversalString + ".${invertedMethodMap[method]}(" + Helper.stringify(*args) + ")"
+    return self
+""")
+            } else {
+                pythonClass.append(
+                        """  def ${method}(self, *args):
+    self.traversalString = self.traversalString + ".${invertedMethodMap[method]}(" + Helper.stringify(*args) + ")"
+    return self.toList()
+""")
+            }
+        };
+        pythonClass.append("\n\n")
+
+////////////////////////
+// AnonymousTraversal //
+////////////////////////
+        methods = __.getMethods().collect { methodMap[it.name] } as Set; []
+        pythonClass.append("class __(object):\n");
+        methods.each { method ->
+            pythonClass.append(
+                    """  @staticmethod
+  def ${method}(*args):
+    return PythonGraphTraversal("__").${method}(*args)
+""")
+        };
+        pythonClass.append("\n\n")
+
+// save to a python file
+        final File file = new File("${outputFileLocation}/gremlin-python-${Gremlin.version()}.py");
+        file.delete()
+        pythonClass.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/6ed7edc0/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/python/GremlinPython.java
----------------------------------------------------------------------
diff --git a/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/python/GremlinPython.java b/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/python/GremlinPython.java
new file mode 100644
index 0000000..6c5310a
--- /dev/null
+++ b/gremlin-variant/src/main/java/org/apache/tinkerpop/gremlin/python/GremlinPython.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class GremlinPython {
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/6ed7edc0/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/python/Test.java
----------------------------------------------------------------------
diff --git a/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/python/Test.java b/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/python/Test.java
new file mode 100644
index 0000000..005a3fd
--- /dev/null
+++ b/gremlin-variant/src/test/java/org/apache/tinkerpop/gremlin/python/Test.java
@@ -0,0 +1,38 @@
+/*
+ * 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 javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class Test {
+
+    @org.junit.Test
+    public void test() throws Exception {
+        GremlinPythonGenerator.create("/tmp");
+        ScriptEngine engine = new ScriptEngineManager().getEngineByName("jython");
+        System.out.println(engine.eval("execfile(\"/tmp/gremlin-python-3.2.1-SNAPSHOT.py\")"));
+        System.out.println(engine.eval("g = PythonGraphTraversalSource(\"ws://localhost:8182/\", \"g\")"));
+        System.out.println(engine.eval("g.V()[1]"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/6ed7edc0/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2ea2270..35254b6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -125,6 +125,7 @@ limitations under the License.
         <module>gremlin-console</module>
         <module>gremlin-server</module>
         <module>gremlin-archetype</module>
+        <module>gremlin-variant</module>
     </modules>
     <scm>
         <connection>scm:git:git@git-wip-us.apache.org:repos/asf/incubator-tinkerpop.git</connection>