2 * Back 2 Browser Bytecode Translator
3 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. Look for COPYING file in the top folder.
16 * If not, see http://opensource.org/licenses/GPL-2.0.
18 package org.apidesign.bck2brwsr.launcher;
20 import org.apidesign.bck2brwsr.launcher.impl.Console;
21 import java.io.IOException;
22 import java.io.InputStream;
24 import java.util.Enumeration;
25 import java.util.LinkedHashSet;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29 import javax.script.Invocable;
30 import javax.script.ScriptEngine;
31 import javax.script.ScriptEngineManager;
32 import javax.script.ScriptException;
33 import org.apidesign.vm4brwsr.Bck2Brwsr;
36 * Tests execution in Java's internal scripting engine.
38 final class JSLauncher extends Launcher {
39 private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
40 private Set<ClassLoader> loaders = new LinkedHashSet<>();
41 private final Res resources = new Res();
42 private Invocable code;
43 private StringBuilder codeSeq;
44 private Object console;
47 addClassLoader(Bck2Brwsr.class.getClassLoader());
50 @Override InvocationContext runMethod(InvocationContext mi) {
51 loaders.add(mi.clazz.getClassLoader());
53 long time = System.currentTimeMillis();
54 LOG.log(Level.FINE, "Invoking {0}.{1}", new Object[]{mi.clazz.getName(), mi.methodName});
55 String res = code.invokeMethod(
57 "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
58 mi.clazz.getName(), mi.methodName).toString();
59 time = System.currentTimeMillis() - time;
60 LOG.log(Level.FINE, "Resut of {0}.{1} = {2} in {3} ms", new Object[]{mi.clazz.getName(), mi.methodName, res, time});
62 } catch (ScriptException | NoSuchMethodException ex) {
68 public void addClassLoader(ClassLoader url) {
69 this.loaders.add(url);
73 public void initialize() throws IOException {
76 } catch (Exception ex) {
77 if (ex instanceof IOException) {
78 throw (IOException)ex;
80 if (ex instanceof RuntimeException) {
81 throw (RuntimeException)ex;
83 throw new IOException(ex);
87 private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
88 StringBuilder sb = new StringBuilder();
89 Bck2Brwsr.generate(sb, new Res());
91 ScriptEngineManager sem = new ScriptEngineManager();
92 ScriptEngine mach = sem.getEngineByExtension("js");
95 "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.impl.Console.read);"
96 + "\nfunction initVM() { return vm; };"
99 Object res = mach.eval(sb.toString());
100 if (!(mach instanceof Invocable)) {
101 throw new IOException("It is invocable object: " + res);
103 code = (Invocable) mach;
106 Object vm = code.invokeFunction("initVM");
107 console = code.invokeMethod(vm, "loadClass", Console.class.getName());
111 public void shutdown() throws IOException {
115 public String toString() {
116 return codeSeq.toString();
119 private class Res implements Bck2Brwsr.Resources {
121 public InputStream get(String resource) throws IOException {
122 for (ClassLoader l : loaders) {
124 Enumeration<URL> en = l.getResources(resource);
125 while (en.hasMoreElements()) {
126 u = en.nextElement();
129 if (u.toExternalForm().contains("/rt.jar")) {
130 LOG.log(Level.WARNING, "No fallback to bootclasspath for {0}", u);
133 return u.openStream();
136 throw new IOException("Can't find " + resource);