Repository: tinkerpop
Updated Branches:
  refs/heads/master f242289a8 -> 7b3adca39


Made some improvements to the BindingsGremlinPlugin

Made it possible to specify scopes to apply the bindings to. Added tests. CTR


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

Branch: refs/heads/master
Commit: c958b220b9559bb5fedbcc6e5c17f2dc142fb430
Parents: 91759a5
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jan 26 14:46:36 2017 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jan 26 14:46:36 2017 -0500

----------------------------------------------------------------------
 .../gremlin/jsr223/BindingsCustomizer.java      | 11 ++-
 .../gremlin/jsr223/BindingsGremlinPlugin.java   | 48 ++++++++--
 .../jsr223/DefaultBindingsCustomizer.java       | 20 ++++-
 .../DefaultGremlinScriptEngineManager.java      | 16 +++-
 .../gremlin/jsr223/LazyBindingsCustomizer.java  | 20 +++++
 .../gremlin/jsr223/ScriptFileGremlinPlugin.java |  4 +-
 .../jsr223/BindingsScriptEngineTest.java        | 95 ++++++++++++++++++++
 .../jsr223/GremlinScriptEngineSuite.java        |  1 +
 8 files changed, 206 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsCustomizer.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsCustomizer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsCustomizer.java
index 02c129e..e8dd9f3 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsCustomizer.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsCustomizer.java
@@ -21,7 +21,9 @@ package org.apache.tinkerpop.gremlin.jsr223;
 import javax.script.Bindings;
 
 /**
- * Provides a way to alter the bindings on a {@link GremlinScriptEngine}.
+ * Provides a way to alter the bindings on a {@link GremlinScriptEngine}. 
Those implementing {@link GremlinScriptEngine}
+ * instances need to be concerned with accounting for this {@link Customizer}. 
It is handled automatically by the
+ * {@link DefaultGremlinScriptEngineManager}.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
@@ -30,4 +32,11 @@ public interface BindingsCustomizer extends Customizer {
      * Gets the bindings to add to a {@link GremlinScriptEngine}.
      */
     public Bindings getBindings();
+
+    /**
+     * Gets the scope to which the bindings apply. The scope is determined by 
the {@code ScriptContext} values where
+     * "100" is {@code EngineScope} (bindings apply to the current {@link 
GremlinScriptEngine}) and "200" is
+     * {@code GlobalScope} (bindings apply to the engines created by the 
current {@link GremlinScriptEngineManager}.
+     */
+    public int getScope();
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsGremlinPlugin.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsGremlinPlugin.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsGremlinPlugin.java
index feb501d..59304df 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsGremlinPlugin.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsGremlinPlugin.java
@@ -19,26 +19,48 @@
 package org.apache.tinkerpop.gremlin.jsr223;
 
 import javax.script.Bindings;
+import javax.script.ScriptContext;
 import javax.script.SimpleBindings;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.Supplier;
 
 /**
+ * A module that allows {@code Bindings} to be applied to a {@link 
GremlinScriptEngine}. The bindings are controled by
+ * their {@code scope} which are determined by the {@code ScriptContext} 
values where "100" is {@code ENGINE_SCOPE}
+ * (bindings apply to the current {@link GremlinScriptEngine}) and "200" is 
{@code GLOBAL_SCOPE} (bindings apply to the
+ * engines created by the current {@link GremlinScriptEngineManager}.
+ * <p/>
+ * Note that bindings are applied in the following order:
+ * <ol>
+ *   <li>The order in which the {@link GremlinScriptEngine} is requested from 
the {@link GremlinScriptEngineManager}</li>
+ *   <li>The order in which the {@code BindingsGremlinPlugin} instances are 
added to the {@link GremlinScriptEngineManager}</li>
+ * </ol>
+ * <p/>
+ * Moreover, they will override one another within a scope and among scopes. 
For instance, {@code ENGINE_SCOPE} bindings
+ * will override {@code GLOBAL_SCOPE}. Those bindings that are {@code 
GLOBAL_SCOPE} and applied to a single
+ * {@link GremlinScriptEngine} via an {@link Builder#appliesTo} configuration 
will still appear present to all other
+ * {@link GremlinScriptEngine} created by the {@link 
GremlinScriptEngineManager} that the plugin was bound to.
+ * <p/>
+ * This {@link GremlinPlugin} is not enabled for the {@code ServiceLoader}. It 
is designed to be instantiated manually.
+ *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class BindingsGremlinPlugin extends AbstractGremlinPlugin {
     private static final String NAME = "tinkerpop.bindings";
 
     private BindingsGremlinPlugin(final Builder builder) {
-        this(builder.bindings);
+        super(NAME, builder.appliesTo, new 
DefaultBindingsCustomizer(builder.bindings, builder.scope));
     }
 
-    public BindingsGremlinPlugin(final Bindings bindings) {
-        super(NAME, new DefaultBindingsCustomizer(bindings));
+    public BindingsGremlinPlugin(final Bindings bindings, final int scope) {
+        super(NAME, new DefaultBindingsCustomizer(bindings, scope));
     }
 
-    public BindingsGremlinPlugin(final Supplier<Bindings> bindingsSupplier) {
-        super(NAME, new LazyBindingsCustomizer(bindingsSupplier));
+    public BindingsGremlinPlugin(final Supplier<Bindings> bindingsSupplier, 
final int scope) {
+        super(NAME, new LazyBindingsCustomizer(bindingsSupplier, scope));
     }
 
     public static BindingsGremlinPlugin.Builder build() {
@@ -48,14 +70,30 @@ public class BindingsGremlinPlugin extends 
AbstractGremlinPlugin {
     public static final class Builder {
 
         private Bindings bindings = new SimpleBindings();
+        private int scope = ScriptContext.ENGINE_SCOPE;
+        private final Set<String> appliesTo = new HashSet<>();
 
         private Builder() {}
 
+        /**
+         * The name of the {@link GremlinScriptEngine} that this module will 
apply to. Setting no values here will
+         * make the module available to all the engines.
+         */
+        public BindingsGremlinPlugin.Builder appliesTo(final 
Collection<String> scriptEngineName) {
+            this.appliesTo.addAll(scriptEngineName);
+            return this;
+        }
+
         public Builder bindings(final Map<String, Object> bindings) {
             this.bindings = new SimpleBindings(bindings);
             return this;
         }
 
+        public Builder scope(final int scope) {
+            this.scope = scope;
+            return this;
+        }
+
         public BindingsGremlinPlugin create() {
             return new BindingsGremlinPlugin(this);
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultBindingsCustomizer.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultBindingsCustomizer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultBindingsCustomizer.java
index 0073d39..cee5182 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultBindingsCustomizer.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultBindingsCustomizer.java
@@ -19,22 +19,40 @@
 package org.apache.tinkerpop.gremlin.jsr223;
 
 import javax.script.Bindings;
+import javax.script.ScriptContext;
 
 /**
- * Default implementation of the {@link BindingsCustomizer}.
+ * Default implementation of the {@link BindingsCustomizer}. If this 
customizer is applied directly to a
+ * {@link GremlinScriptEngine} it will not apply {@code GLOBAL_SCOPE} 
bindings. Those can only be applied if the
+ * customizer is applied via the {@link GremlinScriptEngineManager} (which 
would do so through the
+ * {@link BindingsGremlinPlugin}.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class DefaultBindingsCustomizer implements BindingsCustomizer {
 
     private final Bindings bindings;
+    private final int scope;
 
+    /**
+     * Creates a new object with {@code ScriptContext.ENGINE_SCOPE}.
+     */
     public DefaultBindingsCustomizer(final Bindings bindings) {
+        this(bindings, ScriptContext.ENGINE_SCOPE);
+    }
+
+    public DefaultBindingsCustomizer(final Bindings bindings, final int scope) 
{
         this.bindings = bindings;
+        this.scope = scope;
     }
 
     @Override
     public Bindings getBindings() {
         return bindings;
     }
+
+    @Override
+    public int getScope() {
+        return scope;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
index 436deac..01b4957 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
@@ -23,7 +23,6 @@ import javax.script.ScriptContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -442,8 +441,23 @@ public class DefaultGremlinScriptEngineManager implements 
GremlinScriptEngineMan
 
     private GremlinScriptEngine createGremlinScriptEngine(final 
GremlinScriptEngineFactory spi) {
         final GremlinScriptEngine engine = spi.getScriptEngine();
+
+        // merge in bindings that are marked with global scope. these get 
applied to all GremlinScriptEngine instances
+        getCustomizers(spi.getEngineName()).stream()
+                .filter(p -> p instanceof BindingsCustomizer)
+                .map(p -> ((BindingsCustomizer) p))
+                .filter(bc -> bc.getScope() == ScriptContext.GLOBAL_SCOPE)
+                .forEach(bc -> globalScope.putAll(bc.getBindings()));
         engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
 
+        // merge in bindings that are marked with engine scope. these get 
applied to only those GremlinScriptEngine
+        // instances that are of this gremlin language
+        getCustomizers(spi.getEngineName()).stream()
+                .filter(p -> p instanceof BindingsCustomizer)
+                .map(p -> ((BindingsCustomizer) p))
+                .filter(bc -> bc.getScope() == ScriptContext.ENGINE_SCOPE)
+                .forEach(bc -> engine.setBindings(bc.getBindings(), 
ScriptContext.ENGINE_SCOPE));
+
         final List<ScriptCustomizer> scriptCustomizers = 
getCustomizers(spi.getEngineName()).stream()
                 .filter(p -> p instanceof ScriptCustomizer)
                 .map(p -> ((ScriptCustomizer) p))

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/LazyBindingsCustomizer.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/LazyBindingsCustomizer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/LazyBindingsCustomizer.java
index 01ae662..8feb361 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/LazyBindingsCustomizer.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/LazyBindingsCustomizer.java
@@ -19,21 +19,41 @@
 package org.apache.tinkerpop.gremlin.jsr223;
 
 import javax.script.Bindings;
+import javax.script.ScriptContext;
 import java.util.function.Supplier;
 
 /**
+ * A customizer implementation that provides bindings to a {@link 
GremlinScriptEngine}. If this customizer is applied
+ * directly to a {@link GremlinScriptEngine} it will not apply {@code 
GLOBAL_SCOPE} bindings. Those can only be applied
+ * if the customizer is applied via the {@link GremlinScriptEngineManager} 
(which would do so through the
+ * {@link BindingsGremlinPlugin}.
+ *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class LazyBindingsCustomizer implements BindingsCustomizer {
 
     private final Supplier<Bindings> bindingsSupplier;
+    private final int scope;
 
+    /**
+     * Creates a new object with {@code ScriptContext.ENGINE_SCOPE}.
+     */
     public LazyBindingsCustomizer(final Supplier<Bindings> bindingsSupplier) {
+        this(bindingsSupplier, ScriptContext.ENGINE_SCOPE);
+    }
+
+    public LazyBindingsCustomizer(final Supplier<Bindings> bindingsSupplier, 
final int scope) {
         this.bindingsSupplier = bindingsSupplier;
+        this.scope = scope;
     }
 
     @Override
     public Bindings getBindings() {
         return bindingsSupplier.get();
     }
+
+    @Override
+    public int getScope() {
+        return scope;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/ScriptFileGremlinPlugin.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/ScriptFileGremlinPlugin.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/ScriptFileGremlinPlugin.java
index 0131ca2..3a3f4be 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/ScriptFileGremlinPlugin.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/ScriptFileGremlinPlugin.java
@@ -28,7 +28,9 @@ import java.util.Set;
 
 /**
  * Loads scripts from one or more files into the {@link GremlinScriptEngine} 
at startup. This {@link GremlinPlugin} is
- * not enabled for the {@code ServiceLoader}. It is designed to be 
instantiated manually.
+ * not enabled for the {@code ServiceLoader}. It is designed to be 
instantiated manually. Those implementing
+ * {@link GremlinScriptEngine} instances need to be concerned with accounting 
for this {@link Customizer}. It is
+ * handled automatically by the {@link DefaultGremlinScriptEngineManager}.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsScriptEngineTest.java
----------------------------------------------------------------------
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsScriptEngineTest.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsScriptEngineTest.java
new file mode 100644
index 0000000..e02b834
--- /dev/null
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/BindingsScriptEngineTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.junit.Test;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import java.util.Collections;
+
+import static 
org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngineSuite.ENGINE_TO_TEST;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class BindingsScriptEngineTest {
+
+    @Test
+    public void shouldIncludeGlobalBindings() throws ScriptException {
+        final GremlinScriptEngineManager manager = new 
DefaultGremlinScriptEngineManager();
+        final Bindings b = new SimpleBindings();
+        b.put("x", 1);
+        b.put("y", 2);
+
+        manager.addPlugin(BindingsGremlinPlugin.build().
+                bindings(b).
+                scope(ScriptContext.GLOBAL_SCOPE).
+                appliesTo(Collections.singletonList(ENGINE_TO_TEST)).create());
+
+        final GremlinScriptEngine engine = 
manager.getEngineByName(ENGINE_TO_TEST);
+        assertEquals(1, engine.eval("x"));
+        assertEquals(2, engine.eval("y"));
+    }
+
+    @Test
+    public void shouldIncludeEngineBindings() throws ScriptException {
+        final GremlinScriptEngineManager manager = new 
DefaultGremlinScriptEngineManager();
+        final Bindings b = new SimpleBindings();
+        b.put("x", 1);
+        b.put("y", 2);
+
+        manager.addPlugin(BindingsGremlinPlugin.build().
+                bindings(b).
+                scope(ScriptContext.ENGINE_SCOPE).
+                appliesTo(Collections.singletonList(ENGINE_TO_TEST)).create());
+
+        final GremlinScriptEngine engine = 
manager.getEngineByName(ENGINE_TO_TEST);
+        assertEquals(1, engine.eval("x"));
+        assertEquals(2, engine.eval("y"));
+    }
+
+    @Test
+    public void shouldIncludeEngineBindingsToOverrideGlobalBindings() throws 
ScriptException {
+        final GremlinScriptEngineManager manager = new 
DefaultGremlinScriptEngineManager();
+
+        final Bindings b1 = new SimpleBindings();
+        b1.put("x", 1);
+        b1.put("y", 2);
+        manager.addPlugin(BindingsGremlinPlugin.build().
+                bindings(b1).
+                scope(ScriptContext.GLOBAL_SCOPE).
+                appliesTo(Collections.singletonList(ENGINE_TO_TEST)).create());
+
+        final Bindings b2 = new SimpleBindings();
+        b2.put("x", 100);
+        b2.put("y", 200);
+        manager.addPlugin(BindingsGremlinPlugin.build().
+                bindings(b2).
+                scope(ScriptContext.ENGINE_SCOPE).
+                appliesTo(Collections.singletonList(ENGINE_TO_TEST)).create());
+
+        final GremlinScriptEngine engine = 
manager.getEngineByName(ENGINE_TO_TEST);
+        assertEquals(100, engine.eval("x"));
+        assertEquals(200, engine.eval("y"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c958b220/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptEngineSuite.java
----------------------------------------------------------------------
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptEngineSuite.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptEngineSuite.java
index 8ccde91..70c585c 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptEngineSuite.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptEngineSuite.java
@@ -29,6 +29,7 @@ public class GremlinScriptEngineSuite extends Suite {
     static String ENGINE_TO_TEST;
 
     private static final Class<?>[] allTests = new Class<?>[]{
+            BindingsScriptEngineTest.class,
             CachedGremlinScriptEngineManagerTest.class,
             GremlinEnabledScriptEngineTest.class,
             ScriptEngineLambdaTest.class };

Reply via email to