Package org.geoserver.script.js.engine

Source Code of org.geoserver.script.js.engine.CommonJSEngineFactory

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.script.js.engine;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.commonjs.module.Require;
import org.mozilla.javascript.commonjs.module.RequireBuilder;
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider;
import org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider;
import org.mozilla.javascript.tools.shell.Global;

public class CommonJSEngineFactory implements ScriptEngineFactory {

    private static List<String> names;
    private static List<String> mimeTypes;
    private static List<String> extensions;

    static {
        names = new ArrayList<String>(7);
        names.add("rhino-nonjdk");
        names.add("js");
        names.add("rhino");
        names.add("JavaScript");
        names.add("javascript");
        names.add("ECMAScript");
        names.add("ecmascript");
        names = Collections.unmodifiableList(names);
   
        mimeTypes = new ArrayList<String>(4);
        mimeTypes.add("application/javascript");
        mimeTypes.add("application/ecmascript");
        mimeTypes.add("text/javascript");
        mimeTypes.add("text/ecmascript");
        mimeTypes = Collections.unmodifiableList(mimeTypes);
   
        extensions = new ArrayList<String>(1);
        extensions.add("js");
        extensions = Collections.unmodifiableList(extensions);
    }
   
    private Global global;
    private RequireBuilder requireBuilder;
    private List<String> modulePaths;
   
    public CommonJSEngineFactory(List<String> modulePaths) {
        this.modulePaths = modulePaths;
        Context cx = CommonJSEngine.enterContext();
        try {
            global = new Global();
            global.initStandardObjects(cx, true);
            global.installRequire(cx, modulePaths, true);
        } finally {
            Context.exit();
        }
    }

    /**
     * Create a new require function using the shared global.
     * @return
     */
    @SuppressWarnings("unused")
    private Require createRequire() {
        Require require = null;
        RequireBuilder builder = getRequireBuilder();
        Context cx = CommonJSEngine.enterContext();
        try {
            require = builder.createRequire(cx, global);
        } finally {
            Context.exit();
        }
        return require;
    }

    @Override
    public String getEngineName() {
        return (String) getParameter(ScriptEngine.ENGINE);
    }
   
    @Override
    public String getEngineVersion() {
        return (String)getParameter(ScriptEngine.ENGINE_VERSION);
    }
   
    @Override
    public List<String> getExtensions() {
        return extensions;
    }
   
    @Override
    public String getLanguageName() {
        return (String) getParameter(ScriptEngine.LANGUAGE);
    }
   
    @Override
    public String getLanguageVersion() {
        return (String) getParameter(ScriptEngine.LANGUAGE_VERSION);
    }
   
    @Override
    public String getMethodCallSyntax(String object, String method, String... args) {
        String syntax = object + "." + method + "(";
        int length = args.length;
        for (int i=0; i<length; ++i) {
            syntax += args[i];
            if (i != length - 1) {
                syntax += ",";
            }
        }
        return syntax + ")";
    }
   
    @Override
    public List<String> getMimeTypes() {
        return mimeTypes;
    }
   
    @Override
    public List<String> getNames() {
        return names;
    }
   
    @Override
    public String getOutputStatement(String arg) {
        return "print(" + arg + ")";
    }
   
    @Override
    public Object getParameter(String key) {
        if (key.equals(ScriptEngine.NAME)) {
            return "javascript";
        } else if (key.equals(ScriptEngine.ENGINE)) {
            return "Mozilla Rhino";
        } else if (key.equals(ScriptEngine.ENGINE_VERSION)) {
            return "1.7R4";
        } else if (key.equals(ScriptEngine.LANGUAGE)) {
            return "ECMAScript";
        } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) {
            return "1.8";
        } else if (key.equals("THREADING")) {
            return "MULTITHREADED";
        } else {
            throw new IllegalArgumentException("Invalid key");
        }
    }
   
    @Override
    public String getProgram(String... statements) {
        int length = statements.length;
        String program = "";
        for (int i=0; i<length; ++i) {
            program += statements[i] + ";";
        }
        return program;
    }

    /**
     * Creates and returns a shared require builder.  This allows loaded
     * modules to be cached.  The require builder is constructed with a module
     * provider that reloads modules only when they have changed on disk (with
     * a 60 second interval).  This require builder will be configured with
     * the module paths returned by {@link getModulePahts()}.
     *
     * @return a shared require builder
     */
    private RequireBuilder getRequireBuilder() {
        if (requireBuilder == null) {
            synchronized (this) {
                if (requireBuilder == null) {
                    requireBuilder = new RequireBuilder();
                    requireBuilder.setSandboxed(false);
                    List<URI> uris = new ArrayList<URI>();
                    if (modulePaths != null) {
                        for (String path : modulePaths) {
                            try {
                                URI uri = new URI(path);
                                if (!uri.isAbsolute()) {
                                    // call resolve("") to canonify the path
                                    uri = new File(path).toURI().resolve("");
                                }
                                if (!uri.toString().endsWith("/")) {
                                    // make sure URI always terminates with slash to
                                    // avoid loading from unintended locations
                                    uri = new URI(uri + "/");
                                }
                                uris.add(uri);
                            } catch (URISyntaxException usx) {
                                throw new RuntimeException(usx);
                            }
                        }
                    }
                    requireBuilder.setModuleScriptProvider(
                            new SoftCachingModuleScriptProvider(
                                    new UrlModuleSourceProvider(uris, null)));
                }
            }
        }
        return requireBuilder;
    }

    @Override
    public ScriptEngine getScriptEngine() {
        return new CommonJSEngine(this);
    }

    public Global getGlobal() {
        return global;
    }

}
TOP

Related Classes of org.geoserver.script.js.engine.CommonJSEngineFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.