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 2016/12/01 15:33:59 UTC

[31/48] tinkerpop git commit: TINKERPOP-1562 Hooked up GremlinJythonScriptEngine to Customizers

TINKERPOP-1562 Hooked up GremlinJythonScriptEngine to Customizers

GremlnJythonScriptEngine is now initialized the same way that GremlinGroovyScriptEngine is.


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

Branch: refs/heads/TINKERPOP-1562
Commit: 6e6dd1b4c6a462ae97732553852cc98dbd486df4
Parents: 46ece96
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Nov 24 08:11:35 2016 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Dec 1 06:41:43 2016 -0500

----------------------------------------------------------------------
 .../jsr223/GremlinJythonScriptEngine.java       | 167 ++++++++++++-------
 .../GremlinJythonScriptEngineFactory.java       |   5 +-
 .../jsr223/GremlinJythonScriptEngineTest.java   |  12 +-
 .../jsr223/GremlinEnabledScriptEngineTest.java  |   1 -
 4 files changed, 120 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6e6dd1b4/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
index 554d80a..1b95a02 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
@@ -19,8 +19,10 @@
 
 package org.apache.tinkerpop.gremlin.python.jsr223;
 
+import org.apache.tinkerpop.gremlin.jsr223.Customizer;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngine;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngineFactory;
+import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer;
 import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
@@ -35,7 +37,13 @@ import javax.script.ScriptContext;
 import javax.script.ScriptException;
 import java.io.Reader;
 import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -44,6 +52,10 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
 
     private final PyScriptEngine pyScriptEngine;
 
+    /**
+     * @deprecated As of release 3.2.4, replaced by {@link #GremlinJythonScriptEngine(Customizer...)}.
+     */
+    @Deprecated
     public GremlinJythonScriptEngine() {
         this.pyScriptEngine = (PyScriptEngine) new PyScriptEngineFactory().getScriptEngine();
         try {
@@ -61,70 +73,48 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
                 this.pyScriptEngine.eval(SymbolHelper.toPython(x.name()) + " = " + x.getDeclaringClass().getSimpleName() + "." + x.name());
             }
 
-            // add sugar methods
-            this.pyScriptEngine.eval("def getitem_bypass(self, index):\n" +
-                    "  if isinstance(index,int):\n    return self.range(index,index+1)\n" +
-                    "  elif isinstance(index,slice):\n    return self.range(index.start,index.stop)\n" +
-                    "  else:\n    return TypeError('Index must be int or slice')");
-            this.pyScriptEngine.eval(GraphTraversal.class.getSimpleName() + ".__getitem__ = getitem_bypass");
-            this.pyScriptEngine.eval(GraphTraversal.class.getSimpleName() + ".__getattr__ = lambda self, key: self.values(key)\n");
-            this.pyScriptEngine.eval("\n" +
-                    "from java.lang import Long\n" +
-                    "import org.apache.tinkerpop.gremlin.util.function.Lambda\n" + // todo: remove or remove imported subclass names? (choose)
-                    "from org.apache.tinkerpop.gremlin.util.function.Lambda import AbstractLambda\n" +
-                    "from org.apache.tinkerpop.gremlin.util.function.Lambda import UnknownArgLambda\n" +
-                    "from org.apache.tinkerpop.gremlin.util.function.Lambda import ZeroArgLambda\n" +
-                    "from org.apache.tinkerpop.gremlin.util.function.Lambda import OneArgLambda\n" +
-                    "from org.apache.tinkerpop.gremlin.util.function.Lambda import TwoArgLambda\n\n" +
-
-                    "class JythonUnknownArgLambda(UnknownArgLambda):\n" +
-                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
-                    "    UnknownArgLambda.__init__(self, script, lang, -1)\n" +
-                    "    self.func = func\n" +
-                    "  def __repr__(self):\n" +
-                    "    return self.getLambdaScript()\n\n" +
-
-                    "class JythonZeroArgLambda(ZeroArgLambda):\n" +
-                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
-                    "    ZeroArgLambda.__init__(self, script, lang)\n" +
-                    "    self.func = func\n" +
-                    "  def __repr__(self):\n" +
-                    "    return self.getLambdaScript()\n" +
-                    "  def get(self):\n" +
-                    "    return self.func()\n\n" +
-
-                    "class JythonOneArgLambda(OneArgLambda):\n" +
-                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
-                    "    OneArgLambda.__init__(self, script, lang)\n" +
-                    "    self.func = func\n" +
-                    "  def __repr__(self):\n" +
-                    "    return self.getLambdaScript()\n" +
-                    "  def test(self,a):\n" +
-                    "    return self.func(a)\n" +
-                    "  def apply(self,a):\n" +
-                    "    return self.func(a)\n" +
-                    "  def accept(self,a):\n" +
-                    "    self.func(a)\n" +
-                    "  def compare(self,a,b):\n" +
-                    "    return self.func(a,b)\n\n" +
-
-                    "class JythonTwoArgLambda(TwoArgLambda):\n" +
-                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
-                    "    TwoArgLambda.__init__(self, script, lang)\n" +
-                    "    self.func = func\n" +
-                    "  def __repr__(self):\n" +
-                    "    return self.getLambdaScript()\n" +
-                    "  def apply(self,a,b):\n" +
-                    "    return self.func(a,b)\n" +
-                    "  def compare(self,a,b):\n" +
-                    "    return self.func(a,b)\n"
-            );
+            loadSugar();
 
         } catch (final ScriptException e) {
             throw new IllegalStateException(e.getMessage(), e);
         }
     }
 
+    public GremlinJythonScriptEngine(final Customizer... customizers) {
+        this.pyScriptEngine = (PyScriptEngine) new PyScriptEngineFactory().getScriptEngine();
+        final List<Customizer> listOfCustomizers = Arrays.asList(customizers);
+
+        final List<ImportCustomizer> importCustomizers = listOfCustomizers.stream()
+                .filter(p -> p instanceof ImportCustomizer)
+                .map(p -> (ImportCustomizer) p)
+                .collect(Collectors.toList());
+
+        try {
+            for (ImportCustomizer ic : importCustomizers) {
+                for (Class<?> c : ic.getClassImports()) {
+                    if (null == c.getDeclaringClass())
+                        this.pyScriptEngine.eval("from " + c.getPackage().getName() + " import " + c.getSimpleName());
+                    else
+                        this.pyScriptEngine.eval("from " + c.getPackage().getName() + "." + c.getDeclaringClass().getSimpleName() + " import " + c.getSimpleName());
+                }
+
+                for (Method m : ic.getMethodImports()) {
+                    this.pyScriptEngine.eval(SymbolHelper.toPython(m.getName()) + " = " + m.getDeclaringClass().getSimpleName() + "." + m.getName());
+                }
+
+                // enums need to import after methods for some reason or else label comes in as a PyReflectedFunction
+                for (Enum e : ic.getEnumImports()) {
+                    this.pyScriptEngine.eval(SymbolHelper.toPython(e.name()) + " = " + e.getDeclaringClass().getSimpleName() + "." + e.name());
+                }
+            }
+
+            loadSugar();
+
+        } catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
     @Override
     public Traversal.Admin eval(final Bytecode bytecode, final Bindings bindings) throws ScriptException {
         bindings.putAll(bytecode.getBindings());
@@ -209,4 +199,65 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
     public GremlinScriptEngineFactory getFactory() {
         return new GremlinJythonScriptEngineFactory();
     }
+
+    private void loadSugar() throws ScriptException {
+        // add sugar methods
+        this.pyScriptEngine.eval("def getitem_bypass(self, index):\n" +
+                "  if isinstance(index,int):\n    return self.range(index,index+1)\n" +
+                "  elif isinstance(index,slice):\n    return self.range(index.start,index.stop)\n" +
+                "  else:\n    return TypeError('Index must be int or slice')");
+        this.pyScriptEngine.eval(GraphTraversal.class.getSimpleName() + ".__getitem__ = getitem_bypass");
+        this.pyScriptEngine.eval(GraphTraversal.class.getSimpleName() + ".__getattr__ = lambda self, key: self.values(key)\n");
+        this.pyScriptEngine.eval("\n" +
+                "from java.lang import Long\n" +
+                "import org.apache.tinkerpop.gremlin.util.function.Lambda\n" + // todo: remove or remove imported subclass names? (choose)
+                "from org.apache.tinkerpop.gremlin.util.function.Lambda import AbstractLambda\n" +
+                "from org.apache.tinkerpop.gremlin.util.function.Lambda import UnknownArgLambda\n" +
+                "from org.apache.tinkerpop.gremlin.util.function.Lambda import ZeroArgLambda\n" +
+                "from org.apache.tinkerpop.gremlin.util.function.Lambda import OneArgLambda\n" +
+                "from org.apache.tinkerpop.gremlin.util.function.Lambda import TwoArgLambda\n\n" +
+
+                "class JythonUnknownArgLambda(UnknownArgLambda):\n" +
+                "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
+                "    UnknownArgLambda.__init__(self, script, lang, -1)\n" +
+                "    self.func = func\n" +
+                "  def __repr__(self):\n" +
+                "    return self.getLambdaScript()\n\n" +
+
+                "class JythonZeroArgLambda(ZeroArgLambda):\n" +
+                "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
+                "    ZeroArgLambda.__init__(self, script, lang)\n" +
+                "    self.func = func\n" +
+                "  def __repr__(self):\n" +
+                "    return self.getLambdaScript()\n" +
+                "  def get(self):\n" +
+                "    return self.func()\n\n" +
+
+                "class JythonOneArgLambda(OneArgLambda):\n" +
+                "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
+                "    OneArgLambda.__init__(self, script, lang)\n" +
+                "    self.func = func\n" +
+                "  def __repr__(self):\n" +
+                "    return self.getLambdaScript()\n" +
+                "  def test(self,a):\n" +
+                "    return self.func(a)\n" +
+                "  def apply(self,a):\n" +
+                "    return self.func(a)\n" +
+                "  def accept(self,a):\n" +
+                "    self.func(a)\n" +
+                "  def compare(self,a,b):\n" +
+                "    return self.func(a,b)\n\n" +
+
+                "class JythonTwoArgLambda(TwoArgLambda):\n" +
+                "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
+                "    TwoArgLambda.__init__(self, script, lang)\n" +
+                "    self.func = func\n" +
+                "  def __repr__(self):\n" +
+                "    return self.getLambdaScript()\n" +
+                "  def apply(self,a,b):\n" +
+                "    return self.func(a,b)\n" +
+                "  def compare(self,a,b):\n" +
+                "    return self.func(a,b)\n"
+        );
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6e6dd1b4/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineFactory.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineFactory.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineFactory.java
index c94e94f..696c2ea 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineFactory.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.tinkerpop.gremlin.python.jsr223;
 
+import org.apache.tinkerpop.gremlin.jsr223.Customizer;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngine;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngineFactory;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngineManager;
@@ -100,6 +101,8 @@ public class GremlinJythonScriptEngineFactory extends PyScriptEngineFactory impl
 
     @Override
     public GremlinScriptEngine getScriptEngine() {
-        return new GremlinJythonScriptEngine();
+        final List<Customizer> customizers =  manager.getCustomizers(GREMLIN_JYTHON);
+        return (customizers.isEmpty()) ? new GremlinJythonScriptEngine() :
+                new GremlinJythonScriptEngine(customizers.toArray(new Customizer[customizers.size()]));
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6e6dd1b4/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineTest.java
index 8bc60a5..8ec1cf4 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineTest.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngineTest.java
@@ -36,6 +36,8 @@ import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.HashSet;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -56,11 +58,11 @@ public class GremlinJythonScriptEngineTest {
     @Test
     public void shouldHaveCoreImports() throws Exception {
         final ScriptEngine engine = new DefaultGremlinScriptEngineManager().getEngineByName("gremlin-jython");
-        assertTrue(engine.eval("Graph") instanceof Class);
-        assertTrue(engine.eval("__") instanceof Class);
-        assertTrue(engine.eval("T") instanceof Class);
-        assertTrue(engine.eval("label") instanceof T);
-        assertTrue(engine.eval("T.label") instanceof T);
+        assertThat(engine.eval("Graph"), instanceOf(Class.class));
+        assertThat(engine.eval("__"), instanceOf(Class.class));
+        assertThat(engine.eval("T"), instanceOf(Class.class));
+        assertThat(engine.eval("label"), instanceOf(T.class));
+        assertThat(engine.eval("T.label"), instanceOf(T.class));
         assertEquals(SackFunctions.Barrier.class, engine.eval("Barrier"));
         assertEquals(SackFunctions.Barrier.normSack, engine.eval("Barrier.normSack"));
         assertEquals(Column.class, engine.eval("Column"));

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6e6dd1b4/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinEnabledScriptEngineTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinEnabledScriptEngineTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinEnabledScriptEngineTest.java
index 723d898..f6bbcb8 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinEnabledScriptEngineTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinEnabledScriptEngineTest.java
@@ -55,7 +55,6 @@ public class GremlinEnabledScriptEngineTest {
         }
     }
 
-    @org.junit.Ignore("TEMPORARY - until GremlinJythonScriptEngine supports this stuff")
     @Test
     public void shouldSupportDeprecatedGremlinModules() throws Exception {
         final GremlinScriptEngineManager mgr = new DefaultGremlinScriptEngineManager();