Using URL.getContent to communicate with the launcher and execute two testing methods
1.1 --- a/emul/src/main/java/java/net/URL.java Mon Dec 17 09:57:22 2012 +0100
1.2 +++ b/emul/src/main/java/java/net/URL.java Mon Dec 17 11:58:48 2012 +0100
1.3 @@ -27,6 +27,7 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.InputStream;
1.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.8
1.9 /**
1.10 * Class <code>URL</code> represents a Uniform Resource
1.11 @@ -964,9 +965,16 @@
1.12 * @see java.net.URLConnection#getContent()
1.13 */
1.14 public final Object getContent() throws java.io.IOException {
1.15 - throw new IOException();
1.16 -// return openConnection().getContent();
1.17 + return loadText(toExternalForm());
1.18 }
1.19 +
1.20 + @JavaScriptBody(args = "url", body = ""
1.21 + + "var request = new XMLHttpRequest();\n"
1.22 + + "request.open('GET', url, false);\n"
1.23 + + "request.send();\n"
1.24 + + "return request.responseText;\n"
1.25 + )
1.26 + private static native String loadText(String url) throws IOException;
1.27
1.28 /**
1.29 * Gets the contents of this URL. This method is a shorthand for:
1.30 @@ -984,8 +992,12 @@
1.31 */
1.32 public final Object getContent(Class[] classes)
1.33 throws java.io.IOException {
1.34 - throw new IOException();
1.35 -// return openConnection().getContent(classes);
1.36 + for (Class<?> c : classes) {
1.37 + if (c == String.class) {
1.38 + return getContent();
1.39 + }
1.40 + }
1.41 + return null;
1.42 }
1.43
1.44 static URLStreamHandler getURLStreamHandler(String protocol) {
2.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Mon Dec 17 09:57:22 2012 +0100
2.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Mon Dec 17 11:58:48 2012 +0100
2.3 @@ -25,6 +25,7 @@
2.4 import java.net.URI;
2.5 import java.net.URL;
2.6 import java.util.Enumeration;
2.7 +import java.util.concurrent.CountDownLatch;
2.8 import static org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher.copyStream;
2.9 import org.apidesign.vm4brwsr.Bck2Brwsr;
2.10 import org.glassfish.grizzly.PortRange;
2.11 @@ -40,6 +41,12 @@
2.12 */
2.13 public class Bck2BrwsrLauncher {
2.14 public static void main( String[] args ) throws Exception {
2.15 + final Case[] cases = {
2.16 + new Case("org.apidesign.bck2brwsr.launcher.Console", "welcome"),
2.17 + new Case("org.apidesign.bck2brwsr.launcher.Console", "multiply")
2.18 + };
2.19 + final CountDownLatch wait = new CountDownLatch(1);
2.20 +
2.21 HttpServer server = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
2.22 final ClassLoader loader = Bck2BrwsrLauncher.class.getClassLoader();
2.23
2.24 @@ -70,13 +77,28 @@
2.25 int cnt;
2.26 @Override
2.27 public void service(Request request, Response response) throws Exception {
2.28 + String id = request.getParameter("request");
2.29 + String value = request.getParameter("result");
2.30 + if (id != null && value != null) {
2.31 + value = value.replace("%20", " ");
2.32 + cases[Integer.parseInt(id)].result = value;
2.33 + }
2.34 +
2.35 + if (cnt >= cases.length) {
2.36 + response.getWriter().write("");
2.37 + wait.countDown();
2.38 + cnt = 0;
2.39 + return;
2.40 + }
2.41 +
2.42 response.getWriter().write("{"
2.43 - + "className: 'org.apidesign.bck2brwsr.launcher.Console',"
2.44 - + "methodName: 'welcome',"
2.45 + + "className: '" + cases[cnt].className + "', "
2.46 + + "methodName: '" + cases[cnt].methodName + "', "
2.47 + "request: " + cnt
2.48 + "}");
2.49 + cnt++;
2.50 }
2.51 - }, "execute/data");
2.52 + }, "/data");
2.53 conf.addHttpHandler(new Page("harness.xhtml"), "/execute");
2.54
2.55 server.start();
2.56 @@ -93,10 +115,14 @@
2.57 Runtime.getRuntime().exec(cmd).waitFor();
2.58 }
2.59
2.60 - System.in.read();
2.61 + wait.await();
2.62 +
2.63 + for (Case c : cases) {
2.64 + System.err.println(c.className + "." + c.methodName + " = " + c.result);
2.65 + }
2.66 }
2.67
2.68 - static void copyStream(InputStream is, OutputStream os, String... params) throws IOException {
2.69 + static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
2.70 for (;;) {
2.71 int ch = is.read();
2.72 if (ch == -1) {
2.73 @@ -104,6 +130,9 @@
2.74 }
2.75 if (ch == '$') {
2.76 int cnt = is.read() - '0';
2.77 + if (cnt == 'U' - '0') {
2.78 + os.write(baseURL.getBytes());
2.79 + }
2.80 if (cnt < params.length) {
2.81 os.write(params[cnt].getBytes());
2.82 }
2.83 @@ -127,7 +156,7 @@
2.84 response.setContentType("text/html");
2.85 OutputStream os = response.getOutputStream();
2.86 InputStream is = Bck2BrwsrLauncher.class.getResourceAsStream(resource);
2.87 - copyStream(is, os, args);
2.88 + copyStream(is, os, request.getRequestURL().toString(), args);
2.89 }
2.90 }
2.91
2.92 @@ -210,4 +239,15 @@
2.93 w.append("\n]");
2.94 }
2.95 }
2.96 +
2.97 + private static final class Case {
2.98 + final String className;
2.99 + final String methodName;
2.100 + String result;
2.101 +
2.102 + public Case(String className, String methodName) {
2.103 + this.className = className;
2.104 + this.methodName = methodName;
2.105 + }
2.106 + }
2.107 }
3.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java Mon Dec 17 09:57:22 2012 +0100
3.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java Mon Dec 17 11:58:48 2012 +0100
3.3 @@ -17,7 +17,6 @@
3.4 */
3.5 package org.apidesign.bck2brwsr.launcher;
3.6
3.7 -import java.io.InputStream;
3.8 import java.lang.reflect.InvocationTargetException;
3.9 import java.lang.reflect.Method;
3.10 import java.net.URL;
3.11 @@ -29,13 +28,11 @@
3.12 */
3.13 public class Console {
3.14 public static String welcome() {
3.15 - final String msg = "Hello from Bck2Brwsr!";
3.16 - alert(msg);
3.17 - return msg;
3.18 + return "HellofromBck2Brwsr";
3.19 }
3.20 -
3.21 - @JavaScriptBody(args = "msg", body = "alert(msg);")
3.22 - private static native void alert(String msg);
3.23 + public static String multiply() {
3.24 + return String.valueOf(Integer.MAX_VALUE / 2 + Integer.MAX_VALUE);
3.25 + }
3.26
3.27 @JavaScriptBody(args = {"id", "attr"}, body =
3.28 "return window.document.getElementById(id)[attr].toString();")
3.29 @@ -44,6 +41,10 @@
3.30 @JavaScriptBody(args = {"id", "attr", "value"}, body =
3.31 "window.document.getElementById(id)[attr] = value;")
3.32 private static native void setAttr(String id, String attr, Object value);
3.33 +
3.34 + private static void addAttr(String id, String attr, String newText) {
3.35 + setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
3.36 + }
3.37
3.38 public static void execute() throws Exception {
3.39 String clazz = (String) getAttr("clazz", "value");
3.40 @@ -52,13 +53,41 @@
3.41 setAttr("result", "value", res);
3.42 }
3.43
3.44 - public static void harness() {
3.45 + public static void harness(String url) {
3.46 + setAttr("result", "value", "Connecting to " + url);
3.47 try {
3.48 - URL u = new URL("/execute/data");
3.49 - String data = (String) u.getContent(new Class[] { String.class });
3.50 - setAttr("result", "value", data);
3.51 + URL u = new URL(url);
3.52 + for (;;) {
3.53 + String data = (String) u.getContent(new Class[] { String.class });
3.54 + addAttr("result", "value", data);
3.55 + if (data.isEmpty()) {
3.56 + addAttr("result", "value", "No data, exiting");
3.57 + break;
3.58 + }
3.59 +
3.60 + Case c = Case.parseData(data);
3.61 + addAttr("result", "value", "className: " + c.getClassName());
3.62 + addAttr("result", "value", "methodName: " + c.getMethodName());
3.63 + addAttr("result", "value", "request: " + c.getRequestId());
3.64 +
3.65 + Object result = invokeMethod(c.getClassName(), c.getMethodName());
3.66 +
3.67 + addAttr("result", "value", "result: " + result);
3.68 +
3.69 + String toSend;
3.70 + if (result == null) {
3.71 + toSend = "null";
3.72 + } else {
3.73 + toSend = result.toString();
3.74 + }
3.75 +
3.76 + addAttr("result", "value", "Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + toSend);
3.77 + u = new URL(url + "?request=" + c.getRequestId() + "&result=" + toSend);
3.78 + }
3.79 +
3.80 +
3.81 } catch (Exception ex) {
3.82 - setAttr("result", "value", ex.getMessage());
3.83 + addAttr("result", "value", ex.getMessage());
3.84 }
3.85 }
3.86
3.87 @@ -80,4 +109,34 @@
3.88 }
3.89 return res;
3.90 }
3.91 +
3.92 + private static final class Case {
3.93 + private final Object data;
3.94 +
3.95 + private Case(Object data) {
3.96 + this.data = data;
3.97 + }
3.98 +
3.99 + public static Case parseData(String s) {
3.100 + return new Case(toJSON(s));
3.101 + }
3.102 +
3.103 + public String getMethodName() {
3.104 + return value("methodName", data);
3.105 + }
3.106 +
3.107 + public String getClassName() {
3.108 + return value("className", data);
3.109 + }
3.110 +
3.111 + public String getRequestId() {
3.112 + return value("request", data);
3.113 + }
3.114 +
3.115 + @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
3.116 + private static native Object toJSON(String s);
3.117 +
3.118 + @JavaScriptBody(args = {"p", "d"}, body = "return d[p].toString();")
3.119 + private static native String value(String p, Object d);
3.120 + }
3.121 }
4.1 --- a/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Mon Dec 17 09:57:22 2012 +0100
4.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Mon Dec 17 11:58:48 2012 +0100
4.3 @@ -33,7 +33,7 @@
4.4 </textarea>
4.5
4.6 <script type="text/javascript">
4.7 - vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__V();
4.8 + vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__VLjava_lang_String_2('$U/../data');
4.9 </script>
4.10 </body>
4.11 </html>