Using URL.getContent to communicate with the launcher and execute two testing methods
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 java.awt.Desktop;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.io.Writer;
27 import java.util.Enumeration;
28 import java.util.concurrent.CountDownLatch;
29 import static org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher.copyStream;
30 import org.apidesign.vm4brwsr.Bck2Brwsr;
31 import org.glassfish.grizzly.PortRange;
32 import org.glassfish.grizzly.http.server.HttpHandler;
33 import org.glassfish.grizzly.http.server.HttpServer;
34 import org.glassfish.grizzly.http.server.NetworkListener;
35 import org.glassfish.grizzly.http.server.Request;
36 import org.glassfish.grizzly.http.server.Response;
37 import org.glassfish.grizzly.http.server.ServerConfiguration;
40 * Lightweight server to launch Bck2Brwsr applications in real browser.
42 public class Bck2BrwsrLauncher {
43 public static void main( String[] args ) throws Exception {
44 final Case[] cases = {
45 new Case("org.apidesign.bck2brwsr.launcher.Console", "welcome"),
46 new Case("org.apidesign.bck2brwsr.launcher.Console", "multiply")
48 final CountDownLatch wait = new CountDownLatch(1);
50 HttpServer server = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
51 final ClassLoader loader = Bck2BrwsrLauncher.class.getClassLoader();
53 final ServerConfiguration conf = server.getServerConfiguration();
54 conf.addHttpHandler(new Page("console.xhtml",
55 "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
57 conf.addHttpHandler(new VM(loader), "/bck2brwsr.js");
58 conf.addHttpHandler(new VMInit(), "/vm.js");
59 conf.addHttpHandler(new Classes(loader), "/classes/");
60 conf.addHttpHandler(new HttpHandler() {
62 public void service(Request request, Response response) throws Exception {
63 String clazz = request.getParameter("class");
64 String method = request.getParameter("method");
65 if (clazz == null || method == null) {
67 response.setDetailMessage("Need two parameters: class and method name!");
70 response.setContentType("text/html");
71 OutputStream os = response.getOutputStream();
72 InputStream is = Bck2BrwsrLauncher.class.getResourceAsStream("console.xhtml");
73 copyStream(is, os, clazz, method, "true");
76 conf.addHttpHandler(new HttpHandler() {
79 public void service(Request request, Response response) throws Exception {
80 String id = request.getParameter("request");
81 String value = request.getParameter("result");
82 if (id != null && value != null) {
83 value = value.replace("%20", " ");
84 cases[Integer.parseInt(id)].result = value;
87 if (cnt >= cases.length) {
88 response.getWriter().write("");
94 response.getWriter().write("{"
95 + "className: '" + cases[cnt].className + "', "
96 + "methodName: '" + cases[cnt].methodName + "', "
102 conf.addHttpHandler(new Page("harness.xhtml"), "/execute");
105 NetworkListener listener = server.getListeners().iterator().next();
106 int port = listener.getPort();
108 URI uri = new URI("http://localhost:" + port + "/execute");
110 Desktop.getDesktop().browse(uri);
111 } catch (UnsupportedOperationException ex) {
113 "xdg-open", uri.toString()
115 Runtime.getRuntime().exec(cmd).waitFor();
120 for (Case c : cases) {
121 System.err.println(c.className + "." + c.methodName + " = " + c.result);
125 static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
132 int cnt = is.read() - '0';
133 if (cnt == 'U' - '0') {
134 os.write(baseURL.getBytes());
136 if (cnt < params.length) {
137 os.write(params[cnt].getBytes());
145 private static class Page extends HttpHandler {
146 private final String resource;
147 private final String[] args;
149 public Page(String resource, String... args) {
150 this.resource = resource;
155 public void service(Request request, Response response) throws Exception {
156 response.setContentType("text/html");
157 OutputStream os = response.getOutputStream();
158 InputStream is = Bck2BrwsrLauncher.class.getResourceAsStream(resource);
159 copyStream(is, os, request.getRequestURL().toString(), args);
163 private static class VM extends HttpHandler {
164 private final ClassLoader loader;
166 public VM(ClassLoader loader) {
167 this.loader = loader;
171 public void service(Request request, Response response) throws Exception {
172 response.setCharacterEncoding("UTF-8");
173 response.setContentType("text/javascript");
174 Bck2Brwsr.generate(response.getWriter(), loader);
177 private static class VMInit extends HttpHandler {
182 public void service(Request request, Response response) throws Exception {
183 response.setCharacterEncoding("UTF-8");
184 response.setContentType("text/javascript");
185 response.getWriter().append(
186 "function ldCls(res) {\n"
187 + " var request = new XMLHttpRequest();\n"
188 + " request.open('GET', 'classes/' + res, false);\n"
189 + " request.send();\n"
190 + " var arr = eval('(' + request.responseText + ')');\n"
193 + "var vm = new bck2brwsr(ldCls);\n");
197 private static class Classes extends HttpHandler {
198 private final ClassLoader loader;
200 public Classes(ClassLoader loader) {
201 this.loader = loader;
205 public void service(Request request, Response response) throws Exception {
206 String res = request.getHttpHandlerPath();
207 if (res.startsWith("/")) {
208 res = res.substring(1);
210 Enumeration<URL> en = loader.getResources(res);
212 while (en.hasMoreElements()) {
213 u = en.nextElement();
217 response.setDetailMessage("Can't find resource " + res);
219 response.setContentType("text/javascript");
220 InputStream is = u.openStream();
221 Writer w = response.getWriter();
223 for (int i = 0;; i++) {
237 w.append(Integer.toString(b));
243 private static final class Case {
244 final String className;
245 final String methodName;
248 public Case(String className, String methodName) {
249 this.className = className;
250 this.methodName = methodName;