TINKERPOP-1562 Adapted CompilerCustomizerProvider to Customizer This hooks up all the groovy-specific configurations to the GremlinGroovyScriptEngine.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/70506bf2 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/70506bf2 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/70506bf2 Branch: refs/heads/TINKERPOP-1562 Commit: 70506bf28889f59829b272a5050d91c62d283051 Parents: c310f2b Author: Stephen Mallette <sp...@genoprime.com> Authored: Tue Nov 29 16:15:12 2016 -0500 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Dec 1 06:41:43 2016 -0500 ---------------------------------------------------------------------- .../jsr223/CustomizerProviderCustomizer.java | 40 ++++++ .../jsr223/GremlinGroovyScriptEngine.java | 20 ++- .../jsr223/GroovyCompilerGremlinPlugin.java | 138 +++++++++++++++++++ .../groovy/jsr223/SugarGremlinPlugin.java | 8 +- .../CompileStaticCustomizerProvider.java | 1 + .../ConfigurationCustomizerProvider.java | 1 + .../InterpreterModeCustomizerProvider.java | 1 + .../ThreadInterruptCustomizerProvider.java | 1 + .../TimedInterruptCustomizerProvider.java | 1 + .../TypeCheckedCustomizerProvider.java | 1 + ...mlinGroovyScriptEngineCompileStaticTest.java | 72 +++++++++- .../GremlinGroovyScriptEngineConfigTest.java | 14 +- .../jsr223/GremlinGroovyScriptEngineTest.java | 50 ++++++- ...inGroovyScriptEngineThreadInterruptTest.java | 23 +++- ...linGroovyScriptEngineTimedInterruptTest.java | 69 +++++++++- ...remlinGroovyScriptEngineTypeCheckedTest.java | 72 +++++++++- .../jsr223/GroovyCompilerGremlinPluginTest.java | 128 +++++++++++++++++ 17 files changed, 617 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/CustomizerProviderCustomizer.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/CustomizerProviderCustomizer.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/CustomizerProviderCustomizer.java new file mode 100644 index 0000000..73614a1 --- /dev/null +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/CustomizerProviderCustomizer.java @@ -0,0 +1,40 @@ +/* + * 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.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; + +/** + * An adapter that allows existing {@link CompilerCustomizerProvider} instances to behave as a {#link Customizer}. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +class CustomizerProviderCustomizer implements Customizer { + + private final CompilerCustomizerProvider customizerProvider; + + CustomizerProviderCustomizer(final CompilerCustomizerProvider customizerProvider) { + this.customizerProvider = customizerProvider; + } + + CompilerCustomizerProvider getCustomizerProvider() { + return customizerProvider; + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java index 264587a..2996792 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java @@ -70,7 +70,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -233,16 +232,31 @@ public class GremlinGroovyScriptEngine extends GroovyScriptEngineImpl importCustomizerProvider = new EmptyImportCustomizerProvider(imports, staticImports); } - interpreterModeEnabled = false; + // this is a bit temporary - until CompilerCustomizerProvider is gone + final List<CompilerCustomizerProvider> customizerProviderCustomizer = listOfCustomizers.stream() + .filter(p -> p instanceof CustomizerProviderCustomizer) + .map(p -> ((CustomizerProviderCustomizer) p).getCustomizerProvider()) + .collect(Collectors.toList()); - customizerProviders = Collections.emptyList(); + // determine if interpreter mode should be enabled + interpreterModeEnabled = customizerProviderCustomizer.stream() + .anyMatch(p -> p.getClass().equals(InterpreterModeCustomizerProvider.class)); + + // remove used providers as the rest will be applied directly + customizerProviders = customizerProviderCustomizer.stream() + .filter(p -> p != null && + !((p instanceof ImportCustomizerProvider))) + .collect(Collectors.toList()); createClassLoader(); } /** * Creates a new instance with the specified {@link CompilerCustomizerProvider} objects. + * + * @deprecated As of release 3.2.4, replaced by {@link #GremlinGroovyScriptEngine(Customizer...)}. */ + @Deprecated public GremlinGroovyScriptEngine(final CompilerCustomizerProvider... compilerCustomizerProviders) { final List<CompilerCustomizerProvider> providers = Arrays.asList(compilerCustomizerProviders); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java new file mode 100644 index 0000000..0d2e9c6 --- /dev/null +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java @@ -0,0 +1,138 @@ +/* + * 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.tinkerpop.gremlin.groovy.jsr223.customizer.CompileStaticCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.ConfigurationCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.InterpreterModeCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.ThreadInterruptCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TypeCheckedCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.AbstractGremlinPlugin; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; +import org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +/** + * A {@link GremlinPlugin} that provides access to low-level configuration options of the {@code GroovyScriptEngine} + * itself. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public class GroovyCompilerGremlinPlugin extends AbstractGremlinPlugin { + + public enum Compilation { + COMPILE_STATIC, + TYPE_CHECKED, + NONE + } + + private static final String NAME = "tinkerpop.groovy"; + + private GroovyCompilerGremlinPlugin(final Builder builder) { + super(NAME, new HashSet<>(Collections.singletonList("gremlin-groovy")), builder.asCustomizers()); + } + + public static Builder build() { + return new Builder(); + } + + public static final class Builder { + + private boolean interpreterMode; + private boolean threadInterrupt; + private long timeInMillis = 0; + private Compilation compilation = Compilation.NONE; + private String extensions = null; + + private Map<String,Object> keyValues = Collections.emptyMap(); + + public Builder enableInterpreterMode(final boolean interpreterMode) { + this.interpreterMode = interpreterMode; + return this; + } + + public Builder compilerConfigurationOptions(final Map<String,Object> keyValues) { + this.keyValues = keyValues; + return this; + } + + public Builder enableThreadInterrupt(final boolean threadInterrupt) { + this.threadInterrupt = threadInterrupt; + return this; + } + + public Builder timedInterrupt(final long timeInMillis) { + this.timeInMillis = timeInMillis; + return this; + } + + public Builder compilation(final Compilation compilation) { + this.compilation = compilation; + return this; + } + + public Builder compilation(final String compilation) { + return compilation(Compilation.valueOf(compilation)); + } + + public Builder extensions(final String extensions) { + this.extensions = extensions; + return this; + } + + Customizer[] asCustomizers() { + final List<Customizer> list = new ArrayList<>(); + + if (interpreterMode) + list.add(new CustomizerProviderCustomizer(new InterpreterModeCustomizerProvider())); + + if (!keyValues.isEmpty()) + list.add(new CustomizerProviderCustomizer(new ConfigurationCustomizerProvider(keyValues))); + + if (threadInterrupt) + list.add(new CustomizerProviderCustomizer(new ThreadInterruptCustomizerProvider())); + + if (timeInMillis > 0) + list.add(new CustomizerProviderCustomizer(new TimedInterruptCustomizerProvider(timeInMillis))); + + if (compilation == Compilation.COMPILE_STATIC) + list.add(new CustomizerProviderCustomizer(new CompileStaticCustomizerProvider(extensions))); + else if (compilation == Compilation.TYPE_CHECKED) + list.add(new CustomizerProviderCustomizer(new TypeCheckedCustomizerProvider(extensions))); + else if (compilation != Compilation.NONE) + throw new IllegalStateException("Use of unknown compilation type: " + compilation); + + if (list.isEmpty()) throw new IllegalStateException("No customizer options have been selected for this plugin"); + + final Customizer[] customizers = new Customizer[list.size()]; + list.toArray(customizers); + return customizers; + } + + public GroovyCompilerGremlinPlugin create() { + return new GroovyCompilerGremlinPlugin(this); + } + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/SugarGremlinPlugin.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/SugarGremlinPlugin.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/SugarGremlinPlugin.java index 95c610f..82fbc8e 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/SugarGremlinPlugin.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/SugarGremlinPlugin.java @@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.jsr223.AbstractGremlinPlugin; import org.apache.tinkerpop.gremlin.jsr223.DefaultScriptCustomizer; import java.util.Collections; +import java.util.HashSet; /** * A plugin implementation which allows for the usage of Gremlin Groovy's syntactic sugar. @@ -34,12 +35,7 @@ public class SugarGremlinPlugin extends AbstractGremlinPlugin { private static final String NAME = "tinkerpop.sugar"; public SugarGremlinPlugin() { - super(NAME, new DefaultScriptCustomizer(Collections.singletonList( + super(NAME, new HashSet<>(Collections.singletonList("gremlin-groovy")), new DefaultScriptCustomizer(Collections.singletonList( Collections.singletonList(SugarLoader.class.getPackage().getName() + "." + SugarLoader.class.getSimpleName() + ".load()")))); } - - @Override - public String getName() { - return "tinkerpop.sugar"; - } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/CompileStaticCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/CompileStaticCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/CompileStaticCustomizerProvider.java index 65e1224..ab0bff5 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/CompileStaticCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/CompileStaticCustomizerProvider.java @@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.groovy.jsr223.customizer; import groovy.transform.CompileStatic; import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; import org.codehaus.groovy.control.customizers.CompilationCustomizer; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ConfigurationCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ConfigurationCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ConfigurationCustomizerProvider.java index ba9855c..78357cb 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ConfigurationCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ConfigurationCustomizerProvider.java @@ -19,6 +19,7 @@ package org.apache.tinkerpop.gremlin.groovy.jsr223.customizer; import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.customizers.CompilationCustomizer; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/InterpreterModeCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/InterpreterModeCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/InterpreterModeCustomizerProvider.java index e3f95f4..013ba8b 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/InterpreterModeCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/InterpreterModeCustomizerProvider.java @@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.groovy.jsr223.customizer; import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; import org.apache.tinkerpop.gremlin.groovy.jsr223.ast.InterpreterMode; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; import org.codehaus.groovy.control.customizers.CompilationCustomizer; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ThreadInterruptCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ThreadInterruptCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ThreadInterruptCustomizerProvider.java index 8c942c6..e46e9b7 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ThreadInterruptCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/ThreadInterruptCustomizerProvider.java @@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.groovy.jsr223.customizer; import groovy.transform.ThreadInterrupt; import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; import org.codehaus.groovy.control.customizers.CompilationCustomizer; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TimedInterruptCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TimedInterruptCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TimedInterruptCustomizerProvider.java index e4bdc62..9913088 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TimedInterruptCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TimedInterruptCustomizerProvider.java @@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.groovy.jsr223.customizer; import groovy.transform.TimedInterrupt; import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; import org.codehaus.groovy.ast.tools.GeneralUtils; import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; import org.codehaus.groovy.control.customizers.CompilationCustomizer; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TypeCheckedCustomizerProvider.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TypeCheckedCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TypeCheckedCustomizerProvider.java index f0bc791..cf9147b 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TypeCheckedCustomizerProvider.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/customizer/TypeCheckedCustomizerProvider.java @@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.groovy.jsr223.customizer; import groovy.transform.TypeChecked; import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; import org.codehaus.groovy.control.customizers.CompilationCustomizer; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineCompileStaticTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineCompileStaticTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineCompileStaticTest.java index 3ba3e0b..b62f3f3 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineCompileStaticTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineCompileStaticTest.java @@ -35,7 +35,7 @@ import static org.junit.Assert.fail; */ public class GremlinGroovyScriptEngineCompileStaticTest { @Test - public void shouldCompileStatic() throws Exception { + public void shouldCompileStaticDeprecated() throws Exception { // with no type checking this should pass try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine()) { assertEquals(255, scriptEngine.eval("((Object) new java.awt.Color(255, 255, 255)).getRed()")); @@ -53,7 +53,25 @@ public class GremlinGroovyScriptEngineCompileStaticTest { } @Test - public void shouldCompileStaticWithExtension() throws Exception { + public void shouldCompileStatic() throws Exception { + // with no type checking this should pass + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine()) { + assertEquals(255, scriptEngine.eval("((Object) new java.awt.Color(255, 255, 255)).getRed()")); + } + + final CompileStaticCustomizerProvider provider = new CompileStaticCustomizerProvider(); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(provider))) { + scriptEngine.eval("((Object) new java.awt.Color(255, 255, 255)).getRed()"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + final Throwable root = ExceptionUtils.getRootCause(se); + assertEquals(MultipleCompilationErrorsException.class, root.getClass()); + assertThat(se.getMessage(), containsString("[Static type checking] - Cannot find matching method java.lang.Object#getRed(). Please check if the declared type is right and if the method exists.")); + } + } + + @Test + public void shouldCompileStaticWithExtensionDeprecated() throws Exception { // with no type checking extension this should pass final CompileStaticCustomizerProvider providerNoExtension = new CompileStaticCustomizerProvider(); try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(providerNoExtension)) { @@ -72,7 +90,26 @@ public class GremlinGroovyScriptEngineCompileStaticTest { } @Test - public void shouldCompileStaticWithMultipleExtension() throws Exception { + public void shouldCompileStaticWithExtension() throws Exception { + // with no type checking extension this should pass + final CompileStaticCustomizerProvider providerNoExtension = new CompileStaticCustomizerProvider(); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerNoExtension))) { + assertEquals(255, scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red")); + } + + final CompileStaticCustomizerProvider providerWithExtension = new CompileStaticCustomizerProvider( + PrecompiledExtensions.PreventColorUsageExtension.class.getName()); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerWithExtension))) { + scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + assertEquals(MultipleCompilationErrorsException.class, se.getCause().getClass()); + assertThat(se.getMessage(), containsString("Method call is not allowed!")); + } + } + + @Test + public void shouldCompileStaticWithMultipleExtensionDeprecated() throws Exception { // with no type checking extension this should pass final CompileStaticCustomizerProvider providerNoExtension = new CompileStaticCustomizerProvider(); try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(providerNoExtension)) { @@ -99,4 +136,33 @@ public class GremlinGroovyScriptEngineCompileStaticTest { assertThat(se.getMessage(), containsString("Method call is not allowed!")); } } + + @Test + public void shouldCompileStaticWithMultipleExtension() throws Exception { + // with no type checking extension this should pass + final CompileStaticCustomizerProvider providerNoExtension = new CompileStaticCustomizerProvider(); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerNoExtension))) { + assertEquals(255, scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red")); + assertEquals(1l, scriptEngine.eval("def c = new java.util.concurrent.CountDownLatch(1); c.count")); + } + + final CompileStaticCustomizerProvider providerWithExtension = new CompileStaticCustomizerProvider( + PrecompiledExtensions.PreventColorUsageExtension.class.getName() + + "," + PrecompiledExtensions.PreventCountDownLatchUsageExtension.class.getName()); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerWithExtension))) { + scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + assertEquals(MultipleCompilationErrorsException.class, se.getCause().getClass()); + assertThat(se.getMessage(), containsString("Method call is not allowed!")); + } + + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(providerWithExtension)) { + scriptEngine.eval("def c = new java.util.concurrent.CountDownLatch(1); c.count"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + assertEquals(MultipleCompilationErrorsException.class, se.getCause().getClass()); + assertThat(se.getMessage(), containsString("Method call is not allowed!")); + } + } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineConfigTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineConfigTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineConfigTest.java index d354ffa..6b18ece 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineConfigTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineConfigTest.java @@ -31,9 +31,19 @@ import static org.junit.Assert.assertEquals; */ public class GremlinGroovyScriptEngineConfigTest { @Test - public void shouldAddBaseScriptClass() throws Exception { + public void shouldAddBaseScriptClassDeprecated() throws Exception { final ScriptEngine engine = new GremlinGroovyScriptEngine( - new ConfigurationCustomizerProvider("ScriptBaseClass", BaseScriptForTesting.class.getName()), new DefaultImportCustomizerProvider()); + new ConfigurationCustomizerProvider("ScriptBaseClass", BaseScriptForTesting.class.getName()), + new DefaultImportCustomizerProvider()); + + assertEquals("hello, stephen", engine.eval("hello('stephen')")); + } + + @Test + public void shouldAddBaseScriptClass() throws Exception { + final ScriptEngine engine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer( + new ConfigurationCustomizerProvider("ScriptBaseClass", BaseScriptForTesting.class.getName())), + new CustomizerProviderCustomizer(new DefaultImportCustomizerProvider())); assertEquals("hello, stephen", engine.eval("hello('stephen')")); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java index b18c020..65dc56e 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java @@ -99,7 +99,7 @@ public class GremlinGroovyScriptEngineTest { } @Test - public void shouldPromoteDefinedVarsInInterpreterModeWithNoBindings() throws Exception { + public void shouldPromoteDefinedVarsInInterpreterModeWithNoBindingsDeprecated() throws Exception { final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new InterpreterModeCustomizerProvider()); engine.eval("def addItUp = { x, y -> x + y }"); assertEquals(3, engine.eval("int xxx = 1 + 2")); @@ -121,7 +121,29 @@ public class GremlinGroovyScriptEngineTest { } @Test - public void shouldPromoteDefinedVarsInInterpreterModeWithBindings() throws Exception { + public void shouldPromoteDefinedVarsInInterpreterModeWithNoBindings() throws Exception { + final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(new InterpreterModeCustomizerProvider())); + engine.eval("def addItUp = { x, y -> x + y }"); + assertEquals(3, engine.eval("int xxx = 1 + 2")); + assertEquals(4, engine.eval("yyy = xxx + 1")); + assertEquals(7, engine.eval("def zzz = yyy + xxx")); + assertEquals(4, engine.eval("zzz - xxx")); + assertEquals("accessible-globally", engine.eval("if (yyy > 0) { def inner = 'should-stay-local'; outer = 'accessible-globally' }\n outer")); + assertEquals("accessible-globally", engine.eval("outer")); + + try { + engine.eval("inner"); + fail("Should not have been able to access 'inner'"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(MissingPropertyException.class)); + } + + assertEquals(10, engine.eval("addItUp(zzz,xxx)")); + } + + @Test + public void shouldPromoteDefinedVarsInInterpreterModeWithBindingsDeprecated() throws Exception { final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new InterpreterModeCustomizerProvider()); final Bindings b = new SimpleBindings(); b.put("x", 2); @@ -145,6 +167,30 @@ public class GremlinGroovyScriptEngineTest { } @Test + public void shouldPromoteDefinedVarsInInterpreterModeWithBindings() throws Exception { + final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(new InterpreterModeCustomizerProvider())); + final Bindings b = new SimpleBindings(); + b.put("x", 2); + engine.eval("def addItUp = { x, y -> x + y }", b); + assertEquals(3, engine.eval("int xxx = 1 + x", b)); + assertEquals(4, engine.eval("yyy = xxx + 1", b)); + assertEquals(7, engine.eval("def zzz = yyy + xxx", b)); + assertEquals(4, engine.eval("zzz - xxx", b)); + assertEquals("accessible-globally", engine.eval("if (yyy > 0) { def inner = 'should-stay-local'; outer = 'accessible-globally' }\n outer", b)); + assertEquals("accessible-globally", engine.eval("outer", b)); + + try { + engine.eval("inner", b); + fail("Should not have been able to access 'inner'"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(MissingPropertyException.class)); + } + + assertEquals(10, engine.eval("addItUp(zzz,xxx)", b)); + } + + @Test public void shouldEvalWithBindings() throws Exception { final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(); final Bindings b = new SimpleBindings(); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineThreadInterruptTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineThreadInterruptTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineThreadInterruptTest.java index c002939..ea778c6 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineThreadInterruptTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineThreadInterruptTest.java @@ -33,7 +33,7 @@ import static org.junit.Assert.assertTrue; */ public class GremlinGroovyScriptEngineThreadInterruptTest { @Test - public void shouldInterruptWhile() throws Exception { + public void shouldInterruptWhileDeprecated() throws Exception { final ScriptEngine engine = new GremlinGroovyScriptEngine(new ThreadInterruptCustomizerProvider()); final AtomicBoolean asserted = new AtomicBoolean(false); @@ -54,6 +54,27 @@ public class GremlinGroovyScriptEngineThreadInterruptTest { } @Test + public void shouldInterruptWhile() throws Exception { + final ScriptEngine engine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(new ThreadInterruptCustomizerProvider())); + final AtomicBoolean asserted = new AtomicBoolean(false); + + final Thread t = new Thread(() -> { + try { + engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 10000) {}"); + } catch (ScriptException se) { + asserted.set(se.getCause().getCause() instanceof InterruptedException); + } + }); + + t.start(); + Thread.sleep(100); + t.interrupt(); + while(t.isAlive()) {} + + assertTrue(asserted.get()); + } + + @Test public void shouldNotInterruptWhile() throws Exception { // companion to shouldInterruptWhile t final ScriptEngine engine = new GremlinGroovyScriptEngine(); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTimedInterruptTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTimedInterruptTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTimedInterruptTest.java index c465732..fa8d4ef 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTimedInterruptTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTimedInterruptTest.java @@ -36,21 +36,51 @@ import static org.junit.Assert.fail; public class GremlinGroovyScriptEngineTimedInterruptTest { @Test + public void shouldTimeoutScriptOnTimedWhileDeprecated() throws Exception { + final ScriptEngine engine = new GremlinGroovyScriptEngine( + new TimedInterruptCustomizerProvider(1000), new DefaultImportCustomizerProvider()); + try { + engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 10000) {}"); + fail("This should have timed out"); + } catch (ScriptException se) { + assertEquals(TimedInterruptTimeoutException.class, se.getCause().getCause().getClass()); + } + } + + @Test public void shouldTimeoutScriptOnTimedWhile() throws Exception { final ScriptEngine engine = new GremlinGroovyScriptEngine( + new CustomizerProviderCustomizer(new TimedInterruptCustomizerProvider(1000)), + new CustomizerProviderCustomizer(new DefaultImportCustomizerProvider())); + try { + engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 10000) {}"); + fail("This should have timed out"); + } catch (ScriptException se) { + assertEquals(TimedInterruptTimeoutException.class, se.getCause().getCause().getClass()); + } + } + + @Test + public void shouldTimeoutScriptOnTimedWhileOnceEngineHasBeenAliveForLongerThanTimeoutDeprecated() throws Exception { + final ScriptEngine engine = new GremlinGroovyScriptEngine( new TimedInterruptCustomizerProvider(1000), new DefaultImportCustomizerProvider()); + Thread.sleep(2000); try { engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 10000) {}"); fail("This should have timed out"); } catch (ScriptException se) { assertEquals(TimedInterruptTimeoutException.class, se.getCause().getCause().getClass()); } + + assertEquals(2, engine.eval("1+1")); } + @Test public void shouldTimeoutScriptOnTimedWhileOnceEngineHasBeenAliveForLongerThanTimeout() throws Exception { final ScriptEngine engine = new GremlinGroovyScriptEngine( - new TimedInterruptCustomizerProvider(1000), new DefaultImportCustomizerProvider()); + new CustomizerProviderCustomizer(new TimedInterruptCustomizerProvider(1000)), + new CustomizerProviderCustomizer(new DefaultImportCustomizerProvider())); Thread.sleep(2000); try { engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 10000) {}"); @@ -63,7 +93,7 @@ public class GremlinGroovyScriptEngineTimedInterruptTest { } @Test - public void shouldContinueToEvalScriptsEvenWithTimedInterrupt() throws Exception { + public void shouldContinueToEvalScriptsEvenWithTimedInterruptDeprecated() throws Exception { final ScriptEngine engine = new GremlinGroovyScriptEngine( new TimedInterruptCustomizerProvider(1000), new DefaultImportCustomizerProvider()); @@ -84,7 +114,29 @@ public class GremlinGroovyScriptEngineTimedInterruptTest { } @Test - public void shouldNotTimeoutStandaloneFunction() throws Exception { + public void shouldContinueToEvalScriptsEvenWithTimedInterrupt() throws Exception { + final ScriptEngine engine = new GremlinGroovyScriptEngine( + new CustomizerProviderCustomizer(new TimedInterruptCustomizerProvider(1000)), + new CustomizerProviderCustomizer(new DefaultImportCustomizerProvider())); + + for (int ix = 0; ix < 5; ix++) { + try { + // this script takes 1000 ms longer than the interruptionTimeout + engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 2000) {}"); + fail("This should have timed out"); + } catch (ScriptException se) { + assertEquals(TimedInterruptTimeoutException.class, se.getCause().getCause().getClass()); + } + + // this script takes 500 ms less than the interruptionTimeout + assertEquals("test", engine.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 500) {};'test'")); + } + + assertEquals(2, engine.eval("1+1")); + } + + @Test + public void shouldNotTimeoutStandaloneFunctionDeprecated() throws Exception { // use a super fast timeout which should not prevent the call of a cached function final ScriptEngine engine = new GremlinGroovyScriptEngine( new TimedInterruptCustomizerProvider(1), new DefaultImportCustomizerProvider()); @@ -92,4 +144,15 @@ public class GremlinGroovyScriptEngineTimedInterruptTest { assertEquals(3, engine.eval("addItUp(1,2)")); } + + @Test + public void shouldNotTimeoutStandaloneFunction() throws Exception { + // use a super fast timeout which should not prevent the call of a cached function + final ScriptEngine engine = new GremlinGroovyScriptEngine( + new CustomizerProviderCustomizer(new TimedInterruptCustomizerProvider(1)), + new CustomizerProviderCustomizer(new DefaultImportCustomizerProvider())); + engine.eval("def addItUp(x,y) { x + y }"); + + assertEquals(3, engine.eval("addItUp(1,2)")); + } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTypeCheckedTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTypeCheckedTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTypeCheckedTest.java index a9062a8..0ca12d7 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTypeCheckedTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTypeCheckedTest.java @@ -36,7 +36,7 @@ import static org.junit.Assert.fail; */ public class GremlinGroovyScriptEngineTypeCheckedTest { @Test - public void shouldTypeCheck() throws Exception { + public void shouldTypeCheckDeprecated() throws Exception { // with no type checking this should pass try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine()) { assertEquals(255, scriptEngine.eval("((Object) new java.awt.Color(255, 255, 255)).getRed()")); @@ -54,7 +54,25 @@ public class GremlinGroovyScriptEngineTypeCheckedTest { } @Test - public void shouldTypeCheckWithExtension() throws Exception { + public void shouldTypeCheck() throws Exception { + // with no type checking this should pass + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine()) { + assertEquals(255, scriptEngine.eval("((Object) new java.awt.Color(255, 255, 255)).getRed()")); + } + + final TypeCheckedCustomizerProvider provider = new TypeCheckedCustomizerProvider(); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(provider))) { + scriptEngine.eval("((Object) new java.awt.Color(255, 255, 255)).getRed()"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + final Throwable root = ExceptionUtils.getRootCause(se); + assertEquals(MultipleCompilationErrorsException.class, root.getClass()); + assertThat(se.getMessage(), containsString("[Static type checking] - Cannot find matching method java.lang.Object#getRed(). Please check if the declared type is right and if the method exists.")); + } + } + + @Test + public void shouldTypeCheckWithExtensionDeprecated() throws Exception { // with no type checking extension this should pass final TypeCheckedCustomizerProvider providerNoExtension = new TypeCheckedCustomizerProvider(); try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(providerNoExtension)) { @@ -73,7 +91,26 @@ public class GremlinGroovyScriptEngineTypeCheckedTest { } @Test - public void shouldTypeCheckWithMultipleExtension() throws Exception { + public void shouldTypeCheckWithExtension() throws Exception { + // with no type checking extension this should pass + final TypeCheckedCustomizerProvider providerNoExtension = new TypeCheckedCustomizerProvider(); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerNoExtension))) { + assertEquals(255, scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red")); + } + + final CompileStaticCustomizerProvider providerWithExtension = new CompileStaticCustomizerProvider( + PrecompiledExtensions.PreventColorUsageExtension.class.getName()); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerWithExtension))) { + scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + assertEquals(MultipleCompilationErrorsException.class, se.getCause().getClass()); + assertThat(se.getMessage(), containsString("Method call is not allowed!")); + } + } + + @Test + public void shouldTypeCheckWithMultipleExtensionDeprecated() throws Exception { // with no type checking extension this should pass final TypeCheckedCustomizerProvider providerNoExtension = new TypeCheckedCustomizerProvider(); try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(providerNoExtension)) { @@ -100,4 +137,33 @@ public class GremlinGroovyScriptEngineTypeCheckedTest { assertThat(se.getMessage(), containsString("Method call is not allowed!")); } } + + @Test + public void shouldTypeCheckWithMultipleExtension() throws Exception { + // with no type checking extension this should pass + final TypeCheckedCustomizerProvider providerNoExtension = new TypeCheckedCustomizerProvider(); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerNoExtension))) { + assertEquals(255, scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red")); + assertEquals(1l, scriptEngine.eval("def c = new java.util.concurrent.CountDownLatch(1); c.count")); + } + + final TypeCheckedCustomizerProvider providerWithExtension = new TypeCheckedCustomizerProvider( + PrecompiledExtensions.PreventColorUsageExtension.class.getName() + + "," + PrecompiledExtensions.PreventCountDownLatchUsageExtension.class.getName()); + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(new CustomizerProviderCustomizer(providerWithExtension))) { + scriptEngine.eval("def c = new java.awt.Color(255, 255, 255); c.red"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + assertEquals(MultipleCompilationErrorsException.class, se.getCause().getClass()); + assertThat(se.getMessage(), containsString("Method call is not allowed!")); + } + + try (GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine(providerWithExtension)) { + scriptEngine.eval("def c = new java.util.concurrent.CountDownLatch(1); c.count"); + fail("Should have failed type checking"); + } catch (ScriptException se) { + assertEquals(MultipleCompilationErrorsException.class, se.getCause().getClass()); + assertThat(se.getMessage(), containsString("Method call is not allowed!")); + } + } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70506bf2/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPluginTest.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPluginTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPluginTest.java new file mode 100644 index 0000000..8d2178f --- /dev/null +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPluginTest.java @@ -0,0 +1,128 @@ +/* + * 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.tinkerpop.gremlin.groovy.jsr223.customizer.CompileStaticCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.ConfigurationCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.InterpreterModeCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.ThreadInterruptCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptCustomizerProvider; +import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TypeCheckedCustomizerProvider; +import org.apache.tinkerpop.gremlin.jsr223.Customizer; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyCompilerGremlinPlugin.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsInstanceOf.instanceOf; +import static org.junit.Assert.assertEquals; + +/** + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public class GroovyCompilerGremlinPluginTest { + + @Test + public void shouldConfigureForGroovyOnly() { + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + compilation(Compilation.COMPILE_STATIC).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-not-real"); + assertThat(customizers.isPresent(), is(false)); + } + + @Test + public void shouldConfigureWithCompileStatic() { + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + compilation(Compilation.COMPILE_STATIC).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-groovy"); + assertThat(customizers.isPresent(), is(true)); + assertEquals(1, customizers.get().length); + assertThat(((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(), instanceOf(CompileStaticCustomizerProvider.class)); + } + + @Test + public void shouldConfigureWithTypeChecked() { + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + compilation(Compilation.TYPE_CHECKED).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-groovy"); + assertThat(customizers.isPresent(), is(true)); + assertEquals(1, customizers.get().length); + assertThat(((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(), instanceOf(TypeCheckedCustomizerProvider.class)); + } + + @Test + public void shouldConfigureWithCustomCompilerConfigurations() { + final Map<String,Object> conf = new HashMap<>(); + conf.put("Debug", true); + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + compilerConfigurationOptions(conf).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-groovy"); + assertThat(customizers.isPresent(), is(true)); + assertEquals(1, customizers.get().length); + assertThat(((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(), instanceOf(ConfigurationCustomizerProvider.class)); + + final CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); + assertThat(compilerConfiguration.getDebug(), is(false)); + + final ConfigurationCustomizerProvider provider = (ConfigurationCustomizerProvider) ((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(); + provider.applyCustomization(compilerConfiguration); + + assertThat(compilerConfiguration.getDebug(), is(true)); + } + + @Test + public void shouldConfigureWithInterpreterMode() { + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + enableInterpreterMode(true).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-groovy"); + assertThat(customizers.isPresent(), is(true)); + assertEquals(1, customizers.get().length); + assertThat(((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(), instanceOf(InterpreterModeCustomizerProvider.class)); + } + + @Test + public void shouldConfigureWithThreadInterrupt() { + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + enableThreadInterrupt(true).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-groovy"); + assertThat(customizers.isPresent(), is(true)); + assertEquals(1, customizers.get().length); + assertThat(((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(), instanceOf(ThreadInterruptCustomizerProvider.class)); + } + + @Test + public void shouldConfigureWithTimedInterrupt() { + final GroovyCompilerGremlinPlugin plugin = GroovyCompilerGremlinPlugin.build(). + timedInterrupt(60000).create(); + final Optional<Customizer[]> customizers = plugin.getCustomizers("gremlin-groovy"); + assertThat(customizers.isPresent(), is(true)); + assertEquals(1, customizers.get().length); + assertThat(((CustomizerProviderCustomizer) customizers.get()[0]).getCustomizerProvider(), instanceOf(TimedInterruptCustomizerProvider.class)); + } + + @Test(expected = IllegalStateException.class) + public void shouldNotConfigureIfNoSettingsAreSupplied() { + GroovyCompilerGremlinPlugin.build().create(); + } +}