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

com.tinkerpop.rexster.protocol.EngineHolder Maven / Gradle / Ivy

There is a newer version: 2.6.0
Show newest version
package com.tinkerpop.rexster.protocol;

import com.tinkerpop.gremlin.groovy.jsr223.DefaultImportCustomizerProvider;
import org.apache.log4j.Logger;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Holder class for different script engines.  It keeps track of the number of scripts that have been
 * evaluated against it and re-instantiates it to clear memory that it may hang on to.  This is an
 * issue that is prevalent in gremlin-groovy.  Unsure if it carries over to other implementations.
 *
 * @author Stephen Mallette (http://stephen.genoprime.com)
 * @author Blake Eggleston (bdeggleston.github.com)
 */
public class EngineHolder {
    private static final Logger logger = Logger.getLogger(EngineHolder.class);

    private final String languageName;
    private final String languageVersion;
    private final String engineName;
    private final String engineVersion;
    private final Set initScriptFiles;
    private final ScriptEngineFactory factory;
    private final int engineResetThreshold;

    private ScriptEngine engine;
    private AtomicInteger numberOfScriptsEvaluated = new AtomicInteger(1);

    public EngineHolder(final ScriptEngineFactory factory, final EngineConfiguration configuration) {
        this.languageName = factory.getLanguageName();
        this.languageVersion = factory.getLanguageVersion();
        this.engineName = factory.getEngineName();
        this.engineVersion = factory.getEngineVersion();
        this.engineResetThreshold = configuration.getResetCount();
        this.initScriptFiles = configuration.getInitScriptFiles();
        this.factory = factory;

        // gremlin-groovy allows imports to be customized.  need to figure out how to implement this generically
        // across scriptengines.
        if (this.languageName.equals("gremlin-groovy")) {
            logger.info("Initializing gremlin-groovy engine with additional imports.");
            DefaultImportCustomizerProvider.initializeStatically(configuration.getImports(), configuration.getStaticImports());
        }

        this.engine = initEngine(this.factory, this.initScriptFiles);
    }

    public String getEngineName() {
        return engineName;
    }

    public String getEngineVersion() {
        return engineVersion;
    }

    public String getLanguageName() {
        return languageName;
    }

    public ScriptEngine getEngine() {
        /*
        // commit in Gremlin in 2.3.0 removes the need for this reset. unsure if this should be removed completely
        // though as other scriptengine implementations might need it???
        if (engineResetThreshold > EngineController.RESET_NEVER) {
            // determine if a reset is necessary.
            if (numberOfScriptsEvaluated.get() >= engineResetThreshold) {
                // IMPORTANT: assumes that the factory implementation is not pooling engine instances
                this.engine = initEngine(this.factory, this.initScriptFiles);
                numberOfScriptsEvaluated.set(1);
            } else {
                numberOfScriptsEvaluated.incrementAndGet();
            }
        }
        */

        if (engine == null) {
            // IMPORTANT: assumes that the factory implementation is not pooling engine instances
            this.engine = initEngine(this.factory, this.initScriptFiles);
        }

        return this.engine;
    }

    private static ScriptEngine initEngine(final ScriptEngineFactory factory, final Set scriptFiles) {
        final ScriptEngine engine = factory.getScriptEngine();

        for (String scriptFile : scriptFiles) {
            if (scriptFile != null && !scriptFile.isEmpty()) {
                final File scriptEngineInitFile = new File(scriptFile);

                if (scriptEngineInitFile.exists()) {
                    try {
                        final Reader reader = new FileReader(scriptEngineInitFile);
                        logger.info("ScriptEngine initializing with a custom script");
                        engine.eval(reader);
                    } catch (FileNotFoundException fnfe) {
                        logger.warn(String.format("Could not read ScriptEngine initialization file.  Check location of [%s].", scriptEngineInitFile.getAbsolutePath()));
                    } catch (ScriptException ex) {
                        logger.warn(String.format("ScriptEngine initialization failure. Custom scripts and imports will not be initialized by [%s].", scriptEngineInitFile.getAbsolutePath()), ex);
                    }
                } else {
                    logger.warn(String.format("ScriptEngine initialization file does not exist.  Check location of [%s].", scriptEngineInitFile.getAbsolutePath()));
                }
            }
        }


        return engine;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy