Can execute VMTest in browser, if it is annotated with @Exported annotation like the BooleanTest
1.1 --- a/launcher/fx/pom.xml Fri Apr 25 15:06:09 2014 +0200
1.2 +++ b/launcher/fx/pom.xml Sat Apr 26 19:13:56 2014 +0200
1.3 @@ -53,5 +53,10 @@
1.4 <scope>system</scope>
1.5 <systemPath>${jfxrt.jar}</systemPath>
1.6 </dependency>
1.7 + <dependency>
1.8 + <groupId>org.testng</groupId>
1.9 + <artifactId>testng</artifactId>
1.10 + <scope>test</scope>
1.11 + </dependency>
1.12 </dependencies>
1.13 </project>
2.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java Fri Apr 25 15:06:09 2014 +0200
2.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java Sat Apr 26 19:13:56 2014 +0200
2.3 @@ -26,6 +26,7 @@
2.4 import java.io.Reader;
2.5 import java.io.UnsupportedEncodingException;
2.6 import java.io.Writer;
2.7 +import java.net.JarURLConnection;
2.8 import java.net.URI;
2.9 import java.net.URISyntaxException;
2.10 import java.net.URL;
2.11 @@ -40,6 +41,7 @@
2.12 import java.util.concurrent.CountDownLatch;
2.13 import java.util.concurrent.LinkedBlockingQueue;
2.14 import java.util.concurrent.TimeUnit;
2.15 +import java.util.jar.JarFile;
2.16 import java.util.logging.Level;
2.17 import java.util.logging.Logger;
2.18 import org.apidesign.bck2brwsr.launcher.InvocationContext.Resource;
2.19 @@ -495,16 +497,28 @@
2.20
2.21 abstract void generateBck2BrwsrJS(StringBuilder sb, Res loader) throws IOException;
2.22 abstract String harnessResource();
2.23 + String compileJar(JarFile jar) throws IOException {
2.24 + return null;
2.25 + }
2.26 + String compileFromClassPath(URL f) {
2.27 + return null;
2.28 + }
2.29
2.30 - class Res {
2.31 - public InputStream get(String resource) throws IOException {
2.32 + final class Res {
2.33 + String compileJar(JarFile jar) throws IOException {
2.34 + return BaseHTTPLauncher.this.compileJar(jar);
2.35 + }
2.36 + String compileFromClassPath(URL f) {
2.37 + return BaseHTTPLauncher.this.compileFromClassPath(f);
2.38 + }
2.39 + public URL get(String resource) throws IOException {
2.40 URL u = null;
2.41 for (ClassLoader l : loaders) {
2.42 Enumeration<URL> en = l.getResources(resource);
2.43 while (en.hasMoreElements()) {
2.44 u = en.nextElement();
2.45 if (u.toExternalForm().matches("^.*emul.*rt\\.jar.*$")) {
2.46 - return u.openStream();
2.47 + return u;
2.48 }
2.49 }
2.50 }
2.51 @@ -512,7 +526,7 @@
2.52 if (u.toExternalForm().contains("rt.jar")) {
2.53 LOG.log(Level.WARNING, "Fallback to bootclasspath for {0}", u);
2.54 }
2.55 - return u.openStream();
2.56 + return u;
2.57 }
2.58 throw new IOException("Can't find " + resource);
2.59 }
2.60 @@ -547,7 +561,7 @@
2.61 replace = args;
2.62 }
2.63 OutputStream os = response.getOutputStream();
2.64 - try (InputStream is = res.get(r)) {
2.65 + try (InputStream is = res.get(r).openStream()) {
2.66 copyStream(is, os, request.getRequestURL().toString(), replace);
2.67 } catch (IOException ex) {
2.68 response.setDetailMessage(ex.getLocalizedMessage());
2.69 @@ -603,10 +617,32 @@
2.70 if (res.startsWith("/")) {
2.71 res = res.substring(1);
2.72 }
2.73 - try (InputStream is = loader.get(res)) {
2.74 + URL url = loader.get(res);
2.75 + if (url.getProtocol().equals("jar")) {
2.76 + JarURLConnection juc = (JarURLConnection) url.openConnection();
2.77 + String s = loader.compileJar(juc.getJarFile());
2.78 + if (s != null) {
2.79 + Writer w = response.getWriter();
2.80 + w.append(s);
2.81 + w.close();
2.82 + return;
2.83 + }
2.84 + }
2.85 + if (url.getProtocol().equals("file")) {
2.86 + String s = loader.compileFromClassPath(url);
2.87 + if (s != null) {
2.88 + Writer w = response.getWriter();
2.89 + w.append(s);
2.90 + w.close();
2.91 + return;
2.92 + }
2.93 + }
2.94 + Exception ex = new Exception("Won't server bytes of " + url);
2.95 + /*
2.96 + try (InputStream is = url.openStream()) {
2.97 response.setContentType("text/javascript");
2.98 Writer w = response.getWriter();
2.99 - w.append("[");
2.100 + w.append("([");
2.101 for (int i = 0;; i++) {
2.102 int b = is.read();
2.103 if (b == -1) {
2.104 @@ -623,12 +659,14 @@
2.105 }
2.106 w.append(Integer.toString(b));
2.107 }
2.108 - w.append("\n]");
2.109 - } catch (IOException ex) {
2.110 + w.append("\n])");
2.111 + } catch (IOException ex)
2.112 + */ {
2.113 response.setStatus(HttpStatus.NOT_FOUND_404);
2.114 response.setError();
2.115 response.setDetailMessage(ex.getMessage());
2.116 }
2.117 }
2.118 +
2.119 }
2.120 }
3.1 --- a/launcher/http/pom.xml Fri Apr 25 15:06:09 2014 +0200
3.2 +++ b/launcher/http/pom.xml Sat Apr 26 19:13:56 2014 +0200
3.3 @@ -56,5 +56,16 @@
3.4 <artifactId>vm4brwsr</artifactId>
3.5 <version>${project.version}</version>
3.6 </dependency>
3.7 + <dependency>
3.8 + <groupId>org.testng</groupId>
3.9 + <artifactId>testng</artifactId>
3.10 + <scope>test</scope>
3.11 + </dependency>
3.12 + <dependency>
3.13 + <groupId>${project.groupId}</groupId>
3.14 + <artifactId>emul.mini</artifactId>
3.15 + <version>${project.version}</version>
3.16 + <scope>test</scope>
3.17 + </dependency>
3.18 </dependencies>
3.19 </project>
4.1 --- a/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Fri Apr 25 15:06:09 2014 +0200
4.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Sat Apr 26 19:13:56 2014 +0200
4.3 @@ -17,8 +17,11 @@
4.4 */
4.5 package org.apidesign.bck2brwsr.launcher;
4.6
4.7 +import java.io.File;
4.8 import java.io.IOException;
4.9 import java.io.InputStream;
4.10 +import java.net.URL;
4.11 +import java.util.jar.JarFile;
4.12 import org.apidesign.vm4brwsr.Bck2Brwsr;
4.13
4.14 /**
4.15 @@ -36,13 +39,27 @@
4.16 String harnessResource() {
4.17 return "org/apidesign/bck2brwsr/launcher/harness.xhtml";
4.18 }
4.19 +
4.20 + @Override
4.21 + String compileJar(JarFile jar) throws IOException {
4.22 + return CompileCP.compileJAR(jar);
4.23 + }
4.24 +
4.25 + @Override String compileFromClassPath(URL f) {
4.26 + try {
4.27 + return CompileCP.compileFromClassPath(f);
4.28 + } catch (Exception ex) {
4.29 + ex.printStackTrace();
4.30 + return null;
4.31 + }
4.32 + }
4.33
4.34 @Override
4.35 void generateBck2BrwsrJS(StringBuilder sb, final Res loader) throws IOException {
4.36 class R implements Bck2Brwsr.Resources {
4.37 @Override
4.38 public InputStream get(String resource) throws IOException {
4.39 - return loader.get(resource);
4.40 + return loader.get(resource).openStream();
4.41 }
4.42 }
4.43
4.44 @@ -54,7 +71,7 @@
4.45 + " request.open('GET', '/classes/' + res, false);\n"
4.46 + " request.send();\n"
4.47 + " if (request.status !== 200) return null;\n"
4.48 - + " var arr = eval('(' + request.responseText + ')');\n"
4.49 + + " var arr = eval(request.responseText);\n"
4.50 + " return arr;\n"
4.51 + " }\n"
4.52 + " var prevvm = global.bck2brwsr;\n"
4.53 @@ -63,6 +80,7 @@
4.54 + " args.unshift(ldCls);\n"
4.55 + " return prevvm.apply(null, args);\n"
4.56 + " };\n"
4.57 + + " global.bck2brwsr.registerExtension = prevvm.registerExtension;\n"
4.58 + "})(this);\n"
4.59 );
4.60 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java Sat Apr 26 19:13:56 2014 +0200
5.3 @@ -0,0 +1,154 @@
5.4 +/**
5.5 + * Back 2 Browser Bytecode Translator
5.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.7 + *
5.8 + * This program is free software: you can redistribute it and/or modify
5.9 + * it under the terms of the GNU General Public License as published by
5.10 + * the Free Software Foundation, version 2 of the License.
5.11 + *
5.12 + * This program is distributed in the hope that it will be useful,
5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 + * GNU General Public License for more details.
5.16 + *
5.17 + * You should have received a copy of the GNU General Public License
5.18 + * along with this program. Look for COPYING file in the top folder.
5.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
5.20 + */
5.21 +package org.apidesign.bck2brwsr.launcher;
5.22 +
5.23 +import java.io.File;
5.24 +import java.io.IOException;
5.25 +import java.io.InputStream;
5.26 +import java.io.StringWriter;
5.27 +import java.net.URISyntaxException;
5.28 +import java.net.URL;
5.29 +import java.util.ArrayList;
5.30 +import java.util.Enumeration;
5.31 +import java.util.List;
5.32 +import java.util.jar.JarEntry;
5.33 +import java.util.jar.JarFile;
5.34 +import java.util.zip.ZipEntry;
5.35 +import org.apidesign.vm4brwsr.Bck2Brwsr;
5.36 +
5.37 +/**
5.38 + *
5.39 + * @author Jaroslav Tulach
5.40 + */
5.41 +class CompileCP {
5.42 + static String compileJAR(final JarFile jar) throws IOException {
5.43 + List<String> arr = new ArrayList<>();
5.44 + List<String> classes = new ArrayList<>();
5.45 + listJAR(jar, classes, arr);
5.46 + StringWriter w = new StringWriter();
5.47 + try {
5.48 + class JarRes extends EmulationResources implements Bck2Brwsr.Resources {
5.49 + @Override
5.50 + public InputStream get(String resource) throws IOException {
5.51 + InputStream is = jar.getInputStream(new ZipEntry(resource));
5.52 + return is == null ? super.get(resource) : is;
5.53 + }
5.54 + }
5.55 +
5.56 + Bck2Brwsr.newCompiler()
5.57 + .addRootClasses(classes.toArray(new String[0]))
5.58 + .extension(true)
5.59 + .resources(new JarRes())
5.60 + .generate(w);
5.61 + w.flush();
5.62 + return w.toString();
5.63 + } catch (Throwable ex) {
5.64 + throw new IOException("Cannot compile: ", ex);
5.65 + } finally {
5.66 + w.close();
5.67 + }
5.68 + }
5.69 +
5.70 + static String compileFromClassPath(URL u) throws IOException, URISyntaxException {
5.71 + File f = new File(u.toURI());
5.72 + for (String s : System.getProperty("java.class.path").split(File.pathSeparator)) {
5.73 + if (!f.getPath().startsWith(s)) {
5.74 + continue;
5.75 + }
5.76 + File root = new File(s);
5.77 + List<String> arr = new ArrayList<>();
5.78 + List<String> classes = new ArrayList<>();
5.79 + listDir(root, null, classes, arr);
5.80 + StringWriter w = new StringWriter();
5.81 + try {
5.82 + Bck2Brwsr.newCompiler()
5.83 + .addRootClasses(classes.toArray(new String[0]))
5.84 + .extension(true)
5.85 + .resources(new EmulationResources())
5.86 + .generate(w);
5.87 + w.flush();
5.88 + return w.toString();
5.89 + } catch (ClassFormatError ex) {
5.90 + throw new IOException(ex);
5.91 + } finally {
5.92 + w.close();
5.93 + }
5.94 + }
5.95 + return null;
5.96 + }
5.97 +
5.98 + private static void listJAR(JarFile j, List<String> classes, List<String> resources) throws IOException {
5.99 + Enumeration<JarEntry> en = j.entries();
5.100 + while (en.hasMoreElements()) {
5.101 + JarEntry e = en.nextElement();
5.102 + final String n = e.getName();
5.103 + if (n.endsWith("/")) {
5.104 + continue;
5.105 + }
5.106 + int last = n.lastIndexOf('/');
5.107 + String pkg = n.substring(0, last + 1);
5.108 + if (skipPkg(pkg)) {
5.109 + continue;
5.110 + }
5.111 + if (n.endsWith(".class")) {
5.112 + classes.add(n.substring(0, n.length() - 6));
5.113 + } else {
5.114 + resources.add(n);
5.115 + }
5.116 + }
5.117 + }
5.118 +
5.119 + private static boolean skipPkg(String pkg) {
5.120 + return pkg.equals("org/apidesign/bck2brwsr/launcher/");
5.121 + }
5.122 +
5.123 + private static void listDir(File f, String pref, List<String> classes, List<String> resources) throws IOException {
5.124 + File[] arr = f.listFiles();
5.125 + if (arr == null) {
5.126 + if (f.getName().endsWith(".class")) {
5.127 + classes.add(pref + f.getName().substring(0, f.getName().length() - 6));
5.128 + } else {
5.129 + resources.add(pref + f.getName());
5.130 + }
5.131 + } else {
5.132 + for (File ch : arr) {
5.133 +
5.134 + listDir(ch, pref == null ? "" : pref + f.getName() + "/", classes, resources);
5.135 + }
5.136 + }
5.137 + }
5.138 +
5.139 + static class EmulationResources implements Bck2Brwsr.Resources {
5.140 +
5.141 + @Override
5.142 + public InputStream get(String name) throws IOException {
5.143 + Enumeration<URL> en = CompileCP.class.getClassLoader().getResources(name);
5.144 + URL u = null;
5.145 + while (en.hasMoreElements()) {
5.146 + u = en.nextElement();
5.147 + }
5.148 + if (u == null) {
5.149 + throw new IOException("Can't find " + name);
5.150 + }
5.151 + if (u.toExternalForm().contains("rt.jar!")) {
5.152 + throw new IOException("No emulation for " + u);
5.153 + }
5.154 + return u.openStream();
5.155 + }
5.156 + }
5.157 +}
6.1 --- a/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java Fri Apr 25 15:06:09 2014 +0200
6.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java Sat Apr 26 19:13:56 2014 +0200
6.3 @@ -31,6 +31,7 @@
6.4 *
6.5 * @author Jaroslav Tulach <jtulach@netbeans.org>
6.6 */
6.7 +@org.apidesign.bck2brwsr.core.Exported
6.8 public class Console {
6.9 private Console() {
6.10 }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/launcher/http/src/test/java/org/apidesign/bck2brwsr/launcher/CompileCPTest.java Sat Apr 26 19:13:56 2014 +0200
7.3 @@ -0,0 +1,41 @@
7.4 +/**
7.5 + * Back 2 Browser Bytecode Translator
7.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
7.7 + *
7.8 + * This program is free software: you can redistribute it and/or modify
7.9 + * it under the terms of the GNU General Public License as published by
7.10 + * the Free Software Foundation, version 2 of the License.
7.11 + *
7.12 + * This program is distributed in the hope that it will be useful,
7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.15 + * GNU General Public License for more details.
7.16 + *
7.17 + * You should have received a copy of the GNU General Public License
7.18 + * along with this program. Look for COPYING file in the top folder.
7.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
7.20 + */
7.21 +package org.apidesign.bck2brwsr.launcher;
7.22 +
7.23 +import java.io.File;
7.24 +import java.net.URL;
7.25 +import static org.testng.Assert.*;
7.26 +import org.testng.annotations.Test;
7.27 +
7.28 +/**
7.29 + *
7.30 + * @author Jaroslav Tulach
7.31 + */
7.32 +public class CompileCPTest {
7.33 + public CompileCPTest() {
7.34 + }
7.35 +
7.36 + @Test public void compileClassPath() throws Exception {
7.37 + URL u = CompileCPTest.class.getResource("/" + CompileCPTest.class.getName().replace('.', '/') + ".class");
7.38 + assertNotNull(u, "URL found");
7.39 + assertEquals(u.getProtocol(), "file", "It comes from a disk");
7.40 +
7.41 + String resources = CompileCP.compileFromClassPath(u);
7.42 + assertNotNull(resources, "something compiled");
7.43 + }
7.44 +}
8.1 --- a/rt/emul/brwsrtest/src/test/java/org/apidesign/bck2brwsr/brwsrtest/BooleanTest.java Fri Apr 25 15:06:09 2014 +0200
8.2 +++ b/rt/emul/brwsrtest/src/test/java/org/apidesign/bck2brwsr/brwsrtest/BooleanTest.java Sat Apr 26 19:13:56 2014 +0200
8.3 @@ -19,7 +19,6 @@
8.4
8.5 import org.apidesign.bck2brwsr.core.JavaScriptBody;
8.6 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
8.7 -import org.apidesign.bck2brwsr.vmtest.Compare;
8.8 import org.apidesign.bck2brwsr.vmtest.VMTest;
8.9 import org.testng.annotations.Factory;
8.10
8.11 @@ -27,6 +26,7 @@
8.12 *
8.13 * @author Jaroslav Tulach <jtulach@netbeans.org>
8.14 */
8.15 +@org.apidesign.bck2brwsr.core.Exported
8.16 public class BooleanTest {
8.17 @JavaScriptBody(args = { "tr" }, body = "return tr ? true : false;")
8.18 private static native Object trueFalse(boolean tr);
9.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Fri Apr 25 15:06:09 2014 +0200
9.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sat Apr 26 19:13:56 2014 +0200
9.3 @@ -433,14 +433,24 @@
9.4 + " for (var i = 0; i < extensions.length; ++i) {\n"
9.5 + " extensions[i](vm);\n"
9.6 + " }\n"
9.7 + + " var knownExtensions = extensions.length;\n"
9.8 + " var loader = {};\n"
9.9 + " loader.vm = vm;\n"
9.10 + " loader.loadClass = function(name) {\n"
9.11 + " var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
9.12 + " var fn = vm[attr];\n"
9.13 + " if (fn) return fn(false);\n"
9.14 - + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
9.15 - + " load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
9.16 + + " try {\n"
9.17 + + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
9.18 + + " load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
9.19 + + " } catch (err) {\n"
9.20 + + " while (knownExtensions < extensions.length) {\n"
9.21 + + " extensions[knownExtensions++](vm);\n"
9.22 + + " }\n"
9.23 + + " fn = vm[attr];\n"
9.24 + + " if (fn) return fn(false);\n"
9.25 + + " throw err;\n"
9.26 + + " }\n"
9.27 + " }\n"
9.28 + " if (vm.loadClass) {\n"
9.29 + " throw 'Cannot initialize the bck2brwsr VM twice!';\n"
9.30 @@ -456,9 +466,9 @@
9.31 + " return loader;\n"
9.32 + " };\n");
9.33 out.append(
9.34 - " global.bck2brwsr.registerExtension"
9.35 - + " = function(extension) {\n"
9.36 + " global.bck2brwsr.registerExtension = function(extension) {\n"
9.37 + " extensions.push(extension);\n"
9.38 + + " return null;\n"
9.39 + " };\n");
9.40 out.append("}(this));");
9.41 }