1.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Thu Dec 20 11:03:34 2012 +0100
1.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Thu Dec 20 16:17:31 2012 +0100
1.3 @@ -33,8 +33,6 @@
1.4 import java.util.Set;
1.5 import java.util.concurrent.CountDownLatch;
1.6 import java.util.concurrent.TimeUnit;
1.7 -import java.util.logging.Level;
1.8 -import java.util.logging.Logger;
1.9 import javax.script.Invocable;
1.10 import javax.script.ScriptEngine;
1.11 import javax.script.ScriptEngineManager;
1.12 @@ -50,13 +48,17 @@
1.13 import org.glassfish.grizzly.http.server.ServerConfiguration;
1.14
1.15 /**
1.16 - * Lightweight server to launch Bck2Brwsr applications in real browser.
1.17 + * Lightweight server to launch Bck2Brwsr applications and tests.
1.18 + * Supports execution in native browser as well as Java's internal
1.19 + * execution engine.
1.20 */
1.21 public class Bck2BrwsrLauncher {
1.22 private Set<ClassLoader> loaders = new LinkedHashSet<>();
1.23 private List<MethodInvocation> methods = new ArrayList<>();
1.24 private long timeOut;
1.25 private String sen;
1.26 + private String showURL;
1.27 + private final Res resources = new Res();
1.28
1.29
1.30 public MethodInvocation addMethod(Class<?> clazz, String method) {
1.31 @@ -73,20 +75,24 @@
1.32 public void setScriptEngineName(String sen) {
1.33 this.sen = sen;
1.34 }
1.35 +
1.36 + public void setStartPage(String startpage) {
1.37 + if (!startpage.startsWith("/")) {
1.38 + startpage = "/" + startpage;
1.39 + }
1.40 + this.showURL = startpage;
1.41 + }
1.42 +
1.43 + public void addClassLoader(ClassLoader url) {
1.44 + this.loaders.add(url);
1.45 + }
1.46
1.47 public static void main( String[] args ) throws Exception {
1.48 Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
1.49 -
1.50 - final MethodInvocation[] cases = {
1.51 - l.addMethod(Console.class, "welcome"),
1.52 - l.addMethod(Console.class, "multiply"),
1.53 - };
1.54 -
1.55 + l.setStartPage("org/apidesign/bck2brwsr/launcher/console.xhtml");
1.56 + l.addClassLoader(Bck2BrwsrLauncher.class.getClassLoader());
1.57 l.execute();
1.58 -
1.59 - for (MethodInvocation c : cases) {
1.60 - System.err.println(c.className + "." + c.methodName + " = " + c.result);
1.61 - }
1.62 + System.in.read();
1.63 }
1.64
1.65
1.66 @@ -94,6 +100,10 @@
1.67 try {
1.68 if (sen != null) {
1.69 executeRhino();
1.70 + } else if (showURL != null) {
1.71 + HttpServer server = initServer();
1.72 + server.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
1.73 + launchServerAndBrwsr(server, showURL);
1.74 } else {
1.75 executeInBrowser();
1.76 }
1.77 @@ -142,21 +152,29 @@
1.78 }
1.79 }
1.80
1.81 - private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
1.82 - final CountDownLatch wait = new CountDownLatch(1);
1.83 - final MethodInvocation[] cases = this.methods.toArray(new MethodInvocation[0]);
1.84 -
1.85 + private HttpServer initServer() {
1.86 HttpServer server = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
1.87 -
1.88 - Res resources = new Res();
1.89 -
1.90 +
1.91 final ServerConfiguration conf = server.getServerConfiguration();
1.92 - conf.addHttpHandler(new Page("console.xhtml",
1.93 + conf.addHttpHandler(new Page(resources,
1.94 + "org/apidesign/bck2brwsr/launcher/console.xhtml",
1.95 "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
1.96 ), "/console");
1.97 conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
1.98 conf.addHttpHandler(new VMInit(), "/vm.js");
1.99 conf.addHttpHandler(new Classes(resources), "/classes/");
1.100 + return server;
1.101 + }
1.102 +
1.103 + private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
1.104 + final CountDownLatch wait = new CountDownLatch(1);
1.105 + final MethodInvocation[] cases = this.methods.toArray(new MethodInvocation[0]);
1.106 +
1.107 + HttpServer server = initServer();
1.108 + ServerConfiguration conf = server.getServerConfiguration();
1.109 + conf.addHttpHandler(new Page(resources,
1.110 + "org/apidesign/bck2brwsr/launcher/harness.xhtml"
1.111 + ), "/execute");
1.112 conf.addHttpHandler(new HttpHandler() {
1.113 int cnt;
1.114 @Override
1.115 @@ -183,21 +201,8 @@
1.116 cnt++;
1.117 }
1.118 }, "/data");
1.119 - conf.addHttpHandler(new Page("harness.xhtml"), "/");
1.120 -
1.121 - server.start();
1.122 - NetworkListener listener = server.getListeners().iterator().next();
1.123 - int port = listener.getPort();
1.124 -
1.125 - URI uri = new URI("http://localhost:" + port + "/execute");
1.126 - try {
1.127 - Desktop.getDesktop().browse(uri);
1.128 - } catch (UnsupportedOperationException ex) {
1.129 - String[] cmd = {
1.130 - "xdg-open", uri.toString()
1.131 - };
1.132 - Runtime.getRuntime().exec(cmd).waitFor();
1.133 - }
1.134 +
1.135 + launchServerAndBrwsr(server, "/execute");
1.136
1.137 wait.await(timeOut, TimeUnit.MILLISECONDS);
1.138 server.stop();
1.139 @@ -223,6 +228,23 @@
1.140 }
1.141 }
1.142
1.143 + private void launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
1.144 + server.start();
1.145 + NetworkListener listener = server.getListeners().iterator().next();
1.146 + int port = listener.getPort();
1.147 +
1.148 + URI uri = new URI("http://localhost:" + port + page);
1.149 + try {
1.150 + Desktop.getDesktop().browse(uri);
1.151 + } catch (UnsupportedOperationException ex) {
1.152 + String[] cmd = {
1.153 + "xdg-open", uri.toString()
1.154 + };
1.155 + Runtime.getRuntime().exec(cmd).waitFor();
1.156 + }
1.157 + System.err.println("Showing " + uri);
1.158 + }
1.159 +
1.160 private class Res implements Bck2Brwsr.Resources {
1.161 @Override
1.162 public InputStream get(String resource) throws IOException {
1.163 @@ -243,18 +265,34 @@
1.164 private static class Page extends HttpHandler {
1.165 private final String resource;
1.166 private final String[] args;
1.167 + private final Res res;
1.168
1.169 - public Page(String resource, String... args) {
1.170 + public Page(Res res, String resource, String... args) {
1.171 + this.res = res;
1.172 this.resource = resource;
1.173 this.args = args;
1.174 }
1.175
1.176 @Override
1.177 public void service(Request request, Response response) throws Exception {
1.178 - response.setContentType("text/html");
1.179 + String r = resource;
1.180 + if (r == null) {
1.181 + r = request.getHttpHandlerPath();
1.182 + if (r.startsWith("/")) {
1.183 + r = r.substring(1);
1.184 + }
1.185 + }
1.186 + if (r.endsWith(".html") || r.endsWith(".xhtml")) {
1.187 + response.setContentType("text/html");
1.188 + }
1.189 OutputStream os = response.getOutputStream();
1.190 - InputStream is = Bck2BrwsrLauncher.class.getResourceAsStream(resource);
1.191 - copyStream(is, os, request.getRequestURL().toString(), args);
1.192 + try (InputStream is = res.get(r)) {
1.193 + copyStream(is, os, request.getRequestURL().toString(), args);
1.194 + } catch (IOException ex) {
1.195 + response.setDetailMessage(ex.getLocalizedMessage());
1.196 + response.setError();
1.197 + response.setStatus(404);
1.198 + }
1.199 }
1.200 }
1.201
1.202 @@ -283,7 +321,7 @@
1.203 response.getWriter().append(
1.204 "function ldCls(res) {\n"
1.205 + " var request = new XMLHttpRequest();\n"
1.206 - + " request.open('GET', 'classes/' + res, false);\n"
1.207 + + " request.open('GET', '/classes/' + res, false);\n"
1.208 + " request.send();\n"
1.209 + " var arr = eval('(' + request.responseText + ')');\n"
1.210 + " return arr;\n"