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

com.thorstenmarx.webtools.scripting.GraalScripting Maven / Gradle / Ivy

There is a newer version: 5.2.4
Show newest version
package com.thorstenmarx.webtools.scripting;

/*-
 * #%L
 * webtools-scripting
 * %%
 * Copyright (C) 2016 - 2018 Thorsten Marx
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */
import com.oracle.truffle.js.runtime.JSRealm;
import com.thorstenmarx.webtools.scripting.graal.require.RequireFunction;
import delight.graaljssandbox.GraalSandbox;
import delight.graaljssandbox.GraalSandboxes;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Set;
import java.util.function.Consumer;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;

/**
 *
 * @author marx
 */
public class GraalScripting implements Scripting {

	private ScriptEngine scriptEngine;

	private final String modulePackage;
	
	public GraalSandbox sandbox = null;

	public GraalScripting(final String modulePackage) {
		this(modulePackage, Collections.EMPTY_SET);
	}
	
	public GraalScripting(final String modulePackage, final Set allowedClasses) {
		this.scriptEngine = new ScriptEngineManager().getEngineByName("graal.js");
		this.modulePackage = modulePackage;
		
		sandbox = GraalSandboxes.create();
		sandbox.allowPrintFunctions(true);
		sandbox.allow(System.class);
		sandbox.allow(JSRealm.class);
		allowedClasses.forEach(sandbox::allow);
	}

	private void initContext(final ScriptContext context) throws ScriptException {

		context.getBindings(ScriptContext.ENGINE_SCOPE).put("require", new RequireFunction() {
			@Override
			public Object require(String module) throws ScriptException {
				try {
					System.out.println("loading module: " + (modulePackage + module));
					URL moduleUrl = Scripting.class.getClassLoader().getResource(modulePackage + module);

					final String script = new String(Files.readAllBytes(Paths.get(moduleUrl.toURI())));

					sandbox.eval("var exports = {}", context);
					final Object exports = context.getBindings(ScriptContext.ENGINE_SCOPE).get("exports");
					sandbox.eval(script, context);

					return exports;
				} catch (URISyntaxException | FileNotFoundException ex) {
					throw new ScriptException(ex);
				} catch (IOException ex) {
					throw new ScriptException(ex);
				}
			}
		});
	}

	@Override
	public void eval(final String script) {
		eval(script, c -> {
		});
	}

	@Override
	public void eval(final String script, final Consumer contextInitializer) {
		try {

			ScriptContext context = new SimpleScriptContext();
//			final Bindings engineBindings = scriptEngine.createBindings();
			final Bindings engineBindings = sandbox.createNewBindings();
			engineBindings.put("polyglot.js.allowAllAccess", true);
			context.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
//			final Bindings globalBindings = scriptEngine.createBindings();
			final Bindings globalBindings = sandbox.createNewBindings();
			globalBindings.put("polyglot.js.allowAllAccess", true);
			context.setBindings(globalBindings, ScriptContext.GLOBAL_SCOPE);
			

			contextInitializer.accept(context);

			initContext(context);

//			scriptEngine.eval(script, context);
			sandbox.eval(script, context);
		} catch (ScriptException ex) {
			ex.printStackTrace();
			throw new RuntimeException(ex);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy