1.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Mon Dec 17 17:51:05 2012 +0100
1.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Tue Dec 18 12:43:18 2012 +0100
1.3 @@ -23,8 +23,13 @@
1.4 import java.io.OutputStream;
1.5 import java.io.Writer;
1.6 import java.net.URI;
1.7 +import java.net.URISyntaxException;
1.8 import java.net.URL;
1.9 +import java.util.ArrayList;
1.10 import java.util.Enumeration;
1.11 +import java.util.LinkedHashSet;
1.12 +import java.util.List;
1.13 +import java.util.Set;
1.14 import java.util.concurrent.CountDownLatch;
1.15 import static org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher.copyStream;
1.16 import org.apidesign.vm4brwsr.Bck2Brwsr;
1.17 @@ -40,39 +45,50 @@
1.18 * Lightweight server to launch Bck2Brwsr applications in real browser.
1.19 */
1.20 public class Bck2BrwsrLauncher {
1.21 + private Set<ClassLoader> loaders = new LinkedHashSet<>();
1.22 + private List<MethodInvocation> methods = new ArrayList<>();
1.23 +
1.24 +
1.25 + public MethodInvocation addMethod(Class<?> clazz, String method) {
1.26 + loaders.add(clazz.getClassLoader());
1.27 + MethodInvocation c = new MethodInvocation(clazz.getName(), method);
1.28 + methods.add(c);
1.29 + return c;
1.30 + }
1.31 +
1.32 +
1.33 +
1.34 public static void main( String[] args ) throws Exception {
1.35 - final Case[] cases = {
1.36 - new Case("org.apidesign.bck2brwsr.launcher.Console", "welcome"),
1.37 - new Case("org.apidesign.bck2brwsr.launcher.Console", "multiply")
1.38 + Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
1.39 +
1.40 + final MethodInvocation[] cases = {
1.41 + l.addMethod(Console.class, "welcome"),
1.42 + l.addMethod(Console.class, "multiply"),
1.43 };
1.44 +
1.45 + l.execute();
1.46 +
1.47 + for (MethodInvocation c : cases) {
1.48 + System.err.println(c.className + "." + c.methodName + " = " + c.result);
1.49 + }
1.50 + }
1.51 +
1.52 +
1.53 + public void execute() throws URISyntaxException, IOException, InterruptedException {
1.54 final CountDownLatch wait = new CountDownLatch(1);
1.55 + final MethodInvocation[] cases = this.methods.toArray(new MethodInvocation[0]);
1.56
1.57 HttpServer server = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
1.58 - final ClassLoader loader = Bck2BrwsrLauncher.class.getClassLoader();
1.59 +
1.60 + Res resources = new Res();
1.61
1.62 final ServerConfiguration conf = server.getServerConfiguration();
1.63 conf.addHttpHandler(new Page("console.xhtml",
1.64 "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
1.65 ), "/console");
1.66 - conf.addHttpHandler(new VM(loader), "/bck2brwsr.js");
1.67 + conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
1.68 conf.addHttpHandler(new VMInit(), "/vm.js");
1.69 - conf.addHttpHandler(new Classes(loader), "/classes/");
1.70 - conf.addHttpHandler(new HttpHandler() {
1.71 - @Override
1.72 - public void service(Request request, Response response) throws Exception {
1.73 - String clazz = request.getParameter("class");
1.74 - String method = request.getParameter("method");
1.75 - if (clazz == null || method == null) {
1.76 - response.setError();
1.77 - response.setDetailMessage("Need two parameters: class and method name!");
1.78 - return;
1.79 - }
1.80 - response.setContentType("text/html");
1.81 - OutputStream os = response.getOutputStream();
1.82 - InputStream is = Bck2BrwsrLauncher.class.getResourceAsStream("console.xhtml");
1.83 - copyStream(is, os, clazz, method, "true");
1.84 - }
1.85 - }, "/");
1.86 + conf.addHttpHandler(new Classes(resources), "/classes/");
1.87 conf.addHttpHandler(new HttpHandler() {
1.88 int cnt;
1.89 @Override
1.90 @@ -99,7 +115,7 @@
1.91 cnt++;
1.92 }
1.93 }, "/data");
1.94 - conf.addHttpHandler(new Page("harness.xhtml"), "/execute");
1.95 + conf.addHttpHandler(new Page("harness.xhtml"), "/");
1.96
1.97 server.start();
1.98 NetworkListener listener = server.getListeners().iterator().next();
1.99 @@ -116,10 +132,6 @@
1.100 }
1.101
1.102 wait.await();
1.103 -
1.104 - for (Case c : cases) {
1.105 - System.err.println(c.className + "." + c.methodName + " = " + c.result);
1.106 - }
1.107 }
1.108
1.109 static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
1.110 @@ -141,6 +153,23 @@
1.111 }
1.112 }
1.113 }
1.114 +
1.115 + private class Res implements Bck2Brwsr.Resources {
1.116 + @Override
1.117 + public InputStream get(String resource) throws IOException {
1.118 + for (ClassLoader l : loaders) {
1.119 + URL u = null;
1.120 + Enumeration<URL> en = l.getResources(resource);
1.121 + while (en.hasMoreElements()) {
1.122 + u = en.nextElement();
1.123 + }
1.124 + if (u != null) {
1.125 + return u.openStream();
1.126 + }
1.127 + }
1.128 + throw new IOException("Can't find " + resource);
1.129 + }
1.130 + }
1.131
1.132 private static class Page extends HttpHandler {
1.133 private final String resource;
1.134 @@ -161,9 +190,9 @@
1.135 }
1.136
1.137 private static class VM extends HttpHandler {
1.138 - private final ClassLoader loader;
1.139 + private final Res loader;
1.140
1.141 - public VM(ClassLoader loader) {
1.142 + public VM(Res loader) {
1.143 this.loader = loader;
1.144 }
1.145
1.146 @@ -195,9 +224,9 @@
1.147 }
1.148
1.149 private static class Classes extends HttpHandler {
1.150 - private final ClassLoader loader;
1.151 + private final Res loader;
1.152
1.153 - public Classes(ClassLoader loader) {
1.154 + public Classes(Res loader) {
1.155 this.loader = loader;
1.156 }
1.157
1.158 @@ -207,47 +236,47 @@
1.159 if (res.startsWith("/")) {
1.160 res = res.substring(1);
1.161 }
1.162 - Enumeration<URL> en = loader.getResources(res);
1.163 - URL u = null;
1.164 - while (en.hasMoreElements()) {
1.165 - u = en.nextElement();
1.166 + try (InputStream is = loader.get(res)) {
1.167 + response.setContentType("text/javascript");
1.168 + Writer w = response.getWriter();
1.169 + w.append("[");
1.170 + for (int i = 0;; i++) {
1.171 + int b = is.read();
1.172 + if (b == -1) {
1.173 + break;
1.174 + }
1.175 + if (i > 0) {
1.176 + w.append(", ");
1.177 + }
1.178 + if (i % 20 == 0) {
1.179 + w.write("\n");
1.180 + }
1.181 + if (b > 127) {
1.182 + b = b - 256;
1.183 + }
1.184 + w.append(Integer.toString(b));
1.185 + }
1.186 + w.append("\n]");
1.187 + } catch (IOException ex) {
1.188 + response.setError();
1.189 + response.setDetailMessage(ex.getMessage());
1.190 }
1.191 - if (u == null) {
1.192 - response.setError();
1.193 - response.setDetailMessage("Can't find resource " + res);
1.194 - }
1.195 - response.setContentType("text/javascript");
1.196 - InputStream is = u.openStream();
1.197 - Writer w = response.getWriter();
1.198 - w.append("[");
1.199 - for (int i = 0;; i++) {
1.200 - int b = is.read();
1.201 - if (b == -1) {
1.202 - break;
1.203 - }
1.204 - if (i > 0) {
1.205 - w.append(", ");
1.206 - }
1.207 - if (i % 20 == 0) {
1.208 - w.write("\n");
1.209 - }
1.210 - if (b > 127) {
1.211 - b = b - 256;
1.212 - }
1.213 - w.append(Integer.toString(b));
1.214 - }
1.215 - w.append("\n]");
1.216 }
1.217 }
1.218
1.219 - private static final class Case {
1.220 + public static final class MethodInvocation {
1.221 final String className;
1.222 final String methodName;
1.223 String result;
1.224
1.225 - public Case(String className, String methodName) {
1.226 + MethodInvocation(String className, String methodName) {
1.227 this.className = className;
1.228 this.methodName = methodName;
1.229 }
1.230 +
1.231 + @Override
1.232 + public String toString() {
1.233 + return result;
1.234 + }
1.235 }
1.236 }