TINKERPOP-1562 Add GreminServerGremlinModule for Gremlin Server specific imports
Allow use of instance() as a way for GremlinModules to be instantiated. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/9f65e6aa Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/9f65e6aa Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/9f65e6aa Branch: refs/heads/master Commit: 9f65e6aa3d32eab2ef76bb7e3ae1f60b8332268f Parents: 42194b8 Author: Stephen Mallette <sp...@genoprime.com> Authored: Mon Nov 21 07:36:40 2016 -0500 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Fri Dec 2 06:28:50 2016 -0500 ---------------------------------------------------------------------- .../gremlin/jsr223/AbstractGremlinModule.java | 10 ++++ .../gremlin/jsr223/CoreGremlinModule.java | 18 ------- .../gremlin/groovy/engine/GremlinExecutor.java | 49 +++++++++++--------- .../server/util/GremlinServerGremlinModule.java | 41 ++++++++++++++++ .../server/util/ServerGremlinExecutor.java | 13 +----- 5 files changed, 81 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9f65e6aa/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/AbstractGremlinModule.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/AbstractGremlinModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/AbstractGremlinModule.java index 36104f6..4b9cd2c 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/AbstractGremlinModule.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/AbstractGremlinModule.java @@ -18,6 +18,7 @@ */ package org.apache.tinkerpop.gremlin.jsr223; +import java.util.Collections; import java.util.Optional; import java.util.Set; @@ -29,6 +30,15 @@ public abstract class AbstractGremlinModule implements GremlinModule { protected final Customizer[] customizers; protected final Set<String> appliesTo; + /** + * Creates a base {@link GremlinModule} that will apply to all {@link GremlinScriptEngine} instances. + */ + public AbstractGremlinModule(final String moduleName, final Customizer... customizers) { + this(moduleName, Collections.emptySet(), customizers); + } + /** + * Creates a base {@link GremlinModule} that will apply to specific {@link GremlinScriptEngine} instances. + */ public AbstractGremlinModule(final String moduleName, final Set<String> appliesTo, final Customizer... customizers) { this.moduleName = moduleName; this.appliesTo = appliesTo; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9f65e6aa/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreGremlinModule.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreGremlinModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreGremlinModule.java index f1fdbe4..ff47767 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreGremlinModule.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreGremlinModule.java @@ -37,7 +37,6 @@ public final class CoreGremlinModule implements GremlinModule { .addMethodImports(CoreImports.getMethodImports()).create(); private static final Customizer[] customizers = new Customizer[] {gremlinCore}; - private static final Builder builder = new Builder(); /** * @deprecated As of 3.2.4, replaced by {@link #instance()} as this field will later become private. @@ -60,21 +59,4 @@ public final class CoreGremlinModule implements GremlinModule { public String getName() { return MODULE_NAME; } - - /** - * {@link GremlinModule} instances all use a builder pattern for instantiation via configuration. This method is - * just provided for consistency with that pattern. When instantiating programmatically, use {@link #instance()}. - */ - public static Builder build() { - return builder; - } - - public final static class Builder { - - private Builder() {} - - public CoreGremlinModule create() { - return instance(); - } - } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9f65e6aa/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java ---------------------------------------------------------------------- diff --git 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 index 5f7ab09..1ad41c7 100644 --- 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 @@ -435,30 +435,37 @@ public class GremlinExecutor implements AutoCloseable { for (Map.Entry<String, Map<String,Object>> moduleConfig : moduleConfigs.entrySet()) { try { final Class<?> clazz = Class.forName(moduleConfig.getKey()); - final Method builderMethod = clazz.getMethod("build"); - Object moduleBuilder = builderMethod.invoke(null); - - final Class<?> builderClazz = moduleBuilder.getClass(); - final Map<String,Object> customizerConfigs = moduleConfig.getValue(); - final Method[] methods = builderClazz.getMethods(); - for (Map.Entry<String,Object> customizerConfig : customizerConfigs.entrySet()) { - final Method configMethod = Stream.of(methods).filter(m -> m.getName().equals(customizerConfig.getKey())).findFirst() - .orElseThrow(() -> new IllegalStateException("Could not find builder method on " + builderClazz.getCanonicalName())); - if (null == customizerConfig.getValue()) - moduleBuilder = configMethod.invoke(moduleBuilder); - else - moduleBuilder = configMethod.invoke(moduleBuilder, customizerConfig.getValue()); - } + // first try instance() and if that fails try to use build() try { - final Method appliesTo = builderClazz.getMethod("appliesTo"); - moduleBuilder = appliesTo.invoke(moduleBuilder, language); - } catch (NoSuchMethodException ignored) { - + final Method instanceMethod = clazz.getMethod("instance"); + gremlinScriptEngineManager.addModule((GremlinModule) instanceMethod.invoke(null)); + } catch (Exception ex) { + final Method builderMethod = clazz.getMethod("build"); + Object moduleBuilder = builderMethod.invoke(null); + + final Class<?> builderClazz = moduleBuilder.getClass(); + final Map<String, Object> customizerConfigs = moduleConfig.getValue(); + final Method[] methods = builderClazz.getMethods(); + for (Map.Entry<String, Object> customizerConfig : customizerConfigs.entrySet()) { + final Method configMethod = Stream.of(methods).filter(m -> m.getName().equals(customizerConfig.getKey())).findFirst() + .orElseThrow(() -> new IllegalStateException("Could not find builder method on " + builderClazz.getCanonicalName())); + if (null == customizerConfig.getValue()) + moduleBuilder = configMethod.invoke(moduleBuilder); + else + moduleBuilder = configMethod.invoke(moduleBuilder, customizerConfig.getValue()); + } + + try { + final Method appliesTo = builderClazz.getMethod("appliesTo"); + moduleBuilder = appliesTo.invoke(moduleBuilder, language); + } catch (NoSuchMethodException ignored) { + + } + + final Method create = builderClazz.getMethod("create"); + gremlinScriptEngineManager.addModule((GremlinModule) create.invoke(moduleBuilder)); } - - final Method create = builderClazz.getMethod("create"); - gremlinScriptEngineManager.addModule((GremlinModule) create.invoke(moduleBuilder)); } catch (Exception ex) { throw new IllegalStateException(ex); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9f65e6aa/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerGremlinModule.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerGremlinModule.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerGremlinModule.java new file mode 100644 index 0000000..863c640 --- /dev/null +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinServerGremlinModule.java @@ -0,0 +1,41 @@ +/* + * 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.server.util; + +import org.apache.tinkerpop.gremlin.jsr223.AbstractGremlinModule; +import org.apache.tinkerpop.gremlin.jsr223.GremlinModule; +import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer; + +/** + * A {@link GremlinModule} implementation that adds Gremlin Server specific classes to the imports. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public final class GremlinServerGremlinModule extends AbstractGremlinModule { + private static final String MODULE_NAME = "tinkerpop.server"; + private static final GremlinServerGremlinModule instance = new GremlinServerGremlinModule(); + + public GremlinServerGremlinModule() { + super(MODULE_NAME, ImportCustomizer.build().addClassImports(LifeCycleHook.class, LifeCycleHook.Context.class).create()); + } + + public static GremlinServerGremlinModule instance() { + return instance; + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9f65e6aa/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java index eda1d8d..bb6c9ce 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java @@ -138,17 +138,8 @@ public class ServerGremlinExecutor<T extends ScheduledExecutorService> { v.imports.add(LifeCycleHook.Context.class.getCanonicalName()); gremlinExecutorBuilder.addEngineSettings(k, v.imports, v.staticImports, v.scripts, v.config); } else { - // make sure that server related classes are available at init - ultimately this is the right way to - // do things going forward. - // TODO: though this Import is kinda sketchy. - if (v.modules.containsKey(ImportGremlinModule.class.getName())) { - final List<String> listToAddImportsTo = (List<String>) v.modules.get(ImportGremlinModule.class.getName()).get("classImports"); - listToAddImportsTo.addAll(Arrays.asList(LifeCycleHook.class.getName(), LifeCycleHook.Context.class.getName())); - } else { - final Map<String,Object> imports = new HashMap<>(); - imports.put("classImports", Arrays.asList(LifeCycleHook.class.getName(), LifeCycleHook.Context.class.getName())); - v.modules.put(ImportGremlinModule.class.getName(), imports); - } + // make sure that server related classes are available at init - new approach. the LifeCycleHook stuff + // will be added explicitly via configuration using GremlinServerGremlinModule in the yaml gremlinExecutorBuilder.addModules(k, v.modules); } });