Merge branch 'tp32' Conflicts: gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/ScriptEngines.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/87bf0c62 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/87bf0c62 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/87bf0c62 Branch: refs/heads/master Commit: 87bf0c62ccd30c00aeb8be8306b323ea3ee514c3 Parents: 4c99e53 29b6268 Author: Stephen Mallette <sp...@genoprime.com> Authored: Fri Sep 29 07:20:44 2017 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Fri Sep 29 07:20:44 2017 -0400 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 2 + .../gremlin/jsr223/GremlinScriptEngine.java | 35 +++++- .../gremlin/groovy/engine/GremlinExecutor.java | 7 +- .../jsr223/GremlinGroovyScriptEngine.java | 33 ++++-- .../groovy/jsr223/GroovyTranslatorTest.java | 6 +- .../jsr223/GremlinJythonScriptEngine.java | 34 ++++-- .../op/traversal/TraversalOpProcessor.java | 13 +-- .../jsr223/GremlinEnabledScriptEngineTest.java | 117 +++++++++++++++++++ .../gremlin/jsr223/MockGremlinScriptEngine.java | 6 +- 9 files changed, 215 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/87bf0c62/CHANGELOG.asciidoc ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/87bf0c62/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java ---------------------------------------------------------------------- diff --cc gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java index c520751,945719a..cf41b74 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java @@@ -317,15 -345,47 +317,18 @@@ public class GremlinExecutor implement /** * Evaluates bytecode with bindings for a specific language into a {@link Traversal}. + * + * @deprecated As of release 3.2.7, replaced by {@link #eval(Bytecode, Bindings, String, String)} */ - public Traversal.Admin eval(final Bytecode bytecode, final Bindings boundVars, final String language) throws ScriptException { + @Deprecated - public Traversal.Admin eval(final Bytecode bytecode, final Bindings boundVars, final String language) throws ScriptException { - final String lang = Optional.ofNullable(language).orElse("gremlin-groovy"); - - final Bindings bindings = new SimpleBindings(); - bindings.putAll(globalBindings); - bindings.putAll(boundVars); - - return useGremlinScriptEngineManager ? - gremlinScriptEngineManager.getEngineByName(lang).eval(bytecode, bindings) : scriptEngines.eval(bytecode, bindings, lang); - } - - /** - * Evaluates bytecode with bindings for a specific language into a {@link Traversal}. - * - * @param bytecode to execute as a traversal - * @param boundVars local bindings - * @param language the scripting language to use to process the bytecode - * @param traversalSource the specific traversal source to execute the bytecode against - */ + public Traversal.Admin eval(final Bytecode bytecode, final Bindings boundVars, final String language, final String traversalSource) throws ScriptException { final String lang = Optional.ofNullable(language).orElse("gremlin-groovy"); final Bindings bindings = new SimpleBindings(); bindings.putAll(globalBindings); bindings.putAll(boundVars); - return gremlinScriptEngineManager.getEngineByName(lang).eval(bytecode, bindings); - return useGremlinScriptEngineManager ? - gremlinScriptEngineManager.getEngineByName(lang).eval(bytecode, bindings, traversalSource) : - scriptEngines.eval(bytecode, bindings, lang, traversalSource); - } - - /** - * @deprecated As of release 3.2.4, replaced by {@link #getScriptEngineManager()}. - */ - @Deprecated - public ScriptEngines getScriptEngines() { - return this.scriptEngines; ++ return gremlinScriptEngineManager.getEngineByName(lang).eval(bytecode, bindings, traversalSource); } public GremlinScriptEngineManager getScriptEngineManager() { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/87bf0c62/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/87bf0c62/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java ---------------------------------------------------------------------- diff --cc gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java index a7074b0,0000000..c58f6e7 mode 100644,000000..100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorTest.java @@@ -1,134 -1,0 +1,134 @@@ +/* + * 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.groovy.jsr223; + +import org.apache.commons.configuration.MapConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +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.process.traversal.strategy.decoration.SubgraphStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory; +import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; +import org.apache.tinkerpop.gremlin.util.function.Lambda; +import org.junit.Test; + +import javax.script.Bindings; +import javax.script.SimpleBindings; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class GroovyTranslatorTest { + + @Test + public void shouldHandleStrategies() throws Exception { + final TinkerGraph graph = TinkerFactory.createModern(); + GraphTraversalSource g = graph.traversal(); + g = g.withStrategies(SubgraphStrategy.create(new MapConfiguration(new HashMap<String, Object>() {{ + put(SubgraphStrategy.VERTICES, __.has("name", "marko")); + }}))); + final Bindings bindings = new SimpleBindings(); + bindings.put("g", g); - Traversal.Admin<Vertex, Object> traversal = new GremlinGroovyScriptEngine().eval(g.V().values("name").asAdmin().getBytecode(), bindings); ++ Traversal.Admin<Vertex, Object> traversal = new GremlinGroovyScriptEngine().eval(g.V().values("name").asAdmin().getBytecode(), bindings, "g"); + assertEquals("marko", traversal.next()); + assertFalse(traversal.hasNext()); + // - traversal = new GremlinGroovyScriptEngine().eval(g.withoutStrategies(SubgraphStrategy.class).V().count().asAdmin().getBytecode(), bindings); ++ traversal = new GremlinGroovyScriptEngine().eval(g.withoutStrategies(SubgraphStrategy.class).V().count().asAdmin().getBytecode(), bindings, "g"); + assertEquals(new Long(6), traversal.next()); + assertFalse(traversal.hasNext()); + // + traversal = new GremlinGroovyScriptEngine().eval(g.withStrategies(SubgraphStrategy.create(new MapConfiguration(new HashMap<String, Object>() {{ + put(SubgraphStrategy.VERTICES, __.has("name", "marko")); - }})), ReadOnlyStrategy.instance()).V().values("name").asAdmin().getBytecode(), bindings); ++ }})), ReadOnlyStrategy.instance()).V().values("name").asAdmin().getBytecode(), bindings, "g"); + assertEquals("marko", traversal.next()); + assertFalse(traversal.hasNext()); + } + + @Test + public void shouldSupportStringSupplierLambdas() throws Exception { + final TinkerGraph graph = TinkerFactory.createModern(); + GraphTraversalSource g = graph.traversal(); + g = g.withStrategies(new TranslationStrategy(g, GroovyTranslator.of("g"))); + GraphTraversal.Admin<Vertex, Integer> t = g.withSideEffect("lengthSum", 0).withSack(1) + .V() + .filter(Lambda.predicate("it.get().label().equals('person')")) + .flatMap(Lambda.function("it.get().vertices(Direction.OUT)")) + .map(Lambda.<Traverser<Object>, Integer>function("it.get().value('name').length()")) + .sideEffect(Lambda.consumer("{ x -> x.sideEffects(\"lengthSum\", x.<Integer>sideEffects('lengthSum') + x.get()) }")) + .order().by(Lambda.comparator("a,b -> a <=> b")) + .sack(Lambda.biFunction("{ a,b -> a + b }")) + .asAdmin(); + final List<Integer> sacks = new ArrayList<>(); + final List<Integer> lengths = new ArrayList<>(); + while (t.hasNext()) { + final Traverser.Admin<Integer> traverser = t.nextTraverser(); + sacks.add(traverser.sack()); + lengths.add(traverser.get()); + } + assertFalse(t.hasNext()); + // + assertEquals(6, lengths.size()); + assertEquals(3, lengths.get(0).intValue()); + assertEquals(3, lengths.get(1).intValue()); + assertEquals(3, lengths.get(2).intValue()); + assertEquals(4, lengths.get(3).intValue()); + assertEquals(5, lengths.get(4).intValue()); + assertEquals(6, lengths.get(5).intValue()); + /// + assertEquals(6, sacks.size()); + assertEquals(4, sacks.get(0).intValue()); + assertEquals(4, sacks.get(1).intValue()); + assertEquals(4, sacks.get(2).intValue()); + assertEquals(5, sacks.get(3).intValue()); + assertEquals(6, sacks.get(4).intValue()); + assertEquals(7, sacks.get(5).intValue()); + // + assertEquals(24, t.getSideEffects().<Number>get("lengthSum").intValue()); + } + + @Test + public void shouldHandleMaps() { + final TinkerGraph graph = TinkerFactory.createModern(); + GraphTraversalSource g = graph.traversal(); + String script = GroovyTranslator.of("g").translate(g.V().id().is(new LinkedHashMap() {{ + put(3, "32"); + put(Arrays.asList(1, 2, 3.1d), 4); + }}).asAdmin().getBytecode()); + assertEquals(script, "g.V().id().is([((int) 3):(\"32\"),([(int) 1, (int) 2, 3.1d]):((int) 4)])"); + } + + @Test + public void shouldHaveValidToString() { + assertEquals("translator[h:gremlin-groovy]", GroovyTranslator.of("h").toString()); + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/87bf0c62/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/87bf0c62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinEnabledScriptEngineTest.java ----------------------------------------------------------------------