
org.apidesign.bck2brwsr.launcher.JSLauncher Maven / Gradle / Ivy
/**
* Back 2 Browser Bytecode Translator
* Copyright (C) 2012-2015 Jaroslav Tulach
*
* 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, version 2 of the License.
*
* 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. Look for COPYING file in the top folder.
* If not, see http://opensource.org/licenses/GPL-2.0.
*/
package org.apidesign.bck2brwsr.launcher;
import org.apidesign.bck2brwsr.launcher.impl.Console;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apidesign.bck2brwsr.core.ExtraJavaScript;
import org.apidesign.vm4brwsr.Bck2Brwsr;
/**
* Tests execution in Java's internal scripting engine.
*/
@ExtraJavaScript(processByteCode = false, resource="")
final class JSLauncher extends Launcher {
private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
private Set loaders = new LinkedHashSet<>();
private final Res resources = new Res();
private Invocable code;
private StringBuilder codeSeq;
private Object console;
JSLauncher() {
addClassLoader(Bck2Brwsr.class.getClassLoader());
}
@Override InvocationContext runMethod(InvocationContext mi) {
loaders.add(mi.clazz.getClassLoader());
try {
long time = System.currentTimeMillis();
LOG.log(Level.FINE, "Invoking {0}.{1}", new Object[]{mi.clazz.getName(), mi.methodName});
String res = code.invokeMethod(
console,
"invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
mi.clazz.getName(), mi.methodName).toString();
time = System.currentTimeMillis() - time;
LOG.log(Level.FINE, "Resut of {0}.{1} = {2} in {3} ms", new Object[]{mi.clazz.getName(), mi.methodName, res, time});
mi.result(res, (int)time, null);
} catch (ScriptException | NoSuchMethodException ex) {
mi.result(null, -1, ex);
}
return mi;
}
public void addClassLoader(ClassLoader url) {
this.loaders.add(url);
}
@Override
public void initialize() throws IOException {
try {
initRhino();
} catch (Exception ex) {
if (ex instanceof IOException) {
throw (IOException)ex;
}
if (ex instanceof RuntimeException) {
throw (RuntimeException)ex;
}
throw new IOException(ex);
}
}
private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
StringBuilder sb = new StringBuilder();
Bck2Brwsr.generate(sb, new Res());
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine mach = sem.getEngineByExtension("js");
sb.append(
"\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.impl.Console.read);"
+ "\nfunction initVM() { return vm; };"
+ "\n");
Object res = mach.eval(sb.toString());
if (!(mach instanceof Invocable)) {
throw new IOException("It is invocable object: " + res);
}
code = (Invocable) mach;
codeSeq = sb;
Object vm = code.invokeFunction("initVM");
console = code.invokeMethod(vm, "loadClass", Console.class.getName());
}
@Override
public void shutdown() throws IOException {
}
@Override
public String toString() {
return codeSeq.toString();
}
private class Res implements Bck2Brwsr.Resources {
@Override
public InputStream get(String resource) throws IOException {
for (ClassLoader l : loaders) {
URL u = null;
Enumeration en = l.getResources(resource);
while (en.hasMoreElements()) {
u = en.nextElement();
}
if (u != null) {
if (u.toExternalForm().contains("/rt.jar")) {
LOG.log(Level.WARNING, "No fallback to bootclasspath for {0}", u);
return null;
}
return u.openStream();
}
}
throw new IOException("Can't find " + resource);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy