All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyCompilerGremlinPlugin Maven / Gradle / Ivy

/*
 * 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.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 int expectedCompilationTime = 5000;
        private String cacheSpec = "softValues";

        private Map keyValues = Collections.emptyMap();

        /**
         * If the time it takes to compile a script exceeds the specified time then a warning is written to the logs.
         * Defaults to 5000ms and must be greater than zero.
         */
        public Builder expectedCompilationTime(final int timeInMillis) {
            if (expectedCompilationTime <= 0) throw new IllegalArgumentException("expectedCompilationTime must be greater than zero");
            this.expectedCompilationTime = timeInMillis;
            return this;
        }

        public Builder enableInterpreterMode(final boolean interpreterMode) {
            this.interpreterMode = interpreterMode;
            return this;
        }

        public Builder compilerConfigurationOptions(final Map keyValues) {
            this.keyValues = keyValues;
            return this;
        }

        public Builder enableThreadInterrupt(final boolean threadInterrupt) {
            this.threadInterrupt = threadInterrupt;
            return this;
        }

        /**
         * Introduces timed checks to loops and other portions of a script to provide an interrupt for a long running
         * script. This configuration should not be used in conjunction with the Gremlin Server which has its own
         * {@code scriptEvaluationTimeout} which performs a similar task but in a more complete way specific to the
         * server. Configuring both may lead to inconsistent timeout errors returning from the server. This
         * configuration should only be used if configuring a standalone instance fo the {@link GremlinGroovyScriptEngine}.
         */
        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;
        }

        /**
         * Sets the cache specification for the class map which holds compiled scripts and uses the comma separated
         * syntax of the caffeine cache for configuration.
         * 
    *
  • {@code initialCapacity=[integer]}: sets {@code Caffeine.initialCapacity}. *
  • {@code maximumSize=[long]}: sets {@code Caffeine.maximumSize}. *
  • {@code maximumWeight=[long]}: sets {@code Caffeine.maximumWeight}. *
  • {@code expireAfterAccess=[duration]}: sets {@code Caffeine.expireAfterAccess}. *
  • {@code expireAfterWrite=[duration]}: sets {@code Caffeine.expireAfterWrite}. *
  • {@code refreshAfterWrite=[duration]}: sets {@code Caffeine.refreshAfterWrite}. *
  • {@code weakKeys}: sets {@code Caffeine.weakKeys}. *
  • {@code weakValues}: sets {@code Caffeine.weakValues}. *
  • {@code softValues}: sets {@code Caffeine.softValues}. *
  • {@code recordStats}: sets {@code Caffeine.recordStats}. *
* Durations are represented by an integer, followed by one of "d", "h", "m", or "s", representing * days, hours, minutes, or seconds respectively. Whitespace before and after commas and equal signs is * ignored. Keys may not be repeated; it is also illegal to use the following pairs of keys in a single value: *
    *
  • {@code maximumSize} and {@code maximumWeight} *
  • {@code weakValues} and {@code softValues} *
*/ public Builder classMapCacheSpecification(final String cacheSpec) { this.cacheSpec = cacheSpec; return this; } Customizer[] asCustomizers() { final List list = new ArrayList<>(); if (interpreterMode) list.add(new InterpreterModeGroovyCustomizer()); if (!keyValues.isEmpty()) list.add(new ConfigurationGroovyCustomizer(keyValues)); if (threadInterrupt) list.add(new ThreadInterruptGroovyCustomizer()); if (timeInMillis > 0) list.add(new TimedInterruptGroovyCustomizer(timeInMillis)); list.add(CompilationOptionsCustomizer.build(). setExpectedCompilationTime(expectedCompilationTime > 0 ? expectedCompilationTime : 5000). setClassMapCacheSpecification(cacheSpec).create()); if (compilation == Compilation.COMPILE_STATIC) list.add(new CompileStaticGroovyCustomizer(extensions)); else if (compilation == Compilation.TYPE_CHECKED) list.add(new TypeCheckedGroovyCustomizer(extensions)); else if (compilation != Compilation.NONE) throw new IllegalStateException("Use of unknown compilation type: " + compilation); final Customizer[] customizers = new Customizer[list.size()]; list.toArray(customizers); return customizers; } public GroovyCompilerGremlinPlugin create() { return new GroovyCompilerGremlinPlugin(this); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy