Console using JavaScriptBody classloader
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 17 Jun 2013 17:40:30 +0200
branchclassloader
changeset 11792fee889b9830
parent 1178 4ae766848ce0
child 1180 80affbdece28
Console using JavaScriptBody
launcher/fx/pom.xml
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java
launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java
     1.1 --- a/launcher/fx/pom.xml	Mon Jun 17 16:17:46 2013 +0200
     1.2 +++ b/launcher/fx/pom.xml	Mon Jun 17 17:40:30 2013 +0200
     1.3 @@ -68,7 +68,7 @@
     1.4        <groupId>${project.groupId}</groupId>
     1.5        <artifactId>core</artifactId>
     1.6        <version>${project.version}</version>
     1.7 -      <scope>test</scope>
     1.8 +      <scope>compile</scope>
     1.9      </dependency>
    1.10      <dependency>
    1.11        <groupId>org.ow2.asm</groupId>
     2.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java	Mon Jun 17 16:17:46 2013 +0200
     2.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java	Mon Jun 17 17:40:30 2013 +0200
     2.3 @@ -25,8 +25,8 @@
     2.4  import java.lang.reflect.Modifier;
     2.5  import java.net.URL;
     2.6  import java.util.Enumeration;
     2.7 -import javafx.scene.web.WebEngine;
     2.8  import netscape.javascript.JSObject;
     2.9 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    2.10  
    2.11  /**
    2.12   *
    2.13 @@ -35,17 +35,15 @@
    2.14  public final class Console {
    2.15      public Console() {
    2.16      }
    2.17 -    
    2.18 -    private static Object getAttr(Object elem, String attr) {
    2.19 -        return InvokeJS.CObject.call("getAttr", elem, attr);
    2.20 -    }
    2.21  
    2.22 -    private static void setAttr(String id, String attr, Object value) {
    2.23 -        InvokeJS.CObject.call("setAttrId", id, attr, value);
    2.24 -    }
    2.25 -    private static void setAttr(Object id, String attr, Object value) {
    2.26 -        InvokeJS.CObject.call("setAttr", id, attr, value);
    2.27 -    }
    2.28 +    @JavaScriptBody(args = { "elem", "attr" }, body = "return elem[attr].toString();")
    2.29 +    private static native Object getAttr(Object elem, String attr);
    2.30 +
    2.31 +    @JavaScriptBody(args = { "id", "attr", "value" }, body = "window.document.getElementById(id)[attr] = value;")
    2.32 +    private static native void setAttr(String id, String attr, Object value);
    2.33 +
    2.34 +    @JavaScriptBody(args = { "elem", "attr", "value" }, body = "elem[attr] = value;")
    2.35 +    private static native void setAttr(Object id, String attr, Object value);
    2.36      
    2.37      private static void closeWindow() {}
    2.38  
    2.39 @@ -78,7 +76,7 @@
    2.40          textArea = null;
    2.41      }
    2.42  
    2.43 -    private static final String BEGIN_TEST =  
    2.44 +    @JavaScriptBody(args = { "test", "c", "arr" }, body = 
    2.45          "var ul = window.document.getElementById('bck2brwsr.result');\n"
    2.46          + "var li = window.document.createElement('li');\n"
    2.47          + "var span = window.document.createElement('span');"
    2.48 @@ -103,27 +101,24 @@
    2.49          + "p.appendChild(pre);\n"
    2.50          + "ul.appendChild(li);\n"
    2.51          + "arr[0] = pre;\n"
    2.52 -        + "arr[1] = status;\n";
    2.53 -        
    2.54 -    private static void beginTest(String test, Case c, Object[] arr) {
    2.55 -        InvokeJS.CObject.call("beginTest", test, c, arr);
    2.56 -    }
    2.57 +        + "arr[1] = status;\n"
    2.58 +    )
    2.59 +    private static native void beginTest(String test, Case c, Object[] arr);
    2.60      
    2.61 -    private static final String LOAD_TEXT = 
    2.62 +    @JavaScriptBody(args = { "url", "callback", "arr" }, body =
    2.63            "var request = new XMLHttpRequest();\n"
    2.64          + "request.open('GET', url, true);\n"
    2.65          + "request.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');\n"
    2.66          + "request.onreadystatechange = function() {\n"
    2.67          + "  if (this.readyState!==4) return;\n"
    2.68 -        + " try {"
    2.69 +        + " try {\n"
    2.70          + "  arr[0] = this.responseText;\n"
    2.71 -        + "  callback.run__V();\n"
    2.72 -        + " } catch (e) { alert(e); }"
    2.73 -        + "};"
    2.74 -        + "request.send();";
    2.75 -    private static void loadText(String url, Runnable callback, String[] arr) throws IOException {
    2.76 -        InvokeJS.CObject.call("loadText", url, new Run(callback), arr);
    2.77 -    }
    2.78 +        + "  callback.run();\n"
    2.79 +        + " } catch (e) { alert(e); }\n"
    2.80 +        + "};\n"
    2.81 +        + "request.send();\n"
    2.82 +    )
    2.83 +    private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
    2.84      
    2.85      public static void runHarness(String url) throws IOException {
    2.86          new Console().harness(url);
    2.87 @@ -142,11 +137,11 @@
    2.88  
    2.89          private Request(String url) throws IOException {
    2.90              this.url = url;
    2.91 -            loadText(url, this, arr);
    2.92 +            loadText(url, new Run(this), arr);
    2.93          }
    2.94          private Request(String url, String u) throws IOException {
    2.95              this.url = url;
    2.96 -            loadText(u, this, arr);
    2.97 +            loadText(u, new Run(this), arr);
    2.98          }
    2.99          
   2.100          @Override
   2.101 @@ -181,7 +176,7 @@
   2.102              } catch (Exception ex) {
   2.103                  if (ex instanceof InterruptedException) {
   2.104                      log("Re-scheduling in 100ms");
   2.105 -                    schedule(this, 100);
   2.106 +                    schedule(new Run(this), 100);
   2.107                      return;
   2.108                  }
   2.109                  log(ex.getClass().getName() + ":" + ex.getMessage());
   2.110 @@ -254,9 +249,8 @@
   2.111      private static void turnAssetionStatusOn() {
   2.112      }
   2.113  
   2.114 -    private static Object schedule(Runnable r, int time) {
   2.115 -        return InvokeJS.CObject.call("schedule", new Run(r), time);
   2.116 -    }
   2.117 +    @JavaScriptBody(args = { "r", "time" }, body = "return window.setTimeout(function() { r.run(); }, time);")
   2.118 +    private static native Object schedule(Runnable r, int time);
   2.119      
   2.120      private static final class Case {
   2.121          private final Object data;
   2.122 @@ -352,48 +346,16 @@
   2.123              }
   2.124              return res;
   2.125          }
   2.126 -        
   2.127 -        private static Object toJSON(String s) {
   2.128 -            return InvokeJS.CObject.call("toJSON", s);
   2.129 -        }
   2.130 +
   2.131 +        @JavaScriptBody(args = { "s" }, body = "return eval('(' + s + ')');")
   2.132 +        private static native Object toJSON(String s);
   2.133          
   2.134          private static Object value(String p, Object d) {
   2.135              return ((JSObject)d).getMember(p);
   2.136          }
   2.137      }
   2.138      
   2.139 -    private static String safe(String txt) {
   2.140 -        return "try {" + txt + "} catch (err) { alert(err); }";
   2.141 -    }
   2.142 -    
   2.143      static {
   2.144          turnAssetionStatusOn();
   2.145      }
   2.146 -    
   2.147 -    private static final class InvokeJS {
   2.148 -        static final JSObject CObject = initJS();
   2.149 -
   2.150 -        private static JSObject initJS() {
   2.151 -            WebEngine web = (WebEngine) System.getProperties().get("webEngine");
   2.152 -            return (JSObject) web.executeScript("(function() {"
   2.153 -                + "var CObject = {};"
   2.154 -
   2.155 -                + "CObject.getAttr = function(elem, attr) { return elem[attr].toString(); };"
   2.156 -
   2.157 -                + "CObject.setAttrId = function(id, attr, value) { window.document.getElementById(id)[attr] = value; };"
   2.158 -                + "CObject.setAttr = function(elem, attr, value) { elem[attr] = value; };"
   2.159 -
   2.160 -                + "CObject.beginTest = function(test, c, arr) {" + safe(BEGIN_TEST) + "};"
   2.161 -
   2.162 -                + "CObject.loadText = function(url, callback, arr) {" + safe(LOAD_TEXT.replace("run__V", "run")) + "};"
   2.163 -
   2.164 -                + "CObject.schedule = function(r, time) { return window.setTimeout(function() { r.run(); }, time); };"
   2.165 -
   2.166 -                + "CObject.toJSON = function(s) { return eval('(' + s + ')'); };"
   2.167 -
   2.168 -                + "return CObject;"
   2.169 -            + "})(this)");
   2.170 -        }
   2.171 -    }
   2.172 -    
   2.173  }
     3.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java	Mon Jun 17 16:17:46 2013 +0200
     3.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java	Mon Jun 17 17:40:30 2013 +0200
     3.3 @@ -40,7 +40,7 @@
     3.4      
     3.5      JVMBridge(WebEngine eng) {
     3.6          this.engine = eng;
     3.7 -        this.cl = new WebClassLoader(JVMBridge.class.getClassLoader());
     3.8 +        this.cl = new WebClassLoader(JVMBridge.class.getClassLoader().getParent());
     3.9      }
    3.10          
    3.11      public static void registerClassLoaders(ClassLoader[] loaders) {
    3.12 @@ -126,7 +126,15 @@
    3.13          
    3.14          @Override
    3.15          public Object invoke(Object... args) throws Exception {
    3.16 -            return fn.call("fn", args); // NOI18N
    3.17 +            try {
    3.18 +                return fn.call("fn", args); // NOI18N
    3.19 +            } catch (Error t) {
    3.20 +                t.printStackTrace();
    3.21 +                throw t;
    3.22 +            } catch (Exception t) {
    3.23 +                t.printStackTrace();
    3.24 +                throw t;
    3.25 +            }
    3.26          }
    3.27      }
    3.28  }
     4.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java	Mon Jun 17 16:17:46 2013 +0200
     4.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java	Mon Jun 17 17:40:30 2013 +0200
     4.3 @@ -51,6 +51,21 @@
     4.4  
     4.5      @Override
     4.6      protected Class<?> findClass(String name) throws ClassNotFoundException {
     4.7 +        if (name.startsWith("javafx")) {
     4.8 +            return Class.forName(name);
     4.9 +        }
    4.10 +        if (name.startsWith("netscape")) {
    4.11 +            return Class.forName(name);
    4.12 +        }
    4.13 +        if (name.startsWith("com.sun")) {
    4.14 +            return Class.forName(name);
    4.15 +        }
    4.16 +        if (name.equals(JsClassLoader.class.getName())) {
    4.17 +            return JsClassLoader.class;
    4.18 +        }
    4.19 +        if (name.equals(Fn.class.getName())) {
    4.20 +            return Fn.class;
    4.21 +        }
    4.22          URL u = findResource(name.replace('.', '/') + ".class");
    4.23          if (u != null) {
    4.24              InputStream is = null;