1.1 --- a/emul/src/main/java/java/lang/Class.java Mon Dec 24 07:51:15 2012 +0100
1.2 +++ b/emul/src/main/java/java/lang/Class.java Mon Dec 24 07:57:33 2012 +0100
1.3 @@ -287,7 +287,12 @@
1.4 * @return {@code true} if this object represents an interface;
1.5 * {@code false} otherwise.
1.6 */
1.7 - public native boolean isInterface();
1.8 + public boolean isInterface() {
1.9 + return (getAccess() & 0x200) != 0;
1.10 + }
1.11 +
1.12 + @JavaScriptBody(args = "self", body = "return self.access;")
1.13 + private native int getAccess();
1.14
1.15
1.16 /**
1.17 @@ -330,6 +335,10 @@
1.18 * @see java.lang.Void#TYPE
1.19 * @since JDK1.1
1.20 */
1.21 + @JavaScriptBody(args = "self", body =
1.22 + "if (self.primitive) return true;"
1.23 + + "else return false;"
1.24 + )
1.25 public native boolean isPrimitive();
1.26
1.27 /**
1.28 @@ -1090,10 +1099,13 @@
1.29 throw new UnsupportedOperationException();
1.30 }
1.31
1.32 - static Class getPrimitiveClass(String type) {
1.33 - // XXX
1.34 - return Object.class;
1.35 - }
1.36 + @JavaScriptBody(args = "type", body = ""
1.37 + + "var c = vm.java_lang_Class(true);"
1.38 + + "c.jvmName = type;"
1.39 + + "c.primitive = true;"
1.40 + + "return c;"
1.41 + )
1.42 + native static Class getPrimitiveClass(String type);
1.43
1.44 public boolean desiredAssertionStatus() {
1.45 return false;
2.1 --- a/emul/src/main/java/java/lang/reflect/Method.java Mon Dec 24 07:51:15 2012 +0100
2.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java Mon Dec 24 07:57:33 2012 +0100
2.3 @@ -137,7 +137,24 @@
2.4 * @return the return type for the method this object represents
2.5 */
2.6 public Class<?> getReturnType() {
2.7 - throw new UnsupportedOperationException();
2.8 + switch (sig.charAt(0)) {
2.9 + case 'I': return Integer.TYPE;
2.10 + case 'J': return Long.TYPE;
2.11 + case 'D': return Double.TYPE;
2.12 + case 'F': return Float.TYPE;
2.13 + case 'B': return Byte.TYPE;
2.14 + case 'Z': return Boolean.TYPE;
2.15 + case 'S': return Short.TYPE;
2.16 +// case 'V': return Void.TYPE;
2.17 + case 'L': try {
2.18 + int up = sig.indexOf("_2");
2.19 + String type = sig.substring(1, up);
2.20 + return Class.forName(type);
2.21 + } catch (ClassNotFoundException ex) {
2.22 + // should not happen
2.23 + }
2.24 + }
2.25 + throw new UnsupportedOperationException(sig);
2.26 }
2.27
2.28 /**
2.29 @@ -488,17 +505,54 @@
2.30 * @exception ExceptionInInitializerError if the initialization
2.31 * provoked by this method fails.
2.32 */
2.33 + public Object invoke(Object obj, Object... args)
2.34 + throws IllegalAccessException, IllegalArgumentException,
2.35 + InvocationTargetException
2.36 + {
2.37 + Object res = invoke0(this, obj, args);
2.38 + if (getReturnType().isPrimitive()) {
2.39 + res = fromPrimitive(getReturnType(), res);
2.40 + }
2.41 + return res;
2.42 + }
2.43 +
2.44 @JavaScriptBody(args = { "method", "self", "args" }, body =
2.45 "if (args.length > 0) throw 'unsupported now';"
2.46 + "return method.fld_data(self);"
2.47 )
2.48 - public Object invoke(Object obj, Object... args)
2.49 - throws IllegalAccessException, IllegalArgumentException,
2.50 - InvocationTargetException
2.51 - {
2.52 - throw new UnsupportedOperationException();
2.53 + private static native Object invoke0(Method m, Object self, Object[] args);
2.54 +
2.55 + private static Object fromPrimitive(Class<?> type, Object o) {
2.56 + if (type == Integer.TYPE) {
2.57 + return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
2.58 + }
2.59 + if (type == Long.TYPE) {
2.60 + return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o);
2.61 + }
2.62 + if (type == Double.TYPE) {
2.63 + return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o);
2.64 + }
2.65 + if (type == Float.TYPE) {
2.66 + return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o);
2.67 + }
2.68 + if (type == Byte.TYPE) {
2.69 + return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o);
2.70 + }
2.71 + if (type == Boolean.TYPE) {
2.72 + return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o);
2.73 + }
2.74 + if (type == Short.TYPE) {
2.75 + return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
2.76 + }
2.77 +// case 'V': return Void.TYPE;
2.78 + throw new IllegalStateException("Can't convert " + o);
2.79 }
2.80 -
2.81 +
2.82 + @JavaScriptBody(args = { "cls", "m", "o" },
2.83 + body = "return cls.cnstr(false)[m](o);"
2.84 + )
2.85 + private static native Integer fromRaw(Class<?> cls, String m, Object o);
2.86 +
2.87 /**
2.88 * Returns {@code true} if this method is a bridge
2.89 * method; returns {@code false} otherwise.
3.1 --- a/emul/src/main/java/java/net/URL.java Mon Dec 24 07:51:15 2012 +0100
3.2 +++ b/emul/src/main/java/java/net/URL.java Mon Dec 24 07:57:33 2012 +0100
3.3 @@ -27,6 +27,7 @@
3.4
3.5 import java.io.IOException;
3.6 import java.io.InputStream;
3.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
3.8
3.9 /**
3.10 * Class <code>URL</code> represents a Uniform Resource
3.11 @@ -964,9 +965,16 @@
3.12 * @see java.net.URLConnection#getContent()
3.13 */
3.14 public final Object getContent() throws java.io.IOException {
3.15 - throw new IOException();
3.16 -// return openConnection().getContent();
3.17 + return loadText(toExternalForm());
3.18 }
3.19 +
3.20 + @JavaScriptBody(args = "url", body = ""
3.21 + + "var request = new XMLHttpRequest();\n"
3.22 + + "request.open('GET', url, false);\n"
3.23 + + "request.send();\n"
3.24 + + "return request.responseText;\n"
3.25 + )
3.26 + private static native String loadText(String url) throws IOException;
3.27
3.28 /**
3.29 * Gets the contents of this URL. This method is a shorthand for:
3.30 @@ -984,8 +992,12 @@
3.31 */
3.32 public final Object getContent(Class[] classes)
3.33 throws java.io.IOException {
3.34 - throw new IOException();
3.35 -// return openConnection().getContent(classes);
3.36 + for (Class<?> c : classes) {
3.37 + if (c == String.class) {
3.38 + return getContent();
3.39 + }
3.40 + }
3.41 + return null;
3.42 }
3.43
3.44 static URLStreamHandler getURLStreamHandler(String protocol) {
4.1 --- a/javap/src/main/java/org/apidesign/javap/ClassData.java Mon Dec 24 07:51:15 2012 +0100
4.2 +++ b/javap/src/main/java/org/apidesign/javap/ClassData.java Mon Dec 24 07:57:33 2012 +0100
4.3 @@ -326,6 +326,10 @@
4.4 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
4.5 }
4.6 }
4.7 +
4.8 + public int getAccessFlags() {
4.9 + return access;
4.10 + }
4.11
4.12 /**
4.13 * Returns true if it is a class
5.1 --- a/javaquery/demo-calculator/nbactions.xml Mon Dec 24 07:51:15 2012 +0100
5.2 +++ b/javaquery/demo-calculator/nbactions.xml Mon Dec 24 07:57:33 2012 +0100
5.3 @@ -23,7 +23,7 @@
5.4 <actionName>run</actionName>
5.5 <goals>
5.6 <goal>process-classes</goal>
5.7 - <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
5.8 + <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
5.9 </goals>
5.10 </action>
5.11 </actions>
6.1 --- a/javaquery/demo-calculator/pom.xml Mon Dec 24 07:51:15 2012 +0100
6.2 +++ b/javaquery/demo-calculator/pom.xml Mon Dec 24 07:57:33 2012 +0100
6.3 @@ -16,34 +16,19 @@
6.4 </properties>
6.5 <build>
6.6 <plugins>
6.7 - <plugin>
6.8 - <groupId>org.apidesign.bck2brwsr</groupId>
6.9 - <artifactId>mojo</artifactId>
6.10 - <version>0.3-SNAPSHOT</version>
6.11 - <executions>
6.12 - <execution>
6.13 - <goals>
6.14 - <goal>j2js</goal>
6.15 - </goals>
6.16 - </execution>
6.17 - </executions>
6.18 - </plugin>
6.19 <plugin>
6.20 - <groupId>org.codehaus.mojo</groupId>
6.21 - <artifactId>exec-maven-plugin</artifactId>
6.22 - <version>1.2.1</version>
6.23 + <groupId>org.apidesign.bck2brwsr</groupId>
6.24 + <artifactId>mojo</artifactId>
6.25 + <version>0.3-SNAPSHOT</version>
6.26 <executions>
6.27 <execution>
6.28 <goals>
6.29 - <goal>exec</goal>
6.30 + <goal>brwsr</goal>
6.31 </goals>
6.32 </execution>
6.33 </executions>
6.34 <configuration>
6.35 - <executable>xdg-open</executable>
6.36 - <arguments>
6.37 - <argument>${project.build.directory}/classes/org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml</argument>
6.38 - </arguments>
6.39 + <startpage>org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml</startpage>
6.40 </configuration>
6.41 </plugin>
6.42 <plugin>
7.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml Mon Dec 24 07:51:15 2012 +0100
7.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml Mon Dec 24 07:57:33 2012 +0100
7.3 @@ -77,7 +77,11 @@
7.4 </tbody>
7.5 </table>
7.6
7.7 - <script src="bootjava.js"/>
7.8 + <script src="/bck2brwsr.js"></script>
7.9 + <script src="/vm.js"></script>
7.10 + <script type="text/javascript">
7.11 + vm.loadClass('org.apidesign.bck2brwsr.mavenhtml.Calculator');
7.12 + </script>
7.13
7.14 <hr/>
7.15 <pre>
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/launcher/pom.xml Mon Dec 24 07:57:33 2012 +0100
8.3 @@ -0,0 +1,49 @@
8.4 +<?xml version="1.0"?>
8.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
8.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
8.7 + <modelVersion>4.0.0</modelVersion>
8.8 + <parent>
8.9 + <groupId>org.apidesign</groupId>
8.10 + <artifactId>bck2brwsr</artifactId>
8.11 + <version>0.3-SNAPSHOT</version>
8.12 + </parent>
8.13 + <groupId>org.apidesign.bck2brwsr</groupId>
8.14 + <artifactId>launcher</artifactId>
8.15 + <version>0.3-SNAPSHOT</version>
8.16 + <name>Bck2Brwsr Launcher</name>
8.17 + <url>http://maven.apache.org</url>
8.18 + <build>
8.19 + <plugins>
8.20 + <plugin>
8.21 + <groupId>org.apache.maven.plugins</groupId>
8.22 + <artifactId>maven-compiler-plugin</artifactId>
8.23 + <version>2.3.2</version>
8.24 + <configuration>
8.25 + <source>1.7</source>
8.26 + <target>1.7</target>
8.27 + </configuration>
8.28 + </plugin>
8.29 + </plugins>
8.30 + </build>
8.31 + <properties>
8.32 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
8.33 + </properties>
8.34 + <dependencies>
8.35 + <dependency>
8.36 + <groupId>junit</groupId>
8.37 + <artifactId>junit</artifactId>
8.38 + <version>3.8.1</version>
8.39 + <scope>test</scope>
8.40 + </dependency>
8.41 + <dependency>
8.42 + <groupId>org.glassfish.grizzly</groupId>
8.43 + <artifactId>grizzly-http-server</artifactId>
8.44 + <version>2.2.19</version>
8.45 + </dependency>
8.46 + <dependency>
8.47 + <groupId>${project.groupId}</groupId>
8.48 + <artifactId>vm4brwsr</artifactId>
8.49 + <version>${project.version}</version>
8.50 + </dependency>
8.51 + </dependencies>
8.52 +</project>
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Mon Dec 24 07:57:33 2012 +0100
9.3 @@ -0,0 +1,422 @@
9.4 +/**
9.5 + * Back 2 Browser Bytecode Translator
9.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
9.7 + *
9.8 + * This program is free software: you can redistribute it and/or modify
9.9 + * it under the terms of the GNU General Public License as published by
9.10 + * the Free Software Foundation, version 2 of the License.
9.11 + *
9.12 + * This program is distributed in the hope that it will be useful,
9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.15 + * GNU General Public License for more details.
9.16 + *
9.17 + * You should have received a copy of the GNU General Public License
9.18 + * along with this program. Look for COPYING file in the top folder.
9.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
9.20 + */
9.21 +package org.apidesign.bck2brwsr.launcher;
9.22 +
9.23 +import java.io.File;
9.24 +import java.io.IOException;
9.25 +import java.io.InputStream;
9.26 +import java.io.InterruptedIOException;
9.27 +import java.io.OutputStream;
9.28 +import java.io.Writer;
9.29 +import java.net.URI;
9.30 +import java.net.URISyntaxException;
9.31 +import java.net.URL;
9.32 +import java.util.ArrayList;
9.33 +import java.util.Arrays;
9.34 +import java.util.Enumeration;
9.35 +import java.util.LinkedHashSet;
9.36 +import java.util.List;
9.37 +import java.util.Set;
9.38 +import java.util.concurrent.BlockingQueue;
9.39 +import java.util.concurrent.CountDownLatch;
9.40 +import java.util.concurrent.LinkedBlockingQueue;
9.41 +import java.util.concurrent.TimeUnit;
9.42 +import java.util.logging.Level;
9.43 +import java.util.logging.Logger;
9.44 +import org.apidesign.vm4brwsr.Bck2Brwsr;
9.45 +import org.glassfish.grizzly.PortRange;
9.46 +import org.glassfish.grizzly.http.server.HttpHandler;
9.47 +import org.glassfish.grizzly.http.server.HttpServer;
9.48 +import org.glassfish.grizzly.http.server.NetworkListener;
9.49 +import org.glassfish.grizzly.http.server.Request;
9.50 +import org.glassfish.grizzly.http.server.Response;
9.51 +import org.glassfish.grizzly.http.server.ServerConfiguration;
9.52 +
9.53 +/**
9.54 + * Lightweight server to launch Bck2Brwsr applications and tests.
9.55 + * Supports execution in native browser as well as Java's internal
9.56 + * execution engine.
9.57 + */
9.58 +public class Bck2BrwsrLauncher {
9.59 + private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
9.60 + private static final MethodInvocation END = new MethodInvocation(null, null);
9.61 + private Set<ClassLoader> loaders = new LinkedHashSet<>();
9.62 + private BlockingQueue<MethodInvocation> methods = new LinkedBlockingQueue<>();
9.63 + private long timeOut;
9.64 + private final Res resources = new Res();
9.65 + private Object[] brwsr;
9.66 + private HttpServer server;
9.67 + private CountDownLatch wait;
9.68 +
9.69 +
9.70 + public MethodInvocation addMethod(Class<?> clazz, String method) throws IOException {
9.71 + loaders.add(clazz.getClassLoader());
9.72 + MethodInvocation c = new MethodInvocation(clazz.getName(), method);
9.73 + methods.add(c);
9.74 + try {
9.75 + c.await(timeOut);
9.76 + } catch (InterruptedException ex) {
9.77 + throw new IOException(ex);
9.78 + }
9.79 + return c;
9.80 + }
9.81 +
9.82 + public void setTimeout(long ms) {
9.83 + timeOut = ms;
9.84 + }
9.85 +
9.86 + public void addClassLoader(ClassLoader url) {
9.87 + this.loaders.add(url);
9.88 + }
9.89 +
9.90 + public static void main( String[] args ) throws Exception {
9.91 + Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
9.92 + l.addClassLoader(Bck2BrwsrLauncher.class.getClassLoader());
9.93 + l.showURL("org/apidesign/bck2brwsr/launcher/console.xhtml");
9.94 + System.in.read();
9.95 + }
9.96 +
9.97 + public void showURL(String startpage) throws URISyntaxException, InterruptedException, IOException {
9.98 + if (!startpage.startsWith("/")) {
9.99 + startpage = "/" + startpage;
9.100 + }
9.101 + HttpServer s = initServer();
9.102 + s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
9.103 + launchServerAndBrwsr(s, startpage);
9.104 + }
9.105 +
9.106 + public void initialize() throws IOException {
9.107 + try {
9.108 + executeInBrowser();
9.109 + } catch (InterruptedException ex) {
9.110 + final InterruptedIOException iio = new InterruptedIOException(ex.getMessage());
9.111 + iio.initCause(ex);
9.112 + throw iio;
9.113 + } catch (Exception ex) {
9.114 + if (ex instanceof IOException) {
9.115 + throw (IOException)ex;
9.116 + }
9.117 + if (ex instanceof RuntimeException) {
9.118 + throw (RuntimeException)ex;
9.119 + }
9.120 + throw new IOException(ex);
9.121 + }
9.122 + }
9.123 +
9.124 + private HttpServer initServer() {
9.125 + HttpServer s = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
9.126 +
9.127 + final ServerConfiguration conf = s.getServerConfiguration();
9.128 + conf.addHttpHandler(new Page(resources,
9.129 + "org/apidesign/bck2brwsr/launcher/console.xhtml",
9.130 + "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
9.131 + ), "/console");
9.132 + conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
9.133 + conf.addHttpHandler(new VMInit(), "/vm.js");
9.134 + conf.addHttpHandler(new Classes(resources), "/classes/");
9.135 + return s;
9.136 + }
9.137 +
9.138 + private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
9.139 + wait = new CountDownLatch(1);
9.140 + server = initServer();
9.141 + ServerConfiguration conf = server.getServerConfiguration();
9.142 + conf.addHttpHandler(new Page(resources,
9.143 + "org/apidesign/bck2brwsr/launcher/harness.xhtml"
9.144 + ), "/execute");
9.145 + conf.addHttpHandler(new HttpHandler() {
9.146 + int cnt;
9.147 + List<MethodInvocation> cases = new ArrayList<>();
9.148 + @Override
9.149 + public void service(Request request, Response response) throws Exception {
9.150 + String id = request.getParameter("request");
9.151 + String value = request.getParameter("result");
9.152 +
9.153 + if (id != null && value != null) {
9.154 + LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
9.155 + value = value.replace("%20", " ");
9.156 + cases.get(Integer.parseInt(id)).result(value, null);
9.157 + }
9.158 +
9.159 + MethodInvocation mi = methods.take();
9.160 + if (mi == END) {
9.161 + response.getWriter().write("");
9.162 + wait.countDown();
9.163 + cnt = 0;
9.164 + LOG.log(Level.INFO, "End of data reached. Exiting.");
9.165 + return;
9.166 + }
9.167 +
9.168 + cases.add(mi);
9.169 + final String cn = mi.className;
9.170 + final String mn = mi.methodName;
9.171 + LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{cnt, cn, mn});
9.172 + response.getWriter().write("{"
9.173 + + "className: '" + cn + "', "
9.174 + + "methodName: '" + mn + "', "
9.175 + + "request: " + cnt
9.176 + + "}");
9.177 + cnt++;
9.178 + }
9.179 + }, "/data");
9.180 +
9.181 + this.brwsr = launchServerAndBrwsr(server, "/execute");
9.182 + }
9.183 +
9.184 + public void shutdown() throws InterruptedException, IOException {
9.185 + methods.offer(END);
9.186 + for (;;) {
9.187 + int prev = methods.size();
9.188 + if (wait.await(timeOut, TimeUnit.MILLISECONDS)) {
9.189 + break;
9.190 + }
9.191 + if (prev == methods.size()) {
9.192 + LOG.log(
9.193 + Level.WARNING,
9.194 + "Timeout and no test has been executed meanwhile (at {0}). Giving up.",
9.195 + methods.size()
9.196 + );
9.197 + break;
9.198 + }
9.199 + LOG.log(Level.INFO,
9.200 + "Timeout, but tests got from {0} to {1}. Trying again.",
9.201 + new Object[]{prev, methods.size()}
9.202 + );
9.203 + }
9.204 + stopServerAndBrwsr(server, brwsr);
9.205 + }
9.206 +
9.207 + static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
9.208 + for (;;) {
9.209 + int ch = is.read();
9.210 + if (ch == -1) {
9.211 + break;
9.212 + }
9.213 + if (ch == '$') {
9.214 + int cnt = is.read() - '0';
9.215 + if (cnt == 'U' - '0') {
9.216 + os.write(baseURL.getBytes());
9.217 + }
9.218 + if (cnt < params.length) {
9.219 + os.write(params[cnt].getBytes());
9.220 + }
9.221 + } else {
9.222 + os.write(ch);
9.223 + }
9.224 + }
9.225 + }
9.226 +
9.227 + private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
9.228 + server.start();
9.229 + NetworkListener listener = server.getListeners().iterator().next();
9.230 + int port = listener.getPort();
9.231 +
9.232 + URI uri = new URI("http://localhost:" + port + page);
9.233 + LOG.log(Level.INFO, "Showing {0}", uri);
9.234 +// try {
9.235 +// Desktop.getDesktop().browse(uri);
9.236 +// return null;
9.237 +// } catch (UnsupportedOperationException ex)
9.238 + {
9.239 +// File dir = File.createTempFile("chrome", ".dir");
9.240 +// dir.delete();
9.241 +// dir.mkdirs();
9.242 +// String[] cmd = {
9.243 +// "google-chrome", "--user-data-dir=" + dir, "--app=" + uri.toString()
9.244 +// };
9.245 +// LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmd));
9.246 +// final Process process = Runtime.getRuntime().exec(cmd);
9.247 +// return new Object[] { process, dir };
9.248 + }
9.249 + {
9.250 + String[] cmd = {
9.251 + "xdg-open", uri.toString()
9.252 + };
9.253 + LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmd));
9.254 + final Process process = Runtime.getRuntime().exec(cmd);
9.255 + return new Object[] { process, null };
9.256 + }
9.257 + }
9.258 +
9.259 + private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException, InterruptedException {
9.260 + Process process = (Process)brwsr[0];
9.261 +
9.262 + server.stop();
9.263 + InputStream stdout = process.getInputStream();
9.264 + InputStream stderr = process.getErrorStream();
9.265 + drain("StdOut", stdout);
9.266 + drain("StdErr", stderr);
9.267 + process.destroy();
9.268 + int res = process.waitFor();
9.269 + LOG.log(Level.INFO, "Exit code: {0}", res);
9.270 +
9.271 + deleteTree((File)brwsr[1]);
9.272 + }
9.273 +
9.274 + private static void drain(String name, InputStream is) throws IOException {
9.275 + int av = is.available();
9.276 + if (av > 0) {
9.277 + StringBuilder sb = new StringBuilder();
9.278 + sb.append("v== ").append(name).append(" ==v\n");
9.279 + while (av-- > 0) {
9.280 + sb.append((char)is.read());
9.281 + }
9.282 + sb.append("\n^== ").append(name).append(" ==^");
9.283 + LOG.log(Level.INFO, sb.toString());
9.284 + }
9.285 + }
9.286 +
9.287 + private void deleteTree(File file) {
9.288 + if (file == null) {
9.289 + return;
9.290 + }
9.291 + File[] arr = file.listFiles();
9.292 + if (arr != null) {
9.293 + for (File s : arr) {
9.294 + deleteTree(s);
9.295 + }
9.296 + }
9.297 + file.delete();
9.298 + }
9.299 +
9.300 + private class Res implements Bck2Brwsr.Resources {
9.301 + @Override
9.302 + public InputStream get(String resource) throws IOException {
9.303 + for (ClassLoader l : loaders) {
9.304 + URL u = null;
9.305 + Enumeration<URL> en = l.getResources(resource);
9.306 + while (en.hasMoreElements()) {
9.307 + u = en.nextElement();
9.308 + }
9.309 + if (u != null) {
9.310 + return u.openStream();
9.311 + }
9.312 + }
9.313 + throw new IOException("Can't find " + resource);
9.314 + }
9.315 + }
9.316 +
9.317 + private static class Page extends HttpHandler {
9.318 + private final String resource;
9.319 + private final String[] args;
9.320 + private final Res res;
9.321 +
9.322 + public Page(Res res, String resource, String... args) {
9.323 + this.res = res;
9.324 + this.resource = resource;
9.325 + this.args = args;
9.326 + }
9.327 +
9.328 + @Override
9.329 + public void service(Request request, Response response) throws Exception {
9.330 + String r = resource;
9.331 + if (r == null) {
9.332 + r = request.getHttpHandlerPath();
9.333 + if (r.startsWith("/")) {
9.334 + r = r.substring(1);
9.335 + }
9.336 + }
9.337 + if (r.endsWith(".html") || r.endsWith(".xhtml")) {
9.338 + response.setContentType("text/html");
9.339 + }
9.340 + OutputStream os = response.getOutputStream();
9.341 + try (InputStream is = res.get(r)) {
9.342 + copyStream(is, os, request.getRequestURL().toString(), args);
9.343 + } catch (IOException ex) {
9.344 + response.setDetailMessage(ex.getLocalizedMessage());
9.345 + response.setError();
9.346 + response.setStatus(404);
9.347 + }
9.348 + }
9.349 + }
9.350 +
9.351 + private static class VM extends HttpHandler {
9.352 + private final Res loader;
9.353 +
9.354 + public VM(Res loader) {
9.355 + this.loader = loader;
9.356 + }
9.357 +
9.358 + @Override
9.359 + public void service(Request request, Response response) throws Exception {
9.360 + response.setCharacterEncoding("UTF-8");
9.361 + response.setContentType("text/javascript");
9.362 + Bck2Brwsr.generate(response.getWriter(), loader);
9.363 + }
9.364 + }
9.365 + private static class VMInit extends HttpHandler {
9.366 + public VMInit() {
9.367 + }
9.368 +
9.369 + @Override
9.370 + public void service(Request request, Response response) throws Exception {
9.371 + response.setCharacterEncoding("UTF-8");
9.372 + response.setContentType("text/javascript");
9.373 + response.getWriter().append(
9.374 + "function ldCls(res) {\n"
9.375 + + " var request = new XMLHttpRequest();\n"
9.376 + + " request.open('GET', '/classes/' + res, false);\n"
9.377 + + " request.send();\n"
9.378 + + " var arr = eval('(' + request.responseText + ')');\n"
9.379 + + " return arr;\n"
9.380 + + "}\n"
9.381 + + "var vm = new bck2brwsr(ldCls);\n");
9.382 + }
9.383 + }
9.384 +
9.385 + private static class Classes extends HttpHandler {
9.386 + private final Res loader;
9.387 +
9.388 + public Classes(Res loader) {
9.389 + this.loader = loader;
9.390 + }
9.391 +
9.392 + @Override
9.393 + public void service(Request request, Response response) throws Exception {
9.394 + String res = request.getHttpHandlerPath();
9.395 + if (res.startsWith("/")) {
9.396 + res = res.substring(1);
9.397 + }
9.398 + try (InputStream is = loader.get(res)) {
9.399 + response.setContentType("text/javascript");
9.400 + Writer w = response.getWriter();
9.401 + w.append("[");
9.402 + for (int i = 0;; i++) {
9.403 + int b = is.read();
9.404 + if (b == -1) {
9.405 + break;
9.406 + }
9.407 + if (i > 0) {
9.408 + w.append(", ");
9.409 + }
9.410 + if (i % 20 == 0) {
9.411 + w.write("\n");
9.412 + }
9.413 + if (b > 127) {
9.414 + b = b - 256;
9.415 + }
9.416 + w.append(Integer.toString(b));
9.417 + }
9.418 + w.append("\n]");
9.419 + } catch (IOException ex) {
9.420 + response.setError();
9.421 + response.setDetailMessage(ex.getMessage());
9.422 + }
9.423 + }
9.424 + }
9.425 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java Mon Dec 24 07:57:33 2012 +0100
10.3 @@ -0,0 +1,178 @@
10.4 +/**
10.5 + * Back 2 Browser Bytecode Translator
10.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
10.7 + *
10.8 + * This program is free software: you can redistribute it and/or modify
10.9 + * it under the terms of the GNU General Public License as published by
10.10 + * the Free Software Foundation, version 2 of the License.
10.11 + *
10.12 + * This program is distributed in the hope that it will be useful,
10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.15 + * GNU General Public License for more details.
10.16 + *
10.17 + * You should have received a copy of the GNU General Public License
10.18 + * along with this program. Look for COPYING file in the top folder.
10.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
10.20 + */
10.21 +package org.apidesign.bck2brwsr.launcher;
10.22 +
10.23 +import java.io.IOException;
10.24 +import java.io.InputStream;
10.25 +import java.lang.reflect.InvocationTargetException;
10.26 +import java.lang.reflect.Method;
10.27 +import java.net.URL;
10.28 +import java.util.Enumeration;
10.29 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
10.30 +
10.31 +/**
10.32 + *
10.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
10.34 + */
10.35 +public class Console {
10.36 + public static String welcome() {
10.37 + return "HellofromBck2Brwsr";
10.38 + }
10.39 + public static String multiply() {
10.40 + return String.valueOf(Integer.MAX_VALUE / 2 + Integer.MAX_VALUE);
10.41 + }
10.42 +
10.43 + @JavaScriptBody(args = {"id", "attr"}, body =
10.44 + "return window.document.getElementById(id)[attr].toString();")
10.45 + private static native Object getAttr(String id, String attr);
10.46 +
10.47 + @JavaScriptBody(args = {"id", "attr", "value"}, body =
10.48 + "window.document.getElementById(id)[attr] = value;")
10.49 + private static native void setAttr(String id, String attr, Object value);
10.50 +
10.51 + @JavaScriptBody(args = {}, body = "window.close();")
10.52 + private static native void closeWindow();
10.53 +
10.54 + private static void log(String newText) {
10.55 + String id = "result";
10.56 + String attr = "value";
10.57 + setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
10.58 + setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
10.59 + }
10.60 +
10.61 + public static void execute() throws Exception {
10.62 + String clazz = (String) getAttr("clazz", "value");
10.63 + String method = (String) getAttr("method", "value");
10.64 + Object res = invokeMethod(clazz, method);
10.65 + setAttr("result", "value", res);
10.66 + }
10.67 +
10.68 + public static void harness(String url) {
10.69 + log("Connecting to " + url);
10.70 + try {
10.71 + URL u = new URL(url);
10.72 + for (;;) {
10.73 + String data = (String) u.getContent(new Class[] { String.class });
10.74 + log("\nGot \"" + data + "\"");
10.75 + if (data.isEmpty()) {
10.76 + log("No data, exiting");
10.77 + closeWindow();
10.78 + break;
10.79 + }
10.80 +
10.81 + Case c = Case.parseData(data);
10.82 + log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
10.83 +
10.84 + Object result = invokeMethod(c.getClassName(), c.getMethodName());
10.85 +
10.86 + log("Result: " + result);
10.87 + log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
10.88 + u = new URL(url + "?request=" + c.getRequestId() + "&result=" + result);
10.89 + }
10.90 +
10.91 +
10.92 + } catch (Exception ex) {
10.93 + log(ex.getMessage());
10.94 + }
10.95 + }
10.96 +
10.97 + static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {
10.98 + final Object r = invokeMethod(clazz, method);
10.99 + return r == null ? "null" : r.toString().toString();
10.100 + }
10.101 +
10.102 + /** Helper method that inspects the classpath and loads given resource
10.103 + * (usually a class file). Used while running tests in Rhino.
10.104 + *
10.105 + * @param name resource name to find
10.106 + * @return the array of bytes in the given resource
10.107 + * @throws IOException I/O in case something goes wrong
10.108 + */
10.109 + public static byte[] read(String name) throws IOException {
10.110 + URL u = null;
10.111 + Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
10.112 + while (en.hasMoreElements()) {
10.113 + u = en.nextElement();
10.114 + }
10.115 + if (u == null) {
10.116 + throw new IOException("Can't find " + name);
10.117 + }
10.118 + try (InputStream is = u.openStream()) {
10.119 + byte[] arr;
10.120 + arr = new byte[is.available()];
10.121 + int offset = 0;
10.122 + while (offset < arr.length) {
10.123 + int len = is.read(arr, offset, arr.length - offset);
10.124 + if (len == -1) {
10.125 + throw new IOException("Can't read " + name);
10.126 + }
10.127 + offset += len;
10.128 + }
10.129 + return arr;
10.130 + }
10.131 + }
10.132 +
10.133 + private static Object invokeMethod(String clazz, String method)
10.134 + throws ClassNotFoundException, InvocationTargetException,
10.135 + SecurityException, IllegalAccessException, IllegalArgumentException {
10.136 + Method found = null;
10.137 + Class<?> c = Class.forName(clazz);
10.138 + for (Method m : c.getMethods()) {
10.139 + if (m.getName().equals(method)) {
10.140 + found = m;
10.141 + }
10.142 + }
10.143 + Object res;
10.144 + if (found != null) {
10.145 + res = found.invoke(null);
10.146 + } else {
10.147 + res = "Can't find method " + method + " in " + clazz;
10.148 + }
10.149 + return res;
10.150 + }
10.151 +
10.152 + private static final class Case {
10.153 + private final Object data;
10.154 +
10.155 + private Case(Object data) {
10.156 + this.data = data;
10.157 + }
10.158 +
10.159 + public static Case parseData(String s) {
10.160 + return new Case(toJSON(s));
10.161 + }
10.162 +
10.163 + public String getMethodName() {
10.164 + return value("methodName", data);
10.165 + }
10.166 +
10.167 + public String getClassName() {
10.168 + return value("className", data);
10.169 + }
10.170 +
10.171 + public String getRequestId() {
10.172 + return value("request", data);
10.173 + }
10.174 +
10.175 + @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
10.176 + private static native Object toJSON(String s);
10.177 +
10.178 + @JavaScriptBody(args = {"p", "d"}, body = "return d[p].toString();")
10.179 + private static native String value(String p, Object d);
10.180 + }
10.181 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java Mon Dec 24 07:57:33 2012 +0100
11.3 @@ -0,0 +1,114 @@
11.4 +/**
11.5 + * Back 2 Browser Bytecode Translator
11.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
11.7 + *
11.8 + * This program is free software: you can redistribute it and/or modify
11.9 + * it under the terms of the GNU General Public License as published by
11.10 + * the Free Software Foundation, version 2 of the License.
11.11 + *
11.12 + * This program is distributed in the hope that it will be useful,
11.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.15 + * GNU General Public License for more details.
11.16 + *
11.17 + * You should have received a copy of the GNU General Public License
11.18 + * along with this program. Look for COPYING file in the top folder.
11.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
11.20 + */
11.21 +package org.apidesign.bck2brwsr.launcher;
11.22 +
11.23 +import java.io.IOException;
11.24 +import java.io.InputStream;
11.25 +import java.net.URL;
11.26 +import java.util.Enumeration;
11.27 +import java.util.LinkedHashSet;
11.28 +import java.util.Set;
11.29 +import java.util.logging.Logger;
11.30 +import javax.script.Invocable;
11.31 +import javax.script.ScriptEngine;
11.32 +import javax.script.ScriptEngineManager;
11.33 +import javax.script.ScriptException;
11.34 +import org.apidesign.vm4brwsr.Bck2Brwsr;
11.35 +
11.36 +/**
11.37 + * Tests execution in Java's internal scripting engine.
11.38 + */
11.39 +public final class JSLauncher {
11.40 + private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
11.41 + private Set<ClassLoader> loaders = new LinkedHashSet<>();
11.42 + private final Res resources = new Res();
11.43 + private Invocable code;
11.44 + private Object console;
11.45 +
11.46 +
11.47 + public MethodInvocation addMethod(Class<?> clazz, String method) {
11.48 + loaders.add(clazz.getClassLoader());
11.49 + MethodInvocation mi = new MethodInvocation(clazz.getName(), method);
11.50 + try {
11.51 + mi.result(code.invokeMethod(
11.52 + console,
11.53 + "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
11.54 + mi.className, mi.methodName).toString(), null);
11.55 + } catch (ScriptException | NoSuchMethodException ex) {
11.56 + mi.result(null, ex);
11.57 + }
11.58 + return mi;
11.59 + }
11.60 +
11.61 + public void addClassLoader(ClassLoader url) {
11.62 + this.loaders.add(url);
11.63 + }
11.64 +
11.65 + public void initialize() throws IOException {
11.66 + try {
11.67 + initRhino();
11.68 + } catch (Exception ex) {
11.69 + if (ex instanceof IOException) {
11.70 + throw (IOException)ex;
11.71 + }
11.72 + if (ex instanceof RuntimeException) {
11.73 + throw (RuntimeException)ex;
11.74 + }
11.75 + throw new IOException(ex);
11.76 + }
11.77 + }
11.78 +
11.79 + private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
11.80 + StringBuilder sb = new StringBuilder();
11.81 + Bck2Brwsr.generate(sb, new Res());
11.82 +
11.83 + ScriptEngineManager sem = new ScriptEngineManager();
11.84 + ScriptEngine mach = sem.getEngineByExtension("js");
11.85 +
11.86 + sb.append(
11.87 + "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.Console.read);"
11.88 + + "\nfunction initVM() { return vm; };"
11.89 + + "\n");
11.90 +
11.91 + Object res = mach.eval(sb.toString());
11.92 + if (!(mach instanceof Invocable)) {
11.93 + throw new IOException("It is invocable object: " + res);
11.94 + }
11.95 + code = (Invocable) mach;
11.96 +
11.97 + Object vm = code.invokeFunction("initVM");
11.98 + console = code.invokeMethod(vm, "loadClass", Console.class.getName());
11.99 + }
11.100 +
11.101 + private class Res implements Bck2Brwsr.Resources {
11.102 + @Override
11.103 + public InputStream get(String resource) throws IOException {
11.104 + for (ClassLoader l : loaders) {
11.105 + URL u = null;
11.106 + Enumeration<URL> en = l.getResources(resource);
11.107 + while (en.hasMoreElements()) {
11.108 + u = en.nextElement();
11.109 + }
11.110 + if (u != null) {
11.111 + return u.openStream();
11.112 + }
11.113 + }
11.114 + throw new IOException("Can't find " + resource);
11.115 + }
11.116 + }
11.117 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java Mon Dec 24 07:57:33 2012 +0100
12.3 @@ -0,0 +1,57 @@
12.4 +/**
12.5 + * Back 2 Browser Bytecode Translator
12.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
12.7 + *
12.8 + * This program is free software: you can redistribute it and/or modify
12.9 + * it under the terms of the GNU General Public License as published by
12.10 + * the Free Software Foundation, version 2 of the License.
12.11 + *
12.12 + * This program is distributed in the hope that it will be useful,
12.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.15 + * GNU General Public License for more details.
12.16 + *
12.17 + * You should have received a copy of the GNU General Public License
12.18 + * along with this program. Look for COPYING file in the top folder.
12.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
12.20 + */
12.21 +package org.apidesign.bck2brwsr.launcher;
12.22 +
12.23 +import java.util.concurrent.CountDownLatch;
12.24 +import java.util.concurrent.TimeUnit;
12.25 +
12.26 +/**
12.27 + *
12.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
12.29 + */
12.30 +public final class MethodInvocation {
12.31 + final CountDownLatch wait = new CountDownLatch(1);
12.32 + final String className;
12.33 + final String methodName;
12.34 + private String result;
12.35 + private Exception exception;
12.36 +
12.37 + MethodInvocation(String className, String methodName) {
12.38 + this.className = className;
12.39 + this.methodName = methodName;
12.40 + }
12.41 +
12.42 + void await(long timeOut) throws InterruptedException {
12.43 + wait.await(timeOut, TimeUnit.MILLISECONDS);
12.44 + }
12.45 +
12.46 + void result(String r, Exception e) {
12.47 + this.result = r;
12.48 + this.exception = e;
12.49 + wait.countDown();
12.50 + }
12.51 +
12.52 + @Override
12.53 + public String toString() {
12.54 + if (exception != null) {
12.55 + return exception.toString();
12.56 + }
12.57 + return result;
12.58 + }
12.59 +
12.60 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/console.xhtml Mon Dec 24 07:57:33 2012 +0100
13.3 @@ -0,0 +1,52 @@
13.4 +<?xml version="1.0" encoding="UTF-8"?>
13.5 +<!--
13.6 +
13.7 + Back 2 Browser Bytecode Translator
13.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
13.9 +
13.10 + This program is free software: you can redistribute it and/or modify
13.11 + it under the terms of the GNU General Public License as published by
13.12 + the Free Software Foundation, version 2 of the License.
13.13 +
13.14 + This program is distributed in the hope that it will be useful,
13.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
13.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.17 + GNU General Public License for more details.
13.18 +
13.19 + You should have received a copy of the GNU General Public License
13.20 + along with this program. Look for COPYING file in the top folder.
13.21 + If not, see http://opensource.org/licenses/GPL-2.0.
13.22 +
13.23 +-->
13.24 +<!DOCTYPE html>
13.25 +<html xmlns="http://www.w3.org/1999/xhtml">
13.26 + <head>
13.27 + <title>Bck2Brwsr Launcher</title>
13.28 + </head>
13.29 + <body>
13.30 + <script src="/bck2brwsr.js"></script>
13.31 + <script src="/vm.js"></script>
13.32 +
13.33 + <h1>Bck2Browser Console Launcher</h1>
13.34 +
13.35 + Class Name:
13.36 + <input id="clazz" value="$0"/>
13.37 + <br/>
13.38 + Method Name:
13.39 +
13.40 + <input id="method" value="$1"/>
13.41 + <br/>
13.42 +
13.43 + <button onclick="vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').execute__V();">Execute!</button>
13.44 +
13.45 + <hr/>
13.46 + <textarea id="result" rows="10" cols="80" disabled="">
13.47 + </textarea>
13.48 +
13.49 + <script type="text/javascript">
13.50 + if ($2) {
13.51 + vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').execute__V();
13.52 + }
13.53 + </script>
13.54 + </body>
13.55 +</html>
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Mon Dec 24 07:57:33 2012 +0100
14.3 @@ -0,0 +1,39 @@
14.4 +<?xml version="1.0" encoding="UTF-8"?>
14.5 +<!--
14.6 +
14.7 + Back 2 Browser Bytecode Translator
14.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
14.9 +
14.10 + This program is free software: you can redistribute it and/or modify
14.11 + it under the terms of the GNU General Public License as published by
14.12 + the Free Software Foundation, version 2 of the License.
14.13 +
14.14 + This program is distributed in the hope that it will be useful,
14.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
14.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.17 + GNU General Public License for more details.
14.18 +
14.19 + You should have received a copy of the GNU General Public License
14.20 + along with this program. Look for COPYING file in the top folder.
14.21 + If not, see http://opensource.org/licenses/GPL-2.0.
14.22 +
14.23 +-->
14.24 +<!DOCTYPE html>
14.25 +<html xmlns="http://www.w3.org/1999/xhtml">
14.26 + <head>
14.27 + <title>Bck2Brwsr Harness</title>
14.28 + </head>
14.29 + <body>
14.30 + <script src="/bck2brwsr.js"></script>
14.31 + <script src="/vm.js"></script>
14.32 +
14.33 + <h1>Bck2Browser Execution Harness</h1>
14.34 +
14.35 + <textarea id="result" rows="25" style="width: 100%;" disabled="">
14.36 + </textarea>
14.37 +
14.38 + <script type="text/javascript">
14.39 + vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__VLjava_lang_String_2('$U/../data');
14.40 + </script>
14.41 + </body>
14.42 +</html>
15.1 --- a/mojo/pom.xml Mon Dec 24 07:51:15 2012 +0100
15.2 +++ b/mojo/pom.xml Mon Dec 24 07:57:33 2012 +0100
15.3 @@ -77,5 +77,10 @@
15.4 <version>3.0.2</version>
15.5 <type>jar</type>
15.6 </dependency>
15.7 + <dependency>
15.8 + <groupId>${project.groupId}</groupId>
15.9 + <artifactId>launcher</artifactId>
15.10 + <version>${project.version}</version>
15.11 + </dependency>
15.12 </dependencies>
15.13 </project>
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java Mon Dec 24 07:57:33 2012 +0100
16.3 @@ -0,0 +1,118 @@
16.4 +/**
16.5 + * Back 2 Browser Bytecode Translator
16.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
16.7 + *
16.8 + * This program is free software: you can redistribute it and/or modify
16.9 + * it under the terms of the GNU General Public License as published by
16.10 + * the Free Software Foundation, version 2 of the License.
16.11 + *
16.12 + * This program is distributed in the hope that it will be useful,
16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.15 + * GNU General Public License for more details.
16.16 + *
16.17 + * You should have received a copy of the GNU General Public License
16.18 + * along with this program. Look for COPYING file in the top folder.
16.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
16.20 + */
16.21 +package org.apidesign.bck2brwsr.mojo;
16.22 +
16.23 +import org.apache.maven.plugin.AbstractMojo;
16.24 +
16.25 +import java.io.File;
16.26 +import java.io.IOException;
16.27 +import java.net.MalformedURLException;
16.28 +import java.net.URISyntaxException;
16.29 +import java.net.URL;
16.30 +import java.net.URLClassLoader;
16.31 +import java.util.ArrayList;
16.32 +import java.util.Collection;
16.33 +import java.util.List;
16.34 +import java.util.logging.Level;
16.35 +import java.util.logging.Logger;
16.36 +import org.apache.maven.artifact.Artifact;
16.37 +import org.apache.maven.plugin.MojoExecutionException;
16.38 +import org.apache.maven.plugins.annotations.LifecyclePhase;
16.39 +import org.apache.maven.plugins.annotations.Mojo;
16.40 +import org.apache.maven.plugins.annotations.Parameter;
16.41 +import org.apache.maven.project.MavenProject;
16.42 +import org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher;
16.43 +
16.44 +/** Executes given HTML page in a browser. */
16.45 +@Mojo(name="brwsr", defaultPhase=LifecyclePhase.DEPLOY)
16.46 +public class BrswrMojo extends AbstractMojo {
16.47 + public BrswrMojo() {
16.48 + }
16.49 + /** Resource to show as initial page */
16.50 + @Parameter
16.51 + private String startpage;
16.52 +
16.53 + @Parameter(defaultValue="${project}")
16.54 + private MavenProject prj;
16.55 +
16.56 + /** Root of the class files */
16.57 + @Parameter(defaultValue="${project.build.directory}/classes")
16.58 + private File classes;
16.59 +
16.60 + @Override
16.61 + public void execute() throws MojoExecutionException {
16.62 + if (startpage == null) {
16.63 + throw new MojoExecutionException("You have to provide a start page");
16.64 + }
16.65 +
16.66 + try {
16.67 + URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
16.68 +
16.69 + Bck2BrwsrLauncher httpServer = new Bck2BrwsrLauncher();
16.70 + httpServer.addClassLoader(url);
16.71 + try {
16.72 + httpServer.showURL(startpage);
16.73 + } catch (Exception ex) {
16.74 + throw new MojoExecutionException("Can't open " + startpage, ex);
16.75 + }
16.76 +
16.77 + System.in.read();
16.78 + } catch (IOException ex) {
16.79 + throw new MojoExecutionException("Can't show the browser", ex);
16.80 + }
16.81 + }
16.82 +
16.83 + private static File findNonEmptyFolder(File dir) throws MojoExecutionException {
16.84 + if (!dir.isDirectory()) {
16.85 + throw new MojoExecutionException("Not a directory " + dir);
16.86 + }
16.87 + File[] arr = dir.listFiles();
16.88 + if (arr.length == 1 && arr[0].isDirectory()) {
16.89 + return findNonEmptyFolder(arr[0]);
16.90 + }
16.91 + return dir;
16.92 + }
16.93 +
16.94 + private static long collectAllClasses(String prefix, File toCheck, List<String> arr) {
16.95 + File[] files = toCheck.listFiles();
16.96 + if (files != null) {
16.97 + long newest = 0L;
16.98 + for (File f : files) {
16.99 + long lastModified = collectAllClasses(prefix + f.getName() + "/", f, arr);
16.100 + if (newest < lastModified) {
16.101 + newest = lastModified;
16.102 + }
16.103 + }
16.104 + return newest;
16.105 + } else if (toCheck.getName().endsWith(".class")) {
16.106 + arr.add(prefix.substring(0, prefix.length() - 7));
16.107 + return toCheck.lastModified();
16.108 + } else {
16.109 + return 0L;
16.110 + }
16.111 + }
16.112 +
16.113 + private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
16.114 + List<URL> arr = new ArrayList<URL>();
16.115 + arr.add(root.toURI().toURL());
16.116 + for (Artifact a : deps) {
16.117 + arr.add(a.getFile().toURI().toURL());
16.118 + }
16.119 + return new URLClassLoader(arr.toArray(new URL[0]), BrswrMojo.class.getClassLoader());
16.120 + }
16.121 +}
17.1 --- a/pom.xml Mon Dec 24 07:51:15 2012 +0100
17.2 +++ b/pom.xml Mon Dec 24 07:57:33 2012 +0100
17.3 @@ -14,6 +14,8 @@
17.4 <module>javaquery</module>
17.5 <module>javap</module>
17.6 <module>benchmarks</module>
17.7 + <module>launcher</module>
17.8 + <module>vmtest</module>
17.9 </modules>
17.10 <licenses>
17.11 <license>
17.12 @@ -108,4 +110,4 @@
17.13 <properties>
17.14 <license>COPYING</license>
17.15 </properties>
17.16 -</project>
17.17 +</project>
17.18 \ No newline at end of file
18.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Dec 24 07:51:15 2012 +0100
18.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Dec 24 07:57:33 2012 +0100
18.3 @@ -155,6 +155,7 @@
18.4 out.append(accessClass("java_lang_Class(true);"));
18.5 out.append("\n CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
18.6 out.append("\n CLS.$class.superclass = sprcls;");
18.7 + out.append("\n CLS.$class.access = ").append(jc.getAccessFlags()+";");
18.8 out.append("\n CLS.$class.cnstr = CLS;");
18.9 byte[] classAnno = jc.findAnnotationData(false);
18.10 if (classAnno != null) {
18.11 @@ -1028,7 +1029,7 @@
18.12 int indx = readIntArg(byteCodes, i);
18.13 String[] fi = jc.getFieldInfoName(indx);
18.14 final int type = VarType.fromFieldType(fi[2].charAt(0));
18.15 - emit(out, "@1 = @2.@3;",
18.16 + emit(out, "@1 = @2(false).constructor.@3;",
18.17 smapper.pushT(type),
18.18 accessClass(fi[0].replace('/', '_')), fi[1]);
18.19 i += 2;
18.20 @@ -1048,7 +1049,7 @@
18.21 int indx = readIntArg(byteCodes, i);
18.22 String[] fi = jc.getFieldInfoName(indx);
18.23 final int type = VarType.fromFieldType(fi[2].charAt(0));
18.24 - emit(out, "@1.@2 = @3;",
18.25 + emit(out, "@1(false).constructor.@2 = @3;",
18.26 accessClass(fi[0].replace('/', '_')), fi[1],
18.27 smapper.popT(type));
18.28 i += 2;
19.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Mon Dec 24 07:51:15 2012 +0100
19.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Mon Dec 24 07:57:33 2012 +0100
19.3 @@ -61,10 +61,27 @@
19.4 StringBuilder out = new StringBuilder();
19.5 out.append("var loader = arguments[0];\n");
19.6 out.append("var vm = loader.vm;\n");
19.7 - new Gen(this, out).compile(new ByteArrayInputStream(arr));
19.8 + int prelude = out.length();
19.9 + String initCode = new Gen(this, out).compile(new ByteArrayInputStream(arr));
19.10 String code = out.toString().toString();
19.11 +// dump("Loading " + name);
19.12 + dump(code);
19.13 String under = name.replace('.', '_');
19.14 - return applyCode(loader, under, code, instance);
19.15 + Object fn = applyCode(loader, under, code, instance);
19.16 +
19.17 + if (!initCode.isEmpty()) {
19.18 + out.setLength(prelude);
19.19 + out.append(initCode);
19.20 + code = out.toString().toString();
19.21 + dump(code);
19.22 + applyCode(loader, null, code, false);
19.23 + }
19.24 +
19.25 + return fn;
19.26 + }
19.27 +
19.28 +// @JavaScriptBody(args = "s", body = "java.lang.System.out.println(s.toString());")
19.29 + static void dump(String s) {
19.30 }
19.31
19.32 /* possibly not needed:
19.33 @@ -82,7 +99,7 @@
19.34 "} catch (ex) {\n" +
19.35 " throw 'Cannot compile ' + ex + ' line: ' + ex.lineNumber + ' script:\\n' + script;\n" +
19.36 "}\n" +
19.37 - "return vm[name](instance);\n"
19.38 + "return name != null ? vm[name](instance) : null;\n"
19.39 )
19.40 private static native Object applyCode(Object loader, String name, String script, boolean instance);
19.41
20.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Mon Dec 24 07:51:15 2012 +0100
20.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Mon Dec 24 07:57:33 2012 +0100
20.3 @@ -101,6 +101,18 @@
20.4 "java.io.IOException", false, "name"
20.5 );
20.6 }
20.7 + @Test public void primitiveReturnType() throws Exception {
20.8 + assertExec("Tries to get an integer via reflection", Classes.class,
20.9 + "primitiveType__Ljava_lang_String_2Ljava_lang_String_2",
20.10 + Classes.primitiveType("primitive"), "primitive"
20.11 + );
20.12 + }
20.13 + @Test public void primitiveBoolReturnType() throws Exception {
20.14 + assertExec("Tries to get an integer via reflection", Classes.class,
20.15 + "primitiveType__Ljava_lang_String_2Ljava_lang_String_2",
20.16 + Classes.primitiveType("primitiveB"), "primitiveB"
20.17 + );
20.18 + }
20.19 @Test public void javaAnnotatedMethod() throws Exception {
20.20 assertEquals(Classes.reflectiveMethodCall(false, null), "java.io.IOException", "Calls the name() method via reflection");
20.21 }
20.22 @@ -116,6 +128,26 @@
20.23 "java.io.IOException"
20.24 );
20.25 }
20.26 + @Test public void noInterface() throws Exception {
20.27 + assertExec("Calls Class.isInterface", Classes.class,
20.28 + "isInterface__ZLjava_lang_String_2",
20.29 + 0.0, "java.lang.String"
20.30 + );
20.31 + }
20.32 + /*
20.33 + @Test public void isInterface() throws Exception {
20.34 + assertExec("Calls Class.isInterface", Classes.class,
20.35 + "isInterface__ZLjava_lang_String_2",
20.36 + 1.0, "java.lang.Runnable"
20.37 + );
20.38 + }
20.39 + */
20.40 + @Test public void integerType() throws Exception {
20.41 + assertExec("Computes the type", Classes.class,
20.42 + "intType__Ljava_lang_String_2",
20.43 + Classes.intType()
20.44 + );
20.45 + }
20.46
20.47 private static CharSequence codeSeq;
20.48 private static Invocable code;
21.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Mon Dec 24 07:51:15 2012 +0100
21.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Mon Dec 24 07:57:33 2012 +0100
21.3 @@ -38,6 +38,10 @@
21.4 return c.getName();
21.5 }
21.6
21.7 + public static boolean isInterface(String s) throws ClassNotFoundException {
21.8 + return Class.forName(s).isInterface();
21.9 + }
21.10 +
21.11 public static boolean equalsClassesOfExceptions() {
21.12 return MalformedURLException.class.getSuperclass() == IOException.class;
21.13 }
21.14 @@ -88,6 +92,21 @@
21.15 return null;
21.16 }
21.17
21.18 + public static String intType() {
21.19 + return Integer.TYPE.getName();
21.20 + }
21.21 +
21.22 + public static int primitive() {
21.23 + return 1;
21.24 + }
21.25 + public static boolean primitiveB() {
21.26 + return true;
21.27 + }
21.28 +
21.29 + public static String primitiveType(String method) throws Exception {
21.30 + return reflectiveMethodCall(false, method).getClass().getName();
21.31 + }
21.32 +
21.33 @JavaScriptBody(args = "msg", body = "throw msg;")
21.34 private static native void thrw(String msg);
21.35
22.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Compare.java Mon Dec 24 07:51:15 2012 +0100
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,36 +0,0 @@
22.4 -/**
22.5 - * Back 2 Browser Bytecode Translator
22.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
22.7 - *
22.8 - * This program is free software: you can redistribute it and/or modify
22.9 - * it under the terms of the GNU General Public License as published by
22.10 - * the Free Software Foundation, version 2 of the License.
22.11 - *
22.12 - * This program is distributed in the hope that it will be useful,
22.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.15 - * GNU General Public License for more details.
22.16 - *
22.17 - * You should have received a copy of the GNU General Public License
22.18 - * along with this program. Look for COPYING file in the top folder.
22.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
22.20 - */
22.21 -package org.apidesign.vm4brwsr;
22.22 -
22.23 -import java.lang.annotation.ElementType;
22.24 -import java.lang.annotation.Retention;
22.25 -import java.lang.annotation.RetentionPolicy;
22.26 -import java.lang.annotation.Target;
22.27 -
22.28 -/** Can be applied on a method that yields a return value.
22.29 - * Together with {@link VMCompare#create} it can be used to write
22.30 - * methods which are executed in real as well as JavaScript VMs and
22.31 - * their results are compared.
22.32 - *
22.33 - * @author Jaroslav Tulach <jtulach@netbeans.org>
22.34 - */
22.35 -@Retention(RetentionPolicy.RUNTIME)
22.36 -@Target(ElementType.METHOD)
22.37 -public @interface Compare {
22.38 -
22.39 -}
23.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java Mon Dec 24 07:51:15 2012 +0100
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,197 +0,0 @@
23.4 -/**
23.5 - * Back 2 Browser Bytecode Translator
23.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
23.7 - *
23.8 - * This program is free software: you can redistribute it and/or modify
23.9 - * it under the terms of the GNU General Public License as published by
23.10 - * the Free Software Foundation, version 2 of the License.
23.11 - *
23.12 - * This program is distributed in the hope that it will be useful,
23.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23.15 - * GNU General Public License for more details.
23.16 - *
23.17 - * You should have received a copy of the GNU General Public License
23.18 - * along with this program. Look for COPYING file in the top folder.
23.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
23.20 - */
23.21 -package org.apidesign.vm4brwsr;
23.22 -
23.23 -import java.lang.reflect.Method;
23.24 -import java.util.Map;
23.25 -import java.util.WeakHashMap;
23.26 -import javax.script.Invocable;
23.27 -import javax.script.ScriptContext;
23.28 -import javax.script.ScriptEngine;
23.29 -import javax.script.ScriptEngineManager;
23.30 -import org.testng.Assert;
23.31 -import org.testng.ITest;
23.32 -import org.testng.annotations.Factory;
23.33 -import org.testng.annotations.Test;
23.34 -
23.35 -/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
23.36 - * in provided class and builds set of tests that compare the computations
23.37 - * in real as well as JavaScript virtual machines. Use as:<pre>
23.38 - * {@code @}{@link Factory} public static create() {
23.39 - * return @{link CompareVMs}.{@link #create(YourClass.class);
23.40 - * }</pre>
23.41 - *
23.42 - * @author Jaroslav Tulach <jtulach@netbeans.org>
23.43 - */
23.44 -public final class CompareVMs implements ITest {
23.45 - private final Run first, second;
23.46 - private final Method m;
23.47 -
23.48 - private CompareVMs(Method m, Run first, Run second) {
23.49 - this.first = first;
23.50 - this.second = second;
23.51 - this.m = m;
23.52 - }
23.53 -
23.54 - public static Object[] create(Class<?> clazz) {
23.55 - Method[] arr = clazz.getMethods();
23.56 - Object[] ret = new Object[3 * arr.length];
23.57 - int cnt = 0;
23.58 - for (Method m : arr) {
23.59 - Compare c = m.getAnnotation(Compare.class);
23.60 - if (c == null) {
23.61 - continue;
23.62 - }
23.63 - final Run real = new Run(m, false);
23.64 - final Run js = new Run(m, true);
23.65 - ret[cnt++] = real;
23.66 - ret[cnt++] = js;
23.67 - ret[cnt++] = new CompareVMs(m, real, js);
23.68 - }
23.69 - Object[] r = new Object[cnt];
23.70 - for (int i = 0; i < cnt; i++) {
23.71 - r[i] = ret[i];
23.72 - }
23.73 - return r;
23.74 - }
23.75 -
23.76 - @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
23.77 - Object v1 = first.value;
23.78 - Object v2 = second.value;
23.79 - if (v1 instanceof Number) {
23.80 - v1 = ((Number)v1).doubleValue();
23.81 - }
23.82 - Assert.assertEquals(v2, v1, "Comparing results");
23.83 - }
23.84 -
23.85 - @Override
23.86 - public String getTestName() {
23.87 - return m.getName() + "[Compare]";
23.88 - }
23.89 -
23.90 - public static final class Run implements ITest {
23.91 - private final Method m;
23.92 - private final boolean js;
23.93 - Object value;
23.94 - private Invocable code;
23.95 - private CharSequence codeSeq;
23.96 - private static final Map<Class,Object[]> compiled = new WeakHashMap<Class,Object[]>();
23.97 -
23.98 - private Run(Method m, boolean js) {
23.99 - this.m = m;
23.100 - this.js = js;
23.101 - }
23.102 -
23.103 - private void compileTheCode(Class<?> clazz) throws Exception {
23.104 - final Object[] data = compiled.get(clazz);
23.105 - if (data != null) {
23.106 - code = (Invocable) data[0];
23.107 - codeSeq = (CharSequence) data[1];
23.108 - return;
23.109 - }
23.110 - StringBuilder sb = new StringBuilder();
23.111 - Bck2Brwsr.generate(sb, CompareVMs.class.getClassLoader());
23.112 -
23.113 - ScriptEngineManager sem = new ScriptEngineManager();
23.114 - ScriptEngine js = sem.getEngineByExtension("js");
23.115 - js.getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
23.116 -
23.117 - sb.append("\nfunction initVM() {"
23.118 - + "\n return bck2brwsr("
23.119 - + "\n function(name) { return loader.get(name);}"
23.120 - + "\n );"
23.121 - + "\n};");
23.122 -
23.123 - Object res = js.eval(sb.toString());
23.124 - Assert.assertTrue(js instanceof Invocable, "It is invocable object: " + res);
23.125 - code = (Invocable) js;
23.126 - codeSeq = sb;
23.127 - compiled.put(clazz, new Object[] { code, codeSeq });
23.128 - }
23.129 -
23.130 - @Test(groups = "run") public void executeCode() throws Throwable {
23.131 - if (js) {
23.132 - try {
23.133 - compileTheCode(m.getDeclaringClass());
23.134 - Object vm = code.invokeFunction("initVM");
23.135 - Object inst = code.invokeMethod(vm, "loadClass", m.getDeclaringClass().getName());
23.136 - value = code.invokeMethod(inst, m.getName() + "__" + computeSignature(m));
23.137 - } catch (Exception ex) {
23.138 - throw new AssertionError(StaticMethodTest.dumpJS(codeSeq)).initCause(ex);
23.139 - }
23.140 - } else {
23.141 - value = m.invoke(m.getDeclaringClass().newInstance());
23.142 - }
23.143 - }
23.144 - @Override
23.145 - public String getTestName() {
23.146 - return m.getName() + (js ? "[JavaScript]" : "[Java]");
23.147 - }
23.148 -
23.149 - private static String computeSignature(Method m) {
23.150 - StringBuilder sb = new StringBuilder();
23.151 - appendType(sb, m.getReturnType());
23.152 - for (Class<?> c : m.getParameterTypes()) {
23.153 - appendType(sb, c);
23.154 - }
23.155 - return sb.toString();
23.156 - }
23.157 -
23.158 - private static void appendType(StringBuilder sb, Class<?> t) {
23.159 - if (t == null) {
23.160 - sb.append('V');
23.161 - return;
23.162 - }
23.163 - if (t.isPrimitive()) {
23.164 - int ch = -1;
23.165 - if (t == int.class) {
23.166 - ch = 'I';
23.167 - }
23.168 - if (t == short.class) {
23.169 - ch = 'S';
23.170 - }
23.171 - if (t == byte.class) {
23.172 - ch = 'B';
23.173 - }
23.174 - if (t == boolean.class) {
23.175 - ch = 'Z';
23.176 - }
23.177 - if (t == long.class) {
23.178 - ch = 'J';
23.179 - }
23.180 - if (t == float.class) {
23.181 - ch = 'F';
23.182 - }
23.183 - if (t == double.class) {
23.184 - ch = 'D';
23.185 - }
23.186 - assert ch != -1 : "Unknown primitive type " + t;
23.187 - sb.append((char)ch);
23.188 - return;
23.189 - }
23.190 - if (t.isArray()) {
23.191 - sb.append("_3");
23.192 - appendType(sb, t.getComponentType());
23.193 - return;
23.194 - }
23.195 - sb.append('L');
23.196 - sb.append(t.getName().replace('.', '_'));
23.197 - sb.append("_2");
23.198 - }
23.199 - }
23.200 -}
24.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareHashTest.java Mon Dec 24 07:51:15 2012 +0100
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,42 +0,0 @@
24.4 -/**
24.5 - * Back 2 Browser Bytecode Translator
24.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
24.7 - *
24.8 - * This program is free software: you can redistribute it and/or modify
24.9 - * it under the terms of the GNU General Public License as published by
24.10 - * the Free Software Foundation, version 2 of the License.
24.11 - *
24.12 - * This program is distributed in the hope that it will be useful,
24.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.15 - * GNU General Public License for more details.
24.16 - *
24.17 - * You should have received a copy of the GNU General Public License
24.18 - * along with this program. Look for COPYING file in the top folder.
24.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
24.20 - */
24.21 -package org.apidesign.vm4brwsr.tck;
24.22 -
24.23 -import org.apidesign.vm4brwsr.Compare;
24.24 -import org.apidesign.vm4brwsr.CompareVMs;
24.25 -import org.testng.annotations.Factory;
24.26 -
24.27 -/**
24.28 - *
24.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
24.30 - */
24.31 -public class CompareHashTest {
24.32 - @Compare public int hashOfString() {
24.33 - return "Ahoj".hashCode();
24.34 - }
24.35 -
24.36 - @Compare public int hashRemainsYieldsZero() {
24.37 - Object o = new Object();
24.38 - return o.hashCode() - o.hashCode();
24.39 - }
24.40 -
24.41 - @Factory
24.42 - public static Object[] create() {
24.43 - return CompareVMs.create(CompareHashTest.class);
24.44 - }
24.45 -}
25.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareStringsTest.java Mon Dec 24 07:51:15 2012 +0100
25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3 @@ -1,110 +0,0 @@
25.4 -/**
25.5 - * Back 2 Browser Bytecode Translator
25.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
25.7 - *
25.8 - * This program is free software: you can redistribute it and/or modify
25.9 - * it under the terms of the GNU General Public License as published by
25.10 - * the Free Software Foundation, version 2 of the License.
25.11 - *
25.12 - * This program is distributed in the hope that it will be useful,
25.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.15 - * GNU General Public License for more details.
25.16 - *
25.17 - * You should have received a copy of the GNU General Public License
25.18 - * along with this program. Look for COPYING file in the top folder.
25.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
25.20 - */
25.21 -package org.apidesign.vm4brwsr.tck;
25.22 -
25.23 -import java.net.MalformedURLException;
25.24 -import java.net.URL;
25.25 -import org.apidesign.vm4brwsr.Compare;
25.26 -import org.apidesign.vm4brwsr.CompareVMs;
25.27 -import org.testng.annotations.Factory;
25.28 -
25.29 -/**
25.30 - *
25.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
25.32 - */
25.33 -public class CompareStringsTest {
25.34 - @Compare public static Object compareURLs() throws MalformedURLException {
25.35 - return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
25.36 - }
25.37 -
25.38 - @Compare public String deleteLastTwoCharacters() {
25.39 - StringBuilder sb = new StringBuilder();
25.40 - sb.append("453.0");
25.41 - if (sb.toString().endsWith(".0")) {
25.42 - final int l = sb.length();
25.43 - sb.delete(l - 2, l);
25.44 - }
25.45 - return sb.toString().toString();
25.46 - }
25.47 -
25.48 - @Compare public String nameOfStringClass() throws Exception {
25.49 - return Class.forName("java.lang.String").getName();
25.50 - }
25.51 - @Compare public String nameOfArrayClass() throws Exception {
25.52 - return Class.forName("org.apidesign.vm4brwsr.Array").getName();
25.53 - }
25.54 -
25.55 - @Compare public String lowerHello() {
25.56 - return "HeLlO".toLowerCase();
25.57 - }
25.58 -
25.59 - @Compare public String lowerA() {
25.60 - return String.valueOf(Character.toLowerCase('A')).toString();
25.61 - }
25.62 - @Compare public String upperHello() {
25.63 - return "hello".toUpperCase();
25.64 - }
25.65 -
25.66 - @Compare public String upperA() {
25.67 - return String.valueOf(Character.toUpperCase('a')).toString();
25.68 - }
25.69 -
25.70 - @Compare public boolean matchRegExp() throws Exception {
25.71 - return "58038503".matches("\\d*");
25.72 - }
25.73 -
25.74 - @Compare public boolean doesNotMatchRegExp() throws Exception {
25.75 - return "58038503GH".matches("\\d*");
25.76 - }
25.77 -
25.78 - @Compare public boolean doesNotMatchRegExpFully() throws Exception {
25.79 - return "Hello".matches("Hell");
25.80 - }
25.81 -
25.82 - @Compare public String variousCharacterTests() throws Exception {
25.83 - StringBuilder sb = new StringBuilder();
25.84 -
25.85 - sb.append(Character.isUpperCase('a'));
25.86 - sb.append(Character.isUpperCase('A'));
25.87 - sb.append(Character.isLowerCase('a'));
25.88 - sb.append(Character.isLowerCase('A'));
25.89 -
25.90 - sb.append(Character.isLetter('A'));
25.91 - sb.append(Character.isLetterOrDigit('9'));
25.92 - sb.append(Character.isLetterOrDigit('A'));
25.93 - sb.append(Character.isLetter('0'));
25.94 -
25.95 - return sb.toString().toString();
25.96 - }
25.97 -
25.98 - @Compare
25.99 - public String nullFieldInitialized() {
25.100 - NullField nf = new NullField();
25.101 - return ("" + nf.name).toString();
25.102 - }
25.103 -
25.104 - @Factory
25.105 - public static Object[] create() {
25.106 - return CompareVMs.create(CompareStringsTest.class);
25.107 - }
25.108 -
25.109 - private static final class NullField {
25.110 -
25.111 - String name;
25.112 - }
25.113 -}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/vmtest/pom.xml Mon Dec 24 07:57:33 2012 +0100
26.3 @@ -0,0 +1,61 @@
26.4 +<?xml version="1.0"?>
26.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
26.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
26.7 + <modelVersion>4.0.0</modelVersion>
26.8 + <parent>
26.9 + <groupId>org.apidesign</groupId>
26.10 + <artifactId>bck2brwsr</artifactId>
26.11 + <version>0.3-SNAPSHOT</version>
26.12 + </parent>
26.13 + <groupId>org.apidesign.bck2brwsr</groupId>
26.14 + <artifactId>vmtest</artifactId>
26.15 + <version>0.3-SNAPSHOT</version>
26.16 +
26.17 + <name>VM Testing APIs</name>
26.18 + <url>http://bck2brwsr.apidesign.org</url>
26.19 + <build>
26.20 + <plugins>
26.21 + <plugin>
26.22 + <groupId>org.apache.maven.plugins</groupId>
26.23 + <artifactId>maven-compiler-plugin</artifactId>
26.24 + <version>2.3.2</version>
26.25 + <configuration>
26.26 + <source>1.7</source>
26.27 + <target>1.7</target>
26.28 + </configuration>
26.29 + </plugin>
26.30 + </plugins>
26.31 + </build>
26.32 + <properties>
26.33 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
26.34 + </properties>
26.35 + <dependencies>
26.36 + <dependency>
26.37 + <groupId>org.testng</groupId>
26.38 + <artifactId>testng</artifactId>
26.39 + <scope>compile</scope>
26.40 + <exclusions>
26.41 + <exclusion>
26.42 + <artifactId>junit</artifactId>
26.43 + <groupId>junit</groupId>
26.44 + </exclusion>
26.45 + </exclusions>
26.46 + </dependency>
26.47 + <dependency>
26.48 + <groupId>${project.groupId}</groupId>
26.49 + <artifactId>vm4brwsr</artifactId>
26.50 + <version>0.3-SNAPSHOT</version>
26.51 + <type>jar</type>
26.52 + </dependency>
26.53 + <dependency>
26.54 + <groupId>${project.groupId}</groupId>
26.55 + <artifactId>emul</artifactId>
26.56 + <version>0.3-SNAPSHOT</version>
26.57 + </dependency>
26.58 + <dependency>
26.59 + <groupId>${project.groupId}</groupId>
26.60 + <artifactId>launcher</artifactId>
26.61 + <version>${project.version}</version>
26.62 + </dependency>
26.63 + </dependencies>
26.64 +</project>
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/Compare.java Mon Dec 24 07:57:33 2012 +0100
27.3 @@ -0,0 +1,36 @@
27.4 +/**
27.5 + * Back 2 Browser Bytecode Translator
27.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
27.7 + *
27.8 + * This program is free software: you can redistribute it and/or modify
27.9 + * it under the terms of the GNU General Public License as published by
27.10 + * the Free Software Foundation, version 2 of the License.
27.11 + *
27.12 + * This program is distributed in the hope that it will be useful,
27.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.15 + * GNU General Public License for more details.
27.16 + *
27.17 + * You should have received a copy of the GNU General Public License
27.18 + * along with this program. Look for COPYING file in the top folder.
27.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
27.20 + */
27.21 +package org.apidesign.bck2brwsr.vmtest;
27.22 +
27.23 +import java.lang.annotation.ElementType;
27.24 +import java.lang.annotation.Retention;
27.25 +import java.lang.annotation.RetentionPolicy;
27.26 +import java.lang.annotation.Target;
27.27 +
27.28 +/** Can be applied on a method that yields a return value.
27.29 + * Together with {@link VMTest#create} it can be used to write
27.30 + * methods which are executed in real as well as JavaScript VMs and
27.31 + * their results are compared.
27.32 + *
27.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
27.34 + */
27.35 +@Retention(RetentionPolicy.RUNTIME)
27.36 +@Target(ElementType.METHOD)
27.37 +public @interface Compare {
27.38 +
27.39 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/VMTest.java Mon Dec 24 07:57:33 2012 +0100
28.3 @@ -0,0 +1,43 @@
28.4 +/**
28.5 + * Back 2 Browser Bytecode Translator
28.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
28.7 + *
28.8 + * This program is free software: you can redistribute it and/or modify
28.9 + * it under the terms of the GNU General Public License as published by
28.10 + * the Free Software Foundation, version 2 of the License.
28.11 + *
28.12 + * This program is distributed in the hope that it will be useful,
28.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28.15 + * GNU General Public License for more details.
28.16 + *
28.17 + * You should have received a copy of the GNU General Public License
28.18 + * along with this program. Look for COPYING file in the top folder.
28.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
28.20 + */
28.21 +package org.apidesign.bck2brwsr.vmtest;
28.22 +
28.23 +import org.apidesign.bck2brwsr.vmtest.impl.CompareCase;
28.24 +import org.testng.annotations.Factory;
28.25 +
28.26 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
28.27 + * in provided class and builds set of tests that compare the computations
28.28 + * in real as well as JavaScript virtual machines. Use as:<pre>
28.29 + * {@code @}{@link Factory} public static create() {
28.30 + * return @{link VMTest}.{@link #create(YourClass.class);
28.31 + * }</pre>
28.32 + *
28.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
28.34 + */
28.35 +public final class VMTest {
28.36 + /** Inspects <code>clazz</code> and for each {@lik Compare} method creates
28.37 + * instances of tests. Each instance runs the test in different virtual
28.38 + * machine and at the end they compare the results.
28.39 + *
28.40 + * @param clazz the class to inspect
28.41 + * @return the set of created tests
28.42 + */
28.43 + public static Object[] create(Class<?> clazz) {
28.44 + return CompareCase.create(clazz);
28.45 + }
28.46 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Mon Dec 24 07:57:33 2012 +0100
29.3 @@ -0,0 +1,130 @@
29.4 +/**
29.5 + * Back 2 Browser Bytecode Translator
29.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
29.7 + *
29.8 + * This program is free software: you can redistribute it and/or modify
29.9 + * it under the terms of the GNU General Public License as published by
29.10 + * the Free Software Foundation, version 2 of the License.
29.11 + *
29.12 + * This program is distributed in the hope that it will be useful,
29.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29.15 + * GNU General Public License for more details.
29.16 + *
29.17 + * You should have received a copy of the GNU General Public License
29.18 + * along with this program. Look for COPYING file in the top folder.
29.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
29.20 + */
29.21 +package org.apidesign.bck2brwsr.vmtest.impl;
29.22 +
29.23 +import java.lang.reflect.Method;
29.24 +import java.util.Map;
29.25 +import java.util.WeakHashMap;
29.26 +import javax.script.Invocable;
29.27 +import org.apidesign.bck2brwsr.launcher.MethodInvocation;
29.28 +import org.testng.ITest;
29.29 +import org.testng.annotations.Test;
29.30 +
29.31 +/**
29.32 + *
29.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
29.34 + */
29.35 +public final class Bck2BrwsrCase implements ITest {
29.36 + private final Method m;
29.37 + private final Launchers l;
29.38 + private final int type;
29.39 + Object value;
29.40 + private Invocable code;
29.41 + private CharSequence codeSeq;
29.42 + private static final Map<Class, Object[]> compiled = new WeakHashMap<>();
29.43 + private Object inst;
29.44 +
29.45 + Bck2BrwsrCase(Method m, int type, Launchers l) {
29.46 + this.l = l;
29.47 + this.m = m;
29.48 + this.type = type;
29.49 + }
29.50 +
29.51 + @Test(groups = "run")
29.52 + public void executeCode() throws Throwable {
29.53 + if (type == 1) {
29.54 + MethodInvocation c = l.addMethod(m.getDeclaringClass(), m.getName(), false);
29.55 + value = c.toString();
29.56 + } else if (type == 2) {
29.57 + MethodInvocation c = l.addMethod(m.getDeclaringClass(), m.getName(), true);
29.58 + value = c.toString();
29.59 + } else {
29.60 + value = m.invoke(m.getDeclaringClass().newInstance());
29.61 + }
29.62 + }
29.63 +
29.64 + @Override
29.65 + public String getTestName() {
29.66 + return m.getName() + "[" + typeName() + "]";
29.67 + }
29.68 +
29.69 + final String typeName() {
29.70 + switch (type) {
29.71 + case 0:
29.72 + return "Java";
29.73 + case 1:
29.74 + return "JavaScript";
29.75 + case 2:
29.76 + return "Browser";
29.77 + default:
29.78 + return "Unknown type " + type;
29.79 + }
29.80 + }
29.81 +
29.82 + private static String computeSignature(Method m) {
29.83 + StringBuilder sb = new StringBuilder();
29.84 + appendType(sb, m.getReturnType());
29.85 + for (Class<?> c : m.getParameterTypes()) {
29.86 + appendType(sb, c);
29.87 + }
29.88 + return sb.toString();
29.89 + }
29.90 +
29.91 + private static void appendType(StringBuilder sb, Class<?> t) {
29.92 + if (t == null) {
29.93 + sb.append('V');
29.94 + return;
29.95 + }
29.96 + if (t.isPrimitive()) {
29.97 + int ch = -1;
29.98 + if (t == int.class) {
29.99 + ch = 'I';
29.100 + }
29.101 + if (t == short.class) {
29.102 + ch = 'S';
29.103 + }
29.104 + if (t == byte.class) {
29.105 + ch = 'B';
29.106 + }
29.107 + if (t == boolean.class) {
29.108 + ch = 'Z';
29.109 + }
29.110 + if (t == long.class) {
29.111 + ch = 'J';
29.112 + }
29.113 + if (t == float.class) {
29.114 + ch = 'F';
29.115 + }
29.116 + if (t == double.class) {
29.117 + ch = 'D';
29.118 + }
29.119 + assert ch != -1 : "Unknown primitive type " + t;
29.120 + sb.append((char) ch);
29.121 + return;
29.122 + }
29.123 + if (t.isArray()) {
29.124 + sb.append("_3");
29.125 + appendType(sb, t.getComponentType());
29.126 + return;
29.127 + }
29.128 + sb.append('L');
29.129 + sb.append(t.getName().replace('.', '_'));
29.130 + sb.append("_2");
29.131 + }
29.132 +
29.133 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Mon Dec 24 07:57:33 2012 +0100
30.3 @@ -0,0 +1,114 @@
30.4 +/**
30.5 + * Back 2 Browser Bytecode Translator
30.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
30.7 + *
30.8 + * This program is free software: you can redistribute it and/or modify
30.9 + * it under the terms of the GNU General Public License as published by
30.10 + * the Free Software Foundation, version 2 of the License.
30.11 + *
30.12 + * This program is distributed in the hope that it will be useful,
30.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.15 + * GNU General Public License for more details.
30.16 + *
30.17 + * You should have received a copy of the GNU General Public License
30.18 + * along with this program. Look for COPYING file in the top folder.
30.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
30.20 + */
30.21 +package org.apidesign.bck2brwsr.vmtest.impl;
30.22 +
30.23 +import org.apidesign.bck2brwsr.vmtest.*;
30.24 +import java.io.File;
30.25 +import java.io.FileWriter;
30.26 +import java.io.IOException;
30.27 +import java.lang.reflect.Method;
30.28 +import java.util.ArrayList;
30.29 +import java.util.List;
30.30 +import org.testng.Assert;
30.31 +import org.testng.ITest;
30.32 +import org.testng.annotations.Factory;
30.33 +import org.testng.annotations.Test;
30.34 +
30.35 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
30.36 + * in provided class and builds set of tests that compare the computations
30.37 + * in real as well as JavaScript virtual machines. Use as:<pre>
30.38 + * {@code @}{@link Factory} public static create() {
30.39 + * return @{link VMTest}.{@link #create(YourClass.class);
30.40 + * }</pre>
30.41 + *
30.42 + * @author Jaroslav Tulach <jtulach@netbeans.org>
30.43 + */
30.44 +public final class CompareCase implements ITest {
30.45 + private final Bck2BrwsrCase first, second;
30.46 + private final Method m;
30.47 +
30.48 + private CompareCase(Method m, Bck2BrwsrCase first, Bck2BrwsrCase second) {
30.49 + this.first = first;
30.50 + this.second = second;
30.51 + this.m = m;
30.52 + }
30.53 +
30.54 + /** Inspects <code>clazz</code> and for each {@lik Compare} method creates
30.55 + * instances of tests. Each instance runs the test in different virtual
30.56 + * machine and at the end they compare the results.
30.57 + *
30.58 + * @param clazz the class to inspect
30.59 + * @return the set of created tests
30.60 + */
30.61 + public static Object[] create(Class<?> clazz) {
30.62 + Method[] arr = clazz.getMethods();
30.63 + List<Object> ret = new ArrayList<>();
30.64 +
30.65 + final Launchers l = Launchers.INSTANCE;
30.66 +
30.67 + ret.add(l);
30.68 +
30.69 + for (Method m : arr) {
30.70 + Compare c = m.getAnnotation(Compare.class);
30.71 + if (c == null) {
30.72 + continue;
30.73 + }
30.74 + final Bck2BrwsrCase real = new Bck2BrwsrCase(m, 0, null);
30.75 + final Bck2BrwsrCase js = new Bck2BrwsrCase(m, 1, l);
30.76 + final Bck2BrwsrCase brwsr = new Bck2BrwsrCase(m, 2, l);
30.77 +
30.78 + ret.add(real);
30.79 + ret.add(js);
30.80 + ret.add(brwsr);
30.81 +
30.82 + ret.add(new CompareCase(m, real, js));
30.83 + ret.add(new CompareCase(m, real, brwsr));
30.84 + }
30.85 + return ret.toArray();
30.86 + }
30.87 +
30.88 + /** Test that compares the previous results.
30.89 + * @throws Throwable
30.90 + */
30.91 + @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
30.92 + Object v1 = first.value;
30.93 + Object v2 = second.value;
30.94 + if (v1 != null) {
30.95 + v1 = v1.toString();
30.96 + } else {
30.97 + v1 = "null";
30.98 + }
30.99 + Assert.assertEquals(v2, v1, "Comparing results");
30.100 + }
30.101 +
30.102 + /** Test name.
30.103 + * @return name of the tested method followed by a suffix
30.104 + */
30.105 + @Override
30.106 + public String getTestName() {
30.107 + return m.getName() + "[Compare " + second.typeName() + "]";
30.108 + }
30.109 +
30.110 + static StringBuilder dumpJS(CharSequence sb) throws IOException {
30.111 + File f = File.createTempFile("execution", ".js");
30.112 + try (FileWriter w = new FileWriter(f)) {
30.113 + w.append(sb);
30.114 + }
30.115 + return new StringBuilder(f.getPath());
30.116 + }
30.117 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Launchers.java Mon Dec 24 07:57:33 2012 +0100
31.3 @@ -0,0 +1,67 @@
31.4 +/**
31.5 + * Back 2 Browser Bytecode Translator
31.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
31.7 + *
31.8 + * This program is free software: you can redistribute it and/or modify
31.9 + * it under the terms of the GNU General Public License as published by
31.10 + * the Free Software Foundation, version 2 of the License.
31.11 + *
31.12 + * This program is distributed in the hope that it will be useful,
31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.15 + * GNU General Public License for more details.
31.16 + *
31.17 + * You should have received a copy of the GNU General Public License
31.18 + * along with this program. Look for COPYING file in the top folder.
31.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
31.20 + */
31.21 +package org.apidesign.bck2brwsr.vmtest.impl;
31.22 +
31.23 +import java.io.IOException;
31.24 +import org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher;
31.25 +import org.apidesign.bck2brwsr.launcher.JSLauncher;
31.26 +import org.apidesign.bck2brwsr.launcher.MethodInvocation;
31.27 +import org.apidesign.vm4brwsr.Bck2Brwsr;
31.28 +import org.testng.annotations.AfterGroups;
31.29 +import org.testng.annotations.AfterSuite;
31.30 +import org.testng.annotations.BeforeGroups;
31.31 +import org.testng.annotations.BeforeSuite;
31.32 +
31.33 +/**
31.34 + *
31.35 + * @author Jaroslav Tulach <jtulach@netbeans.org>
31.36 + */
31.37 +public final class Launchers {
31.38 + public static final Launchers INSTANCE = new Launchers();
31.39 +
31.40 + private JSLauncher jsl;
31.41 + private Bck2BrwsrLauncher brwsr;
31.42 +
31.43 + private Launchers() {
31.44 + }
31.45 +
31.46 + @BeforeGroups("run")
31.47 + public void initializeLauncher() throws IOException {
31.48 + jsl = new JSLauncher();
31.49 + jsl.addClassLoader(Bck2Brwsr.class.getClassLoader());
31.50 + jsl.initialize();
31.51 + Bck2BrwsrLauncher l = new Bck2BrwsrLauncher();
31.52 + l.addClassLoader(Bck2Brwsr.class.getClassLoader());
31.53 + l.initialize();
31.54 + l.setTimeout(180000);
31.55 + brwsr = l;
31.56 + }
31.57 +
31.58 + @AfterGroups("run")
31.59 + public void shutDownLauncher() throws IOException, InterruptedException {
31.60 + brwsr.shutdown();
31.61 + }
31.62 +
31.63 + public MethodInvocation addMethod(Class<?> clazz, String name, boolean inBrwsr) throws IOException {
31.64 + if (!inBrwsr) {
31.65 + return jsl.addMethod(clazz, name);
31.66 + } else {
31.67 + return brwsr.addMethod(clazz, name);
31.68 + }
31.69 + }
31.70 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java Mon Dec 24 07:57:33 2012 +0100
32.3 @@ -0,0 +1,46 @@
32.4 +/**
32.5 + * Back 2 Browser Bytecode Translator
32.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
32.7 + *
32.8 + * This program is free software: you can redistribute it and/or modify
32.9 + * it under the terms of the GNU General Public License as published by
32.10 + * the Free Software Foundation, version 2 of the License.
32.11 + *
32.12 + * This program is distributed in the hope that it will be useful,
32.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
32.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32.15 + * GNU General Public License for more details.
32.16 + *
32.17 + * You should have received a copy of the GNU General Public License
32.18 + * along with this program. Look for COPYING file in the top folder.
32.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
32.20 + */
32.21 +package org.apidesign.bck2brwsr.tck;
32.22 +
32.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
32.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
32.25 +import org.testng.annotations.Factory;
32.26 +
32.27 +/**
32.28 + *
32.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
32.30 + */
32.31 +public class CompareHashTest {
32.32 + @Compare public int hashOfString() {
32.33 + return "Ahoj".hashCode();
32.34 + }
32.35 +
32.36 + @Compare public int hashRemainsYieldsZero() {
32.37 + Object o = new Object();
32.38 + return o.hashCode() - o.hashCode();
32.39 + }
32.40 +
32.41 + @Compare public int initializeInStatic() {
32.42 + return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
32.43 + }
32.44 +
32.45 + @Factory
32.46 + public static Object[] create() {
32.47 + return VMTest.create(CompareHashTest.class);
32.48 + }
32.49 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Mon Dec 24 07:57:33 2012 +0100
33.3 @@ -0,0 +1,110 @@
33.4 +/**
33.5 + * Back 2 Browser Bytecode Translator
33.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
33.7 + *
33.8 + * This program is free software: you can redistribute it and/or modify
33.9 + * it under the terms of the GNU General Public License as published by
33.10 + * the Free Software Foundation, version 2 of the License.
33.11 + *
33.12 + * This program is distributed in the hope that it will be useful,
33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33.15 + * GNU General Public License for more details.
33.16 + *
33.17 + * You should have received a copy of the GNU General Public License
33.18 + * along with this program. Look for COPYING file in the top folder.
33.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
33.20 + */
33.21 +package org.apidesign.bck2brwsr.tck;
33.22 +
33.23 +import java.net.MalformedURLException;
33.24 +import java.net.URL;
33.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
33.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
33.27 +import org.testng.annotations.Factory;
33.28 +
33.29 +/**
33.30 + *
33.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
33.32 + */
33.33 +public class CompareStringsTest {
33.34 + @Compare public static Object compareURLs() throws MalformedURLException {
33.35 + return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
33.36 + }
33.37 +
33.38 + @Compare public String deleteLastTwoCharacters() {
33.39 + StringBuilder sb = new StringBuilder();
33.40 + sb.append("453.0");
33.41 + if (sb.toString().endsWith(".0")) {
33.42 + final int l = sb.length();
33.43 + sb.delete(l - 2, l);
33.44 + }
33.45 + return sb.toString().toString();
33.46 + }
33.47 +
33.48 + @Compare public String nameOfStringClass() throws Exception {
33.49 + return Class.forName("java.lang.String").getName();
33.50 + }
33.51 + @Compare public String nameOfArrayClass() throws Exception {
33.52 + return Class.forName("org.apidesign.bck2brwsr.tck.CompareHashTest").getName();
33.53 + }
33.54 +
33.55 + @Compare public String lowerHello() {
33.56 + return "HeLlO".toLowerCase();
33.57 + }
33.58 +
33.59 + @Compare public String lowerA() {
33.60 + return String.valueOf(Character.toLowerCase('A')).toString();
33.61 + }
33.62 + @Compare public String upperHello() {
33.63 + return "hello".toUpperCase();
33.64 + }
33.65 +
33.66 + @Compare public String upperA() {
33.67 + return String.valueOf(Character.toUpperCase('a')).toString();
33.68 + }
33.69 +
33.70 + @Compare public boolean matchRegExp() throws Exception {
33.71 + return "58038503".matches("\\d*");
33.72 + }
33.73 +
33.74 + @Compare public boolean doesNotMatchRegExp() throws Exception {
33.75 + return "58038503GH".matches("\\d*");
33.76 + }
33.77 +
33.78 + @Compare public boolean doesNotMatchRegExpFully() throws Exception {
33.79 + return "Hello".matches("Hell");
33.80 + }
33.81 +
33.82 + @Compare public String variousCharacterTests() throws Exception {
33.83 + StringBuilder sb = new StringBuilder();
33.84 +
33.85 + sb.append(Character.isUpperCase('a'));
33.86 + sb.append(Character.isUpperCase('A'));
33.87 + sb.append(Character.isLowerCase('a'));
33.88 + sb.append(Character.isLowerCase('A'));
33.89 +
33.90 + sb.append(Character.isLetter('A'));
33.91 + sb.append(Character.isLetterOrDigit('9'));
33.92 + sb.append(Character.isLetterOrDigit('A'));
33.93 + sb.append(Character.isLetter('0'));
33.94 +
33.95 + return sb.toString().toString();
33.96 + }
33.97 +
33.98 + @Compare
33.99 + public String nullFieldInitialized() {
33.100 + NullField nf = new NullField();
33.101 + return ("" + nf.name).toString();
33.102 + }
33.103 +
33.104 + @Factory
33.105 + public static Object[] create() {
33.106 + return VMTest.create(CompareStringsTest.class);
33.107 + }
33.108 +
33.109 + private static final class NullField {
33.110 +
33.111 + String name;
33.112 + }
33.113 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Mon Dec 24 07:57:33 2012 +0100
34.3 @@ -0,0 +1,43 @@
34.4 +/**
34.5 + * Back 2 Browser Bytecode Translator
34.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
34.7 + *
34.8 + * This program is free software: you can redistribute it and/or modify
34.9 + * it under the terms of the GNU General Public License as published by
34.10 + * the Free Software Foundation, version 2 of the License.
34.11 + *
34.12 + * This program is distributed in the hope that it will be useful,
34.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
34.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34.15 + * GNU General Public License for more details.
34.16 + *
34.17 + * You should have received a copy of the GNU General Public License
34.18 + * along with this program. Look for COPYING file in the top folder.
34.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
34.20 + */
34.21 +package org.apidesign.bck2brwsr.tck;
34.22 +
34.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
34.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
34.25 +import org.testng.annotations.Factory;
34.26 +
34.27 +/**
34.28 + *
34.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
34.30 + */
34.31 +public class ReflectionTest {
34.32 + @Compare public String intType() {
34.33 + return Integer.TYPE.toString();
34.34 + }
34.35 +
34.36 + @Compare public String longClass() {
34.37 + return long.class.toString();
34.38 + }
34.39 +
34.40 +
34.41 + @Factory
34.42 + public static Object[] create() {
34.43 + return VMTest.create(ReflectionTest.class);
34.44 + }
34.45 +
34.46 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java Mon Dec 24 07:57:33 2012 +0100
35.3 @@ -0,0 +1,22 @@
35.4 +/**
35.5 + * Back 2 Browser Bytecode Translator
35.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
35.7 + *
35.8 + * This program is free software: you can redistribute it and/or modify
35.9 + * it under the terms of the GNU General Public License as published by
35.10 + * the Free Software Foundation, version 2 of the License.
35.11 + *
35.12 + * This program is distributed in the hope that it will be useful,
35.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
35.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35.15 + * GNU General Public License for more details.
35.16 + *
35.17 + * You should have received a copy of the GNU General Public License
35.18 + * along with this program. Look for COPYING file in the top folder.
35.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
35.20 + */
35.21 +package org.apidesign.bck2brwsr.tck;
35.22 +
35.23 +class StaticUse {
35.24 + public static final Object NON_NULL = new Object();
35.25 +}