Separation of launchers into three pieces seems to work ok. Merging work from model branch to default one.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 29 Apr 2013 16:32:14 +0200
changeset 10593f7991249a20
parent 1027 c7a085d63ab5
parent 1058 e61f24684a69
child 1060 e3845e4f0ec8
Separation of launchers into three pieces seems to work ok. Merging work from model branch to default one.
javaquery/demo-twitter/bck2brwsr-assembly.xml
rt/launcher/pom.xml
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java
rt/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml
rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/BrwsrCheckTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CloneTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareIntArrayTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/DoubleTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceA.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceB.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionArrayTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ShortArithmeticTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUseSub.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUseSubTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CallMeTwiceTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java
rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java
rt/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/0xfe
rt/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/Resources.txt
     1.1 --- a/benchmarks/matrix-multiplication/pom.xml	Fri Apr 26 15:09:59 2013 +0200
     1.2 +++ b/benchmarks/matrix-multiplication/pom.xml	Mon Apr 29 16:32:14 2013 +0200
     1.3 @@ -94,5 +94,11 @@
     1.4        <version>0.7-SNAPSHOT</version>
     1.5        <scope>test</scope>
     1.6      </dependency>
     1.7 +    <dependency>
     1.8 +      <groupId>org.apidesign.bck2brwsr</groupId>
     1.9 +      <artifactId>launcher.http</artifactId>
    1.10 +      <version>0.7-SNAPSHOT</version>
    1.11 +      <scope>test</scope>
    1.12 +    </dependency>
    1.13    </dependencies>
    1.14  </project>
     2.1 --- a/javaquery/api/pom.xml	Fri Apr 26 15:09:59 2013 +0200
     2.2 +++ b/javaquery/api/pom.xml	Mon Apr 29 16:32:14 2013 +0200
     2.3 @@ -73,5 +73,11 @@
     2.4        <version>${project.version}</version>
     2.5        <scope>test</scope>
     2.6      </dependency>
     2.7 +    <dependency>
     2.8 +      <groupId>${project.groupId}</groupId>
     2.9 +      <artifactId>launcher.http</artifactId>
    2.10 +      <version>${project.version}</version>
    2.11 +      <scope>test</scope>
    2.12 +    </dependency>    
    2.13    </dependencies>
    2.14  </project>
     3.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/ComputedProperty.java	Fri Apr 26 15:09:59 2013 +0200
     3.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/ComputedProperty.java	Mon Apr 29 16:32:14 2013 +0200
     3.3 @@ -22,16 +22,11 @@
     3.4  import java.lang.annotation.RetentionPolicy;
     3.5  import java.lang.annotation.Target;
     3.6  
     3.7 -/** Can be used in classes annotated with {@link Page} annotation to
     3.8 - * define a derived property. Value of derived property is based on values
     3.9 - * of {@link Property} as enumerated by {@link Page#properties()}.
    3.10 - * <p>
    3.11 - * The name of the derived property is the name of the method. The arguments
    3.12 - * of the method define the property names (from {@link Page#properties()} list)
    3.13 - * the value of property depends on. 
    3.14 - *
    3.15 +/** 
    3.16 + * @deprecated Replaced by new {@link net.java.html.json.ComputedProperty net.java.html.json} API.
    3.17   * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.18   */
    3.19 +@Deprecated
    3.20  @Retention(RetentionPolicy.SOURCE)
    3.21  @Target(ElementType.METHOD)
    3.22  public @interface ComputedProperty {
     4.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Model.java	Fri Apr 26 15:09:59 2013 +0200
     4.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Model.java	Mon Apr 29 16:32:14 2013 +0200
     4.3 @@ -22,19 +22,13 @@
     4.4  import java.lang.annotation.RetentionPolicy;
     4.5  import java.lang.annotation.Target;
     4.6  
     4.7 -/** Defines a model class named {@link #className()} which contains
     4.8 - * defined {@link #properties()}. This class can have methods 
     4.9 - * annotated by {@link ComputedProperty} which define derived
    4.10 - * properties in the model class.
    4.11 - * <p>
    4.12 - * The {@link #className() generated class}'s <code>toString</code>
    4.13 - * converts the state of the object into 
    4.14 - * <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> format.
    4.15 - *
    4.16 +/** 
    4.17 + * @deprecated Replaced by new {@link net.java.html.json.Model net.java.html.json} API.
    4.18   * @author Jaroslav Tulach <jtulach@netbeans.org>
    4.19   */
    4.20  @Retention(RetentionPolicy.SOURCE)
    4.21  @Target(ElementType.TYPE)
    4.22 +@Deprecated
    4.23  public @interface Model {
    4.24      /** Name of the model class */
    4.25      String className();
     5.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnFunction.java	Fri Apr 26 15:09:59 2013 +0200
     5.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnFunction.java	Mon Apr 29 16:32:14 2013 +0200
     5.3 @@ -22,13 +22,12 @@
     5.4  import java.lang.annotation.RetentionPolicy;
     5.5  import java.lang.annotation.Target;
     5.6  
     5.7 -/** Methods in class annotated by {@link Model} or {@link Page} can be 
     5.8 - * annotated by this annotation to signal that they should be available
     5.9 - * as functions to users of the model classes.
    5.10 - *
    5.11 +/** 
    5.12 + * @deprecated Replaced by new {@link net.java.html.json.Function net.java.html.json} API.
    5.13   * @author Jaroslav Tulach <jtulach@netbeans.org>
    5.14   */
    5.15  @Target(ElementType.METHOD)
    5.16  @Retention(RetentionPolicy.SOURCE)
    5.17 +@Deprecated
    5.18  public @interface OnFunction {
    5.19  }
     6.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnPropertyChange.java	Fri Apr 26 15:09:59 2013 +0200
     6.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnPropertyChange.java	Mon Apr 29 16:32:14 2013 +0200
     6.3 @@ -22,13 +22,13 @@
     6.4  import java.lang.annotation.RetentionPolicy;
     6.5  import java.lang.annotation.Target;
     6.6  
     6.7 -/** Represents a property. Either in a generated model of an HTML
     6.8 - * {@link Page} or in a class defined by {@link Model}.
     6.9 - *
    6.10 +/** 
    6.11 + * @deprecated Replaced by new {@link net.java.html.json.OnPropertyChange net.java.html.json} API.
    6.12   * @author Jaroslav Tulach <jtulach@netbeans.org>
    6.13   */
    6.14  @Retention(RetentionPolicy.SOURCE)
    6.15  @Target(ElementType.METHOD)
    6.16 +@Deprecated
    6.17  public @interface OnPropertyChange {
    6.18      /** Name(s) of the properties. One wishes to observe.
    6.19       * 
     7.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnReceive.java	Fri Apr 26 15:09:59 2013 +0200
     7.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnReceive.java	Mon Apr 29 16:32:14 2013 +0200
     7.3 @@ -22,54 +22,14 @@
     7.4  import java.lang.annotation.RetentionPolicy;
     7.5  import java.lang.annotation.Target;
     7.6  
     7.7 -/** Static methods in classes annotated by {@link Page}
     7.8 - * can be marked by this annotation to establish a 
     7.9 - * <a href="http://en.wikipedia.org/wiki/JSON">JSON</a>
    7.10 - * communication point.
    7.11 - * The associated model page then gets new method to invoke a network
    7.12 - * connection. Example follows:
    7.13 - * 
    7.14 - * <pre>
    7.15 - * {@link Page @Page}(className="MyModel", xhtml="page.html", properties={
    7.16 - *   {@link Property @Property}(name = "people", type=Person.class, array=true)
    7.17 - * })
    7.18 - * class MyModelImpl {
    7.19 - *   {@link Model @Model}(className="Person", properties={
    7.20 - *     {@link Property @Property}(name = "firstName", type=String.class),
    7.21 - *     {@link Property @Property}(name = "lastName", type=String.class)
    7.22 - *   })
    7.23 - *   static class PersonImpl {
    7.24 - *     {@link ComputedProperty @ComputedProperty}
    7.25 - *     static String fullName(String firstName, String lastName) {
    7.26 - *       return firstName + " " + lastName;
    7.27 - *     }
    7.28 - *   }
    7.29 - * 
    7.30 - *   {@link OnReceive @OnReceive}(url = "{protocol}://your.server.com/person/{name}")
    7.31 - *   static void getANewPerson(MyModel m, Person p) {
    7.32 - *     {@link Element#alert Element.alert}("Adding " + p.getFullName() + '!');
    7.33 - *     m.getPeople().add(p);
    7.34 - *   }
    7.35 - * 
    7.36 - *   // the above will generate method <code>getANewPerson</code> in class <code>MyModel</code>.
    7.37 - *   // with <code>protocol</code> and <code>name</code> arguments
    7.38 - *   // which asynchronously contacts the server and in case of success calls
    7.39 - *   // your {@link OnReceive @OnReceive} with parsed in data
    7.40 - * 
    7.41 - *   {@link On @On}(event={@link OnEvent#CLICK OnEvent.CLICK}, id="rqst")
    7.42 - *   static void requestSmith(MyModel m) {
    7.43 - *     m.getANewPerson("http", "Smith");
    7.44 - *   }
    7.45 - * }
    7.46 - * </pre>
    7.47 - * When the server returns <code>{ "firstName" : "John", "lastName" : "Smith" }</code>
    7.48 - * the browser will show alert message <em>Adding John Smith!</em>.
    7.49 - * 
    7.50 +/** 
    7.51 + * @deprecated Replaced by new {@link net.java.html.json.OnReceive net.java.html.json} API.
    7.52   * @author Jaroslav Tulach <jtulach@netbeans.org>
    7.53   * @since 0.6
    7.54   */
    7.55  @Retention(RetentionPolicy.SOURCE)
    7.56  @Target(ElementType.METHOD)
    7.57 +@Deprecated
    7.58  public @interface OnReceive {
    7.59      /** The URL to connect to. Can contain variable names surrounded by '{' and '}'.
    7.60       * Those parameters will then become variables of the associated method.
     8.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Property.java	Fri Apr 26 15:09:59 2013 +0200
     8.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Property.java	Mon Apr 29 16:32:14 2013 +0200
     8.3 @@ -22,13 +22,13 @@
     8.4  import java.lang.annotation.Target;
     8.5  import java.util.List;
     8.6  
     8.7 -/** Represents a property. Either in a generated model of an HTML
     8.8 - * {@link Page} or in a class defined by {@link Model}.
     8.9 - *
    8.10 +/** 
    8.11 + * @deprecated Replaced by new {@link net.java.html.json.Property net.java.html.json} API.
    8.12   * @author Jaroslav Tulach <jtulach@netbeans.org>
    8.13   */
    8.14  @Retention(RetentionPolicy.SOURCE)
    8.15  @Target({})
    8.16 +@Deprecated
    8.17  public @interface Property {
    8.18      /** Name of the property. Will be used to define proper getter and setter
    8.19       * in the associated class.
     9.1 --- a/javaquery/demo-calculator/pom.xml	Fri Apr 26 15:09:59 2013 +0200
     9.2 +++ b/javaquery/demo-calculator/pom.xml	Mon Apr 29 16:32:14 2013 +0200
     9.3 @@ -12,7 +12,7 @@
     9.4  
     9.5    <properties>
     9.6      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     9.7 -    <bck2brwsr.obfuscationlevel>FULL</bck2brwsr.obfuscationlevel>
     9.8 +    <bck2brwsr.obfuscationlevel>MINIMAL</bck2brwsr.obfuscationlevel>
     9.9    </properties>
    9.10    <build>
    9.11        <plugins>
    10.1 --- a/javaquery/demo-twitter/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    10.2 +++ b/javaquery/demo-twitter/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    10.3 @@ -141,5 +141,11 @@
    10.4        <version>${project.version}</version>
    10.5        <scope>test</scope>
    10.6      </dependency>
    10.7 +    <dependency>
    10.8 +      <groupId>org.apidesign.bck2brwsr</groupId>
    10.9 +      <artifactId>launcher.http</artifactId>
   10.10 +      <version>${project.version}</version>
   10.11 +      <scope>runtime</scope>
   10.12 +    </dependency>
   10.13    </dependencies>
   10.14  </project>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/launcher/api/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    11.3 @@ -0,0 +1,20 @@
    11.4 +<?xml version="1.0"?>
    11.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"
    11.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    11.7 +  <modelVersion>4.0.0</modelVersion>
    11.8 +  <parent>
    11.9 +    <groupId>org.apidesign.bck2brwsr</groupId>
   11.10 +    <artifactId>launcher-pom</artifactId>
   11.11 +    <version>0.7-SNAPSHOT</version>
   11.12 +  </parent>
   11.13 +  <groupId>org.apidesign.bck2brwsr</groupId>
   11.14 +  <artifactId>launcher</artifactId>
   11.15 +  <version>0.7-SNAPSHOT</version>
   11.16 +  <name>Launcher API</name>
   11.17 +  <url>http://maven.apache.org</url>
   11.18 +  <properties>
   11.19 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   11.20 +  </properties>
   11.21 +  <dependencies>
   11.22 +  </dependencies>
   11.23 +</project>
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/launcher/api/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java	Mon Apr 29 16:32:14 2013 +0200
    12.3 @@ -0,0 +1,115 @@
    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.io.IOException;
   12.24 +import java.io.InputStream;
   12.25 +import java.util.ArrayList;
   12.26 +import java.util.List;
   12.27 +import java.util.concurrent.CountDownLatch;
   12.28 +import java.util.concurrent.TimeUnit;
   12.29 +
   12.30 +/** Represents individual method invocation, its context and its result.
   12.31 + *
   12.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   12.33 + */
   12.34 +public final class InvocationContext {
   12.35 +    final CountDownLatch wait = new CountDownLatch(1);
   12.36 +    final Class<?> clazz;
   12.37 +    final String methodName;
   12.38 +    private final Launcher launcher;
   12.39 +    private String result;
   12.40 +    private Throwable exception;
   12.41 +    String html;
   12.42 +    final List<Resource> resources = new ArrayList<>();
   12.43 +
   12.44 +    InvocationContext(Launcher launcher, Class<?> clazz, String methodName) {
   12.45 +        this.launcher = launcher;
   12.46 +        this.clazz = clazz;
   12.47 +        this.methodName = methodName;
   12.48 +    }
   12.49 +    
   12.50 +    /** An HTML fragment to be available for the execution. Useful primarily when
   12.51 +     * executing in a browser via {@link Launcher#createBrowser(java.lang.String)}.
   12.52 +     * @param html the html fragment
   12.53 +     */
   12.54 +    public void setHtmlFragment(String html) {
   12.55 +        this.html = html;
   12.56 +    }
   12.57 +    
   12.58 +    /** HTTP resource to be available during execution. An invocation may
   12.59 +     * perform an HTTP query and obtain a resource relative to the page.
   12.60 +     */
   12.61 +    public void addHttpResource(String relativePath, String mimeType, String[] parameters, InputStream content) {
   12.62 +        if (relativePath == null || mimeType == null || content == null || parameters == null) {
   12.63 +            throw new NullPointerException();
   12.64 +        }
   12.65 +        resources.add(new Resource(content, mimeType, relativePath, parameters));
   12.66 +    }
   12.67 +    
   12.68 +    /** Invokes the associated method. 
   12.69 +     * @return the textual result of the invocation
   12.70 +     */
   12.71 +    public String invoke() throws IOException {
   12.72 +        launcher.runMethod(this);
   12.73 +        return toString();
   12.74 +    }
   12.75 +    
   12.76 +    /** Obtains textual result of the invocation.
   12.77 +     * @return text representing the exception or result value
   12.78 +     */
   12.79 +    @Override
   12.80 +    public String toString() {
   12.81 +        if (exception != null) {
   12.82 +            return exception.toString();
   12.83 +        }
   12.84 +        return result;
   12.85 +    }
   12.86 +    
   12.87 +    /**
   12.88 +     * @param timeOut
   12.89 +     * @throws InterruptedException 
   12.90 +     */
   12.91 +    void await(long timeOut) throws InterruptedException {
   12.92 +        wait.await(timeOut, TimeUnit.MILLISECONDS);
   12.93 +    }
   12.94 +    
   12.95 +    void result(String r, Throwable e) {
   12.96 +        this.result = r;
   12.97 +        this.exception = e;
   12.98 +        wait.countDown();
   12.99 +    }
  12.100 +
  12.101 +
  12.102 +    static final class Resource {
  12.103 +        final InputStream httpContent;
  12.104 +        final String httpType;
  12.105 +        final String httpPath;
  12.106 +        final String[] parameters;
  12.107 +
  12.108 +        Resource(InputStream httpContent, String httpType, String httpPath,
  12.109 +            String[] parameters
  12.110 +        ) {
  12.111 +            httpContent.mark(Integer.MAX_VALUE);
  12.112 +            this.httpContent = httpContent;
  12.113 +            this.httpType = httpType;
  12.114 +            this.httpPath = httpPath;
  12.115 +            this.parameters = parameters;
  12.116 +        }
  12.117 +    }
  12.118 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/launcher/api/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Mon Apr 29 16:32:14 2013 +0200
    13.3 @@ -0,0 +1,166 @@
    13.4 +/**
    13.5 + * Back 2 Browser Bytecode Translator
    13.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    13.7 + *
    13.8 + * This program is free software: you can redistribute it and/or modify
    13.9 + * it under the terms of the GNU General Public License as published by
   13.10 + * the Free Software Foundation, version 2 of the License.
   13.11 + *
   13.12 + * This program is distributed in the hope that it will be useful,
   13.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.15 + * GNU General Public License for more details.
   13.16 + *
   13.17 + * You should have received a copy of the GNU General Public License
   13.18 + * along with this program. Look for COPYING file in the top folder.
   13.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   13.20 + */
   13.21 +package org.apidesign.bck2brwsr.launcher;
   13.22 +
   13.23 +import java.io.Closeable;
   13.24 +import java.io.File;
   13.25 +import java.io.IOException;
   13.26 +import java.lang.reflect.Constructor;
   13.27 +
   13.28 +/** An abstraction for executing tests in a Bck2Brwsr virtual machine.
   13.29 + * Either in {@link Launcher#createJavaScript JavaScript engine}, 
   13.30 + * or in {@link Launcher#createBrowser external browser}.
   13.31 + * <p>
   13.32 + * There also are methods to {@link #showDir(java.io.File, java.lang.String) display pages} 
   13.33 + * in an external browser served by internal HTTP server.
   13.34 + *
   13.35 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   13.36 + */
   13.37 +public abstract class Launcher {
   13.38 +
   13.39 +    Launcher() {
   13.40 +    }
   13.41 +
   13.42 +    /** Initializes the launcher. This may mean starting a web browser or
   13.43 +     * initializing execution engine.
   13.44 +     * @throws IOException if something goes wrong
   13.45 +     */
   13.46 +    public abstract void initialize() throws IOException;
   13.47 +    
   13.48 +    /** Shuts down the launcher.
   13.49 +     * @throws IOException if something goes wrong
   13.50 +     */
   13.51 +    public abstract void shutdown() throws IOException;
   13.52 +    
   13.53 +    
   13.54 +    /** Builds an invocation context. The context can later be customized
   13.55 +     * and {@link InvocationContext#invoke() invoked}.
   13.56 +     * 
   13.57 +     * @param clazz the class to execute method from
   13.58 +     * @param method the method to execute
   13.59 +     * @return the context pointing to the selected method
   13.60 +     */
   13.61 +    public InvocationContext createInvocation(Class<?> clazz, String method) {
   13.62 +        return new InvocationContext(this, clazz, method);
   13.63 +    }
   13.64 +    
   13.65 +
   13.66 +    /** Creates launcher that uses internal JavaScript engine (Rhino).
   13.67 +     * @return the launcher
   13.68 +     */
   13.69 +    public static Launcher createJavaScript() {
   13.70 +        try {
   13.71 +            Class<?> c = loadClass("org.apidesign.bck2brwsr.launcher.JSLauncher");
   13.72 +            return (Launcher) c.newInstance();
   13.73 +        } catch (Exception ex) {
   13.74 +            throw new IllegalStateException("Please include org.apidesign.bck2brwsr:launcher.html dependency!", ex);
   13.75 +        }
   13.76 +    }
   13.77 +    
   13.78 +    /** Creates launcher that is using external browser.
   13.79 +     * 
   13.80 +     * @param cmd <code>null</code> to use <code>java.awt.Desktop</code> to show the launcher
   13.81 +     *    or a string to execute in an external process (with a parameter to the URL)
   13.82 +     * @return launcher executing in external browser.
   13.83 +     */
   13.84 +    public static Launcher createBrowser(String cmd) {
   13.85 +        String msg = "Trying to create browser '" + cmd + "'";
   13.86 +        try {
   13.87 +            Class<?> c;
   13.88 +            if ("fxbrwsr".equals(cmd)) { // NOI18N
   13.89 +                msg = "Please include org.apidesign.bck2brwsr:launcher.fx dependency!";
   13.90 +                c = loadClass("org.apidesign.bck2brwsr.launcher.FXBrwsrLauncher"); // NOI18N
   13.91 +            } else {
   13.92 +                msg = "Please include org.apidesign.bck2brwsr:launcher.html dependency!";
   13.93 +                c = loadClass("org.apidesign.bck2brwsr.launcher.Bck2BrwsrLauncher"); // NOI18N
   13.94 +                if ("bck2brwsr".equals(cmd)) { // NOI18N
   13.95 +                    // use default executable
   13.96 +                    cmd = null;
   13.97 +                }
   13.98 +            }
   13.99 +            Constructor<?> cnstr = c.getConstructor(String.class);
  13.100 +            return (Launcher) cnstr.newInstance(cmd);
  13.101 +        } catch (Exception ex) {
  13.102 +            throw new IllegalStateException(msg, ex);
  13.103 +        }
  13.104 +    }
  13.105 +    
  13.106 +    /** Starts an HTTP server which provides access to classes and resources
  13.107 +     * available in the <code>classes</code> URL and shows a start page
  13.108 +     * available as {@link ClassLoader#getResource(java.lang.String)} from the
  13.109 +     * provide classloader. Opens a browser with URL showing the start page.
  13.110 +     * 
  13.111 +     * @param classes classloader offering access to classes and resources
  13.112 +     * @param startpage page to show in the browser
  13.113 +     * @return interface that allows one to stop the server
  13.114 +     * @throws IOException if something goes wrong
  13.115 +     */
  13.116 +    public static Closeable showURL(ClassLoader classes, String startpage) throws IOException {
  13.117 +        return showURL(null, classes, startpage);
  13.118 +    }
  13.119 +    /** Starts an HTTP server which provides access to classes and resources
  13.120 +     * available in the <code>classes</code> URL and shows a start page
  13.121 +     * available as {@link ClassLoader#getResource(java.lang.String)} from the
  13.122 +     * provide classloader. Opens a browser with URL showing the start page.
  13.123 +     * 
  13.124 +     * @param brwsr name of browser to use or <code>null</code>
  13.125 +     * @param classes classloader offering access to classes and resources
  13.126 +     * @param startpage page to show in the browser
  13.127 +     * @return interface that allows one to stop the server
  13.128 +     * @throws IOException if something goes wrong
  13.129 +     * @since 0.7
  13.130 +     */
  13.131 +    public static Closeable showURL(String brwsr, ClassLoader classes, String startpage) throws IOException {
  13.132 +        Launcher l = createBrowser(brwsr);
  13.133 +        l.addClassLoader(classes);
  13.134 +        l.showURL(startpage);
  13.135 +        return (Closeable) l;
  13.136 +    }
  13.137 +    /** Starts an HTTP server which provides access to certain directory.
  13.138 +     * The <code>startpage</code> should be relative location inside the root 
  13.139 +     * directory. Opens a browser with URL showing the start page.
  13.140 +     * 
  13.141 +     * @param directory the root directory on disk
  13.142 +     * @param startpage relative path from the root to the page
  13.143 +     * @exception IOException if something goes wrong.
  13.144 +     */
  13.145 +    public static Closeable showDir(File directory, String startpage) throws IOException {
  13.146 +        Launcher l = createBrowser(null);
  13.147 +        l.showDirectory(directory, startpage);
  13.148 +        return (Closeable) l;
  13.149 +    }
  13.150 +
  13.151 +    abstract InvocationContext runMethod(InvocationContext c) throws IOException; 
  13.152 +
  13.153 +
  13.154 +    private static Class<?> loadClass(String cn) throws ClassNotFoundException {
  13.155 +        return Launcher.class.getClassLoader().loadClass(cn);
  13.156 +    }
  13.157 +
  13.158 +    void showDirectory(File directory, String startpage) throws IOException {
  13.159 +        throw new UnsupportedOperationException();
  13.160 +    }
  13.161 +
  13.162 +    void showURL(String startpage) throws IOException {
  13.163 +        throw new UnsupportedOperationException();
  13.164 +    }
  13.165 +
  13.166 +    void addClassLoader(ClassLoader classes) {
  13.167 +        throw new UnsupportedOperationException();
  13.168 +    }
  13.169 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/launcher/fx/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    14.3 @@ -0,0 +1,49 @@
    14.4 +<?xml version="1.0"?>
    14.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    14.6 +  <modelVersion>4.0.0</modelVersion>
    14.7 +  <parent>
    14.8 +    <groupId>org.apidesign.bck2brwsr</groupId>
    14.9 +    <artifactId>launcher-pom</artifactId>
   14.10 +    <version>0.7-SNAPSHOT</version>
   14.11 +  </parent>
   14.12 +  <groupId>org.apidesign.bck2brwsr</groupId>
   14.13 +  <artifactId>launcher.fx</artifactId>
   14.14 +  <version>0.7-SNAPSHOT</version>
   14.15 +  <name>FXBrwsr Launcher</name>
   14.16 +  <url>http://maven.apache.org</url>
   14.17 +    <build>
   14.18 +        <plugins>
   14.19 +            <plugin>
   14.20 +                <groupId>org.apache.maven.plugins</groupId>
   14.21 +                <artifactId>maven-compiler-plugin</artifactId>
   14.22 +                <version>2.3.2</version>
   14.23 +                <configuration>
   14.24 +                    <source>1.7</source>
   14.25 +                    <target>1.7</target>
   14.26 +                </configuration>
   14.27 +            </plugin>
   14.28 +        </plugins>
   14.29 +    </build>
   14.30 +    <properties>
   14.31 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   14.32 +  </properties>
   14.33 +  <dependencies>
   14.34 +    <dependency>
   14.35 +      <groupId>${project.groupId}</groupId>
   14.36 +      <artifactId>launcher</artifactId>
   14.37 +      <version>${project.version}</version>
   14.38 +    </dependency>
   14.39 +    <dependency>
   14.40 +      <groupId>org.glassfish.grizzly</groupId>
   14.41 +      <artifactId>grizzly-http-server</artifactId>
   14.42 +      <version>2.2.19</version>
   14.43 +    </dependency>
   14.44 +    <dependency>
   14.45 +      <groupId>com.oracle</groupId>
   14.46 +      <artifactId>javafx</artifactId>
   14.47 +      <version>2.2</version>
   14.48 +      <scope>system</scope>
   14.49 +      <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
   14.50 +    </dependency>
   14.51 +  </dependencies>
   14.52 +</project>
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java	Mon Apr 29 16:32:14 2013 +0200
    15.3 @@ -0,0 +1,588 @@
    15.4 +/**
    15.5 + * Back 2 Browser Bytecode Translator
    15.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    15.7 + *
    15.8 + * This program is free software: you can redistribute it and/or modify
    15.9 + * it under the terms of the GNU General Public License as published by
   15.10 + * the Free Software Foundation, version 2 of the License.
   15.11 + *
   15.12 + * This program is distributed in the hope that it will be useful,
   15.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.15 + * GNU General Public License for more details.
   15.16 + *
   15.17 + * You should have received a copy of the GNU General Public License
   15.18 + * along with this program. Look for COPYING file in the top folder.
   15.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   15.20 + */
   15.21 +package org.apidesign.bck2brwsr.launcher;
   15.22 +
   15.23 +import java.io.Closeable;
   15.24 +import java.io.File;
   15.25 +import java.io.IOException;
   15.26 +import java.io.InputStream;
   15.27 +import java.io.InterruptedIOException;
   15.28 +import java.io.OutputStream;
   15.29 +import java.io.UnsupportedEncodingException;
   15.30 +import java.io.Writer;
   15.31 +import java.net.URI;
   15.32 +import java.net.URISyntaxException;
   15.33 +import java.net.URL;
   15.34 +import java.util.ArrayList;
   15.35 +import java.util.Arrays;
   15.36 +import java.util.Enumeration;
   15.37 +import java.util.LinkedHashSet;
   15.38 +import java.util.List;
   15.39 +import java.util.Set;
   15.40 +import java.util.concurrent.BlockingQueue;
   15.41 +import java.util.concurrent.CountDownLatch;
   15.42 +import java.util.concurrent.LinkedBlockingQueue;
   15.43 +import java.util.concurrent.TimeUnit;
   15.44 +import java.util.logging.Level;
   15.45 +import java.util.logging.Logger;
   15.46 +import org.apidesign.bck2brwsr.launcher.InvocationContext.Resource;
   15.47 +import org.glassfish.grizzly.PortRange;
   15.48 +import org.glassfish.grizzly.http.server.HttpHandler;
   15.49 +import org.glassfish.grizzly.http.server.HttpServer;
   15.50 +import org.glassfish.grizzly.http.server.NetworkListener;
   15.51 +import org.glassfish.grizzly.http.server.Request;
   15.52 +import org.glassfish.grizzly.http.server.Response;
   15.53 +import org.glassfish.grizzly.http.server.ServerConfiguration;
   15.54 +import org.glassfish.grizzly.http.util.HttpStatus;
   15.55 +
   15.56 +/**
   15.57 + * Lightweight server to launch Bck2Brwsr applications and tests.
   15.58 + * Supports execution in native browser as well as Java's internal 
   15.59 + * execution engine.
   15.60 + */
   15.61 +abstract class BaseHTTPLauncher extends Launcher implements Closeable {
   15.62 +    private static final Logger LOG = Logger.getLogger(BaseHTTPLauncher.class.getName());
   15.63 +    private static final InvocationContext END = new InvocationContext(null, null, null);
   15.64 +    private final Set<ClassLoader> loaders = new LinkedHashSet<>();
   15.65 +    private final BlockingQueue<InvocationContext> methods = new LinkedBlockingQueue<>();
   15.66 +    private long timeOut;
   15.67 +    private final Res resources = new Res();
   15.68 +    private final String cmd;
   15.69 +    private Object[] brwsr;
   15.70 +    private HttpServer server;
   15.71 +    private CountDownLatch wait;
   15.72 +    
   15.73 +    public BaseHTTPLauncher(String cmd) {
   15.74 +        this.cmd = cmd;
   15.75 +        addClassLoader(BaseHTTPLauncher.class.getClassLoader());
   15.76 +        setTimeout(180000);
   15.77 +    }
   15.78 +    
   15.79 +    @Override
   15.80 +    InvocationContext runMethod(InvocationContext c) throws IOException {
   15.81 +        loaders.add(c.clazz.getClassLoader());
   15.82 +        methods.add(c);
   15.83 +        try {
   15.84 +            c.await(timeOut);
   15.85 +        } catch (InterruptedException ex) {
   15.86 +            throw new IOException(ex);
   15.87 +        }
   15.88 +        return c;
   15.89 +    }
   15.90 +    
   15.91 +    public void setTimeout(long ms) {
   15.92 +        timeOut = ms;
   15.93 +    }
   15.94 +    
   15.95 +    public void addClassLoader(ClassLoader url) {
   15.96 +        this.loaders.add(url);
   15.97 +    }
   15.98 +    
   15.99 +    ClassLoader[] loaders() {
  15.100 +        return loaders.toArray(new ClassLoader[loaders.size()]);
  15.101 +    }
  15.102 +
  15.103 +    public void showURL(String startpage) throws IOException {
  15.104 +        if (!startpage.startsWith("/")) {
  15.105 +            startpage = "/" + startpage;
  15.106 +        }
  15.107 +        HttpServer s = initServer(".", true);
  15.108 +        int last = startpage.lastIndexOf('/');
  15.109 +        String prefix = startpage.substring(0, last);
  15.110 +        String simpleName = startpage.substring(last);
  15.111 +        s.getServerConfiguration().addHttpHandler(new SubTree(resources, prefix), "/");
  15.112 +        try {
  15.113 +            launchServerAndBrwsr(s, simpleName);
  15.114 +        } catch (URISyntaxException | InterruptedException ex) {
  15.115 +            throw new IOException(ex);
  15.116 +        }
  15.117 +    }
  15.118 +
  15.119 +    void showDirectory(File dir, String startpage) throws IOException {
  15.120 +        if (!startpage.startsWith("/")) {
  15.121 +            startpage = "/" + startpage;
  15.122 +        }
  15.123 +        HttpServer s = initServer(dir.getPath(), false);
  15.124 +        try {
  15.125 +            launchServerAndBrwsr(s, startpage);
  15.126 +        } catch (URISyntaxException | InterruptedException ex) {
  15.127 +            throw new IOException(ex);
  15.128 +        }
  15.129 +    }
  15.130 +
  15.131 +    @Override
  15.132 +    public void initialize() throws IOException {
  15.133 +        try {
  15.134 +            executeInBrowser();
  15.135 +        } catch (InterruptedException ex) {
  15.136 +            final InterruptedIOException iio = new InterruptedIOException(ex.getMessage());
  15.137 +            iio.initCause(ex);
  15.138 +            throw iio;
  15.139 +        } catch (Exception ex) {
  15.140 +            if (ex instanceof IOException) {
  15.141 +                throw (IOException)ex;
  15.142 +            }
  15.143 +            if (ex instanceof RuntimeException) {
  15.144 +                throw (RuntimeException)ex;
  15.145 +            }
  15.146 +            throw new IOException(ex);
  15.147 +        }
  15.148 +    }
  15.149 +    
  15.150 +    private HttpServer initServer(String path, boolean addClasses) throws IOException {
  15.151 +        HttpServer s = HttpServer.createSimpleServer(path, new PortRange(8080, 65535));
  15.152 +
  15.153 +        final ServerConfiguration conf = s.getServerConfiguration();
  15.154 +        if (addClasses) {
  15.155 +            conf.addHttpHandler(new VM(), "/bck2brwsr.js");
  15.156 +            conf.addHttpHandler(new Classes(resources), "/classes/");
  15.157 +        }
  15.158 +        return s;
  15.159 +    }
  15.160 +    
  15.161 +    private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
  15.162 +        wait = new CountDownLatch(1);
  15.163 +        server = initServer(".", true);
  15.164 +        final ServerConfiguration conf = server.getServerConfiguration();
  15.165 +        
  15.166 +        class DynamicResourceHandler extends HttpHandler {
  15.167 +            private final InvocationContext ic;
  15.168 +            public DynamicResourceHandler(InvocationContext ic) {
  15.169 +                if (ic == null || ic.resources.isEmpty()) {
  15.170 +                    throw new NullPointerException();
  15.171 +                }
  15.172 +                this.ic = ic;
  15.173 +                for (Resource r : ic.resources) {
  15.174 +                    conf.addHttpHandler(this, r.httpPath);
  15.175 +                }
  15.176 +            }
  15.177 +
  15.178 +            public void close() {
  15.179 +                conf.removeHttpHandler(this);
  15.180 +            }
  15.181 +            
  15.182 +            @Override
  15.183 +            public void service(Request request, Response response) throws Exception {
  15.184 +                for (Resource r : ic.resources) {
  15.185 +                    if (r.httpPath.equals(request.getRequestURI())) {
  15.186 +                        LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
  15.187 +                        response.setContentType(r.httpType);
  15.188 +                        r.httpContent.reset();
  15.189 +                        String[] params = null;
  15.190 +                        if (r.parameters.length != 0) {
  15.191 +                            params = new String[r.parameters.length];
  15.192 +                            for (int i = 0; i < r.parameters.length; i++) {
  15.193 +                                params[i] = request.getParameter(r.parameters[i]);
  15.194 +                            }
  15.195 +                        }
  15.196 +                        
  15.197 +                        copyStream(r.httpContent, response.getOutputStream(), null, params);
  15.198 +                    }
  15.199 +                }
  15.200 +            }
  15.201 +        }
  15.202 +        
  15.203 +        conf.addHttpHandler(new Page(resources, 
  15.204 +            "org/apidesign/bck2brwsr/launcher/fximpl/harness.xhtml"
  15.205 +        ), "/execute");
  15.206 +        
  15.207 +        conf.addHttpHandler(new HttpHandler() {
  15.208 +            int cnt;
  15.209 +            List<InvocationContext> cases = new ArrayList<>();
  15.210 +            DynamicResourceHandler prev;
  15.211 +            @Override
  15.212 +            public void service(Request request, Response response) throws Exception {
  15.213 +                String id = request.getParameter("request");
  15.214 +                String value = request.getParameter("result");
  15.215 +                if (value != null && value.indexOf((char)0xC5) != -1) {
  15.216 +                    value = toUTF8(value);
  15.217 +                }
  15.218 +                
  15.219 +                
  15.220 +                InvocationContext mi = null;
  15.221 +                int caseNmbr = -1;
  15.222 +                
  15.223 +                if (id != null && value != null) {
  15.224 +                    LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
  15.225 +                    value = decodeURL(value);
  15.226 +                    int indx = Integer.parseInt(id);
  15.227 +                    cases.get(indx).result(value, null);
  15.228 +                    if (++indx < cases.size()) {
  15.229 +                        mi = cases.get(indx);
  15.230 +                        LOG.log(Level.INFO, "Re-executing case {0}", indx);
  15.231 +                        caseNmbr = indx;
  15.232 +                    }
  15.233 +                } else {
  15.234 +                    if (!cases.isEmpty()) {
  15.235 +                        LOG.info("Re-executing test cases");
  15.236 +                        mi = cases.get(0);
  15.237 +                        caseNmbr = 0;
  15.238 +                    }
  15.239 +                }
  15.240 +                
  15.241 +                if (prev != null) {
  15.242 +                    prev.close();
  15.243 +                    prev = null;
  15.244 +                }
  15.245 +                
  15.246 +                if (mi == null) {
  15.247 +                    mi = methods.take();
  15.248 +                    caseNmbr = cnt++;
  15.249 +                }
  15.250 +                if (mi == END) {
  15.251 +                    response.getWriter().write("");
  15.252 +                    wait.countDown();
  15.253 +                    cnt = 0;
  15.254 +                    LOG.log(Level.INFO, "End of data reached. Exiting.");
  15.255 +                    return;
  15.256 +                }
  15.257 +                
  15.258 +                if (!mi.resources.isEmpty()) {
  15.259 +                    prev = new DynamicResourceHandler(mi);
  15.260 +                }
  15.261 +                
  15.262 +                cases.add(mi);
  15.263 +                final String cn = mi.clazz.getName();
  15.264 +                final String mn = mi.methodName;
  15.265 +                LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{caseNmbr, cn, mn});
  15.266 +                response.getWriter().write("{"
  15.267 +                    + "className: '" + cn + "', "
  15.268 +                    + "methodName: '" + mn + "', "
  15.269 +                    + "request: " + caseNmbr
  15.270 +                );
  15.271 +                if (mi.html != null) {
  15.272 +                    response.getWriter().write(", html: '");
  15.273 +                    response.getWriter().write(encodeJSON(mi.html));
  15.274 +                    response.getWriter().write("'");
  15.275 +                }
  15.276 +                response.getWriter().write("}");
  15.277 +            }
  15.278 +        }, "/data");
  15.279 +
  15.280 +        this.brwsr = launchServerAndBrwsr(server, "/execute");
  15.281 +    }
  15.282 +    
  15.283 +    private static String encodeJSON(String in) {
  15.284 +        StringBuilder sb = new StringBuilder();
  15.285 +        for (int i = 0; i < in.length(); i++) {
  15.286 +            char ch = in.charAt(i);
  15.287 +            if (ch < 32 || ch == '\'' || ch == '"') {
  15.288 +                sb.append("\\u");
  15.289 +                String hs = "0000" + Integer.toHexString(ch);
  15.290 +                hs = hs.substring(hs.length() - 4);
  15.291 +                sb.append(hs);
  15.292 +            } else {
  15.293 +                sb.append(ch);
  15.294 +            }
  15.295 +        }
  15.296 +        return sb.toString();
  15.297 +    }
  15.298 +    
  15.299 +    @Override
  15.300 +    public void shutdown() throws IOException {
  15.301 +        methods.offer(END);
  15.302 +        for (;;) {
  15.303 +            int prev = methods.size();
  15.304 +            try {
  15.305 +                if (wait != null && wait.await(timeOut, TimeUnit.MILLISECONDS)) {
  15.306 +                    break;
  15.307 +                }
  15.308 +            } catch (InterruptedException ex) {
  15.309 +                throw new IOException(ex);
  15.310 +            }
  15.311 +            if (prev == methods.size()) {
  15.312 +                LOG.log(
  15.313 +                    Level.WARNING, 
  15.314 +                    "Timeout and no test has been executed meanwhile (at {0}). Giving up.", 
  15.315 +                    methods.size()
  15.316 +                );
  15.317 +                break;
  15.318 +            }
  15.319 +            LOG.log(Level.INFO, 
  15.320 +                "Timeout, but tests got from {0} to {1}. Trying again.", 
  15.321 +                new Object[]{prev, methods.size()}
  15.322 +            );
  15.323 +        }
  15.324 +        stopServerAndBrwsr(server, brwsr);
  15.325 +    }
  15.326 +    
  15.327 +    static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
  15.328 +        for (;;) {
  15.329 +            int ch = is.read();
  15.330 +            if (ch == -1) {
  15.331 +                break;
  15.332 +            }
  15.333 +            if (ch == '$' && params.length > 0) {
  15.334 +                int cnt = is.read() - '0';
  15.335 +                if (baseURL != null && cnt == 'U' - '0') {
  15.336 +                    os.write(baseURL.getBytes("UTF-8"));
  15.337 +                } else {
  15.338 +                    if (cnt >= 0 && cnt < params.length) {
  15.339 +                        os.write(params[cnt].getBytes("UTF-8"));
  15.340 +                    } else {
  15.341 +                        os.write('$');
  15.342 +                        os.write(cnt + '0');
  15.343 +                    }
  15.344 +                }
  15.345 +            } else {
  15.346 +                os.write(ch);
  15.347 +            }
  15.348 +        }
  15.349 +    }
  15.350 +
  15.351 +    private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
  15.352 +        server.start();
  15.353 +        NetworkListener listener = server.getListeners().iterator().next();
  15.354 +        int port = listener.getPort();
  15.355 +        
  15.356 +        URI uri = new URI("http://localhost:" + port + page);
  15.357 +        return showBrwsr(uri);
  15.358 +    }
  15.359 +    private static String toUTF8(String value) throws UnsupportedEncodingException {
  15.360 +        byte[] arr = new byte[value.length()];
  15.361 +        for (int i = 0; i < arr.length; i++) {
  15.362 +            arr[i] = (byte)value.charAt(i);
  15.363 +        }
  15.364 +        return new String(arr, "UTF-8");
  15.365 +    }
  15.366 +    
  15.367 +    private static String decodeURL(String s) {
  15.368 +        for (;;) {
  15.369 +            int pos = s.indexOf('%');
  15.370 +            if (pos == -1) {
  15.371 +                return s;
  15.372 +            }
  15.373 +            int i = Integer.parseInt(s.substring(pos + 1, pos + 2), 16);
  15.374 +            s = s.substring(0, pos) + (char)i + s.substring(pos + 2);
  15.375 +        }
  15.376 +    }
  15.377 +    
  15.378 +    private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException {
  15.379 +        if (brwsr == null) {
  15.380 +            return;
  15.381 +        }
  15.382 +        Process process = (Process)brwsr[0];
  15.383 +        
  15.384 +        server.stop();
  15.385 +        InputStream stdout = process.getInputStream();
  15.386 +        InputStream stderr = process.getErrorStream();
  15.387 +        drain("StdOut", stdout);
  15.388 +        drain("StdErr", stderr);
  15.389 +        process.destroy();
  15.390 +        int res;
  15.391 +        try {
  15.392 +            res = process.waitFor();
  15.393 +        } catch (InterruptedException ex) {
  15.394 +            throw new IOException(ex);
  15.395 +        }
  15.396 +        LOG.log(Level.INFO, "Exit code: {0}", res);
  15.397 +
  15.398 +        deleteTree((File)brwsr[1]);
  15.399 +    }
  15.400 +    
  15.401 +    private static void drain(String name, InputStream is) throws IOException {
  15.402 +        int av = is.available();
  15.403 +        if (av > 0) {
  15.404 +            StringBuilder sb = new StringBuilder();
  15.405 +            sb.append("v== ").append(name).append(" ==v\n");
  15.406 +            while (av-- > 0) {
  15.407 +                sb.append((char)is.read());
  15.408 +            }
  15.409 +            sb.append("\n^== ").append(name).append(" ==^");
  15.410 +            LOG.log(Level.INFO, sb.toString());
  15.411 +        }
  15.412 +    }
  15.413 +
  15.414 +    private void deleteTree(File file) {
  15.415 +        if (file == null) {
  15.416 +            return;
  15.417 +        }
  15.418 +        File[] arr = file.listFiles();
  15.419 +        if (arr != null) {
  15.420 +            for (File s : arr) {
  15.421 +                deleteTree(s);
  15.422 +            }
  15.423 +        }
  15.424 +        file.delete();
  15.425 +    }
  15.426 +
  15.427 +    @Override
  15.428 +    public void close() throws IOException {
  15.429 +        shutdown();
  15.430 +    }
  15.431 +
  15.432 +    protected Object[] showBrwsr(URI uri) throws IOException {
  15.433 +        LOG.log(Level.INFO, "Showing {0}", uri);
  15.434 +        if (cmd == null) {
  15.435 +            try {
  15.436 +                LOG.log(Level.INFO, "Trying Desktop.browse on {0} {2} by {1}", new Object[] {
  15.437 +                    System.getProperty("java.vm.name"),
  15.438 +                    System.getProperty("java.vm.vendor"),
  15.439 +                    System.getProperty("java.vm.version"),
  15.440 +                });
  15.441 +                java.awt.Desktop.getDesktop().browse(uri);
  15.442 +                LOG.log(Level.INFO, "Desktop.browse successfully finished");
  15.443 +                return null;
  15.444 +            } catch (UnsupportedOperationException ex) {
  15.445 +                LOG.log(Level.INFO, "Desktop.browse not supported: {0}", ex.getMessage());
  15.446 +                LOG.log(Level.FINE, null, ex);
  15.447 +            }
  15.448 +        }
  15.449 +        {
  15.450 +            String cmdName = cmd == null ? "xdg-open" : cmd;
  15.451 +            String[] cmdArr = { 
  15.452 +                cmdName, uri.toString()
  15.453 +            };
  15.454 +            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmdArr));
  15.455 +            final Process process = Runtime.getRuntime().exec(cmdArr);
  15.456 +            return new Object[] { process, null };
  15.457 +        }
  15.458 +    }
  15.459 +
  15.460 +    abstract void generateBck2BrwsrJS(StringBuilder sb, Object loader) throws IOException;
  15.461 +
  15.462 +    private class Res {
  15.463 +        public InputStream get(String resource) throws IOException {
  15.464 +            for (ClassLoader l : loaders) {
  15.465 +                URL u = null;
  15.466 +                Enumeration<URL> en = l.getResources(resource);
  15.467 +                while (en.hasMoreElements()) {
  15.468 +                    u = en.nextElement();
  15.469 +                }
  15.470 +                if (u != null) {
  15.471 +                    return u.openStream();
  15.472 +                }
  15.473 +            }
  15.474 +            throw new IOException("Can't find " + resource);
  15.475 +        }
  15.476 +    }
  15.477 +
  15.478 +    private static class Page extends HttpHandler {
  15.479 +        final String resource;
  15.480 +        private final String[] args;
  15.481 +        private final Res res;
  15.482 +        
  15.483 +        public Page(Res res, String resource, String... args) {
  15.484 +            this.res = res;
  15.485 +            this.resource = resource;
  15.486 +            this.args = args.length == 0 ? new String[] { "$0" } : args;
  15.487 +        }
  15.488 +
  15.489 +        @Override
  15.490 +        public void service(Request request, Response response) throws Exception {
  15.491 +            String r = computePage(request);
  15.492 +            if (r.startsWith("/")) {
  15.493 +                r = r.substring(1);
  15.494 +            }
  15.495 +            String[] replace = {};
  15.496 +            if (r.endsWith(".html")) {
  15.497 +                response.setContentType("text/html");
  15.498 +                LOG.info("Content type text/html");
  15.499 +                replace = args;
  15.500 +            }
  15.501 +            if (r.endsWith(".xhtml")) {
  15.502 +                response.setContentType("application/xhtml+xml");
  15.503 +                LOG.info("Content type application/xhtml+xml");
  15.504 +                replace = args;
  15.505 +            }
  15.506 +            OutputStream os = response.getOutputStream();
  15.507 +            try (InputStream is = res.get(r)) {
  15.508 +                copyStream(is, os, request.getRequestURL().toString(), replace);
  15.509 +            } catch (IOException ex) {
  15.510 +                response.setDetailMessage(ex.getLocalizedMessage());
  15.511 +                response.setError();
  15.512 +                response.setStatus(404);
  15.513 +            }
  15.514 +        }
  15.515 +
  15.516 +        protected String computePage(Request request) {
  15.517 +            String r = resource;
  15.518 +            if (r == null) {
  15.519 +                r = request.getHttpHandlerPath();
  15.520 +            }
  15.521 +            return r;
  15.522 +        }
  15.523 +    }
  15.524 +    
  15.525 +    private static class SubTree extends Page {
  15.526 +
  15.527 +        public SubTree(Res res, String resource, String... args) {
  15.528 +            super(res, resource, args);
  15.529 +        }
  15.530 +
  15.531 +        @Override
  15.532 +        protected String computePage(Request request) {
  15.533 +            return resource + request.getHttpHandlerPath();
  15.534 +        }
  15.535 +        
  15.536 +        
  15.537 +    }
  15.538 +
  15.539 +    private class VM extends HttpHandler {
  15.540 +        @Override
  15.541 +        public void service(Request request, Response response) throws Exception {
  15.542 +            response.setCharacterEncoding("UTF-8");
  15.543 +            response.setContentType("text/javascript");
  15.544 +            StringBuilder sb = new StringBuilder();
  15.545 +            generateBck2BrwsrJS(sb, BaseHTTPLauncher.this.resources);
  15.546 +            response.getWriter().write(sb.toString());
  15.547 +        }
  15.548 +    }
  15.549 +
  15.550 +    private static class Classes extends HttpHandler {
  15.551 +        private final Res loader;
  15.552 +
  15.553 +        public Classes(Res loader) {
  15.554 +            this.loader = loader;
  15.555 +        }
  15.556 +
  15.557 +        @Override
  15.558 +        public void service(Request request, Response response) throws Exception {
  15.559 +            String res = request.getHttpHandlerPath();
  15.560 +            if (res.startsWith("/")) {
  15.561 +                res = res.substring(1);
  15.562 +            }
  15.563 +            try (InputStream is = loader.get(res)) {
  15.564 +                response.setContentType("text/javascript");
  15.565 +                Writer w = response.getWriter();
  15.566 +                w.append("[");
  15.567 +                for (int i = 0;; i++) {
  15.568 +                    int b = is.read();
  15.569 +                    if (b == -1) {
  15.570 +                        break;
  15.571 +                    }
  15.572 +                    if (i > 0) {
  15.573 +                        w.append(", ");
  15.574 +                    }
  15.575 +                    if (i % 20 == 0) {
  15.576 +                        w.write("\n");
  15.577 +                    }
  15.578 +                    if (b > 127) {
  15.579 +                        b = b - 256;
  15.580 +                    }
  15.581 +                    w.append(Integer.toString(b));
  15.582 +                }
  15.583 +                w.append("\n]");
  15.584 +            } catch (IOException ex) {
  15.585 +                response.setStatus(HttpStatus.NOT_FOUND_404);
  15.586 +                response.setError();
  15.587 +                response.setDetailMessage(ex.getMessage());
  15.588 +            }
  15.589 +        }
  15.590 +    }
  15.591 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java	Mon Apr 29 16:32:14 2013 +0200
    16.3 @@ -0,0 +1,129 @@
    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.launcher;
   16.22 +
   16.23 +import org.apidesign.bck2brwsr.launcher.fximpl.FXBrwsr;
   16.24 +import java.io.IOException;
   16.25 +import java.io.InputStream;
   16.26 +import java.lang.reflect.Method;
   16.27 +import java.net.URI;
   16.28 +import java.net.URL;
   16.29 +import java.net.URLClassLoader;
   16.30 +import java.util.Enumeration;
   16.31 +
   16.32 +import java.util.concurrent.Executors;
   16.33 +import java.util.jar.Manifest;
   16.34 +import java.util.logging.Level;
   16.35 +import java.util.logging.Logger;
   16.36 +import javafx.application.Platform;
   16.37 +import org.apidesign.bck2brwsr.launcher.fximpl.JVMBridge;
   16.38 +
   16.39 +/**
   16.40 + *
   16.41 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   16.42 + */
   16.43 +final class FXBrwsrLauncher extends BaseHTTPLauncher {
   16.44 +    private static final Logger LOG = Logger.getLogger(FXBrwsrLauncher.class.getName());
   16.45 +    static {
   16.46 +        try {
   16.47 +            Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
   16.48 +            m.setAccessible(true);
   16.49 +            URL l = new URL("file://" + System.getProperty("java.home") + "/lib/jfxrt.jar");
   16.50 +            LOG.log(Level.INFO, "url : {0}", l);
   16.51 +            m.invoke(ClassLoader.getSystemClassLoader(), l);
   16.52 +        } catch (Exception ex) {
   16.53 +            throw new LinkageError("Can't add jfxrt.jar on the classpath", ex);
   16.54 +        }
   16.55 +    }
   16.56 +
   16.57 +    public FXBrwsrLauncher(String ignore) {
   16.58 +        super(null);
   16.59 +    }
   16.60 +
   16.61 +    @Override
   16.62 +    protected Object[] showBrwsr(final URI url) throws IOException {
   16.63 +        try {
   16.64 +            LOG.log(Level.INFO, "showBrwsr for {0}", url);
   16.65 +            JVMBridge.registerClassLoaders(loaders());
   16.66 +            LOG.info("About to launch WebView");
   16.67 +            Executors.newSingleThreadExecutor().submit(new Runnable() {
   16.68 +                @Override
   16.69 +                public void run() {
   16.70 +                    LOG.log(Level.INFO, "In FX thread. Launching!");
   16.71 +                    try {
   16.72 +                        FXBrwsr.launch(FXBrwsr.class, url.toString());
   16.73 +                        LOG.log(Level.INFO, "Launcher is back. Closing");
   16.74 +                        close();
   16.75 +                    } catch (Throwable ex) {
   16.76 +                        LOG.log(Level.WARNING, "Error launching Web View", ex);
   16.77 +                    }
   16.78 +                }
   16.79 +            });
   16.80 +        } catch (Throwable ex) {
   16.81 +            LOG.log(Level.WARNING, "Can't open WebView", ex);
   16.82 +        }
   16.83 +        return null;
   16.84 +    }
   16.85 +    
   16.86 +    @Override
   16.87 +    void generateBck2BrwsrJS(StringBuilder sb, Object loader) throws IOException {
   16.88 +        sb.append("(function() {\n"
   16.89 +            + "  var impl = this.bck2brwsr;\n"
   16.90 +            + "  this.bck2brwsr = function() { return impl; };\n"
   16.91 +            + "})(window);\n"
   16.92 +        );
   16.93 +        JVMBridge.onBck2BrwsrLoad();
   16.94 +    }
   16.95 +    
   16.96 +    
   16.97 +    
   16.98 +    @Override
   16.99 +    public void close() throws IOException {
  16.100 +        super.close();
  16.101 +        Platform.exit();
  16.102 +    }
  16.103 +
  16.104 +    public static void main(String... args) throws IOException {
  16.105 +        String startPage = null;
  16.106 +
  16.107 +        final ClassLoader cl = FXBrwsrLauncher.class.getClassLoader();
  16.108 +        startPage = findStartPage(cl, startPage);
  16.109 +        if (startPage == null) {
  16.110 +            throw new NullPointerException("Can't find StartPage tag in manifests!");
  16.111 +        }
  16.112 +        
  16.113 +        Launcher.showURL("fxbrwsr", cl, startPage);
  16.114 +    }
  16.115 +    
  16.116 +    private static String findStartPage(final ClassLoader cl, String startPage) throws IOException {
  16.117 +        Enumeration<URL> en = cl.getResources("META-INF/MANIFEST.MF");
  16.118 +        while (en.hasMoreElements()) {
  16.119 +            URL url = en.nextElement();
  16.120 +            Manifest mf;
  16.121 +            try (InputStream is = url.openStream()) {
  16.122 +                mf = new Manifest(is);
  16.123 +            }
  16.124 +            String sp = mf.getMainAttributes().getValue("StartPage");
  16.125 +            if (sp != null) {
  16.126 +                startPage = sp;
  16.127 +                break;
  16.128 +            }
  16.129 +        }
  16.130 +        return startPage;
  16.131 +    }
  16.132 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Console.java	Mon Apr 29 16:32:14 2013 +0200
    17.3 @@ -0,0 +1,395 @@
    17.4 +/**
    17.5 + * Back 2 Browser Bytecode Translator
    17.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    17.7 + *
    17.8 + * This program is free software: you can redistribute it and/or modify
    17.9 + * it under the terms of the GNU General Public License as published by
   17.10 + * the Free Software Foundation, version 2 of the License.
   17.11 + *
   17.12 + * This program is distributed in the hope that it will be useful,
   17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.15 + * GNU General Public License for more details.
   17.16 + *
   17.17 + * You should have received a copy of the GNU General Public License
   17.18 + * along with this program. Look for COPYING file in the top folder.
   17.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   17.20 + */
   17.21 +package org.apidesign.bck2brwsr.launcher.fximpl;
   17.22 +
   17.23 +import java.io.IOException;
   17.24 +import java.io.InputStream;
   17.25 +import java.io.UnsupportedEncodingException;
   17.26 +import java.lang.reflect.InvocationTargetException;
   17.27 +import java.lang.reflect.Method;
   17.28 +import java.lang.reflect.Modifier;
   17.29 +import java.net.URL;
   17.30 +import java.util.Enumeration;
   17.31 +import javafx.scene.web.WebEngine;
   17.32 +import netscape.javascript.JSObject;
   17.33 +
   17.34 +/**
   17.35 + *
   17.36 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   17.37 + */
   17.38 +public final class Console {
   17.39 +    public Console() {
   17.40 +    }
   17.41 +    
   17.42 +    private static Object getAttr(Object elem, String attr) {
   17.43 +        return InvokeJS.CObject.call("getAttr", elem, attr);
   17.44 +    }
   17.45 +
   17.46 +    private static void setAttr(String id, String attr, Object value) {
   17.47 +        InvokeJS.CObject.call("setAttrId", id, attr, value);
   17.48 +    }
   17.49 +    private static void setAttr(Object id, String attr, Object value) {
   17.50 +        InvokeJS.CObject.call("setAttr", id, attr, value);
   17.51 +    }
   17.52 +    
   17.53 +    private static void closeWindow() {}
   17.54 +
   17.55 +    private static Object textArea;
   17.56 +    private static Object statusArea;
   17.57 +    
   17.58 +    private static void log(String newText) {
   17.59 +        if (textArea == null) {
   17.60 +            return;
   17.61 +        }
   17.62 +        String attr = "value";
   17.63 +        setAttr(textArea, attr, getAttr(textArea, attr) + "\n" + newText);
   17.64 +        setAttr(textArea, "scrollTop", getAttr(textArea, "scrollHeight"));
   17.65 +    }
   17.66 +    
   17.67 +    private static void beginTest(Case c) {
   17.68 +        Object[] arr = new Object[2];
   17.69 +        beginTest(c.getClassName() + "." + c.getMethodName(), c, arr);
   17.70 +        textArea = arr[0];
   17.71 +        statusArea = arr[1];
   17.72 +    }
   17.73 +    
   17.74 +    private static void finishTest(Case c, Object res) {
   17.75 +        if ("null".equals(res)) {
   17.76 +            setAttr(statusArea, "innerHTML", "Success");
   17.77 +        } else {
   17.78 +            setAttr(statusArea, "innerHTML", "Result " + res);
   17.79 +        }
   17.80 +        statusArea = null;
   17.81 +        textArea = null;
   17.82 +    }
   17.83 +
   17.84 +    private static final String BEGIN_TEST =  
   17.85 +        "var ul = window.document.getElementById('bck2brwsr.result');\n"
   17.86 +        + "var li = window.document.createElement('li');\n"
   17.87 +        + "var span = window.document.createElement('span');"
   17.88 +        + "span.innerHTML = test + ' - ';\n"
   17.89 +        + "var details = window.document.createElement('a');\n"
   17.90 +        + "details.innerHTML = 'Details';\n"
   17.91 +        + "details.href = '#';\n"
   17.92 +        + "var p = window.document.createElement('p');\n"
   17.93 +        + "var status = window.document.createElement('a');\n"
   17.94 +        + "status.innerHTML = 'running';"
   17.95 +        + "details.onclick = function() { li.appendChild(p); li.removeChild(details); status.innerHTML = 'Run Again'; status.href = '#'; };\n"
   17.96 +        + "status.onclick = function() { c.again(arr); }\n"
   17.97 +        + "var pre = window.document.createElement('textarea');\n"
   17.98 +        + "pre.cols = 100;"
   17.99 +        + "pre.rows = 10;"
  17.100 +        + "li.appendChild(span);\n"
  17.101 +        + "li.appendChild(status);\n"
  17.102 +        + "var span = window.document.createElement('span');"
  17.103 +        + "span.innerHTML = ' ';\n"
  17.104 +        + "li.appendChild(span);\n"
  17.105 +        + "li.appendChild(details);\n"
  17.106 +        + "p.appendChild(pre);\n"
  17.107 +        + "ul.appendChild(li);\n"
  17.108 +        + "arr[0] = pre;\n"
  17.109 +        + "arr[1] = status;\n";
  17.110 +        
  17.111 +    private static void beginTest(String test, Case c, Object[] arr) {
  17.112 +        InvokeJS.CObject.call("beginTest", test, c, arr);
  17.113 +    }
  17.114 +    
  17.115 +    private static final String LOAD_TEXT = 
  17.116 +          "var request = new XMLHttpRequest();\n"
  17.117 +        + "request.open('GET', url, true);\n"
  17.118 +        + "request.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');\n"
  17.119 +        + "request.onreadystatechange = function() {\n"
  17.120 +        + "  if (this.readyState!==4) return;\n"
  17.121 +        + " try {"
  17.122 +        + "  arr[0] = this.responseText;\n"
  17.123 +        + "  callback.run__V();\n"
  17.124 +        + " } catch (e) { alert(e); }"
  17.125 +        + "};"
  17.126 +        + "request.send();";
  17.127 +    private static void loadText(String url, Runnable callback, String[] arr) throws IOException {
  17.128 +        InvokeJS.CObject.call("loadText", url, new Run(callback), arr);
  17.129 +    }
  17.130 +    
  17.131 +    public static void runHarness(String url) throws IOException {
  17.132 +        new Console().harness(url);
  17.133 +    }
  17.134 +    
  17.135 +    public void harness(String url) throws IOException {
  17.136 +        log("Connecting to " + url);
  17.137 +        Request r = new Request(url);
  17.138 +    }
  17.139 +    
  17.140 +    private static class Request implements Runnable {
  17.141 +        private final String[] arr = { null };
  17.142 +        private final String url;
  17.143 +        private Case c;
  17.144 +        private int retries;
  17.145 +
  17.146 +        private Request(String url) throws IOException {
  17.147 +            this.url = url;
  17.148 +            loadText(url, this, arr);
  17.149 +        }
  17.150 +        private Request(String url, String u) throws IOException {
  17.151 +            this.url = url;
  17.152 +            loadText(u, this, arr);
  17.153 +        }
  17.154 +        
  17.155 +        @Override
  17.156 +        public void run() {
  17.157 +            try {
  17.158 +                if (c == null) {
  17.159 +                    String data = arr[0];
  17.160 +
  17.161 +                    if (data == null) {
  17.162 +                        log("Some error exiting");
  17.163 +                        closeWindow();
  17.164 +                        return;
  17.165 +                    }
  17.166 +
  17.167 +                    if (data.isEmpty()) {
  17.168 +                        log("No data, exiting");
  17.169 +                        closeWindow();
  17.170 +                        return;
  17.171 +                    }
  17.172 +
  17.173 +                    c = Case.parseData(data);
  17.174 +                    beginTest(c);
  17.175 +                    log("Got \"" + data + "\"");
  17.176 +                } else {
  17.177 +                    log("Processing \"" + arr[0] + "\" for " + retries + " time");
  17.178 +                }
  17.179 +                Object result = retries++ >= 10 ? "java.lang.InterruptedException:timeout" : c.runTest();
  17.180 +                finishTest(c, result);
  17.181 +                
  17.182 +                String u = url + "?request=" + c.getRequestId() + "&result=" + result;
  17.183 +                new Request(url, u);
  17.184 +            } catch (Exception ex) {
  17.185 +                if (ex instanceof InterruptedException) {
  17.186 +                    log("Re-scheduling in 100ms");
  17.187 +                    schedule(this, 100);
  17.188 +                    return;
  17.189 +                }
  17.190 +                log(ex.getClass().getName() + ":" + ex.getMessage());
  17.191 +            }
  17.192 +        }
  17.193 +    }
  17.194 +    
  17.195 +    private static String encodeURL(String r) throws UnsupportedEncodingException {
  17.196 +        final String SPECIAL = "%$&+,/:;=?@";
  17.197 +        StringBuilder sb = new StringBuilder();
  17.198 +        byte[] utf8 = r.getBytes("UTF-8");
  17.199 +        for (int i = 0; i < utf8.length; i++) {
  17.200 +            int ch = utf8[i] & 0xff;
  17.201 +            if (ch < 32 || ch > 127 || SPECIAL.indexOf(ch) >= 0) {
  17.202 +                final String numbers = "0" + Integer.toHexString(ch);
  17.203 +                sb.append("%").append(numbers.substring(numbers.length() - 2));
  17.204 +            } else {
  17.205 +                if (ch == 32) {
  17.206 +                    sb.append("+");
  17.207 +                } else {
  17.208 +                    sb.append((char)ch);
  17.209 +                }
  17.210 +            }
  17.211 +        }
  17.212 +        return sb.toString();
  17.213 +    }
  17.214 +    
  17.215 +    static String invoke(String clazz, String method) throws 
  17.216 +    ClassNotFoundException, InvocationTargetException, IllegalAccessException, 
  17.217 +    InstantiationException, InterruptedException {
  17.218 +        final Object r = new Case(null).invokeMethod(clazz, method);
  17.219 +        return r == null ? "null" : r.toString().toString();
  17.220 +    }
  17.221 +
  17.222 +    /** Helper method that inspects the classpath and loads given resource
  17.223 +     * (usually a class file). Used while running tests in Rhino.
  17.224 +     * 
  17.225 +     * @param name resource name to find
  17.226 +     * @return the array of bytes in the given resource
  17.227 +     * @throws IOException I/O in case something goes wrong
  17.228 +     */
  17.229 +    public static byte[] read(String name) throws IOException {
  17.230 +        URL u = null;
  17.231 +        Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
  17.232 +        while (en.hasMoreElements()) {
  17.233 +            u = en.nextElement();
  17.234 +        }
  17.235 +        if (u == null) {
  17.236 +            throw new IOException("Can't find " + name);
  17.237 +        }
  17.238 +        try (InputStream is = u.openStream()) {
  17.239 +            byte[] arr;
  17.240 +            arr = new byte[is.available()];
  17.241 +            int offset = 0;
  17.242 +            while (offset < arr.length) {
  17.243 +                int len = is.read(arr, offset, arr.length - offset);
  17.244 +                if (len == -1) {
  17.245 +                    throw new IOException("Can't read " + name);
  17.246 +                }
  17.247 +                offset += len;
  17.248 +            }
  17.249 +            return arr;
  17.250 +        }
  17.251 +    }
  17.252 +   
  17.253 +    private static void turnAssetionStatusOn() {
  17.254 +    }
  17.255 +
  17.256 +    private static Object schedule(Runnable r, int time) {
  17.257 +        return InvokeJS.CObject.call("schedule", new Run(r), time);
  17.258 +    }
  17.259 +    
  17.260 +    private static final class Case {
  17.261 +        private final Object data;
  17.262 +        private Object inst;
  17.263 +
  17.264 +        private Case(Object data) {
  17.265 +            this.data = data;
  17.266 +        }
  17.267 +        
  17.268 +        public static Case parseData(String s) {
  17.269 +            return new Case(toJSON(s));
  17.270 +        }
  17.271 +        
  17.272 +        public String getMethodName() {
  17.273 +            return (String) value("methodName", data);
  17.274 +        }
  17.275 +
  17.276 +        public String getClassName() {
  17.277 +            return (String) value("className", data);
  17.278 +        }
  17.279 +        
  17.280 +        public int getRequestId() {
  17.281 +            Object v = value("request", data);
  17.282 +            if (v instanceof Number) {
  17.283 +                return ((Number)v).intValue();
  17.284 +            }
  17.285 +            return Integer.parseInt(v.toString());
  17.286 +        }
  17.287 +
  17.288 +        public String getHtmlFragment() {
  17.289 +            return (String) value("html", data);
  17.290 +        }
  17.291 +        
  17.292 +        void again(Object[] arr) {
  17.293 +            try {
  17.294 +                textArea = arr[0];
  17.295 +                statusArea = arr[1];
  17.296 +                setAttr(textArea, "value", "");
  17.297 +                runTest();
  17.298 +            } catch (Exception ex) {
  17.299 +                log(ex.getClass().getName() + ":" + ex.getMessage());
  17.300 +            }
  17.301 +        }
  17.302 +
  17.303 +        private Object runTest() throws IllegalAccessException, 
  17.304 +        IllegalArgumentException, ClassNotFoundException, UnsupportedEncodingException, 
  17.305 +        InvocationTargetException, InstantiationException, InterruptedException {
  17.306 +            if (this.getHtmlFragment() != null) {
  17.307 +                setAttr("bck2brwsr.fragment", "innerHTML", this.getHtmlFragment());
  17.308 +            }
  17.309 +            log("Invoking " + this.getClassName() + '.' + this.getMethodName() + " as request: " + this.getRequestId());
  17.310 +            Object result = invokeMethod(this.getClassName(), this.getMethodName());
  17.311 +            setAttr("bck2brwsr.fragment", "innerHTML", "");
  17.312 +            log("Result: " + result);
  17.313 +            result = encodeURL("" + result);
  17.314 +            log("Sending back: ...?request=" + this.getRequestId() + "&result=" + result);
  17.315 +            return result;
  17.316 +        }
  17.317 +
  17.318 +        private Object invokeMethod(String clazz, String method)
  17.319 +        throws ClassNotFoundException, InvocationTargetException,
  17.320 +        InterruptedException, IllegalAccessException, IllegalArgumentException,
  17.321 +        InstantiationException {
  17.322 +            Method found = null;
  17.323 +            Class<?> c = Class.forName(clazz);
  17.324 +            for (Method m : c.getMethods()) {
  17.325 +                if (m.getName().equals(method)) {
  17.326 +                    found = m;
  17.327 +                }
  17.328 +            }
  17.329 +            Object res;
  17.330 +            if (found != null) {
  17.331 +                try {
  17.332 +                    if ((found.getModifiers() & Modifier.STATIC) != 0) {
  17.333 +                        res = found.invoke(null);
  17.334 +                    } else {
  17.335 +                        if (inst == null) {
  17.336 +                            inst = c.newInstance();
  17.337 +                        }
  17.338 +                        res = found.invoke(inst);
  17.339 +                    }
  17.340 +                } catch (Throwable ex) {
  17.341 +                    if (ex instanceof InvocationTargetException) {
  17.342 +                        ex = ((InvocationTargetException) ex).getTargetException();
  17.343 +                    }
  17.344 +                    if (ex instanceof InterruptedException) {
  17.345 +                        throw (InterruptedException)ex;
  17.346 +                    }
  17.347 +                    res = ex.getClass().getName() + ":" + ex.getMessage();
  17.348 +                }
  17.349 +            } else {
  17.350 +                res = "Can't find method " + method + " in " + clazz;
  17.351 +            }
  17.352 +            return res;
  17.353 +        }
  17.354 +        
  17.355 +        private static Object toJSON(String s) {
  17.356 +            return InvokeJS.CObject.call("toJSON", s);
  17.357 +        }
  17.358 +        
  17.359 +        private static Object value(String p, Object d) {
  17.360 +            return ((JSObject)d).getMember(p);
  17.361 +        }
  17.362 +    }
  17.363 +    
  17.364 +    private static String safe(String txt) {
  17.365 +        return "try {" + txt + "} catch (err) { alert(err); }";
  17.366 +    }
  17.367 +    
  17.368 +    static {
  17.369 +        turnAssetionStatusOn();
  17.370 +    }
  17.371 +    
  17.372 +    private static final class InvokeJS {
  17.373 +        static final JSObject CObject = initJS();
  17.374 +
  17.375 +        private static JSObject initJS() {
  17.376 +            WebEngine web = (WebEngine) System.getProperties().get("webEngine");
  17.377 +            return (JSObject) web.executeScript("(function() {"
  17.378 +                + "var CObject = {};"
  17.379 +
  17.380 +                + "CObject.getAttr = function(elem, attr) { return elem[attr].toString(); };"
  17.381 +
  17.382 +                + "CObject.setAttrId = function(id, attr, value) { window.document.getElementById(id)[attr] = value; };"
  17.383 +                + "CObject.setAttr = function(elem, attr, value) { elem[attr] = value; };"
  17.384 +
  17.385 +                + "CObject.beginTest = function(test, c, arr) {" + safe(BEGIN_TEST) + "};"
  17.386 +
  17.387 +                + "CObject.loadText = function(url, callback, arr) {" + safe(LOAD_TEXT.replace("run__V", "run")) + "};"
  17.388 +
  17.389 +                + "CObject.schedule = function(r, time) { return window.setTimeout(function() { r.run(); }, time); };"
  17.390 +
  17.391 +                + "CObject.toJSON = function(s) { return eval('(' + s + ')'); };"
  17.392 +
  17.393 +                + "return CObject;"
  17.394 +            + "})(this)");
  17.395 +        }
  17.396 +    }
  17.397 +    
  17.398 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/FXBrwsr.java	Mon Apr 29 16:32:14 2013 +0200
    18.3 @@ -0,0 +1,184 @@
    18.4 +/**
    18.5 + * Back 2 Browser Bytecode Translator
    18.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    18.7 + *
    18.8 + * This program is free software: you can redistribute it and/or modify
    18.9 + * it under the terms of the GNU General Public License as published by
   18.10 + * the Free Software Foundation, version 2 of the License.
   18.11 + *
   18.12 + * This program is distributed in the hope that it will be useful,
   18.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.15 + * GNU General Public License for more details.
   18.16 + *
   18.17 + * You should have received a copy of the GNU General Public License
   18.18 + * along with this program. Look for COPYING file in the top folder.
   18.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   18.20 + */
   18.21 +package org.apidesign.bck2brwsr.launcher.fximpl;
   18.22 +
   18.23 +import java.util.List;
   18.24 +import java.util.TooManyListenersException;
   18.25 +import java.util.logging.Level;
   18.26 +import java.util.logging.Logger;
   18.27 +import javafx.application.Application;
   18.28 +import javafx.application.Platform;
   18.29 +import javafx.beans.value.ChangeListener;
   18.30 +import javafx.beans.value.ObservableValue;
   18.31 +import javafx.event.ActionEvent;
   18.32 +import javafx.event.EventHandler;
   18.33 +import javafx.geometry.HPos;
   18.34 +import javafx.geometry.Insets;
   18.35 +import javafx.geometry.Pos;
   18.36 +import javafx.geometry.VPos;
   18.37 +import javafx.scene.Node;
   18.38 +import javafx.scene.Scene;
   18.39 +import javafx.scene.control.Button;
   18.40 +import javafx.scene.layout.ColumnConstraints;
   18.41 +import javafx.scene.layout.GridPane;
   18.42 +import javafx.scene.layout.Pane;
   18.43 +import javafx.scene.layout.Priority;
   18.44 +import javafx.scene.layout.VBox;
   18.45 +import javafx.scene.text.Text;
   18.46 +import javafx.scene.web.WebEngine;
   18.47 +import javafx.scene.web.WebEvent;
   18.48 +import javafx.scene.web.WebView;
   18.49 +import javafx.stage.Modality;
   18.50 +import javafx.stage.Stage;
   18.51 +import netscape.javascript.JSObject;
   18.52 +
   18.53 +/**
   18.54 + * Demonstrates a WebView object accessing a web page.
   18.55 + *
   18.56 + * @see javafx.scene.web.WebView
   18.57 + * @see javafx.scene.web.WebEngine
   18.58 + */
   18.59 +public class FXBrwsr extends Application {
   18.60 +    private static final Logger LOG = Logger.getLogger(FXBrwsr.class.getName());
   18.61 +
   18.62 +    @Override
   18.63 +    public void start(Stage primaryStage) throws Exception {
   18.64 +        Pane root = new WebViewPane(getParameters().getUnnamed());
   18.65 +        primaryStage.setScene(new Scene(root, 1024, 768));
   18.66 +        LOG.info("Showing the stage");
   18.67 +        primaryStage.show();
   18.68 +        LOG.log(Level.INFO, "State shown: {0}", primaryStage.isShowing());
   18.69 +    }
   18.70 +    
   18.71 +    /**
   18.72 +     * Create a resizable WebView pane
   18.73 +     */
   18.74 +    private class WebViewPane extends Pane {
   18.75 +        private final JVMBridge bridge = new JVMBridge();
   18.76 +
   18.77 +        public WebViewPane(List<String> params) {
   18.78 +            LOG.log(Level.INFO, "Initializing WebView with {0}", params);
   18.79 +            VBox.setVgrow(this, Priority.ALWAYS);
   18.80 +            setMaxWidth(Double.MAX_VALUE);
   18.81 +            setMaxHeight(Double.MAX_VALUE);
   18.82 +            WebView view = new WebView();
   18.83 +            view.setMinSize(500, 400);
   18.84 +            view.setPrefSize(500, 400);
   18.85 +            final WebEngine eng = view.getEngine();
   18.86 +            try {
   18.87 +                JVMBridge.addBck2BrwsrLoad(new InitBck2Brwsr(eng));
   18.88 +            } catch (TooManyListenersException ex) {
   18.89 +                LOG.log(Level.SEVERE, null, ex);
   18.90 +            }
   18.91 +            
   18.92 +            if (params.size() > 0) {
   18.93 +                LOG.log(Level.INFO, "loading page {0}", params.get(0));
   18.94 +                eng.load(params.get(0));
   18.95 +                LOG.fine("back from load");
   18.96 +            }
   18.97 +            eng.setOnAlert(new EventHandler<WebEvent<String>>() {
   18.98 +                @Override
   18.99 +                public void handle(WebEvent<String> t) {
  18.100 +                    final Stage dialogStage = new Stage();
  18.101 +                    dialogStage.initModality(Modality.WINDOW_MODAL);
  18.102 +                    dialogStage.setTitle("Warning");
  18.103 +                    final Button button = new Button("Close");
  18.104 +                    final Text text = new Text(t.getData());
  18.105 +                    
  18.106 +                    VBox box = new VBox();
  18.107 +                    box.setAlignment(Pos.CENTER);
  18.108 +                    box.setSpacing(10);
  18.109 +                    box.setPadding(new Insets(10));
  18.110 +                    box.getChildren().addAll(text, button);
  18.111 +                    
  18.112 +                    dialogStage.setScene(new Scene(box));
  18.113 +                    
  18.114 +                    button.setCancelButton(true);
  18.115 +                    button.setOnAction(new EventHandler<ActionEvent>() {
  18.116 +                        @Override
  18.117 +                        public void handle(ActionEvent t) {
  18.118 +                            dialogStage.close();
  18.119 +                        }
  18.120 +                    });
  18.121 +                    
  18.122 +                    dialogStage.centerOnScreen();
  18.123 +                    dialogStage.showAndWait();
  18.124 +                }
  18.125 +            });
  18.126 +            GridPane grid = new GridPane();
  18.127 +            grid.setVgap(5);
  18.128 +            grid.setHgap(5);
  18.129 +            GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
  18.130 +            grid.getColumnConstraints().addAll(new ColumnConstraints(100, 100, Double.MAX_VALUE, Priority.ALWAYS, HPos.CENTER, true), new ColumnConstraints(40, 40, 40, Priority.NEVER, HPos.CENTER, true));
  18.131 +            grid.getChildren().addAll(view);
  18.132 +            getChildren().add(grid);
  18.133 +        }
  18.134 +
  18.135 +        boolean initBck2Brwsr(WebEngine webEngine) {
  18.136 +            JSObject jsobj = (JSObject) webEngine.executeScript("window");
  18.137 +            LOG.log(Level.FINE, "window: {0}", jsobj);
  18.138 +            Object prev = jsobj.getMember("bck2brwsr");
  18.139 +            if ("undefined".equals(prev)) {
  18.140 +                System.getProperties().put("webEngine", webEngine);
  18.141 +                jsobj.setMember("bck2brwsr", bridge);
  18.142 +                return true;
  18.143 +            }
  18.144 +            return false;
  18.145 +        }
  18.146 +
  18.147 +        @Override
  18.148 +        protected void layoutChildren() {
  18.149 +            List<Node> managed = getManagedChildren();
  18.150 +            double width = getWidth();
  18.151 +            double height = getHeight();
  18.152 +            double top = getInsets().getTop();
  18.153 +            double right = getInsets().getRight();
  18.154 +            double left = getInsets().getLeft();
  18.155 +            double bottom = getInsets().getBottom();
  18.156 +            for (int i = 0; i < managed.size(); i++) {
  18.157 +                Node child = managed.get(i);
  18.158 +                layoutInArea(child, left, top, width - left - right, height - top - bottom, 0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER);
  18.159 +            }
  18.160 +        }
  18.161 +
  18.162 +        private class InitBck2Brwsr implements ChangeListener<Void>, Runnable {
  18.163 +            private final WebEngine eng;
  18.164 +
  18.165 +            public InitBck2Brwsr(WebEngine eng) {
  18.166 +                this.eng = eng;
  18.167 +            }
  18.168 +
  18.169 +            @Override
  18.170 +            public synchronized void changed(ObservableValue<? extends Void> ov, Void t, Void t1) {
  18.171 +                Platform.runLater(this);
  18.172 +                try {
  18.173 +                    wait();
  18.174 +                } catch (InterruptedException ex) {
  18.175 +                    LOG.log(Level.SEVERE, null, ex);
  18.176 +                }
  18.177 +            }
  18.178 +
  18.179 +            @Override
  18.180 +            public synchronized void run() {
  18.181 +                initBck2Brwsr(eng);
  18.182 +                notifyAll();
  18.183 +            }
  18.184 +        }
  18.185 +    }
  18.186 +    
  18.187 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java	Mon Apr 29 16:32:14 2013 +0200
    19.3 @@ -0,0 +1,64 @@
    19.4 +/**
    19.5 + * Back 2 Browser Bytecode Translator
    19.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    19.7 + *
    19.8 + * This program is free software: you can redistribute it and/or modify
    19.9 + * it under the terms of the GNU General Public License as published by
   19.10 + * the Free Software Foundation, version 2 of the License.
   19.11 + *
   19.12 + * This program is distributed in the hope that it will be useful,
   19.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.15 + * GNU General Public License for more details.
   19.16 + *
   19.17 + * You should have received a copy of the GNU General Public License
   19.18 + * along with this program. Look for COPYING file in the top folder.
   19.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   19.20 + */
   19.21 +package org.apidesign.bck2brwsr.launcher.fximpl;
   19.22 +
   19.23 +import java.util.TooManyListenersException;
   19.24 +import javafx.beans.value.ChangeListener;
   19.25 +
   19.26 +/**
   19.27 + *
   19.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   19.29 + */
   19.30 +public final class JVMBridge {
   19.31 +    private static ClassLoader[] ldrs;
   19.32 +    private static ChangeListener<Void> onBck2BrwsrLoad;
   19.33 +        
   19.34 +    public static void registerClassLoaders(ClassLoader[] loaders) {
   19.35 +        ldrs = loaders.clone();
   19.36 +    }
   19.37 +    
   19.38 +    public static void addBck2BrwsrLoad(ChangeListener<Void> l) throws TooManyListenersException {
   19.39 +        if (onBck2BrwsrLoad != null) {
   19.40 +            throw new TooManyListenersException();
   19.41 +        }
   19.42 +        onBck2BrwsrLoad = l;
   19.43 +    }
   19.44 +
   19.45 +    public static void onBck2BrwsrLoad() {
   19.46 +        ChangeListener<Void> l = onBck2BrwsrLoad;
   19.47 +        if (l != null) {
   19.48 +            l.changed(null, null, null);
   19.49 +        }
   19.50 +    }
   19.51 +    
   19.52 +    public Class<?> loadClass(String name) throws ClassNotFoundException {
   19.53 +        System.err.println("trying to load " + name);
   19.54 +        ClassNotFoundException ex = null;
   19.55 +        if (ldrs != null) for (ClassLoader l : ldrs) {
   19.56 +            try {
   19.57 +                return Class.forName(name, true, l);
   19.58 +            } catch (ClassNotFoundException ex2) {
   19.59 +                ex = ex2;
   19.60 +            }
   19.61 +        }
   19.62 +        if (ex == null) {
   19.63 +            ex = new ClassNotFoundException("No loaders");
   19.64 +        }
   19.65 +        throw ex;
   19.66 +    }
   19.67 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Run.java	Mon Apr 29 16:32:14 2013 +0200
    20.3 @@ -0,0 +1,35 @@
    20.4 +/**
    20.5 + * Back 2 Browser Bytecode Translator
    20.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    20.7 + *
    20.8 + * This program is free software: you can redistribute it and/or modify
    20.9 + * it under the terms of the GNU General Public License as published by
   20.10 + * the Free Software Foundation, version 2 of the License.
   20.11 + *
   20.12 + * This program is distributed in the hope that it will be useful,
   20.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.15 + * GNU General Public License for more details.
   20.16 + *
   20.17 + * You should have received a copy of the GNU General Public License
   20.18 + * along with this program. Look for COPYING file in the top folder.
   20.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   20.20 + */
   20.21 +
   20.22 +package org.apidesign.bck2brwsr.launcher.fximpl;
   20.23 +
   20.24 +/**
   20.25 + *
   20.26 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   20.27 + */
   20.28 +public final class Run implements Runnable {
   20.29 +    private final Runnable r;
   20.30 +    Run(Runnable r) {
   20.31 +        this.r = r;
   20.32 +    }
   20.33 +
   20.34 +    @Override
   20.35 +    public void run() {
   20.36 +        r.run();
   20.37 +    }
   20.38 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/launcher/fx/src/main/resources/org/apidesign/bck2brwsr/launcher/fximpl/harness.xhtml	Mon Apr 29 16:32:14 2013 +0200
    21.3 @@ -0,0 +1,52 @@
    21.4 +<?xml version="1.0" encoding="UTF-8"?>
    21.5 +<!--
    21.6 +
    21.7 +    Back 2 Browser Bytecode Translator
    21.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    21.9 +
   21.10 +    This program is free software: you can redistribute it and/or modify
   21.11 +    it under the terms of the GNU General Public License as published by
   21.12 +    the Free Software Foundation, version 2 of the License.
   21.13 +
   21.14 +    This program is distributed in the hope that it will be useful,
   21.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.17 +    GNU General Public License for more details.
   21.18 +
   21.19 +    You should have received a copy of the GNU General Public License
   21.20 +    along with this program. Look for COPYING file in the top folder.
   21.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   21.22 +
   21.23 +-->
   21.24 +<!DOCTYPE html>
   21.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   21.26 +    <head>
   21.27 +        <title>Bck2Brwsr Harness</title>
   21.28 +    </head>
   21.29 +    <body>
   21.30 +        <script src="/bck2brwsr.js"></script>
   21.31 +        <script>
   21.32 +            var vm = bck2brwsr();
   21.33 +        </script>
   21.34 +        
   21.35 +        <h1>Bck2Brwsr Execution Harness</h1>
   21.36 +        
   21.37 +        <ul id="bck2brwsr.result" style="width: 100%;" >
   21.38 +        </ul>
   21.39 +
   21.40 +        <div id="bck2brwsr.fragment"/>
   21.41 +        
   21.42 +        <script type="text/javascript">
   21.43 +            try {
   21.44 +                (function() {
   21.45 +                    var cls = vm.loadClass('org.apidesign.bck2brwsr.launcher.fximpl.Console');
   21.46 +                    // fxbrwsr mangling
   21.47 +                    var inst = cls.newInstance();
   21.48 +                    inst.harness('$U/../data');
   21.49 +                })();
   21.50 +            } catch (err) { 
   21.51 +                alert('Error executing harness: ' + err); 
   21.52 +            }
   21.53 +        </script>
   21.54 +    </body>
   21.55 +</html>
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/launcher/http/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    22.3 @@ -0,0 +1,47 @@
    22.4 +<?xml version="1.0"?>
    22.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    22.6 +  <modelVersion>4.0.0</modelVersion>
    22.7 +  <parent>
    22.8 +    <groupId>org.apidesign.bck2brwsr</groupId>
    22.9 +    <artifactId>launcher-pom</artifactId>
   22.10 +    <version>0.7-SNAPSHOT</version>
   22.11 +  </parent>
   22.12 +  <groupId>org.apidesign.bck2brwsr</groupId>
   22.13 +  <artifactId>launcher.http</artifactId>
   22.14 +  <version>0.7-SNAPSHOT</version>
   22.15 +  <name>Bck2Brwsr Launcher</name>
   22.16 +  <url>http://maven.apache.org</url>
   22.17 +    <build>
   22.18 +        <plugins>
   22.19 +            <plugin>
   22.20 +                <groupId>org.apache.maven.plugins</groupId>
   22.21 +                <artifactId>maven-compiler-plugin</artifactId>
   22.22 +                <version>2.3.2</version>
   22.23 +                <configuration>
   22.24 +                    <source>1.7</source>
   22.25 +                    <target>1.7</target>
   22.26 +                </configuration>
   22.27 +            </plugin>
   22.28 +        </plugins>
   22.29 +    </build>
   22.30 +    <properties>
   22.31 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   22.32 +  </properties>
   22.33 +  <dependencies>
   22.34 +    <dependency>
   22.35 +      <groupId>${project.groupId}</groupId>
   22.36 +      <artifactId>launcher</artifactId>
   22.37 +      <version>${project.version}</version>
   22.38 +    </dependency>
   22.39 +    <dependency>
   22.40 +      <groupId>org.glassfish.grizzly</groupId>
   22.41 +      <artifactId>grizzly-http-server</artifactId>
   22.42 +      <version>2.2.19</version>
   22.43 +    </dependency>
   22.44 +    <dependency>
   22.45 +      <groupId>${project.groupId}</groupId>
   22.46 +      <artifactId>vm4brwsr</artifactId>
   22.47 +      <version>${project.version}</version>
   22.48 +    </dependency>
   22.49 +  </dependencies>
   22.50 +</project>
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Mon Apr 29 16:32:14 2013 +0200
    23.3 @@ -0,0 +1,604 @@
    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.bck2brwsr.launcher;
   23.22 +
   23.23 +import java.io.Closeable;
   23.24 +import java.io.File;
   23.25 +import java.io.IOException;
   23.26 +import java.io.InputStream;
   23.27 +import java.io.InterruptedIOException;
   23.28 +import java.io.OutputStream;
   23.29 +import java.io.UnsupportedEncodingException;
   23.30 +import java.io.Writer;
   23.31 +import java.net.URI;
   23.32 +import java.net.URISyntaxException;
   23.33 +import java.net.URL;
   23.34 +import java.util.ArrayList;
   23.35 +import java.util.Arrays;
   23.36 +import java.util.Enumeration;
   23.37 +import java.util.LinkedHashSet;
   23.38 +import java.util.List;
   23.39 +import java.util.Set;
   23.40 +import java.util.concurrent.BlockingQueue;
   23.41 +import java.util.concurrent.CountDownLatch;
   23.42 +import java.util.concurrent.LinkedBlockingQueue;
   23.43 +import java.util.concurrent.TimeUnit;
   23.44 +import java.util.logging.Level;
   23.45 +import java.util.logging.Logger;
   23.46 +import org.apidesign.bck2brwsr.launcher.InvocationContext.Resource;
   23.47 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   23.48 +import org.glassfish.grizzly.PortRange;
   23.49 +import org.glassfish.grizzly.http.server.HttpHandler;
   23.50 +import org.glassfish.grizzly.http.server.HttpServer;
   23.51 +import org.glassfish.grizzly.http.server.NetworkListener;
   23.52 +import org.glassfish.grizzly.http.server.Request;
   23.53 +import org.glassfish.grizzly.http.server.Response;
   23.54 +import org.glassfish.grizzly.http.server.ServerConfiguration;
   23.55 +import org.glassfish.grizzly.http.util.HttpStatus;
   23.56 +
   23.57 +/**
   23.58 + * Lightweight server to launch Bck2Brwsr applications and tests.
   23.59 + * Supports execution in native browser as well as Java's internal 
   23.60 + * execution engine.
   23.61 + */
   23.62 +final class Bck2BrwsrLauncher extends Launcher implements Closeable {
   23.63 +    private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
   23.64 +    private static final InvocationContext END = new InvocationContext(null, null, null);
   23.65 +    private final Set<ClassLoader> loaders = new LinkedHashSet<>();
   23.66 +    private final BlockingQueue<InvocationContext> methods = new LinkedBlockingQueue<>();
   23.67 +    private long timeOut;
   23.68 +    private final Res resources = new Res();
   23.69 +    private final String cmd;
   23.70 +    private Object[] brwsr;
   23.71 +    private HttpServer server;
   23.72 +    private CountDownLatch wait;
   23.73 +    
   23.74 +    public Bck2BrwsrLauncher(String cmd) {
   23.75 +        this.cmd = cmd;
   23.76 +        addClassLoader(Bck2Brwsr.class.getClassLoader());
   23.77 +        setTimeout(180000);
   23.78 +    }
   23.79 +    
   23.80 +    @Override
   23.81 +    InvocationContext runMethod(InvocationContext c) throws IOException {
   23.82 +        loaders.add(c.clazz.getClassLoader());
   23.83 +        methods.add(c);
   23.84 +        try {
   23.85 +            c.await(timeOut);
   23.86 +        } catch (InterruptedException ex) {
   23.87 +            throw new IOException(ex);
   23.88 +        }
   23.89 +        return c;
   23.90 +    }
   23.91 +    
   23.92 +    public void setTimeout(long ms) {
   23.93 +        timeOut = ms;
   23.94 +    }
   23.95 +    
   23.96 +    public void addClassLoader(ClassLoader url) {
   23.97 +        this.loaders.add(url);
   23.98 +    }
   23.99 +
  23.100 +    public void showURL(String startpage) throws IOException {
  23.101 +        if (!startpage.startsWith("/")) {
  23.102 +            startpage = "/" + startpage;
  23.103 +        }
  23.104 +        HttpServer s = initServer(".", true);
  23.105 +        int last = startpage.lastIndexOf('/');
  23.106 +        String prefix = startpage.substring(0, last);
  23.107 +        String simpleName = startpage.substring(last);
  23.108 +        s.getServerConfiguration().addHttpHandler(new SubTree(resources, prefix), "/");
  23.109 +        try {
  23.110 +            launchServerAndBrwsr(s, simpleName);
  23.111 +        } catch (URISyntaxException | InterruptedException ex) {
  23.112 +            throw new IOException(ex);
  23.113 +        }
  23.114 +    }
  23.115 +
  23.116 +    void showDirectory(File dir, String startpage) throws IOException {
  23.117 +        if (!startpage.startsWith("/")) {
  23.118 +            startpage = "/" + startpage;
  23.119 +        }
  23.120 +        HttpServer s = initServer(dir.getPath(), false);
  23.121 +        try {
  23.122 +            launchServerAndBrwsr(s, startpage);
  23.123 +        } catch (URISyntaxException | InterruptedException ex) {
  23.124 +            throw new IOException(ex);
  23.125 +        }
  23.126 +    }
  23.127 +
  23.128 +    @Override
  23.129 +    public void initialize() throws IOException {
  23.130 +        try {
  23.131 +            executeInBrowser();
  23.132 +        } catch (InterruptedException ex) {
  23.133 +            final InterruptedIOException iio = new InterruptedIOException(ex.getMessage());
  23.134 +            iio.initCause(ex);
  23.135 +            throw iio;
  23.136 +        } catch (Exception ex) {
  23.137 +            if (ex instanceof IOException) {
  23.138 +                throw (IOException)ex;
  23.139 +            }
  23.140 +            if (ex instanceof RuntimeException) {
  23.141 +                throw (RuntimeException)ex;
  23.142 +            }
  23.143 +            throw new IOException(ex);
  23.144 +        }
  23.145 +    }
  23.146 +    
  23.147 +    private HttpServer initServer(String path, boolean addClasses) throws IOException {
  23.148 +        HttpServer s = HttpServer.createSimpleServer(path, new PortRange(8080, 65535));
  23.149 +
  23.150 +        final ServerConfiguration conf = s.getServerConfiguration();
  23.151 +        if (addClasses) {
  23.152 +            conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
  23.153 +            conf.addHttpHandler(new Classes(resources), "/classes/");
  23.154 +        }
  23.155 +        return s;
  23.156 +    }
  23.157 +    
  23.158 +    private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
  23.159 +        wait = new CountDownLatch(1);
  23.160 +        server = initServer(".", true);
  23.161 +        final ServerConfiguration conf = server.getServerConfiguration();
  23.162 +        
  23.163 +        class DynamicResourceHandler extends HttpHandler {
  23.164 +            private final InvocationContext ic;
  23.165 +            public DynamicResourceHandler(InvocationContext ic) {
  23.166 +                if (ic == null || ic.resources.isEmpty()) {
  23.167 +                    throw new NullPointerException();
  23.168 +                }
  23.169 +                this.ic = ic;
  23.170 +                for (Resource r : ic.resources) {
  23.171 +                    conf.addHttpHandler(this, r.httpPath);
  23.172 +                }
  23.173 +            }
  23.174 +
  23.175 +            public void close() {
  23.176 +                conf.removeHttpHandler(this);
  23.177 +            }
  23.178 +            
  23.179 +            @Override
  23.180 +            public void service(Request request, Response response) throws Exception {
  23.181 +                for (Resource r : ic.resources) {
  23.182 +                    if (r.httpPath.equals(request.getRequestURI())) {
  23.183 +                        LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
  23.184 +                        response.setContentType(r.httpType);
  23.185 +                        r.httpContent.reset();
  23.186 +                        String[] params = null;
  23.187 +                        if (r.parameters.length != 0) {
  23.188 +                            params = new String[r.parameters.length];
  23.189 +                            for (int i = 0; i < r.parameters.length; i++) {
  23.190 +                                params[i] = request.getParameter(r.parameters[i]);
  23.191 +                            }
  23.192 +                        }
  23.193 +                        
  23.194 +                        copyStream(r.httpContent, response.getOutputStream(), null, params);
  23.195 +                    }
  23.196 +                }
  23.197 +            }
  23.198 +        }
  23.199 +        
  23.200 +        conf.addHttpHandler(new Page(resources, 
  23.201 +            "org/apidesign/bck2brwsr/launcher/harness.xhtml"
  23.202 +        ), "/execute");
  23.203 +        
  23.204 +        conf.addHttpHandler(new HttpHandler() {
  23.205 +            int cnt;
  23.206 +            List<InvocationContext> cases = new ArrayList<>();
  23.207 +            DynamicResourceHandler prev;
  23.208 +            @Override
  23.209 +            public void service(Request request, Response response) throws Exception {
  23.210 +                String id = request.getParameter("request");
  23.211 +                String value = request.getParameter("result");
  23.212 +                if (value != null && value.indexOf((char)0xC5) != -1) {
  23.213 +                    value = toUTF8(value);
  23.214 +                }
  23.215 +                
  23.216 +                
  23.217 +                InvocationContext mi = null;
  23.218 +                int caseNmbr = -1;
  23.219 +                
  23.220 +                if (id != null && value != null) {
  23.221 +                    LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
  23.222 +                    value = decodeURL(value);
  23.223 +                    int indx = Integer.parseInt(id);
  23.224 +                    cases.get(indx).result(value, null);
  23.225 +                    if (++indx < cases.size()) {
  23.226 +                        mi = cases.get(indx);
  23.227 +                        LOG.log(Level.INFO, "Re-executing case {0}", indx);
  23.228 +                        caseNmbr = indx;
  23.229 +                    }
  23.230 +                } else {
  23.231 +                    if (!cases.isEmpty()) {
  23.232 +                        LOG.info("Re-executing test cases");
  23.233 +                        mi = cases.get(0);
  23.234 +                        caseNmbr = 0;
  23.235 +                    }
  23.236 +                }
  23.237 +                
  23.238 +                if (prev != null) {
  23.239 +                    prev.close();
  23.240 +                    prev = null;
  23.241 +                }
  23.242 +                
  23.243 +                if (mi == null) {
  23.244 +                    mi = methods.take();
  23.245 +                    caseNmbr = cnt++;
  23.246 +                }
  23.247 +                if (mi == END) {
  23.248 +                    response.getWriter().write("");
  23.249 +                    wait.countDown();
  23.250 +                    cnt = 0;
  23.251 +                    LOG.log(Level.INFO, "End of data reached. Exiting.");
  23.252 +                    return;
  23.253 +                }
  23.254 +                
  23.255 +                if (!mi.resources.isEmpty()) {
  23.256 +                    prev = new DynamicResourceHandler(mi);
  23.257 +                }
  23.258 +                
  23.259 +                cases.add(mi);
  23.260 +                final String cn = mi.clazz.getName();
  23.261 +                final String mn = mi.methodName;
  23.262 +                LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{caseNmbr, cn, mn});
  23.263 +                response.getWriter().write("{"
  23.264 +                    + "className: '" + cn + "', "
  23.265 +                    + "methodName: '" + mn + "', "
  23.266 +                    + "request: " + caseNmbr
  23.267 +                );
  23.268 +                if (mi.html != null) {
  23.269 +                    response.getWriter().write(", html: '");
  23.270 +                    response.getWriter().write(encodeJSON(mi.html));
  23.271 +                    response.getWriter().write("'");
  23.272 +                }
  23.273 +                response.getWriter().write("}");
  23.274 +            }
  23.275 +        }, "/data");
  23.276 +
  23.277 +        this.brwsr = launchServerAndBrwsr(server, "/execute");
  23.278 +    }
  23.279 +    
  23.280 +    private static String encodeJSON(String in) {
  23.281 +        StringBuilder sb = new StringBuilder();
  23.282 +        for (int i = 0; i < in.length(); i++) {
  23.283 +            char ch = in.charAt(i);
  23.284 +            if (ch < 32 || ch == '\'' || ch == '"') {
  23.285 +                sb.append("\\u");
  23.286 +                String hs = "0000" + Integer.toHexString(ch);
  23.287 +                hs = hs.substring(hs.length() - 4);
  23.288 +                sb.append(hs);
  23.289 +            } else {
  23.290 +                sb.append(ch);
  23.291 +            }
  23.292 +        }
  23.293 +        return sb.toString();
  23.294 +    }
  23.295 +    
  23.296 +    @Override
  23.297 +    public void shutdown() throws IOException {
  23.298 +        methods.offer(END);
  23.299 +        for (;;) {
  23.300 +            int prev = methods.size();
  23.301 +            try {
  23.302 +                if (wait != null && wait.await(timeOut, TimeUnit.MILLISECONDS)) {
  23.303 +                    break;
  23.304 +                }
  23.305 +            } catch (InterruptedException ex) {
  23.306 +                throw new IOException(ex);
  23.307 +            }
  23.308 +            if (prev == methods.size()) {
  23.309 +                LOG.log(
  23.310 +                    Level.WARNING, 
  23.311 +                    "Timeout and no test has been executed meanwhile (at {0}). Giving up.", 
  23.312 +                    methods.size()
  23.313 +                );
  23.314 +                break;
  23.315 +            }
  23.316 +            LOG.log(Level.INFO, 
  23.317 +                "Timeout, but tests got from {0} to {1}. Trying again.", 
  23.318 +                new Object[]{prev, methods.size()}
  23.319 +            );
  23.320 +        }
  23.321 +        stopServerAndBrwsr(server, brwsr);
  23.322 +    }
  23.323 +    
  23.324 +    static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
  23.325 +        for (;;) {
  23.326 +            int ch = is.read();
  23.327 +            if (ch == -1) {
  23.328 +                break;
  23.329 +            }
  23.330 +            if (ch == '$' && params.length > 0) {
  23.331 +                int cnt = is.read() - '0';
  23.332 +                if (baseURL != null && cnt == 'U' - '0') {
  23.333 +                    os.write(baseURL.getBytes("UTF-8"));
  23.334 +                } else {
  23.335 +                    if (cnt >= 0 && cnt < params.length) {
  23.336 +                        os.write(params[cnt].getBytes("UTF-8"));
  23.337 +                    } else {
  23.338 +                        os.write('$');
  23.339 +                        os.write(cnt + '0');
  23.340 +                    }
  23.341 +                }
  23.342 +            } else {
  23.343 +                os.write(ch);
  23.344 +            }
  23.345 +        }
  23.346 +    }
  23.347 +
  23.348 +    private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
  23.349 +        server.start();
  23.350 +        NetworkListener listener = server.getListeners().iterator().next();
  23.351 +        int port = listener.getPort();
  23.352 +        
  23.353 +        URI uri = new URI("http://localhost:" + port + page);
  23.354 +        LOG.log(Level.INFO, "Showing {0}", uri);
  23.355 +        if (cmd == null) {
  23.356 +            try {
  23.357 +                LOG.log(Level.INFO, "Trying Desktop.browse on {0} {2} by {1}", new Object[] {
  23.358 +                    System.getProperty("java.vm.name"),
  23.359 +                    System.getProperty("java.vm.vendor"),
  23.360 +                    System.getProperty("java.vm.version"),
  23.361 +                });
  23.362 +                java.awt.Desktop.getDesktop().browse(uri);
  23.363 +                LOG.log(Level.INFO, "Desktop.browse successfully finished");
  23.364 +                return null;
  23.365 +            } catch (UnsupportedOperationException ex) {
  23.366 +                LOG.log(Level.INFO, "Desktop.browse not supported: {0}", ex.getMessage());
  23.367 +                LOG.log(Level.FINE, null, ex);
  23.368 +            }
  23.369 +        }
  23.370 +        {
  23.371 +            String cmdName = cmd == null ? "xdg-open" : cmd;
  23.372 +            String[] cmdArr = { 
  23.373 +                cmdName, uri.toString()
  23.374 +            };
  23.375 +            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmdArr));
  23.376 +            final Process process = Runtime.getRuntime().exec(cmdArr);
  23.377 +            return new Object[] { process, null };
  23.378 +        }
  23.379 +    }
  23.380 +    private static String toUTF8(String value) throws UnsupportedEncodingException {
  23.381 +        byte[] arr = new byte[value.length()];
  23.382 +        for (int i = 0; i < arr.length; i++) {
  23.383 +            arr[i] = (byte)value.charAt(i);
  23.384 +        }
  23.385 +        return new String(arr, "UTF-8");
  23.386 +    }
  23.387 +    
  23.388 +    private static String decodeURL(String s) {
  23.389 +        for (;;) {
  23.390 +            int pos = s.indexOf('%');
  23.391 +            if (pos == -1) {
  23.392 +                return s;
  23.393 +            }
  23.394 +            int i = Integer.parseInt(s.substring(pos + 1, pos + 2), 16);
  23.395 +            s = s.substring(0, pos) + (char)i + s.substring(pos + 2);
  23.396 +        }
  23.397 +    }
  23.398 +    
  23.399 +    private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException {
  23.400 +        if (brwsr == null) {
  23.401 +            return;
  23.402 +        }
  23.403 +        Process process = (Process)brwsr[0];
  23.404 +        
  23.405 +        server.stop();
  23.406 +        InputStream stdout = process.getInputStream();
  23.407 +        InputStream stderr = process.getErrorStream();
  23.408 +        drain("StdOut", stdout);
  23.409 +        drain("StdErr", stderr);
  23.410 +        process.destroy();
  23.411 +        int res;
  23.412 +        try {
  23.413 +            res = process.waitFor();
  23.414 +        } catch (InterruptedException ex) {
  23.415 +            throw new IOException(ex);
  23.416 +        }
  23.417 +        LOG.log(Level.INFO, "Exit code: {0}", res);
  23.418 +
  23.419 +        deleteTree((File)brwsr[1]);
  23.420 +    }
  23.421 +    
  23.422 +    private static void drain(String name, InputStream is) throws IOException {
  23.423 +        int av = is.available();
  23.424 +        if (av > 0) {
  23.425 +            StringBuilder sb = new StringBuilder();
  23.426 +            sb.append("v== ").append(name).append(" ==v\n");
  23.427 +            while (av-- > 0) {
  23.428 +                sb.append((char)is.read());
  23.429 +            }
  23.430 +            sb.append("\n^== ").append(name).append(" ==^");
  23.431 +            LOG.log(Level.INFO, sb.toString());
  23.432 +        }
  23.433 +    }
  23.434 +
  23.435 +    private void deleteTree(File file) {
  23.436 +        if (file == null) {
  23.437 +            return;
  23.438 +        }
  23.439 +        File[] arr = file.listFiles();
  23.440 +        if (arr != null) {
  23.441 +            for (File s : arr) {
  23.442 +                deleteTree(s);
  23.443 +            }
  23.444 +        }
  23.445 +        file.delete();
  23.446 +    }
  23.447 +
  23.448 +    @Override
  23.449 +    public void close() throws IOException {
  23.450 +        shutdown();
  23.451 +    }
  23.452 +
  23.453 +    private class Res implements Bck2Brwsr.Resources {
  23.454 +        @Override
  23.455 +        public InputStream get(String resource) throws IOException {
  23.456 +            URL u = null;
  23.457 +            for (ClassLoader l : loaders) {
  23.458 +                Enumeration<URL> en = l.getResources(resource);
  23.459 +                while (en.hasMoreElements()) {
  23.460 +                    u = en.nextElement();
  23.461 +                }
  23.462 +            }
  23.463 +            if (u != null) {
  23.464 +                return u.openStream();
  23.465 +            }
  23.466 +            throw new IOException("Can't find " + resource);
  23.467 +        }
  23.468 +    }
  23.469 +
  23.470 +    private static class Page extends HttpHandler {
  23.471 +        final String resource;
  23.472 +        private final String[] args;
  23.473 +        private final Res res;
  23.474 +        
  23.475 +        public Page(Res res, String resource, String... args) {
  23.476 +            this.res = res;
  23.477 +            this.resource = resource;
  23.478 +            this.args = args.length == 0 ? new String[] { "$0" } : args;
  23.479 +        }
  23.480 +
  23.481 +        @Override
  23.482 +        public void service(Request request, Response response) throws Exception {
  23.483 +            String r = computePage(request);
  23.484 +            if (r.startsWith("/")) {
  23.485 +                r = r.substring(1);
  23.486 +            }
  23.487 +            String[] replace = {};
  23.488 +            if (r.endsWith(".html")) {
  23.489 +                response.setContentType("text/html");
  23.490 +                LOG.info("Content type text/html");
  23.491 +                replace = args;
  23.492 +            }
  23.493 +            if (r.endsWith(".xhtml")) {
  23.494 +                response.setContentType("application/xhtml+xml");
  23.495 +                LOG.info("Content type application/xhtml+xml");
  23.496 +                replace = args;
  23.497 +            }
  23.498 +            OutputStream os = response.getOutputStream();
  23.499 +            try (InputStream is = res.get(r)) {
  23.500 +                copyStream(is, os, request.getRequestURL().toString(), replace);
  23.501 +            } catch (IOException ex) {
  23.502 +                response.setDetailMessage(ex.getLocalizedMessage());
  23.503 +                response.setError();
  23.504 +                response.setStatus(404);
  23.505 +            }
  23.506 +        }
  23.507 +
  23.508 +        protected String computePage(Request request) {
  23.509 +            String r = resource;
  23.510 +            if (r == null) {
  23.511 +                r = request.getHttpHandlerPath();
  23.512 +            }
  23.513 +            return r;
  23.514 +        }
  23.515 +    }
  23.516 +    
  23.517 +    private static class SubTree extends Page {
  23.518 +
  23.519 +        public SubTree(Res res, String resource, String... args) {
  23.520 +            super(res, resource, args);
  23.521 +        }
  23.522 +
  23.523 +        @Override
  23.524 +        protected String computePage(Request request) {
  23.525 +            return resource + request.getHttpHandlerPath();
  23.526 +        }
  23.527 +        
  23.528 +        
  23.529 +    }
  23.530 +
  23.531 +    private static class VM extends HttpHandler {
  23.532 +        private final String bck2brwsr;
  23.533 +
  23.534 +        public VM(Res loader) throws IOException {
  23.535 +            StringBuilder sb = new StringBuilder();
  23.536 +            Bck2Brwsr.generate(sb, loader);
  23.537 +            sb.append(
  23.538 +                  "(function WrapperVM(global) {"
  23.539 +                + "  function ldCls(res) {\n"
  23.540 +                + "    var request = new XMLHttpRequest();\n"
  23.541 +                + "    request.open('GET', '/classes/' + res, false);\n"
  23.542 +                + "    request.send();\n"
  23.543 +                + "    if (request.status !== 200) return null;\n"
  23.544 +                + "    var arr = eval('(' + request.responseText + ')');\n"
  23.545 +                + "    return arr;\n"
  23.546 +                + "  }\n"
  23.547 +                + "  var prevvm = global.bck2brwsr;\n"
  23.548 +                + "  global.bck2brwsr = function() {\n"
  23.549 +                + "    var args = Array.prototype.slice.apply(arguments);\n"
  23.550 +                + "    args.unshift(ldCls);\n"
  23.551 +                + "    return prevvm.apply(null, args);\n"
  23.552 +                + "  };\n"
  23.553 +                + "})(this);\n"
  23.554 +            );
  23.555 +            this.bck2brwsr = sb.toString();
  23.556 +        }
  23.557 +
  23.558 +        @Override
  23.559 +        public void service(Request request, Response response) throws Exception {
  23.560 +            response.setCharacterEncoding("UTF-8");
  23.561 +            response.setContentType("text/javascript");
  23.562 +            response.getWriter().write(bck2brwsr);
  23.563 +        }
  23.564 +    }
  23.565 +
  23.566 +    private static class Classes extends HttpHandler {
  23.567 +        private final Res loader;
  23.568 +
  23.569 +        public Classes(Res loader) {
  23.570 +            this.loader = loader;
  23.571 +        }
  23.572 +
  23.573 +        @Override
  23.574 +        public void service(Request request, Response response) throws Exception {
  23.575 +            String res = request.getHttpHandlerPath();
  23.576 +            if (res.startsWith("/")) {
  23.577 +                res = res.substring(1);
  23.578 +            }
  23.579 +            try (InputStream is = loader.get(res)) {
  23.580 +                response.setContentType("text/javascript");
  23.581 +                Writer w = response.getWriter();
  23.582 +                w.append("[");
  23.583 +                for (int i = 0;; i++) {
  23.584 +                    int b = is.read();
  23.585 +                    if (b == -1) {
  23.586 +                        break;
  23.587 +                    }
  23.588 +                    if (i > 0) {
  23.589 +                        w.append(", ");
  23.590 +                    }
  23.591 +                    if (i % 20 == 0) {
  23.592 +                        w.write("\n");
  23.593 +                    }
  23.594 +                    if (b > 127) {
  23.595 +                        b = b - 256;
  23.596 +                    }
  23.597 +                    w.append(Integer.toString(b));
  23.598 +                }
  23.599 +                w.append("\n]");
  23.600 +            } catch (IOException ex) {
  23.601 +                response.setStatus(HttpStatus.NOT_FOUND_404);
  23.602 +                response.setError();
  23.603 +                response.setDetailMessage(ex.getMessage());
  23.604 +            }
  23.605 +        }
  23.606 +    }
  23.607 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Mon Apr 29 16:32:14 2013 +0200
    24.3 @@ -0,0 +1,135 @@
    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.bck2brwsr.launcher;
   24.22 +
   24.23 +import org.apidesign.bck2brwsr.launcher.impl.Console;
   24.24 +import java.io.IOException;
   24.25 +import java.io.InputStream;
   24.26 +import java.net.URL;
   24.27 +import java.util.Enumeration;
   24.28 +import java.util.LinkedHashSet;
   24.29 +import java.util.Set;
   24.30 +import java.util.logging.Level;
   24.31 +import java.util.logging.Logger;
   24.32 +import javax.script.Invocable;
   24.33 +import javax.script.ScriptEngine;
   24.34 +import javax.script.ScriptEngineManager;
   24.35 +import javax.script.ScriptException;
   24.36 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   24.37 +
   24.38 +/**
   24.39 + * Tests execution in Java's internal scripting engine.
   24.40 + */
   24.41 +final class JSLauncher extends Launcher {
   24.42 +    private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
   24.43 +    private Set<ClassLoader> loaders = new LinkedHashSet<>();
   24.44 +    private final Res resources = new Res();
   24.45 +    private Invocable code;
   24.46 +    private StringBuilder codeSeq;
   24.47 +    private Object console;
   24.48 +
   24.49 +    JSLauncher() {
   24.50 +        addClassLoader(Bck2Brwsr.class.getClassLoader());
   24.51 +    }
   24.52 +    
   24.53 +    @Override InvocationContext runMethod(InvocationContext mi) {
   24.54 +        loaders.add(mi.clazz.getClassLoader());
   24.55 +        try {
   24.56 +            long time = System.currentTimeMillis();
   24.57 +            LOG.log(Level.FINE, "Invoking {0}.{1}", new Object[]{mi.clazz.getName(), mi.methodName});
   24.58 +            String res = code.invokeMethod(
   24.59 +                console,
   24.60 +                "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
   24.61 +                mi.clazz.getName(), mi.methodName).toString();
   24.62 +            time = System.currentTimeMillis() - time;
   24.63 +            LOG.log(Level.FINE, "Resut of {0}.{1} = {2} in {3} ms", new Object[]{mi.clazz.getName(), mi.methodName, res, time});
   24.64 +            mi.result(res, null);
   24.65 +        } catch (ScriptException | NoSuchMethodException ex) {
   24.66 +            mi.result(null, ex);
   24.67 +        }
   24.68 +        return mi;
   24.69 +    }
   24.70 +    
   24.71 +    public void addClassLoader(ClassLoader url) {
   24.72 +        this.loaders.add(url);
   24.73 +    }
   24.74 +
   24.75 +    @Override
   24.76 +    public void initialize() throws IOException {
   24.77 +        try {
   24.78 +            initRhino();
   24.79 +        } catch (Exception ex) {
   24.80 +            if (ex instanceof IOException) {
   24.81 +                throw (IOException)ex;
   24.82 +            }
   24.83 +            if (ex instanceof RuntimeException) {
   24.84 +                throw (RuntimeException)ex;
   24.85 +            }
   24.86 +            throw new IOException(ex);
   24.87 +        }
   24.88 +    }
   24.89 +    
   24.90 +    private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
   24.91 +        StringBuilder sb = new StringBuilder();
   24.92 +        Bck2Brwsr.generate(sb, new Res());
   24.93 +
   24.94 +        ScriptEngineManager sem = new ScriptEngineManager();
   24.95 +        ScriptEngine mach = sem.getEngineByExtension("js");
   24.96 +
   24.97 +        sb.append(
   24.98 +              "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.impl.Console.read);"
   24.99 +            + "\nfunction initVM() { return vm; };"
  24.100 +            + "\n");
  24.101 +
  24.102 +        Object res = mach.eval(sb.toString());
  24.103 +        if (!(mach instanceof Invocable)) {
  24.104 +            throw new IOException("It is invocable object: " + res);
  24.105 +        }
  24.106 +        code = (Invocable) mach;
  24.107 +        codeSeq = sb;
  24.108 +        
  24.109 +        Object vm = code.invokeFunction("initVM");
  24.110 +        console = code.invokeMethod(vm, "loadClass", Console.class.getName());
  24.111 +    }
  24.112 +
  24.113 +    @Override
  24.114 +    public void shutdown() throws IOException {
  24.115 +    }
  24.116 +
  24.117 +    @Override
  24.118 +    public String toString() {
  24.119 +        return codeSeq.toString();
  24.120 +    }
  24.121 +    
  24.122 +    private class Res implements Bck2Brwsr.Resources {
  24.123 +        @Override
  24.124 +        public InputStream get(String resource) throws IOException {
  24.125 +            for (ClassLoader l : loaders) {
  24.126 +                URL u = null;
  24.127 +                Enumeration<URL> en = l.getResources(resource);
  24.128 +                while (en.hasMoreElements()) {
  24.129 +                    u = en.nextElement();
  24.130 +                }
  24.131 +                if (u != null) {
  24.132 +                    return u.openStream();
  24.133 +                }
  24.134 +            }
  24.135 +            throw new IOException("Can't find " + resource);
  24.136 +        }
  24.137 +    }
  24.138 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java	Mon Apr 29 16:32:14 2013 +0200
    25.3 @@ -0,0 +1,356 @@
    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.bck2brwsr.launcher.impl;
   25.22 +
   25.23 +import java.io.IOException;
   25.24 +import java.io.InputStream;
   25.25 +import java.io.UnsupportedEncodingException;
   25.26 +import java.lang.reflect.InvocationTargetException;
   25.27 +import java.lang.reflect.Method;
   25.28 +import java.lang.reflect.Modifier;
   25.29 +import java.net.URL;
   25.30 +import java.util.Enumeration;
   25.31 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   25.32 +
   25.33 +/**
   25.34 + *
   25.35 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   25.36 + */
   25.37 +public class Console {
   25.38 +    private Console() {
   25.39 +    }
   25.40 +    static {
   25.41 +        turnAssetionStatusOn();
   25.42 +    }
   25.43 +    
   25.44 +    @JavaScriptBody(args = {"id", "attr"}, body = 
   25.45 +        "return window.document.getElementById(id)[attr].toString();")
   25.46 +    private static native Object getAttr(String id, String attr);
   25.47 +    @JavaScriptBody(args = {"elem", "attr"}, body = 
   25.48 +        "return elem[attr].toString();")
   25.49 +    private static native Object getAttr(Object elem, String attr);
   25.50 +
   25.51 +    @JavaScriptBody(args = {"id", "attr", "value"}, body = 
   25.52 +        "window.document.getElementById(id)[attr] = value;")
   25.53 +    private static native void setAttr(String id, String attr, Object value);
   25.54 +    @JavaScriptBody(args = {"elem", "attr", "value"}, body = 
   25.55 +        "elem[attr] = value;")
   25.56 +    private static native void setAttr(Object id, String attr, Object value);
   25.57 +    
   25.58 +    @JavaScriptBody(args = {}, body = "return; window.close();")
   25.59 +    private static native void closeWindow();
   25.60 +
   25.61 +    private static Object textArea;
   25.62 +    private static Object statusArea;
   25.63 +    
   25.64 +    private static void log(String newText) {
   25.65 +        if (textArea == null) {
   25.66 +            return;
   25.67 +        }
   25.68 +        String attr = "value";
   25.69 +        setAttr(textArea, attr, getAttr(textArea, attr) + "\n" + newText);
   25.70 +        setAttr(textArea, "scrollTop", getAttr(textArea, "scrollHeight"));
   25.71 +    }
   25.72 +    
   25.73 +    private static void beginTest(Case c) {
   25.74 +        Object[] arr = new Object[2];
   25.75 +        beginTest(c.getClassName() + "." + c.getMethodName(), c, arr);
   25.76 +        textArea = arr[0];
   25.77 +        statusArea = arr[1];
   25.78 +    }
   25.79 +    
   25.80 +    private static void finishTest(Case c, Object res) {
   25.81 +        if ("null".equals(res)) {
   25.82 +            setAttr(statusArea, "innerHTML", "Success");
   25.83 +        } else {
   25.84 +            setAttr(statusArea, "innerHTML", "Result " + res);
   25.85 +        }
   25.86 +        statusArea = null;
   25.87 +        textArea = null;
   25.88 +    }
   25.89 +
   25.90 +    @JavaScriptBody(args = { "test", "c", "arr" }, body = 
   25.91 +          "var ul = window.document.getElementById('bck2brwsr.result');\n"
   25.92 +        + "var li = window.document.createElement('li');\n"
   25.93 +        + "var span = window.document.createElement('span');"
   25.94 +        + "span.innerHTML = test + ' - ';\n"
   25.95 +        + "var details = window.document.createElement('a');\n"
   25.96 +        + "details.innerHTML = 'Details';\n"
   25.97 +        + "details.href = '#';\n"
   25.98 +        + "var p = window.document.createElement('p');\n"
   25.99 +        + "var status = window.document.createElement('a');\n"
  25.100 +        + "status.innerHTML = 'running';"
  25.101 +        + "details.onclick = function() { li.appendChild(p); li.removeChild(details); status.innerHTML = 'Run Again'; status.href = '#'; };\n"
  25.102 +        + "status.onclick = function() { c.again__V_3Ljava_lang_Object_2(arr); }\n"
  25.103 +        + "var pre = window.document.createElement('textarea');\n"
  25.104 +        + "pre.cols = 100;"
  25.105 +        + "pre.rows = 10;"
  25.106 +        + "li.appendChild(span);\n"
  25.107 +        + "li.appendChild(status);\n"
  25.108 +        + "var span = window.document.createElement('span');"
  25.109 +        + "span.innerHTML = ' ';\n"
  25.110 +        + "li.appendChild(span);\n"
  25.111 +        + "li.appendChild(details);\n"
  25.112 +        + "p.appendChild(pre);\n"
  25.113 +        + "ul.appendChild(li);\n"
  25.114 +        + "arr[0] = pre;\n"
  25.115 +        + "arr[1] = status;\n"
  25.116 +    )
  25.117 +    private static native void beginTest(String test, Case c, Object[] arr);
  25.118 +    
  25.119 +    @JavaScriptBody(args = { "url", "callback", "arr" }, body = ""
  25.120 +        + "var request = new XMLHttpRequest();\n"
  25.121 +        + "request.open('GET', url, true);\n"
  25.122 +        + "request.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');\n"
  25.123 +        + "request.onreadystatechange = function() {\n"
  25.124 +        + "  if (this.readyState!==4) return;\n"
  25.125 +        + "  arr[0] = this.responseText;\n"
  25.126 +        + "  callback.run__V();\n"
  25.127 +        + "};"
  25.128 +        + "request.send();"
  25.129 +    )
  25.130 +    private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
  25.131 +    
  25.132 +    public static void harness(String url) throws IOException {
  25.133 +        log("Connecting to " + url);
  25.134 +        Request r = new Request(url);
  25.135 +    }
  25.136 +    
  25.137 +    private static class Request implements Runnable {
  25.138 +        private final String[] arr = { null };
  25.139 +        private final String url;
  25.140 +        private Case c;
  25.141 +        private int retries;
  25.142 +
  25.143 +        private Request(String url) throws IOException {
  25.144 +            this.url = url;
  25.145 +            loadText(url, this, arr);
  25.146 +        }
  25.147 +        private Request(String url, String u) throws IOException {
  25.148 +            this.url = url;
  25.149 +            loadText(u, this, arr);
  25.150 +        }
  25.151 +        
  25.152 +        @Override
  25.153 +        public void run() {
  25.154 +            try {
  25.155 +                if (c == null) {
  25.156 +                    String data = arr[0];
  25.157 +
  25.158 +                    if (data == null) {
  25.159 +                        log("Some error exiting");
  25.160 +                        closeWindow();
  25.161 +                        return;
  25.162 +                    }
  25.163 +
  25.164 +                    if (data.isEmpty()) {
  25.165 +                        log("No data, exiting");
  25.166 +                        closeWindow();
  25.167 +                        return;
  25.168 +                    }
  25.169 +
  25.170 +                    c = Case.parseData(data);
  25.171 +                    beginTest(c);
  25.172 +                    log("Got \"" + data + "\"");
  25.173 +                } else {
  25.174 +                    log("Processing \"" + arr[0] + "\" for " + retries + " time");
  25.175 +                }
  25.176 +                Object result = retries++ >= 10 ? "java.lang.InterruptedException:timeout" : c.runTest();
  25.177 +                finishTest(c, result);
  25.178 +                
  25.179 +                String u = url + "?request=" + c.getRequestId() + "&result=" + result;
  25.180 +                new Request(url, u);
  25.181 +            } catch (Exception ex) {
  25.182 +                if (ex instanceof InterruptedException) {
  25.183 +                    log("Re-scheduling in 100ms");
  25.184 +                    schedule(this, 100);
  25.185 +                    return;
  25.186 +                }
  25.187 +                log(ex.getClass().getName() + ":" + ex.getMessage());
  25.188 +            }
  25.189 +        }
  25.190 +    }
  25.191 +    
  25.192 +    private static String encodeURL(String r) throws UnsupportedEncodingException {
  25.193 +        final String SPECIAL = "%$&+,/:;=?@";
  25.194 +        StringBuilder sb = new StringBuilder();
  25.195 +        byte[] utf8 = r.getBytes("UTF-8");
  25.196 +        for (int i = 0; i < utf8.length; i++) {
  25.197 +            int ch = utf8[i] & 0xff;
  25.198 +            if (ch < 32 || ch > 127 || SPECIAL.indexOf(ch) >= 0) {
  25.199 +                final String numbers = "0" + Integer.toHexString(ch);
  25.200 +                sb.append("%").append(numbers.substring(numbers.length() - 2));
  25.201 +            } else {
  25.202 +                if (ch == 32) {
  25.203 +                    sb.append("+");
  25.204 +                } else {
  25.205 +                    sb.append((char)ch);
  25.206 +                }
  25.207 +            }
  25.208 +        }
  25.209 +        return sb.toString();
  25.210 +    }
  25.211 +    
  25.212 +    static String invoke(String clazz, String method) throws 
  25.213 +    ClassNotFoundException, InvocationTargetException, IllegalAccessException, 
  25.214 +    InstantiationException, InterruptedException {
  25.215 +        final Object r = new Case(null).invokeMethod(clazz, method);
  25.216 +        return r == null ? "null" : r.toString().toString();
  25.217 +    }
  25.218 +
  25.219 +    /** Helper method that inspects the classpath and loads given resource
  25.220 +     * (usually a class file). Used while running tests in Rhino.
  25.221 +     * 
  25.222 +     * @param name resource name to find
  25.223 +     * @return the array of bytes in the given resource
  25.224 +     * @throws IOException I/O in case something goes wrong
  25.225 +     */
  25.226 +    public static byte[] read(String name) throws IOException {
  25.227 +        URL u = null;
  25.228 +        Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
  25.229 +        while (en.hasMoreElements()) {
  25.230 +            u = en.nextElement();
  25.231 +        }
  25.232 +        if (u == null) {
  25.233 +            throw new IOException("Can't find " + name);
  25.234 +        }
  25.235 +        try (InputStream is = u.openStream()) {
  25.236 +            byte[] arr;
  25.237 +            arr = new byte[is.available()];
  25.238 +            int offset = 0;
  25.239 +            while (offset < arr.length) {
  25.240 +                int len = is.read(arr, offset, arr.length - offset);
  25.241 +                if (len == -1) {
  25.242 +                    throw new IOException("Can't read " + name);
  25.243 +                }
  25.244 +                offset += len;
  25.245 +            }
  25.246 +            return arr;
  25.247 +        }
  25.248 +    }
  25.249 +   
  25.250 +    @JavaScriptBody(args = {}, body = "vm.desiredAssertionStatus = true;")
  25.251 +    private static void turnAssetionStatusOn() {
  25.252 +    }
  25.253 +
  25.254 +    @JavaScriptBody(args = {"r", "time"}, body =
  25.255 +        "return window.setTimeout(function() { r.run__V(); }, time);")
  25.256 +    private static native Object schedule(Runnable r, int time);
  25.257 +    
  25.258 +    private static final class Case {
  25.259 +        private final Object data;
  25.260 +        private Object inst;
  25.261 +
  25.262 +        private Case(Object data) {
  25.263 +            this.data = data;
  25.264 +        }
  25.265 +        
  25.266 +        public static Case parseData(String s) {
  25.267 +            return new Case(toJSON(s));
  25.268 +        }
  25.269 +        
  25.270 +        public String getMethodName() {
  25.271 +            return value("methodName", data);
  25.272 +        }
  25.273 +
  25.274 +        public String getClassName() {
  25.275 +            return value("className", data);
  25.276 +        }
  25.277 +        
  25.278 +        public String getRequestId() {
  25.279 +            return value("request", data);
  25.280 +        }
  25.281 +
  25.282 +        public String getHtmlFragment() {
  25.283 +            return value("html", data);
  25.284 +        }
  25.285 +        
  25.286 +        void again(Object[] arr) {
  25.287 +            try {
  25.288 +                textArea = arr[0];
  25.289 +                statusArea = arr[1];
  25.290 +                setAttr(textArea, "value", "");
  25.291 +                runTest();
  25.292 +            } catch (Exception ex) {
  25.293 +                log(ex.getClass().getName() + ":" + ex.getMessage());
  25.294 +            }
  25.295 +        }
  25.296 +
  25.297 +        private Object runTest() throws IllegalAccessException, 
  25.298 +        IllegalArgumentException, ClassNotFoundException, UnsupportedEncodingException, 
  25.299 +        InvocationTargetException, InstantiationException, InterruptedException {
  25.300 +            if (this.getHtmlFragment() != null) {
  25.301 +                setAttr("bck2brwsr.fragment", "innerHTML", this.getHtmlFragment());
  25.302 +            }
  25.303 +            log("Invoking " + this.getClassName() + '.' + this.getMethodName() + " as request: " + this.getRequestId());
  25.304 +            Object result = invokeMethod(this.getClassName(), this.getMethodName());
  25.305 +            setAttr("bck2brwsr.fragment", "innerHTML", "");
  25.306 +            log("Result: " + result);
  25.307 +            result = encodeURL("" + result);
  25.308 +            log("Sending back: ...?request=" + this.getRequestId() + "&result=" + result);
  25.309 +            return result;
  25.310 +        }
  25.311 +
  25.312 +        private Object invokeMethod(String clazz, String method)
  25.313 +        throws ClassNotFoundException, InvocationTargetException,
  25.314 +        InterruptedException, IllegalAccessException, IllegalArgumentException,
  25.315 +        InstantiationException {
  25.316 +            Method found = null;
  25.317 +            Class<?> c = Class.forName(clazz);
  25.318 +            for (Method m : c.getMethods()) {
  25.319 +                if (m.getName().equals(method)) {
  25.320 +                    found = m;
  25.321 +                }
  25.322 +            }
  25.323 +            Object res;
  25.324 +            if (found != null) {
  25.325 +                try {
  25.326 +                    if ((found.getModifiers() & Modifier.STATIC) != 0) {
  25.327 +                        res = found.invoke(null);
  25.328 +                    } else {
  25.329 +                        if (inst == null) {
  25.330 +                            inst = c.newInstance();
  25.331 +                        }
  25.332 +                        res = found.invoke(inst);
  25.333 +                    }
  25.334 +                } catch (Throwable ex) {
  25.335 +                    if (ex instanceof InvocationTargetException) {
  25.336 +                        ex = ((InvocationTargetException) ex).getTargetException();
  25.337 +                    }
  25.338 +                    if (ex instanceof InterruptedException) {
  25.339 +                        throw (InterruptedException)ex;
  25.340 +                    }
  25.341 +                    res = ex.getClass().getName() + ":" + ex.getMessage();
  25.342 +                }
  25.343 +            } else {
  25.344 +                res = "Can't find method " + method + " in " + clazz;
  25.345 +            }
  25.346 +            return res;
  25.347 +        }
  25.348 +        
  25.349 +        @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
  25.350 +        private static native Object toJSON(String s);
  25.351 +        
  25.352 +        @JavaScriptBody(args = {"p", "d"}, body = 
  25.353 +              "var v = d[p];\n"
  25.354 +            + "if (typeof v === 'undefined') return null;\n"
  25.355 +            + "return v.toString();"
  25.356 +        )
  25.357 +        private static native String value(String p, Object d);
  25.358 +    }
  25.359 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/launcher/http/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Mon Apr 29 16:32:14 2013 +0200
    26.3 @@ -0,0 +1,43 @@
    26.4 +<?xml version="1.0" encoding="UTF-8"?>
    26.5 +<!--
    26.6 +
    26.7 +    Back 2 Browser Bytecode Translator
    26.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    26.9 +
   26.10 +    This program is free software: you can redistribute it and/or modify
   26.11 +    it under the terms of the GNU General Public License as published by
   26.12 +    the Free Software Foundation, version 2 of the License.
   26.13 +
   26.14 +    This program is distributed in the hope that it will be useful,
   26.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.17 +    GNU General Public License for more details.
   26.18 +
   26.19 +    You should have received a copy of the GNU General Public License
   26.20 +    along with this program. Look for COPYING file in the top folder.
   26.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   26.22 +
   26.23 +-->
   26.24 +<!DOCTYPE html>
   26.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   26.26 +    <head>
   26.27 +        <title>Bck2Brwsr Harness</title>
   26.28 +    </head>
   26.29 +    <body>
   26.30 +        <script src="/bck2brwsr.js"></script>
   26.31 +        <script>
   26.32 +            var vm = bck2brwsr();
   26.33 +        </script>
   26.34 +        
   26.35 +        <h1>Bck2Brwsr Execution Harness</h1>
   26.36 +        
   26.37 +        <ul id="bck2brwsr.result" style="width: 100%;" >
   26.38 +        </ul>
   26.39 +
   26.40 +        <div id="bck2brwsr.fragment"/>
   26.41 +        
   26.42 +        <script type="text/javascript">
   26.43 +            vm.loadClass('org.apidesign.bck2brwsr.launcher.impl.Console').harness__VLjava_lang_String_2('$U/../data');
   26.44 +        </script>
   26.45 +    </body>
   26.46 +</html>
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/launcher/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    27.3 @@ -0,0 +1,19 @@
    27.4 +<?xml version="1.0" encoding="UTF-8"?>
    27.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    27.6 +  <modelVersion>4.0.0</modelVersion>
    27.7 +  <parent>
    27.8 +    <artifactId>bck2brwsr</artifactId>
    27.9 +    <groupId>org.apidesign</groupId>
   27.10 +    <version>0.7-SNAPSHOT</version>
   27.11 +  </parent>
   27.12 +  <groupId>org.apidesign.bck2brwsr</groupId>
   27.13 +  <artifactId>launcher-pom</artifactId>
   27.14 +  <version>0.7-SNAPSHOT</version>
   27.15 +  <packaging>pom</packaging>
   27.16 +  <name>Launchers</name>
   27.17 +  <modules>
   27.18 +    <module>api</module>
   27.19 +    <module>http</module>
   27.20 +    <module>fx</module>
   27.21 +  </modules>
   27.22 +</project>
   27.23 \ No newline at end of file
    28.1 --- a/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    28.2 +++ b/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    28.3 @@ -21,6 +21,7 @@
    28.4      <module>javaquery</module>
    28.5      <module>benchmarks</module>
    28.6      <module>ide</module>
    28.7 +    <module>launcher</module>
    28.8      <module>rt</module>
    28.9    </modules>
   28.10    <licenses>
   28.11 @@ -86,7 +87,7 @@
   28.12                         <exclude>rt/emul/*/src/main/**</exclude>
   28.13                         <exclude>rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java</exclude>
   28.14                         <exclude>rt/archetype/src/main/resources/archetype-resources/**</exclude>
   28.15 -                       <exclude>rt/vmtest/src/test/resources/**</exclude>
   28.16 +                       <exclude>rt/emul/compact/src/test/resources/**</exclude>
   28.17                         <exclude>dew/src/main/resources/org/apidesign/bck2brwsr/dew/**</exclude>
   28.18                         <exclude>javaquery/api/src/main/resources/org/apidesign/bck2brwsr/htmlpage/knockout*.js</exclude>
   28.19                    </excludes>
   28.20 @@ -256,4 +257,4 @@
   28.21          </dependency>
   28.22        </dependencies>
   28.23    </dependencyManagement>
   28.24 -</project>
   28.25 \ No newline at end of file
   28.26 +</project>
    29.1 --- a/rt/emul/brwsrtest/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    29.2 +++ b/rt/emul/brwsrtest/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    29.3 @@ -42,5 +42,11 @@
    29.4        <version>${project.version}</version>
    29.5        <scope>test</scope>
    29.6      </dependency>
    29.7 +    <dependency>
    29.8 +      <groupId>${project.groupId}</groupId>
    29.9 +      <artifactId>launcher.http</artifactId>
   29.10 +      <version>${project.version}</version>
   29.11 +      <scope>provided</scope>
   29.12 +    </dependency>
   29.13    </dependencies>
   29.14  </project>
    30.1 --- a/rt/emul/compact/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    30.2 +++ b/rt/emul/compact/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    30.3 @@ -28,6 +28,12 @@
    30.4        <scope>test</scope>
    30.5      </dependency>
    30.6      <dependency>
    30.7 +      <groupId>${project.groupId}</groupId>
    30.8 +      <artifactId>launcher.http</artifactId>
    30.9 +      <version>${project.version}</version>
   30.10 +      <scope>test</scope>
   30.11 +    </dependency>
   30.12 +    <dependency>
   30.13        <groupId>org.netbeans.api</groupId>
   30.14        <artifactId>org-openide-util-lookup</artifactId>
   30.15        <scope>test</scope>
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java	Mon Apr 29 16:32:14 2013 +0200
    31.3 @@ -0,0 +1,43 @@
    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.tck;
   31.22 +
   31.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   31.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   31.25 +import org.testng.annotations.Factory;
   31.26 +
   31.27 +/**
   31.28 + *
   31.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   31.30 + */
   31.31 +public class AssertionTest {
   31.32 +
   31.33 +    @Compare public Object checkAssert() throws ClassNotFoundException {
   31.34 +        try {
   31.35 +            assert false : "Is assertion status on?";
   31.36 +            return null;
   31.37 +        } catch (AssertionError ex) {
   31.38 +            return ex.getClass().getName();
   31.39 +        }
   31.40 +    }
   31.41 +    
   31.42 +    @Factory
   31.43 +    public static Object[] create() {
   31.44 +        return VMTest.create(AssertionTest.class);
   31.45 +    }
   31.46 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/BrwsrCheckTest.java	Mon Apr 29 16:32:14 2013 +0200
    32.3 @@ -0,0 +1,57 @@
    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.core.JavaScriptBody;
   32.24 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   32.25 +import org.apidesign.bck2brwsr.vmtest.HtmlFragment;
   32.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   32.27 +import org.testng.annotations.Factory;
   32.28 +
   32.29 +/**
   32.30 + *
   32.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   32.32 + */
   32.33 +public class BrwsrCheckTest {
   32.34 +
   32.35 +    @BrwsrTest public void assertWindowObjectIsDefined() {
   32.36 +        assert window() != null : "No window object found!";
   32.37 +    }
   32.38 +
   32.39 +    
   32.40 +    
   32.41 +    
   32.42 +    @HtmlFragment("<h1 id='hello'>\n"
   32.43 +        + "Hello!\n"
   32.44 +        + "</h1>\n")
   32.45 +    @BrwsrTest public void accessProvidedFragment() {
   32.46 +        assert getElementById("hello") != null : "Element with 'hello' ID found";
   32.47 +    }
   32.48 +    
   32.49 +    @Factory
   32.50 +    public static Object[] create() {
   32.51 +        return VMTest.create(BrwsrCheckTest.class);
   32.52 +    }
   32.53 +    
   32.54 +
   32.55 +    @JavaScriptBody(args = {}, body = "return window;")
   32.56 +    private static native Object window();
   32.57 +
   32.58 +    @JavaScriptBody(args = { "id" }, body = "return window.document.getElementById(id);")
   32.59 +    private static native Object getElementById(String id);
   32.60 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java	Mon Apr 29 16:32:14 2013 +0200
    33.3 @@ -0,0 +1,147 @@
    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 org.apidesign.bck2brwsr.core.JavaScriptBody;
   33.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
   33.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   33.26 +import org.testng.annotations.Factory;
   33.27 +
   33.28 +/**
   33.29 + *
   33.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   33.31 + */
   33.32 +public class ByteArithmeticTest {
   33.33 +    
   33.34 +    private static byte add(byte x, byte y) {
   33.35 +        return (byte)(x + y);
   33.36 +    }
   33.37 +    
   33.38 +    private static byte sub(byte x, byte y) {
   33.39 +        return (byte)(x - y);
   33.40 +    }
   33.41 +    
   33.42 +    private static byte mul(byte x, byte y) {
   33.43 +        return (byte)(x * y);
   33.44 +    }
   33.45 +    
   33.46 +    private static byte div(byte x, byte y) {
   33.47 +        return (byte)(x / y);
   33.48 +    }
   33.49 +    
   33.50 +    private static byte mod(byte x, byte y) {
   33.51 +        return (byte)(x % y);
   33.52 +    }
   33.53 +    
   33.54 +    @Compare public byte conversion() {
   33.55 +        return (byte)123456;
   33.56 +    }
   33.57 +    
   33.58 +    @Compare public byte addOverflow() {
   33.59 +        return add(Byte.MAX_VALUE, (byte)1);
   33.60 +    }
   33.61 +    
   33.62 +    @Compare public byte subUnderflow() {
   33.63 +        return sub(Byte.MIN_VALUE, (byte)1);
   33.64 +    }
   33.65 +    
   33.66 +    @Compare public byte addMaxByteAndMaxByte() {
   33.67 +        return add(Byte.MAX_VALUE, Byte.MAX_VALUE);
   33.68 +    }
   33.69 +    
   33.70 +    @Compare public byte subMinByteAndMinByte() {
   33.71 +        return sub(Byte.MIN_VALUE, Byte.MIN_VALUE);
   33.72 +    }
   33.73 +    
   33.74 +    @Compare public byte multiplyMaxByte() {
   33.75 +        return mul(Byte.MAX_VALUE, (byte)2);
   33.76 +    }
   33.77 +    
   33.78 +    @Compare public byte multiplyMaxByteAndMaxByte() {
   33.79 +        return mul(Byte.MAX_VALUE, Byte.MAX_VALUE);
   33.80 +    }
   33.81 +    
   33.82 +    @Compare public byte multiplyMinByte() {
   33.83 +        return mul(Byte.MIN_VALUE, (byte)2);
   33.84 +    }
   33.85 +    
   33.86 +    @Compare public byte multiplyMinByteAndMinByte() {
   33.87 +        return mul(Byte.MIN_VALUE, Byte.MIN_VALUE);
   33.88 +    }
   33.89 +    
   33.90 +    @Compare public byte multiplyPrecision() {
   33.91 +        return mul((byte)17638, (byte)1103);
   33.92 +    }
   33.93 +    
   33.94 +    @Compare public byte division() {
   33.95 +        return div((byte)1, (byte)2);
   33.96 +    }
   33.97 +    
   33.98 +    @Compare public byte divisionReminder() {
   33.99 +        return mod((byte)1, (byte)2);
  33.100 +    }
  33.101 +
  33.102 +    private static int readShort(byte[] byteCodes, int offset) {
  33.103 +        int signed = byteCodes[offset];
  33.104 +        byte b0 = (byte)signed;
  33.105 +        return (b0 << 8) | (byteCodes[offset + 1] & 0xff);
  33.106 +    }
  33.107 +    
  33.108 +    private static int readShortArg(byte[] byteCodes, int offsetInstruction) {
  33.109 +        return readShort(byteCodes, offsetInstruction + 1);
  33.110 +    }
  33.111 +    
  33.112 +    @Compare public int readIntArgs255and156() {
  33.113 +        final byte[] arr = new byte[] { (byte)0, (byte)255, (byte)156 };
  33.114 +        
  33.115 +        assert arr[1] == -1 : "First byte: " + arr[1];
  33.116 +        assert arr[2] == -100 : "Second byte: " + arr[2];
  33.117 +        final int ret = readShortArg(arr, 0);
  33.118 +        assert ret < 65000: "Value: " + ret;
  33.119 +        return ret;
  33.120 +    }
  33.121 +    
  33.122 +    @JavaScriptBody(args = { "arr" }, body = "arr[1] = 255; arr[2] = 156; return arr;")
  33.123 +    private static byte[] fill255and156(byte[] arr) {
  33.124 +        arr[1] = (byte)255;
  33.125 +        arr[2] = (byte)156;
  33.126 +        return arr;
  33.127 +    }
  33.128 +
  33.129 +    @Compare public int readIntArgs255and156JSArray() {
  33.130 +        final byte[] arr = fill255and156(new byte[] { 0, 0, 0 });
  33.131 +        
  33.132 +        final int ret = readShortArg(arr, 0);
  33.133 +        assert ret < 65000: "Value: " + ret;
  33.134 +        return ret;
  33.135 +    }
  33.136 +    
  33.137 +    @Compare public int readIntArgsMinus1andMinus100() {
  33.138 +        final byte[] arr = new byte[] { (byte)0, (byte)-1, (byte)-100 };
  33.139 +        
  33.140 +        assert arr[1] == -1 : "First byte: " + arr[1];
  33.141 +        assert arr[2] == -100 : "Second byte: " + arr[2];
  33.142 +        
  33.143 +        return readShortArg(arr, 0);
  33.144 +    }
  33.145 +    
  33.146 +    @Factory
  33.147 +    public static Object[] create() {
  33.148 +        return VMTest.create(ByteArithmeticTest.class);
  33.149 +    }
  33.150 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CloneTest.java	Mon Apr 29 16:32:14 2013 +0200
    34.3 @@ -0,0 +1,73 @@
    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 CloneTest {
   34.32 +    private int value;
   34.33 +    
   34.34 +    @Compare
   34.35 +    public Object notSupported() throws CloneNotSupportedException {
   34.36 +        return this.clone();
   34.37 +    }
   34.38 +
   34.39 +    @Compare public String sameClass() throws CloneNotSupportedException {
   34.40 +        return new Clnbl().clone().getClass().getName();
   34.41 +    }
   34.42 +
   34.43 +    @Compare public boolean differentInstance() throws CloneNotSupportedException {
   34.44 +        Clnbl orig = new Clnbl();
   34.45 +        return orig == orig.clone();
   34.46 +    }
   34.47 +
   34.48 +    @Compare public int sameReference() throws CloneNotSupportedException {
   34.49 +        CloneTest self = this;
   34.50 +        Clnbl orig = new Clnbl();
   34.51 +        self.value = 33;
   34.52 +        orig.ref = self;
   34.53 +        return ((Clnbl)orig.clone()).ref.value;
   34.54 +    }
   34.55 +
   34.56 +    @Compare public int sameValue() throws CloneNotSupportedException {
   34.57 +        Clnbl orig = new Clnbl();
   34.58 +        orig.value = 10;
   34.59 +        return ((Clnbl)orig.clone()).value;
   34.60 +    }
   34.61 +    
   34.62 +    @Factory
   34.63 +    public static Object[] create() {
   34.64 +        return VMTest.create(CloneTest.class);
   34.65 +    }
   34.66 +    
   34.67 +    public static final class Clnbl implements Cloneable {
   34.68 +        public CloneTest ref;
   34.69 +        private int value;
   34.70 +
   34.71 +        @Override
   34.72 +        public Object clone() throws CloneNotSupportedException {
   34.73 +            return super.clone();
   34.74 +        }
   34.75 +    }
   34.76 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Mon Apr 29 16:32:14 2013 +0200
    35.3 @@ -0,0 +1,103 @@
    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 +import org.apidesign.bck2brwsr.vmtest.Compare;
   35.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   35.25 +import org.testng.annotations.Factory;
   35.26 +
   35.27 +/**
   35.28 + *
   35.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   35.30 + */
   35.31 +public class CompareByteArrayTest {
   35.32 +    @Compare public int byteArraySum() {
   35.33 +        byte[] arr = createArray();
   35.34 +        return sumByteArr(arr);
   35.35 +    }
   35.36 +    
   35.37 +    @Compare public int countZeros() {
   35.38 +        int zeros = 0;
   35.39 +        for (Byte b : createArray()) {
   35.40 +            if (b == 0) {
   35.41 +                zeros++;
   35.42 +            }
   35.43 +        }
   35.44 +        return zeros;
   35.45 +    }
   35.46 +    
   35.47 +    private static int sumByteArr(byte[] arr) {
   35.48 +        int sum = 0;
   35.49 +        for (int i = 0; i < arr.length; i++) {
   35.50 +            sum += arr[i];
   35.51 +        }
   35.52 +        return sum;
   35.53 +    }
   35.54 +    
   35.55 +    @Compare public String noOutOfBounds() {
   35.56 +        return atIndex(1);
   35.57 +    }
   35.58 +
   35.59 +    @Compare public String outOfBounds() {
   35.60 +        return atIndex(5);
   35.61 +    }
   35.62 +
   35.63 +    @Compare public String outOfBoundsMinus() {
   35.64 +        return atIndex(-1);
   35.65 +    }
   35.66 +
   35.67 +    @Compare public String toOfBounds() {
   35.68 +        return toIndex(5);
   35.69 +    }
   35.70 +
   35.71 +    @Compare public String toOfBoundsMinus() {
   35.72 +        return toIndex(-1);
   35.73 +    }
   35.74 +    
   35.75 +    @Compare public int multiArrayLength() {
   35.76 +         int[][] arr = new int[1][0];
   35.77 +         return arr[0].length;
   35.78 +    }
   35.79 +
   35.80 +    @Compare public int multiObjectArrayLength() {
   35.81 +         Object[][] arr = new Object[1][0];
   35.82 +         return arr[0].length;
   35.83 +    }
   35.84 +
   35.85 +    private static final int[] arr = { 0, 1, 2 };
   35.86 +    public static String atIndex(int at) {
   35.87 +        return "at@" + arr[at];
   35.88 +    }
   35.89 +    public static String toIndex(int at) {
   35.90 +        arr[at] = 10;
   35.91 +        return "ok";
   35.92 +    }
   35.93 +    
   35.94 +    
   35.95 +    @Factory
   35.96 +    public static Object[] create() {
   35.97 +        return VMTest.create(CompareByteArrayTest.class);
   35.98 +    }
   35.99 +
  35.100 +    private byte[] createArray() {
  35.101 +        byte[] arr = new byte[10];
  35.102 +        arr[5] = 3;
  35.103 +        arr[7] = 8;
  35.104 +        return arr;
  35.105 +    }
  35.106 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Mon Apr 29 16:32:14 2013 +0200
    36.3 @@ -0,0 +1,50 @@
    36.4 +/**
    36.5 + * Back 2 Browser Bytecode Translator
    36.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    36.7 + *
    36.8 + * This program is free software: you can redistribute it and/or modify
    36.9 + * it under the terms of the GNU General Public License as published by
   36.10 + * the Free Software Foundation, version 2 of the License.
   36.11 + *
   36.12 + * This program is distributed in the hope that it will be useful,
   36.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   36.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   36.15 + * GNU General Public License for more details.
   36.16 + *
   36.17 + * You should have received a copy of the GNU General Public License
   36.18 + * along with this program. Look for COPYING file in the top folder.
   36.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   36.20 + */
   36.21 +package org.apidesign.bck2brwsr.tck;
   36.22 +
   36.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   36.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   36.25 +import org.testng.annotations.Factory;
   36.26 +
   36.27 +/**
   36.28 + *
   36.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   36.30 + */
   36.31 +public class CompareHashTest {
   36.32 +    @Compare public int hashOfString() {
   36.33 +        return "Ahoj".hashCode();
   36.34 +    }
   36.35 +    
   36.36 +    @Compare public int hashRemainsYieldsZero() {
   36.37 +        Object o = new Object();
   36.38 +        return o.hashCode() - o.hashCode();
   36.39 +    }
   36.40 +    
   36.41 +    @Compare public int initializeInStatic() {
   36.42 +        return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
   36.43 +    }
   36.44 +    
   36.45 +    @Compare public int hashOfInt() {
   36.46 +        return Integer.valueOf(Integer.MAX_VALUE).hashCode();
   36.47 +    }
   36.48 +    
   36.49 +    @Factory
   36.50 +    public static Object[] create() {
   36.51 +        return VMTest.create(CompareHashTest.class);
   36.52 +    }
   36.53 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareIntArrayTest.java	Mon Apr 29 16:32:14 2013 +0200
    37.3 @@ -0,0 +1,63 @@
    37.4 +/**
    37.5 + * Back 2 Browser Bytecode Translator
    37.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    37.7 + *
    37.8 + * This program is free software: you can redistribute it and/or modify
    37.9 + * it under the terms of the GNU General Public License as published by
   37.10 + * the Free Software Foundation, version 2 of the License.
   37.11 + *
   37.12 + * This program is distributed in the hope that it will be useful,
   37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.15 + * GNU General Public License for more details.
   37.16 + *
   37.17 + * You should have received a copy of the GNU General Public License
   37.18 + * along with this program. Look for COPYING file in the top folder.
   37.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   37.20 + */
   37.21 +package org.apidesign.bck2brwsr.tck;
   37.22 +
   37.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   37.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   37.25 +import org.testng.annotations.Factory;
   37.26 +
   37.27 +/**
   37.28 + *
   37.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   37.30 + */
   37.31 +public class CompareIntArrayTest {
   37.32 +    @Compare public int integerArraySum() {
   37.33 +        int[] arr = createArray();
   37.34 +        return sumIntArr(arr);
   37.35 +    }
   37.36 +    
   37.37 +    @Compare public int countZeros() {
   37.38 +        int zeros = 0;
   37.39 +        for (Integer i : createArray()) {
   37.40 +            if (i == 0) {
   37.41 +                zeros++;
   37.42 +            }
   37.43 +        }
   37.44 +        return zeros;
   37.45 +    }
   37.46 +    
   37.47 +    private static int sumIntArr(int[] arr) {
   37.48 +        int sum = 0;
   37.49 +        for (int i = 0; i < arr.length; i++) {
   37.50 +            sum += arr[i];
   37.51 +        }
   37.52 +        return sum;
   37.53 +    }
   37.54 +    
   37.55 +    @Factory
   37.56 +    public static Object[] create() {
   37.57 +        return VMTest.create(CompareIntArrayTest.class);
   37.58 +    }
   37.59 +
   37.60 +    private int[] createArray() {
   37.61 +        int[] arr = new int[10];
   37.62 +        arr[5] = 3;
   37.63 +        arr[7] = 8;
   37.64 +        return arr;
   37.65 +    }
   37.66 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Mon Apr 29 16:32:14 2013 +0200
    38.3 @@ -0,0 +1,174 @@
    38.4 +/**
    38.5 + * Back 2 Browser Bytecode Translator
    38.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    38.7 + *
    38.8 + * This program is free software: you can redistribute it and/or modify
    38.9 + * it under the terms of the GNU General Public License as published by
   38.10 + * the Free Software Foundation, version 2 of the License.
   38.11 + *
   38.12 + * This program is distributed in the hope that it will be useful,
   38.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   38.15 + * GNU General Public License for more details.
   38.16 + *
   38.17 + * You should have received a copy of the GNU General Public License
   38.18 + * along with this program. Look for COPYING file in the top folder.
   38.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   38.20 + */
   38.21 +package org.apidesign.bck2brwsr.tck;
   38.22 +
   38.23 +import java.io.UnsupportedEncodingException;
   38.24 +import java.net.MalformedURLException;
   38.25 +import java.net.URL;
   38.26 +import org.apidesign.bck2brwsr.vmtest.Compare;
   38.27 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   38.28 +import org.testng.annotations.Factory;
   38.29 +
   38.30 +/**
   38.31 + *
   38.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   38.33 + */
   38.34 +public class CompareStringsTest {
   38.35 +    @Compare public String firstChar() {
   38.36 +        return "" + ("Hello".toCharArray()[0]);
   38.37 +    }
   38.38 +    
   38.39 +    @Compare public String classCast() {
   38.40 +        Object o = firstChar();
   38.41 +        return String.class.cast(o);
   38.42 +    }
   38.43 +
   38.44 +    @Compare public String classCastThrown() {
   38.45 +        Object o = null;
   38.46 +        return String.class.cast(o);
   38.47 +    }
   38.48 +    
   38.49 +    @Compare public boolean equalToNull() {
   38.50 +        return "Ahoj".equals(null);
   38.51 +    }
   38.52 +    
   38.53 +    @Compare public int highByteLenght() {
   38.54 +        byte[] arr= { 77,97,110,105,102,101,115,116,45,86,101,114,115,105,111,110 };
   38.55 +        return new String(arr, 0).length();
   38.56 +    }
   38.57 +    
   38.58 +    @Compare public String highByte() {
   38.59 +        byte[] arr= { 77,97,110,105,102,101,115,116,45,86,101,114,115,105,111,110 };
   38.60 +        StringBuilder sb = new StringBuilder();
   38.61 +        sb.append("pref:");
   38.62 +        sb.append(new String(arr, 0));
   38.63 +        return sb.toString();
   38.64 +    }
   38.65 +    
   38.66 +    @Compare public static Object compareURLs() throws MalformedURLException {
   38.67 +        return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
   38.68 +    }
   38.69 +    
   38.70 +    @Compare public String deleteLastTwoCharacters() {
   38.71 +        StringBuilder sb = new StringBuilder();
   38.72 +        sb.append("453.0");
   38.73 +        if (sb.toString().endsWith(".0")) {
   38.74 +            final int l = sb.length();
   38.75 +            sb.delete(l - 2, l);
   38.76 +        }
   38.77 +        return sb.toString().toString();
   38.78 +    }
   38.79 +    
   38.80 +    @Compare public String nameOfStringClass() throws Exception {
   38.81 +        return Class.forName("java.lang.String").getName();
   38.82 +    }
   38.83 +    @Compare public String nameOfArrayClass() throws Exception {
   38.84 +        return Class.forName("org.apidesign.bck2brwsr.tck.CompareHashTest").getName();
   38.85 +    }
   38.86 +    
   38.87 +    @Compare public String lowerHello() {
   38.88 +        return "HeLlO".toLowerCase();
   38.89 +    }
   38.90 +    
   38.91 +    @Compare public String lowerA() {
   38.92 +        return String.valueOf(Character.toLowerCase('A')).toString();
   38.93 +    }
   38.94 +    @Compare public String upperHello() {
   38.95 +        return "hello".toUpperCase();
   38.96 +    }
   38.97 +    
   38.98 +    @Compare public String upperA() {
   38.99 +        return String.valueOf(Character.toUpperCase('a')).toString();
  38.100 +    }
  38.101 +    
  38.102 +    @Compare public boolean matchRegExp() throws Exception {
  38.103 +        return "58038503".matches("\\d*");
  38.104 +    }
  38.105 +
  38.106 +    @Compare public boolean doesNotMatchRegExp() throws Exception {
  38.107 +        return "58038503GH".matches("\\d*");
  38.108 +    }
  38.109 +
  38.110 +    @Compare public boolean doesNotMatchRegExpFully() throws Exception {
  38.111 +        return "Hello".matches("Hell");
  38.112 +    }
  38.113 +    
  38.114 +    @Compare public String emptyCharArray() {
  38.115 +        char[] arr = new char[10];
  38.116 +        return new String(arr);
  38.117 +    }
  38.118 +    
  38.119 +    @Compare public String variousCharacterTests() throws Exception {
  38.120 +        StringBuilder sb = new StringBuilder();
  38.121 +        
  38.122 +        sb.append(Character.isUpperCase('a'));
  38.123 +        sb.append(Character.isUpperCase('A'));
  38.124 +        sb.append(Character.isLowerCase('a'));
  38.125 +        sb.append(Character.isLowerCase('A'));
  38.126 +        
  38.127 +        sb.append(Character.isLetter('A'));
  38.128 +        sb.append(Character.isLetterOrDigit('9'));
  38.129 +        sb.append(Character.isLetterOrDigit('A'));
  38.130 +        sb.append(Character.isLetter('0'));
  38.131 +        
  38.132 +        return sb.toString().toString();
  38.133 +    }
  38.134 +        
  38.135 +    @Compare
  38.136 +    public String nullFieldInitialized() {
  38.137 +        NullField nf = new NullField();
  38.138 +        return ("" + nf.name).toString();
  38.139 +    }
  38.140 +    @Compare
  38.141 +    public String toUTFString() throws UnsupportedEncodingException {
  38.142 +        byte[] arr = {
  38.143 +            (byte) -59, (byte) -67, (byte) 108, (byte) 117, (byte) -59, (byte) -91,
  38.144 +            (byte) 111, (byte) 117, (byte) -60, (byte) -115, (byte) 107, (byte) -61,
  38.145 +            (byte) -67, (byte) 32, (byte) 107, (byte) -59, (byte) -81, (byte) -59,
  38.146 +            (byte) -120
  38.147 +        };
  38.148 +        return new String(arr, "utf-8");
  38.149 +    }
  38.150 +
  38.151 +    @Compare
  38.152 +    public int stringToBytesLenght() throws UnsupportedEncodingException {
  38.153 +        return "\u017dlu\u0165ou\u010dk\u00fd k\u016f\u0148".getBytes("utf8").length;
  38.154 +    }
  38.155 +    
  38.156 +    @Compare public String replaceSeq() {
  38.157 +        return "Hello World.".replace(".", "!");
  38.158 +    }
  38.159 +    @Compare public String replaceSeqAll() {
  38.160 +        return "Hello World! Hello World.".replace("World", "Jarda");
  38.161 +    }
  38.162 +    @Compare public String replaceSeqAA() {
  38.163 +        String res = "aaa".replace("aa", "b");
  38.164 +        assert res.equals("ba") : "Expecting ba: " + res;
  38.165 +        return res;
  38.166 +    }
  38.167 +
  38.168 +    @Factory
  38.169 +    public static Object[] create() {
  38.170 +        return VMTest.create(CompareStringsTest.class);
  38.171 +    }
  38.172 +
  38.173 +    private static final class NullField {
  38.174 +
  38.175 +        String name;
  38.176 +    }
  38.177 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/DoubleTest.java	Mon Apr 29 16:32:14 2013 +0200
    39.3 @@ -0,0 +1,65 @@
    39.4 +/**
    39.5 + * Back 2 Browser Bytecode Translator
    39.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    39.7 + *
    39.8 + * This program is free software: you can redistribute it and/or modify
    39.9 + * it under the terms of the GNU General Public License as published by
   39.10 + * the Free Software Foundation, version 2 of the License.
   39.11 + *
   39.12 + * This program is distributed in the hope that it will be useful,
   39.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   39.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   39.15 + * GNU General Public License for more details.
   39.16 + *
   39.17 + * You should have received a copy of the GNU General Public License
   39.18 + * along with this program. Look for COPYING file in the top folder.
   39.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   39.20 + */
   39.21 +package org.apidesign.bck2brwsr.tck;
   39.22 +
   39.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   39.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   39.25 +import org.testng.annotations.Factory;
   39.26 +
   39.27 +/**
   39.28 + *
   39.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   39.30 + */
   39.31 +public class DoubleTest {
   39.32 +    @Compare public String integerToString() {
   39.33 +        return toStr(1);
   39.34 +    }
   39.35 +
   39.36 +    @Compare public String integerAndHalfToString() {
   39.37 +        return toStr(1.5);
   39.38 +    }
   39.39 +
   39.40 +    @Compare public double longToAndBack() {
   39.41 +        return Double.parseDouble(toStr(Long.MAX_VALUE / 10));
   39.42 +    }
   39.43 +
   39.44 +    @Compare public String negativeIntToString() {
   39.45 +        return toStr(-10);
   39.46 +    }
   39.47 +
   39.48 +    @Compare public String negativeIntAndHalfToString() {
   39.49 +        return toStr(-10.5);
   39.50 +    }
   39.51 +
   39.52 +    @Compare public double negativeLongAndBack() {
   39.53 +        return Double.parseDouble(toStr(Long.MIN_VALUE / 10));
   39.54 +    }
   39.55 +    
   39.56 +    @Compare public double canParseExp() {
   39.57 +        return Double.parseDouble(toStr(1.7976931348623157e+308));
   39.58 +    }
   39.59 +    
   39.60 +    private static String toStr(double d) {
   39.61 +        return Double.toString(d);
   39.62 +    }
   39.63 +    
   39.64 +    @Factory 
   39.65 +    public static Object[] create() {
   39.66 +        return VMTest.create(DoubleTest.class);
   39.67 +    }
   39.68 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java	Mon Apr 29 16:32:14 2013 +0200
    40.3 @@ -0,0 +1,106 @@
    40.4 +/**
    40.5 + * Back 2 Browser Bytecode Translator
    40.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    40.7 + *
    40.8 + * This program is free software: you can redistribute it and/or modify
    40.9 + * it under the terms of the GNU General Public License as published by
   40.10 + * the Free Software Foundation, version 2 of the License.
   40.11 + *
   40.12 + * This program is distributed in the hope that it will be useful,
   40.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   40.15 + * GNU General Public License for more details.
   40.16 + *
   40.17 + * You should have received a copy of the GNU General Public License
   40.18 + * along with this program. Look for COPYING file in the top folder.
   40.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   40.20 + */
   40.21 +package org.apidesign.bck2brwsr.tck;
   40.22 +
   40.23 +import java.io.InputStream;
   40.24 +import java.net.URL;
   40.25 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   40.26 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   40.27 +import org.apidesign.bck2brwsr.vmtest.Http;
   40.28 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   40.29 +import org.testng.annotations.Factory;
   40.30 +
   40.31 +/**
   40.32 + *
   40.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   40.34 + */
   40.35 +public class HttpResourceTest {
   40.36 +    
   40.37 +    @Http({
   40.38 +        @Http.Resource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain")
   40.39 +    })
   40.40 +    @BrwsrTest
   40.41 +    
   40.42 +    
   40.43 +    public String testReadContentViaXHR() throws Exception {
   40.44 +        String msg = read("/xhr");
   40.45 +        assert "Hello Brwsr!".equals(msg) : "The message was " + msg;
   40.46 +        return msg;
   40.47 +    }
   40.48 +
   40.49 +    @Http({
   40.50 +        @Http.Resource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
   40.51 +    })
   40.52 +    @BrwsrTest
   40.53 +    public String testReadContentViaURL() throws Exception {
   40.54 +        URL url = new URL("http:/url");
   40.55 +        String msg = (String) url.getContent();
   40.56 +        assert "Hello via URL!".equals(msg) : "The message was " + msg;
   40.57 +        return msg;
   40.58 +    }
   40.59 +    @Http({
   40.60 +        @Http.Resource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
   40.61 +    })
   40.62 +    @BrwsrTest
   40.63 +    public String testReadContentViaURLWithStringParam() throws Exception {
   40.64 +        URL url = new URL("http:/url");
   40.65 +        String msg = (String) url.getContent(new Class[] { String.class });
   40.66 +        assert "Hello via URL!".equals(msg) : "The message was " + msg;
   40.67 +        return msg;
   40.68 +    }
   40.69 +
   40.70 +    @Http({
   40.71 +        @Http.Resource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
   40.72 +    })
   40.73 +    @BrwsrTest
   40.74 +    public void testReadByte() throws Exception {
   40.75 +        URL url = new URL("http:/bytes");
   40.76 +        final Object res = url.getContent(new Class[] { byte[].class });
   40.77 +        assert res instanceof byte[] : "Expecting byte[]: " + res;
   40.78 +        byte[] arr = (byte[]) res;
   40.79 +        assert arr.length == 1 : "One byte " + arr.length;
   40.80 +        assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
   40.81 +    }
   40.82 +
   40.83 +    @Http({
   40.84 +        @Http.Resource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
   40.85 +    })
   40.86 +    @BrwsrTest
   40.87 +    public void testReadByteViaInputStream() throws Exception {
   40.88 +        URL url = new URL("http:/bytes");
   40.89 +        InputStream is = url.openStream();
   40.90 +        byte[] arr = new byte[10];
   40.91 +        int len = is.read(arr);
   40.92 +        assert len == 1 : "One byte " + len;
   40.93 +        assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
   40.94 +    }
   40.95 +    
   40.96 +    @JavaScriptBody(args = { "url" }, body = 
   40.97 +          "var req = new XMLHttpRequest();\n"
   40.98 +        + "req.open('GET', url, false);\n"
   40.99 +        + "req.send();\n"
  40.100 +        + "return req.responseText;"
  40.101 +    )
  40.102 +    private static native String read(String url);
  40.103 +    
  40.104 +    
  40.105 +    @Factory
  40.106 +    public static Object[] create() {
  40.107 +        return VMTest.create(HttpResourceTest.class);
  40.108 +    }
  40.109 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceA.java	Mon Apr 29 16:32:14 2013 +0200
    41.3 @@ -0,0 +1,34 @@
    41.4 +/**
    41.5 + * Back 2 Browser Bytecode Translator
    41.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    41.7 + *
    41.8 + * This program is free software: you can redistribute it and/or modify
    41.9 + * it under the terms of the GNU General Public License as published by
   41.10 + * the Free Software Foundation, version 2 of the License.
   41.11 + *
   41.12 + * This program is distributed in the hope that it will be useful,
   41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   41.15 + * GNU General Public License for more details.
   41.16 + *
   41.17 + * You should have received a copy of the GNU General Public License
   41.18 + * along with this program. Look for COPYING file in the top folder.
   41.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   41.20 + */
   41.21 +package org.apidesign.bck2brwsr.tck;
   41.22 +
   41.23 +/**
   41.24 + *
   41.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   41.26 + */
   41.27 +public class InheritanceA {
   41.28 +    private String name;
   41.29 +    
   41.30 +    public void setA(String n) {
   41.31 +        this.name = n;
   41.32 +    }
   41.33 +    
   41.34 +    public String getA() {
   41.35 +        return name;
   41.36 +    }
   41.37 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceB.java	Mon Apr 29 16:32:14 2013 +0200
    42.3 @@ -0,0 +1,34 @@
    42.4 +/**
    42.5 + * Back 2 Browser Bytecode Translator
    42.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    42.7 + *
    42.8 + * This program is free software: you can redistribute it and/or modify
    42.9 + * it under the terms of the GNU General Public License as published by
   42.10 + * the Free Software Foundation, version 2 of the License.
   42.11 + *
   42.12 + * This program is distributed in the hope that it will be useful,
   42.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   42.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   42.15 + * GNU General Public License for more details.
   42.16 + *
   42.17 + * You should have received a copy of the GNU General Public License
   42.18 + * along with this program. Look for COPYING file in the top folder.
   42.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   42.20 + */
   42.21 +package org.apidesign.bck2brwsr.tck;
   42.22 +
   42.23 +/**
   42.24 + *
   42.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   42.26 + */
   42.27 +public class InheritanceB extends InheritanceA {
   42.28 +    private String name;
   42.29 +    
   42.30 +    public void setB(String n) {
   42.31 +        this.name = n;
   42.32 +    }
   42.33 +    
   42.34 +    public String getB() {
   42.35 +        return name;
   42.36 +    }
   42.37 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceTest.java	Mon Apr 29 16:32:14 2013 +0200
    43.3 @@ -0,0 +1,41 @@
    43.4 +/**
    43.5 + * Back 2 Browser Bytecode Translator
    43.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    43.7 + *
    43.8 + * This program is free software: you can redistribute it and/or modify
    43.9 + * it under the terms of the GNU General Public License as published by
   43.10 + * the Free Software Foundation, version 2 of the License.
   43.11 + *
   43.12 + * This program is distributed in the hope that it will be useful,
   43.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.15 + * GNU General Public License for more details.
   43.16 + *
   43.17 + * You should have received a copy of the GNU General Public License
   43.18 + * along with this program. Look for COPYING file in the top folder.
   43.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   43.20 + */
   43.21 +package org.apidesign.bck2brwsr.tck;
   43.22 +
   43.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   43.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   43.25 +import org.testng.annotations.Factory;
   43.26 +
   43.27 +/**
   43.28 + *
   43.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   43.30 + */
   43.31 +public class InheritanceTest {
   43.32 +
   43.33 +    @Compare public String checkFieldsIndependent() throws ClassNotFoundException {
   43.34 +        InheritanceB ib = new InheritanceB();
   43.35 +        ib.setA("A");
   43.36 +        ib.setB("B");
   43.37 +        return "A: " + ib.getA() + " B: " + ib.getB();
   43.38 +    }
   43.39 +    
   43.40 +    @Factory
   43.41 +    public static Object[] create() {
   43.42 +        return VMTest.create(InheritanceTest.class);
   43.43 +    }
   43.44 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java	Mon Apr 29 16:32:14 2013 +0200
    44.3 @@ -0,0 +1,166 @@
    44.4 +/**
    44.5 + * Back 2 Browser Bytecode Translator
    44.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    44.7 + *
    44.8 + * This program is free software: you can redistribute it and/or modify
    44.9 + * it under the terms of the GNU General Public License as published by
   44.10 + * the Free Software Foundation, version 2 of the License.
   44.11 + *
   44.12 + * This program is distributed in the hope that it will be useful,
   44.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   44.15 + * GNU General Public License for more details.
   44.16 + *
   44.17 + * You should have received a copy of the GNU General Public License
   44.18 + * along with this program. Look for COPYING file in the top folder.
   44.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   44.20 + */
   44.21 +package org.apidesign.bck2brwsr.tck;
   44.22 +
   44.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   44.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   44.25 +import org.testng.annotations.Factory;
   44.26 +
   44.27 +/**
   44.28 + *
   44.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   44.30 + */
   44.31 +public class IntegerArithmeticTest {
   44.32 +    
   44.33 +    private static int add(int x, int y) {
   44.34 +        return x + y;
   44.35 +    }
   44.36 +    
   44.37 +    private static int sub(int x, int y) {
   44.38 +        return x - y;
   44.39 +    }
   44.40 +    
   44.41 +    private static int mul(int x, int y) {
   44.42 +        return x * y;
   44.43 +    }
   44.44 +    
   44.45 +    private static int div(int x, int y) {
   44.46 +        return x / y;
   44.47 +    }
   44.48 +    
   44.49 +    private static int mod(int x, int y) {
   44.50 +        return x % y;
   44.51 +    }
   44.52 +    
   44.53 +    private static int neg(int x) {
   44.54 +        return (-x);
   44.55 +    }
   44.56 +
   44.57 +    private static float fadd(float x, float y) {
   44.58 +        return x + y;
   44.59 +    }
   44.60 +
   44.61 +    private static double dadd(double x, double y) {
   44.62 +        return x + y;
   44.63 +    }
   44.64 +    
   44.65 +    @Compare public int addOverflow() {
   44.66 +        return add(Integer.MAX_VALUE, 1);
   44.67 +    }
   44.68 +    
   44.69 +    @Compare public int subUnderflow() {
   44.70 +        return sub(Integer.MIN_VALUE, 1);
   44.71 +    }
   44.72 +    
   44.73 +    @Compare public int addMaxIntAndMaxInt() {
   44.74 +        return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
   44.75 +    }
   44.76 +    
   44.77 +    @Compare public int subMinIntAndMinInt() {
   44.78 +        return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
   44.79 +    }
   44.80 +    
   44.81 +    @Compare public int multiplyMaxInt() {
   44.82 +        return mul(Integer.MAX_VALUE, 2);
   44.83 +    }
   44.84 +    
   44.85 +    @Compare public int multiplyMaxIntAndMaxInt() {
   44.86 +        return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
   44.87 +    }
   44.88 +    
   44.89 +    @Compare public int multiplyMinInt() {
   44.90 +        return mul(Integer.MIN_VALUE, 2);
   44.91 +    }
   44.92 +    
   44.93 +    @Compare public int multiplyMinIntAndMinInt() {
   44.94 +        return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
   44.95 +    }
   44.96 +    
   44.97 +    @Compare public int multiplyPrecision() {
   44.98 +        return mul(119106029, 1103515245);
   44.99 +    }
  44.100 +    
  44.101 +    @Compare public int division() {
  44.102 +        return div(1, 2);
  44.103 +    }
  44.104 +
  44.105 +    @Compare public int divisionReminder() {
  44.106 +        return mod(1, 2);
  44.107 +    }
  44.108 +
  44.109 +    @Compare public int negativeDivision() {
  44.110 +        return div(-7, 3);
  44.111 +    }
  44.112 +
  44.113 +    @Compare public int negativeDivisionReminder() {
  44.114 +        return mod(-7, 3);
  44.115 +    }
  44.116 +
  44.117 +    @Compare public int conversionFromFloat() {
  44.118 +        return (int) fadd(-2, -0.6f);
  44.119 +    }
  44.120 +
  44.121 +    @Compare public int conversionFromDouble() {
  44.122 +        return (int) dadd(-2, -0.6);
  44.123 +    }
  44.124 +
  44.125 +    @Compare public boolean divByZeroThrowsArithmeticException() {
  44.126 +        try {
  44.127 +            div(1, 0);
  44.128 +            return false;
  44.129 +        } catch (final ArithmeticException e) {
  44.130 +            return true;
  44.131 +        }
  44.132 +    }
  44.133 +
  44.134 +    @Compare public boolean modByZeroThrowsArithmeticException() {
  44.135 +        try {
  44.136 +            mod(1, 0);
  44.137 +            return false;
  44.138 +        } catch (final ArithmeticException e) {
  44.139 +            return true;
  44.140 +        }
  44.141 +    }
  44.142 +
  44.143 +    @Compare public int negate() {
  44.144 +        return neg(123456);
  44.145 +    }
  44.146 +    
  44.147 +    @Compare public int negateMaxInt() {
  44.148 +        return neg(Integer.MAX_VALUE);
  44.149 +    }
  44.150 +    
  44.151 +    @Compare public int negateMinInt() {
  44.152 +        return neg(Integer.MIN_VALUE);
  44.153 +    }
  44.154 +    
  44.155 +    @Compare public int sumTwoDimensions() {
  44.156 +        int[][] matrix = createMatrix(4, 3);
  44.157 +        matrix[0][0] += 10;
  44.158 +        return matrix[0][0];
  44.159 +    }
  44.160 +    
  44.161 +    static int[][] createMatrix(int x, int y) {
  44.162 +        return new int[x][y];
  44.163 +    }
  44.164 +    
  44.165 +    @Factory
  44.166 +    public static Object[] create() {
  44.167 +        return VMTest.create(IntegerArithmeticTest.class);
  44.168 +    }
  44.169 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java	Mon Apr 29 16:32:14 2013 +0200
    45.3 @@ -0,0 +1,376 @@
    45.4 +/**
    45.5 + * Back 2 Browser Bytecode Translator
    45.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    45.7 + *
    45.8 + * This program is free software: you can redistribute it and/or modify
    45.9 + * it under the terms of the GNU General Public License as published by
   45.10 + * the Free Software Foundation, version 2 of the License.
   45.11 + *
   45.12 + * This program is distributed in the hope that it will be useful,
   45.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   45.15 + * GNU General Public License for more details.
   45.16 + *
   45.17 + * You should have received a copy of the GNU General Public License
   45.18 + * along with this program. Look for COPYING file in the top folder.
   45.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   45.20 + */
   45.21 +package org.apidesign.bck2brwsr.tck;
   45.22 +
   45.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   45.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   45.25 +import org.testng.annotations.Factory;
   45.26 +
   45.27 +/**
   45.28 + *
   45.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   45.30 + */
   45.31 +public class LongArithmeticTest {
   45.32 +
   45.33 +    private static long add(long x, long y) {
   45.34 +        return (x + y);
   45.35 +    }
   45.36 +
   45.37 +    private static long sub(long x, long y) {
   45.38 +        return (x - y);
   45.39 +    }
   45.40 +
   45.41 +    private static long mul(long x, long y) {
   45.42 +        return (x * y);
   45.43 +    }
   45.44 +
   45.45 +    private static long div(long x, long y) {
   45.46 +        return (x / y);
   45.47 +    }
   45.48 +
   45.49 +    private static long mod(long x, long y) {
   45.50 +        return (x % y);
   45.51 +    }
   45.52 +
   45.53 +    private static long neg(long x) {
   45.54 +        return (-x);
   45.55 +    }
   45.56 +
   45.57 +    private static long shl(long x, int b) {
   45.58 +        return (x << b);
   45.59 +    }
   45.60 +
   45.61 +    private static long shr(long x, int b) {
   45.62 +        return (x >> b);
   45.63 +    }
   45.64 +
   45.65 +    private static long ushr(long x, int b) {
   45.66 +        return (x >>> b);
   45.67 +    }
   45.68 +
   45.69 +    private static long and(long x, long y) {
   45.70 +        return (x & y);
   45.71 +    }
   45.72 +
   45.73 +    private static long or(long x, long y) {
   45.74 +        return (x | y);
   45.75 +    }
   45.76 +
   45.77 +    private static long xor(long x, long y) {
   45.78 +        return (x ^ y);
   45.79 +    }
   45.80 +
   45.81 +    private static float fadd(float x, float y) {
   45.82 +        return x + y;
   45.83 +    }
   45.84 +
   45.85 +    private static double dadd(double x, double y) {
   45.86 +        return x + y;
   45.87 +    }
   45.88 +
   45.89 +    public static int compare(long x, long y, int zero) {
   45.90 +        final int xyResult = compareL(x, y, zero);
   45.91 +        final int yxResult = compareL(y, x, zero);
   45.92 +
   45.93 +        return ((xyResult + yxResult) == 0) ? xyResult : -2;
   45.94 +    }
   45.95 +
   45.96 +    private static int compareL(long x, long y, int zero) {
   45.97 +        int result = -2;
   45.98 +        int trueCount = 0;
   45.99 +
  45.100 +        x += zero;
  45.101 +        if (x == y) {
  45.102 +            result = 0;
  45.103 +            ++trueCount;
  45.104 +        }
  45.105 +
  45.106 +        x += zero;
  45.107 +        if (x < y) {
  45.108 +            result = -1;
  45.109 +            ++trueCount;
  45.110 +        }
  45.111 +
  45.112 +        x += zero;
  45.113 +        if (x > y) {
  45.114 +            result = 1;
  45.115 +            ++trueCount;
  45.116 +        }
  45.117 +
  45.118 +        return (trueCount == 1) ? result : -2;
  45.119 +    }
  45.120 +
  45.121 +    @Compare public long conversion() {
  45.122 +        return Long.MAX_VALUE;
  45.123 +    }
  45.124 +
  45.125 +    @Compare public long negate1() {
  45.126 +        return neg(0x00fa37d7763e0ca1l);
  45.127 +    }
  45.128 +
  45.129 +    @Compare public long negate2() {
  45.130 +        return neg(0x80fa37d7763e0ca1l);
  45.131 +    }
  45.132 +
  45.133 +    @Compare public long negate3() {
  45.134 +        return neg(0xfffffffffffffeddl);
  45.135 +    }
  45.136 +
  45.137 +    @Compare public long addOverflow() {
  45.138 +        return add(Long.MAX_VALUE, 1l);
  45.139 +    }
  45.140 +
  45.141 +    @Compare public long subUnderflow() {
  45.142 +        return sub(Long.MIN_VALUE, 1l);
  45.143 +    }
  45.144 +
  45.145 +    @Compare public long addMaxLongAndMaxLong() {
  45.146 +        return add(Long.MAX_VALUE, Long.MAX_VALUE);
  45.147 +    }
  45.148 +
  45.149 +    @Compare public long subMinLongAndMinLong() {
  45.150 +        return sub(Long.MIN_VALUE, Long.MIN_VALUE);
  45.151 +    }
  45.152 +
  45.153 +    @Compare public long subMinLongAndMaxLong() {
  45.154 +        return sub(Long.MIN_VALUE, Long.MAX_VALUE);
  45.155 +    }
  45.156 +
  45.157 +    @Compare public long multiplyMaxLong() {
  45.158 +        return mul(Long.MAX_VALUE, 2l);
  45.159 +    }
  45.160 +
  45.161 +    @Compare public long multiplyMaxLongAndMaxLong() {
  45.162 +        return mul(Long.MAX_VALUE, Long.MAX_VALUE);
  45.163 +    }
  45.164 +
  45.165 +    @Compare public long multiplyMinLong() {
  45.166 +        return mul(Long.MIN_VALUE, 2l);
  45.167 +    }
  45.168 +
  45.169 +    @Compare public long multiplyMinLongAndMinLong() {
  45.170 +        return mul(Long.MIN_VALUE, Long.MIN_VALUE);
  45.171 +    }
  45.172 +
  45.173 +    @Compare public long multiplyPrecision() {
  45.174 +        return mul(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  45.175 +    }
  45.176 +
  45.177 +    @Compare public long divideSmallPositiveNumbers() {
  45.178 +        return div(0xabcdef, 0x123);
  45.179 +    }
  45.180 +
  45.181 +    @Compare public long divideSmallNegativeNumbers() {
  45.182 +        return div(-0xabcdef, -0x123);
  45.183 +    }
  45.184 +
  45.185 +    @Compare public long divideSmallMixedNumbers() {
  45.186 +        return div(0xabcdef, -0x123);
  45.187 +    }
  45.188 +
  45.189 +    @Compare public long dividePositiveNumbersOneDigitDenom() {
  45.190 +        return div(0xabcdef0102ffffl, 0x654);
  45.191 +    }
  45.192 +
  45.193 +    @Compare public long divideNegativeNumbersOneDigitDenom() {
  45.194 +        return div(-0xabcdef0102ffffl, -0x654);
  45.195 +    }
  45.196 +
  45.197 +    @Compare public long divideMixedNumbersOneDigitDenom() {
  45.198 +        return div(-0xabcdef0102ffffl, 0x654);
  45.199 +    }
  45.200 +
  45.201 +    @Compare public long dividePositiveNumbersMultiDigitDenom() {
  45.202 +        return div(0x7ffefc003322aabbl, 0x89ab1000l);
  45.203 +    }
  45.204 +
  45.205 +    @Compare public long divideNegativeNumbersMultiDigitDenom() {
  45.206 +        return div(-0x7ffefc003322aabbl, -0x123489ab1001l);
  45.207 +    }
  45.208 +
  45.209 +    @Compare public long divideMixedNumbersMultiDigitDenom() {
  45.210 +        return div(0x7ffefc003322aabbl, -0x38f49b0b7574e36l);
  45.211 +    }
  45.212 +
  45.213 +    @Compare public long divideWithOverflow() {
  45.214 +        return div(0x8000fffe0000l, 0x8000ffffl);
  45.215 +    }
  45.216 +
  45.217 +    @Compare public long divideWithCorrection() {
  45.218 +        return div(0x7fff800000000000l, 0x800000000001l);
  45.219 +    }
  45.220 +
  45.221 +    @Compare public long moduloSmallPositiveNumbers() {
  45.222 +        return mod(0xabcdef, 0x123);
  45.223 +    }
  45.224 +
  45.225 +    @Compare public long moduloSmallNegativeNumbers() {
  45.226 +        return mod(-0xabcdef, -0x123);
  45.227 +    }
  45.228 +
  45.229 +    @Compare public long moduloSmallMixedNumbers() {
  45.230 +        return mod(0xabcdef, -0x123);
  45.231 +    }
  45.232 +
  45.233 +    @Compare public long moduloPositiveNumbersOneDigitDenom() {
  45.234 +        return mod(0xabcdef0102ffffl, 0x654);
  45.235 +    }
  45.236 +
  45.237 +    @Compare public long moduloNegativeNumbersOneDigitDenom() {
  45.238 +        return mod(-0xabcdef0102ffffl, -0x654);
  45.239 +    }
  45.240 +
  45.241 +    @Compare public long moduloMixedNumbersOneDigitDenom() {
  45.242 +        return mod(-0xabcdef0102ffffl, 0x654);
  45.243 +    }
  45.244 +
  45.245 +    @Compare public long moduloPositiveNumbersMultiDigitDenom() {
  45.246 +        return mod(0x7ffefc003322aabbl, 0x89ab1000l);
  45.247 +    }
  45.248 +
  45.249 +    @Compare public long moduloNegativeNumbersMultiDigitDenom() {
  45.250 +        return mod(-0x7ffefc003322aabbl, -0x123489ab1001l);
  45.251 +    }
  45.252 +
  45.253 +    @Compare public long moduloMixedNumbersMultiDigitDenom() {
  45.254 +        return mod(0x7ffefc003322aabbl, -0x38f49b0b7574e36l);
  45.255 +    }
  45.256 +
  45.257 +    @Compare public long moduloWithOverflow() {
  45.258 +        return mod(0x8000fffe0000l, 0x8000ffffl);
  45.259 +    }
  45.260 +
  45.261 +    @Compare public long moduloWithCorrection() {
  45.262 +        return mod(0x7fff800000000000l, 0x800000000001l);
  45.263 +    }
  45.264 +
  45.265 +    @Compare public long conversionFromFloatPositive() {
  45.266 +        return (long) fadd(2, 0.6f);
  45.267 +    }
  45.268 +
  45.269 +    @Compare public long conversionFromFloatNegative() {
  45.270 +        return (long) fadd(-2, -0.6f);
  45.271 +    }
  45.272 +
  45.273 +    @Compare public long conversionFromDoublePositive() {
  45.274 +        return (long) dadd(0x20ffff0000L, 0.6);
  45.275 +    }
  45.276 +
  45.277 +    @Compare public long conversionFromDoubleNegative() {
  45.278 +        return (long) dadd(-0x20ffff0000L, -0.6);
  45.279 +    }
  45.280 +
  45.281 +    @Compare public boolean divByZeroThrowsArithmeticException() {
  45.282 +        try {
  45.283 +            div(1, 0);
  45.284 +            return false;
  45.285 +        } catch (final ArithmeticException e) {
  45.286 +            return true;
  45.287 +        }
  45.288 +    }
  45.289 +
  45.290 +    @Compare public boolean modByZeroThrowsArithmeticException() {
  45.291 +        try {
  45.292 +            mod(1, 0);
  45.293 +            return false;
  45.294 +        } catch (final ArithmeticException e) {
  45.295 +            return true;
  45.296 +        }
  45.297 +    }
  45.298 +
  45.299 +    @Compare public long shiftL1() {
  45.300 +        return shl(0x00fa37d7763e0ca1l, 5);
  45.301 +    }
  45.302 +
  45.303 +    @Compare public long shiftL2() {
  45.304 +        return shl(0x00fa37d7763e0ca1l, 32);
  45.305 +    }
  45.306 +
  45.307 +    @Compare public long shiftL3() {
  45.308 +        return shl(0x00fa37d7763e0ca1l, 45);
  45.309 +    }
  45.310 +
  45.311 +    @Compare public long shiftR1() {
  45.312 +        return shr(0x00fa37d7763e0ca1l, 5);
  45.313 +    }
  45.314 +
  45.315 +    @Compare public long shiftR2() {
  45.316 +        return shr(0x00fa37d7763e0ca1l, 32);
  45.317 +    }
  45.318 +
  45.319 +    @Compare public long shiftR3() {
  45.320 +        return shr(0x00fa37d7763e0ca1l, 45);
  45.321 +    }
  45.322 +
  45.323 +    @Compare public long uShiftR1() {
  45.324 +        return ushr(0x00fa37d7763e0ca1l, 5);
  45.325 +    }
  45.326 +
  45.327 +    @Compare public long uShiftR2() {
  45.328 +        return ushr(0x00fa37d7763e0ca1l, 45);
  45.329 +    }
  45.330 +
  45.331 +    @Compare public long uShiftR3() {
  45.332 +        return ushr(0xf0fa37d7763e0ca1l, 5);
  45.333 +    }
  45.334 +
  45.335 +    @Compare public long uShiftR4() {
  45.336 +        return ushr(0xf0fa37d7763e0ca1l, 45);
  45.337 +    }
  45.338 +
  45.339 +    @Compare public long and1() {
  45.340 +        return and(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  45.341 +    }
  45.342 +
  45.343 +    @Compare public long or1() {
  45.344 +        return or(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  45.345 +    }
  45.346 +
  45.347 +    @Compare public long xor1() {
  45.348 +        return xor(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  45.349 +    }
  45.350 +
  45.351 +    @Compare public long xor2() {
  45.352 +        return xor(0x00fa37d7763e0ca1l, 0x00000000ff00123el);
  45.353 +    }
  45.354 +
  45.355 +    @Compare public long xor3() {
  45.356 +        return xor(0x00000000763e0ca1l, 0x00000000ff00123el);
  45.357 +    }
  45.358 +
  45.359 +    @Compare public int compareSameNumbers() {
  45.360 +        return compare(0x0000000000000000l, 0x0000000000000000l, 0);
  45.361 +    }
  45.362 +
  45.363 +    @Compare public int comparePositiveNumbers() {
  45.364 +        return compare(0x0000000000200000l, 0x0000000010000000l, 0);
  45.365 +    }
  45.366 +
  45.367 +    @Compare public int compareNegativeNumbers() {
  45.368 +        return compare(0xffffffffffffffffl, 0xffffffff00000000l, 0);
  45.369 +    }
  45.370 +
  45.371 +    @Compare public int compareMixedNumbers() {
  45.372 +        return compare(0x8000000000000000l, 0x7fffffffffffffffl, 0);
  45.373 +    }
  45.374 +    
  45.375 +    @Factory
  45.376 +    public static Object[] create() {
  45.377 +        return VMTest.create(LongArithmeticTest.class);
  45.378 +    }
  45.379 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionArrayTest.java	Mon Apr 29 16:32:14 2013 +0200
    46.3 @@ -0,0 +1,161 @@
    46.4 +/**
    46.5 + * Back 2 Browser Bytecode Translator
    46.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    46.7 + *
    46.8 + * This program is free software: you can redistribute it and/or modify
    46.9 + * it under the terms of the GNU General Public License as published by
   46.10 + * the Free Software Foundation, version 2 of the License.
   46.11 + *
   46.12 + * This program is distributed in the hope that it will be useful,
   46.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   46.15 + * GNU General Public License for more details.
   46.16 + *
   46.17 + * You should have received a copy of the GNU General Public License
   46.18 + * along with this program. Look for COPYING file in the top folder.
   46.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   46.20 + */
   46.21 +package org.apidesign.bck2brwsr.tck;
   46.22 +
   46.23 +import java.lang.reflect.Array;
   46.24 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   46.25 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   46.26 +import org.apidesign.bck2brwsr.vmtest.Compare;
   46.27 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   46.28 +import org.testng.annotations.Factory;
   46.29 +
   46.30 +/**
   46.31 + *
   46.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   46.33 + */
   46.34 +public class ReflectionArrayTest {
   46.35 +    @Compare public int lengthOfStringArray() {
   46.36 +        String[] arr = (String[]) Array.newInstance(String.class, 10);
   46.37 +        return arr.length;
   46.38 +    }
   46.39 +    
   46.40 +    @Compare public int reflectiveLengthOfStringArray() {
   46.41 +        Object arr = Array.newInstance(String.class, 10);
   46.42 +        return Array.getLength(arr);
   46.43 +    }
   46.44 +
   46.45 +    @Compare public int reflectiveLengthOneNonArray() {
   46.46 +        Object arr = "non-array";
   46.47 +        return Array.getLength(arr);
   46.48 +    }
   46.49 +
   46.50 +    @Compare public String compTypeOfStringArray() {
   46.51 +        String[] arr = (String[]) Array.newInstance(String.class, 10);
   46.52 +        return arr.getClass().getComponentType().getName();
   46.53 +    }
   46.54 +
   46.55 +    @Compare public Object negativeArrayExcp() {
   46.56 +        return Array.newInstance(String.class, -5);
   46.57 +    }
   46.58 +    
   46.59 +    @Compare public int lengthOfIntArray() {
   46.60 +        int[] arr = (int[]) Array.newInstance(Integer.TYPE, 10);
   46.61 +        return arr.length;
   46.62 +    }
   46.63 +
   46.64 +    @Compare public int reflectiveLengthOfIntArray() {
   46.65 +        Object arr = Array.newInstance(Integer.TYPE, 10);
   46.66 +        return Array.getLength(arr);
   46.67 +    }
   46.68 +
   46.69 +    @Compare public String compTypeOfIntArray() {
   46.70 +        int[] arr = (int[]) Array.newInstance(int.class, 10);
   46.71 +        return arr.getClass().getComponentType().getName();
   46.72 +    }
   46.73 +
   46.74 +    @Compare public Object intNegativeArrayExcp() {
   46.75 +        return Array.newInstance(int.class, -5);
   46.76 +    }
   46.77 +
   46.78 +    @Compare public Integer verifyAutobox() {
   46.79 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
   46.80 +        return (Integer) Array.get(arr, 0);
   46.81 +    }
   46.82 +    @Compare public String verifyObjectArray() {
   46.83 +        String[] arr = (String[]) Array.newInstance(String.class, 5);
   46.84 +        Array.set(arr, 0, "Hello");
   46.85 +        return (String) Array.get(arr, 0);
   46.86 +    }
   46.87 +    @Compare public int verifyInt() {
   46.88 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
   46.89 +        return Array.getInt(arr, 0);
   46.90 +    }
   46.91 +    @Compare public long verifyConvertToLong() {
   46.92 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
   46.93 +        return Array.getLong(arr, 0);
   46.94 +    }
   46.95 +
   46.96 +    @Compare public Object verifySetIntToObject() {
   46.97 +        try {
   46.98 +            Object[] arr = (Object[]) Array.newInstance(Object.class, 5);
   46.99 +            Array.setInt(arr, 0, 10);
  46.100 +            return Array.get(arr, 0);
  46.101 +        } catch (Exception exception) {
  46.102 +            return exception.getClass().getName();
  46.103 +        }
  46.104 +    }
  46.105 +    @Compare public long verifySetShort() {
  46.106 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
  46.107 +        Array.setShort(arr, 0, (short)10);
  46.108 +        return Array.getLong(arr, 0);
  46.109 +    }
  46.110 +    @Compare public long verifyCantSetLong() {
  46.111 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
  46.112 +        Array.setLong(arr, 0, 10);
  46.113 +        return Array.getLong(arr, 0);
  46.114 +    }
  46.115 +    @Compare public float verifyLongToFloat() {
  46.116 +        Object arr = Array.newInstance(float.class, 5);
  46.117 +        Array.setLong(arr, 0, 10);
  46.118 +        return Array.getFloat(arr, 0);
  46.119 +    }
  46.120 +
  46.121 +    @Compare public double verifyConvertToDouble() {
  46.122 +        int[] arr = (int[]) Array.newInstance(int.class, 5);
  46.123 +        return Array.getDouble(arr, 0);
  46.124 +    }
  46.125 +    
  46.126 +    @Compare public int multiIntArray() {
  46.127 +        int[][][] arr = (int[][][]) Array.newInstance(int.class, 3, 3, 3);
  46.128 +        return arr[0][1][2] + 5 + arr[2][2][0];
  46.129 +    }
  46.130 +
  46.131 +    @Compare public String multiIntArrayCompType() {
  46.132 +        return Array.newInstance(int.class, 3, 3, 3).getClass().getName();
  46.133 +    }
  46.134 +    
  46.135 +    @JavaScriptBody(args = {}, body = "return [1, 2];")
  46.136 +    private static native Object crtarr();
  46.137 +
  46.138 +    @JavaScriptBody(args = {}, body = "return new Object();")
  46.139 +    private static native Object newobj();
  46.140 +
  46.141 +    @BrwsrTest
  46.142 +    public static void toStringArray() {
  46.143 +        final Object arr = crtarr();
  46.144 +        final Object real = new Object[2];
  46.145 +        assert arr instanceof Object[] : "Any array is Java array: " + arr;
  46.146 +        assert arr.getClass() == real.getClass() : "Same classes " + arr + " and " + real.getClass();
  46.147 +        final String str = arr.toString();
  46.148 +        assert str != null;
  46.149 +        assert str.startsWith("[Ljava.lang.Object;@") : str;
  46.150 +    }
  46.151 +    
  46.152 +    @BrwsrTest
  46.153 +    public static void objectToString() {
  46.154 +        String s = newobj().toString();
  46.155 +        assert s != null : "Some string computed";
  46.156 +        assert s.startsWith("java.lang.Object@") : "Regular object toString(): " + s;
  46.157 +    }
  46.158 +
  46.159 +    
  46.160 +    @Factory
  46.161 +    public static Object[] create() {
  46.162 +        return VMTest.create(ReflectionArrayTest.class);
  46.163 +    }
  46.164 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Mon Apr 29 16:32:14 2013 +0200
    47.3 @@ -0,0 +1,272 @@
    47.4 +/**
    47.5 + * Back 2 Browser Bytecode Translator
    47.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    47.7 + *
    47.8 + * This program is free software: you can redistribute it and/or modify
    47.9 + * it under the terms of the GNU General Public License as published by
   47.10 + * the Free Software Foundation, version 2 of the License.
   47.11 + *
   47.12 + * This program is distributed in the hope that it will be useful,
   47.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.15 + * GNU General Public License for more details.
   47.16 + *
   47.17 + * You should have received a copy of the GNU General Public License
   47.18 + * along with this program. Look for COPYING file in the top folder.
   47.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   47.20 + */
   47.21 +package org.apidesign.bck2brwsr.tck;
   47.22 +
   47.23 +import java.lang.annotation.Retention;
   47.24 +import java.lang.annotation.RetentionPolicy;
   47.25 +import java.lang.reflect.Method;
   47.26 +import java.util.Arrays;
   47.27 +import java.util.Collections;
   47.28 +import java.util.List;
   47.29 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   47.30 +import org.apidesign.bck2brwsr.vmtest.Compare;
   47.31 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   47.32 +import org.testng.annotations.Factory;
   47.33 +
   47.34 +/**
   47.35 + *
   47.36 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   47.37 + */
   47.38 +public class ReflectionTest {
   47.39 +    @Compare public boolean nonNullThis() {
   47.40 +        return this == null;
   47.41 +    }
   47.42 +    
   47.43 +    @Compare public String intType() {
   47.44 +        return Integer.TYPE.toString();
   47.45 +    }
   47.46 +
   47.47 +    @Compare public String voidType() throws Exception {
   47.48 +        return void.class.toString();
   47.49 +    }
   47.50 +
   47.51 +    @Compare public String longClass() {
   47.52 +        return long.class.toString();
   47.53 +    }
   47.54 +    
   47.55 +    @Compare public boolean isRunnableInterface() {
   47.56 +        return Runnable.class.isInterface();
   47.57 +    }
   47.58 +
   47.59 +    @Compare public boolean isAssignableToPrimitiveType() {
   47.60 +        return boolean.class.isAssignableFrom(Runnable.class);
   47.61 +    }
   47.62 +
   47.63 +    @Compare public boolean isAssignableFromPrimitiveType() {
   47.64 +        return Runnable.class.isAssignableFrom(boolean.class);
   47.65 +    }
   47.66 +
   47.67 +    @Compare public boolean isAssignableLongFromInt() {
   47.68 +        return long.class.isAssignableFrom(int.class);
   47.69 +    }
   47.70 +
   47.71 +    @Compare public boolean isAssignableIntFromLong() {
   47.72 +        return int.class.isAssignableFrom(long.class);
   47.73 +    }
   47.74 +
   47.75 +    @Compare public String isRunnableHasRunMethod() throws NoSuchMethodException {
   47.76 +        return Runnable.class.getMethod("run").getName();
   47.77 +    }
   47.78 +    
   47.79 +    @Compare public String namesOfMethods() {
   47.80 +        StringBuilder sb = new StringBuilder();
   47.81 +        String[] arr = new String[20];
   47.82 +        int i = 0;
   47.83 +        for (Method m : StaticUse.class.getMethods()) {
   47.84 +            arr[i++] = m.getName();
   47.85 +        }
   47.86 +        for (String s : sort(arr, i)) {
   47.87 +            sb.append(s).append("\n");
   47.88 +        }
   47.89 +        return sb.toString();
   47.90 +    }
   47.91 +
   47.92 +    @Compare public String namesOfDeclaringClassesOfMethods() {
   47.93 +        StringBuilder sb = new StringBuilder();
   47.94 +        String[] arr = new String[20];
   47.95 +        int i = 0;
   47.96 +        for (Method m : StaticUse.class.getMethods()) {
   47.97 +            arr[i++] = m.getName() + "@" + m.getDeclaringClass().getName();
   47.98 +        }
   47.99 +        for (String s : sort(arr, i)) {
  47.100 +            sb.append(s).append("\n");
  47.101 +        }
  47.102 +        return sb.toString();
  47.103 +    }
  47.104 +    
  47.105 +    @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
  47.106 +        StaticUse.class.getMethod("instanceMethod").invoke(null);
  47.107 +        return "should not happen";
  47.108 +    }
  47.109 +    
  47.110 +    @Compare public String classCastException() {
  47.111 +        try {
  47.112 +            Integer i = (Integer)StaticUseSub.getNonNull();
  47.113 +            return "" + i.intValue();
  47.114 +        } catch (ClassCastException ex) {
  47.115 +            return ex.getClass().getName();
  47.116 +        }
  47.117 +    }
  47.118 +
  47.119 +    @Compare public String methodThatThrowsException() throws Exception {
  47.120 +        StaticUse.class.getMethod("instanceMethod").invoke(new StaticUse());
  47.121 +        return "should not happen";
  47.122 +    }
  47.123 +
  47.124 +    @Compare public Object voidReturnType() throws Exception {
  47.125 +        return StaticUse.class.getMethod("instanceMethod").getReturnType();
  47.126 +    }
  47.127 +    
  47.128 +    @Retention(RetentionPolicy.RUNTIME)
  47.129 +    @interface Ann {
  47.130 +    }
  47.131 +    
  47.132 +    @Compare public String annoClass() throws Exception {
  47.133 +        Retention r = Ann.class.getAnnotation(Retention.class);
  47.134 +        assert r != null : "Annotation is present";
  47.135 +        assert r.value() == RetentionPolicy.RUNTIME : "Policy value is OK: " + r.value();
  47.136 +        return r.annotationType().getName();
  47.137 +    }
  47.138 +    
  47.139 +    @Compare public boolean isAnnotation() {
  47.140 +        return Ann.class.isAnnotation();
  47.141 +    }
  47.142 +    @Compare public boolean isNotAnnotation() {
  47.143 +        return String.class.isAnnotation();
  47.144 +    }
  47.145 +    @Compare public boolean isNotAnnotationEnum() {
  47.146 +        return E.class.isAnnotation();
  47.147 +    }
  47.148 +    enum E { A, B };
  47.149 +    @Compare public boolean isEnum() {
  47.150 +        return E.A.getClass().isEnum();
  47.151 +    }
  47.152 +
  47.153 +    @Compare public boolean isNotEnum() {
  47.154 +        return "".getClass().isEnum();
  47.155 +    }
  47.156 +    
  47.157 +    @Compare public String newInstanceFails() throws InstantiationException {
  47.158 +        try {
  47.159 +            return "success: " + StaticUseSub.class.newInstance();
  47.160 +        } catch (IllegalAccessException ex) {
  47.161 +            return ex.getClass().getName();
  47.162 +        }
  47.163 +    }
  47.164 +    
  47.165 +    @Compare public String paramTypes() throws Exception {
  47.166 +        Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
  47.167 +        final Class[] pt = plus.getParameterTypes();
  47.168 +        return pt[0].getName();
  47.169 +    }
  47.170 +    @Compare public String paramTypesNotFound() throws Exception {
  47.171 +        return StaticUse.class.getMethod("plus", int.class, double.class).toString();
  47.172 +    }
  47.173 +    @Compare public int methodWithArgs() throws Exception {
  47.174 +        Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
  47.175 +        return (Integer)plus.invoke(null, 2, 3);
  47.176 +    }
  47.177 +    
  47.178 +    @Compare public String classGetNameForByte() {
  47.179 +         return byte.class.getName();
  47.180 +    }
  47.181 +    @Compare public String classGetNameForBaseObject() {
  47.182 +        return newObject().getClass().getName();
  47.183 +    }
  47.184 +    @Compare public String classGetNameForJavaObject() {
  47.185 +        return new Object().getClass().getName();
  47.186 +    }
  47.187 +    @Compare public String classGetNameForObjectArray() {
  47.188 +        return (new Object[3]).getClass().getName();
  47.189 +    }
  47.190 +    @Compare public String classGetNameForSimpleIntArray() {
  47.191 +        return (new int[3]).getClass().getName();
  47.192 +    }
  47.193 +    @Compare public boolean sameClassGetNameForSimpleCharArray() {
  47.194 +        return (new char[3]).getClass() == (new char[34]).getClass();
  47.195 +    }
  47.196 +    @Compare public String classGetNameForMultiIntArray() {
  47.197 +        return (new int[3][4][5][6][7][8][9]).getClass().getName();
  47.198 +    }
  47.199 +    @Compare public String classGetNameForMultiIntArrayInner() {
  47.200 +        final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
  47.201 +        int[][][][][][] subarr = arr[0];
  47.202 +        int[][][][][] subsubarr = subarr[0];
  47.203 +        return subsubarr.getClass().getName();
  47.204 +    }
  47.205 +    @Compare public String classGetNameForMultiStringArray() {
  47.206 +        return (new String[3][4][5][6][7][8][9]).getClass().getName();
  47.207 +    }
  47.208 +    
  47.209 +    @Compare public String classForByte() throws Exception {
  47.210 +        return Class.forName("[Z").getName();
  47.211 +    }
  47.212 +
  47.213 +    @Compare public String classForUnknownArray() {
  47.214 +        try {
  47.215 +            return Class.forName("[W").getName();
  47.216 +        } catch (Exception ex) {
  47.217 +            return ex.getClass().getName();
  47.218 +        }
  47.219 +    }
  47.220 +    
  47.221 +    @Compare public String classForUnknownDeepArray() {
  47.222 +        try {
  47.223 +            return Class.forName("[[[[[W").getName();
  47.224 +        } catch (Exception ex) {
  47.225 +            return ex.getClass().getName();
  47.226 +        }
  47.227 +    }
  47.228 +    
  47.229 +    @Compare public String componentGetNameForObjectArray() {
  47.230 +        return (new Object[3]).getClass().getComponentType().getName();
  47.231 +    }
  47.232 +    @Compare public boolean sameComponentGetNameForObjectArray() {
  47.233 +        return (new Object[3]).getClass().getComponentType() == Object.class;
  47.234 +    }
  47.235 +    @Compare public String componentGetNameForSimpleIntArray() {
  47.236 +        return (new int[3]).getClass().getComponentType().getName();
  47.237 +    }
  47.238 +    @Compare public String componentGetNameForMultiIntArray() {
  47.239 +        return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
  47.240 +    }
  47.241 +    @Compare public String componentGetNameForMultiStringArray() {
  47.242 +        Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
  47.243 +        StringBuilder sb = new StringBuilder();
  47.244 +        for (;;) {
  47.245 +            sb.append(c.getName()).append("\n");
  47.246 +            c = c.getComponentType();
  47.247 +            if (c == null) {
  47.248 +                break;
  47.249 +            }
  47.250 +        }
  47.251 +        return sb.toString();
  47.252 +    }
  47.253 +    
  47.254 +    @Compare public boolean isArray() {
  47.255 +        return new Object[0].getClass().isArray();
  47.256 +    }
  47.257 +    
  47.258 +    @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
  47.259 +    private static String[] sort(String[] arr, int len) {
  47.260 +        List<String> list = Arrays.asList(arr).subList(0, len);
  47.261 +        Collections.sort(list);
  47.262 +        return list.toArray(new String[0]);
  47.263 +    }
  47.264 +    
  47.265 +    @JavaScriptBody(args = {}, body = "return new Object();")
  47.266 +    private static Object newObject() {
  47.267 +        return new Object();
  47.268 +    }
  47.269 +    
  47.270 +    @Factory
  47.271 +    public static Object[] create() {
  47.272 +        return VMTest.create(ReflectionTest.class);
  47.273 +    }
  47.274 +    
  47.275 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java	Mon Apr 29 16:32:14 2013 +0200
    48.3 @@ -0,0 +1,45 @@
    48.4 +/**
    48.5 + * Back 2 Browser Bytecode Translator
    48.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    48.7 + *
    48.8 + * This program is free software: you can redistribute it and/or modify
    48.9 + * it under the terms of the GNU General Public License as published by
   48.10 + * the Free Software Foundation, version 2 of the License.
   48.11 + *
   48.12 + * This program is distributed in the hope that it will be useful,
   48.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   48.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   48.15 + * GNU General Public License for more details.
   48.16 + *
   48.17 + * You should have received a copy of the GNU General Public License
   48.18 + * along with this program. Look for COPYING file in the top folder.
   48.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   48.20 + */
   48.21 +package org.apidesign.bck2brwsr.tck;
   48.22 +
   48.23 +import java.io.InputStream;
   48.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
   48.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   48.26 +import org.testng.annotations.Factory;
   48.27 +
   48.28 +/**
   48.29 + *
   48.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   48.31 + */
   48.32 +public class ResourcesTest {
   48.33 +    
   48.34 +    @Compare public String readResourceAsStream() throws Exception {
   48.35 +        InputStream is = getClass().getResourceAsStream("Resources.txt");
   48.36 +        byte[] b = new byte[30];
   48.37 +        int len = is.read(b);
   48.38 +        StringBuilder sb = new StringBuilder();
   48.39 +        for (int i = 0; i < len; i++) {
   48.40 +            sb.append((char)b[i]);
   48.41 +        }
   48.42 +        return sb.toString();
   48.43 +    }
   48.44 +    
   48.45 +    @Factory public static Object[] create() {
   48.46 +        return VMTest.create(ResourcesTest.class);
   48.47 +    }
   48.48 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ShortArithmeticTest.java	Mon Apr 29 16:32:14 2013 +0200
    49.3 @@ -0,0 +1,102 @@
    49.4 +/**
    49.5 + * Back 2 Browser Bytecode Translator
    49.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    49.7 + *
    49.8 + * This program is free software: you can redistribute it and/or modify
    49.9 + * it under the terms of the GNU General Public License as published by
   49.10 + * the Free Software Foundation, version 2 of the License.
   49.11 + *
   49.12 + * This program is distributed in the hope that it will be useful,
   49.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   49.15 + * GNU General Public License for more details.
   49.16 + *
   49.17 + * You should have received a copy of the GNU General Public License
   49.18 + * along with this program. Look for COPYING file in the top folder.
   49.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   49.20 + */
   49.21 +package org.apidesign.bck2brwsr.tck;
   49.22 +
   49.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   49.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   49.25 +import org.testng.annotations.Factory;
   49.26 +
   49.27 +/**
   49.28 + *
   49.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   49.30 + */
   49.31 +public class ShortArithmeticTest {
   49.32 +    
   49.33 +    private static short add(short x, short y) {
   49.34 +        return (short)(x + y);
   49.35 +    }
   49.36 +    
   49.37 +    private static short sub(short x, short y) {
   49.38 +        return (short)(x - y);
   49.39 +    }
   49.40 +    
   49.41 +    private static short mul(short x, short y) {
   49.42 +        return (short)(x * y);
   49.43 +    }
   49.44 +    
   49.45 +    private static short div(short x, short y) {
   49.46 +        return (short)(x / y);
   49.47 +    }
   49.48 +    
   49.49 +    private static short mod(short x, short y) {
   49.50 +        return (short)(x % y);
   49.51 +    }
   49.52 +    
   49.53 +    @Compare public short conversion() {
   49.54 +        return (short)123456;
   49.55 +    }
   49.56 +    
   49.57 +    @Compare public short addOverflow() {
   49.58 +        return add(Short.MAX_VALUE, (short)1);
   49.59 +    }
   49.60 +    
   49.61 +    @Compare public short subUnderflow() {
   49.62 +        return sub(Short.MIN_VALUE, (short)1);
   49.63 +    }
   49.64 +    
   49.65 +    @Compare public short addMaxShortAndMaxShort() {
   49.66 +        return add(Short.MAX_VALUE, Short.MAX_VALUE);
   49.67 +    }
   49.68 +    
   49.69 +    @Compare public short subMinShortAndMinShort() {
   49.70 +        return sub(Short.MIN_VALUE, Short.MIN_VALUE);
   49.71 +    }
   49.72 +    
   49.73 +    @Compare public short multiplyMaxShort() {
   49.74 +        return mul(Short.MAX_VALUE, (short)2);
   49.75 +    }
   49.76 +    
   49.77 +    @Compare public short multiplyMaxShortAndMaxShort() {
   49.78 +        return mul(Short.MAX_VALUE, Short.MAX_VALUE);
   49.79 +    }
   49.80 +    
   49.81 +    @Compare public short multiplyMinShort() {
   49.82 +        return mul(Short.MIN_VALUE, (short)2);
   49.83 +    }
   49.84 +    
   49.85 +    @Compare public short multiplyMinShortAndMinShort() {
   49.86 +        return mul(Short.MIN_VALUE, Short.MIN_VALUE);
   49.87 +    }
   49.88 +    
   49.89 +    @Compare public short multiplyPrecision() {
   49.90 +        return mul((short)17638, (short)1103);
   49.91 +    }
   49.92 +    
   49.93 +    @Compare public short division() {
   49.94 +        return div((short)1, (short)2);
   49.95 +    }
   49.96 +    
   49.97 +    @Compare public short divisionReminder() {
   49.98 +        return mod((short)1, (short)2);
   49.99 +    }
  49.100 +    
  49.101 +    @Factory
  49.102 +    public static Object[] create() {
  49.103 +        return VMTest.create(ShortArithmeticTest.class);
  49.104 +    }
  49.105 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java	Mon Apr 29 16:32:14 2013 +0200
    50.3 @@ -0,0 +1,39 @@
    50.4 +/**
    50.5 + * Back 2 Browser Bytecode Translator
    50.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    50.7 + *
    50.8 + * This program is free software: you can redistribute it and/or modify
    50.9 + * it under the terms of the GNU General Public License as published by
   50.10 + * the Free Software Foundation, version 2 of the License.
   50.11 + *
   50.12 + * This program is distributed in the hope that it will be useful,
   50.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   50.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   50.15 + * GNU General Public License for more details.
   50.16 + *
   50.17 + * You should have received a copy of the GNU General Public License
   50.18 + * along with this program. Look for COPYING file in the top folder.
   50.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   50.20 + */
   50.21 +package org.apidesign.bck2brwsr.tck;
   50.22 +
   50.23 +class StaticUse {
   50.24 +    public static final Object NON_NULL = new Object();
   50.25 +    public static int cnt;
   50.26 +    static {
   50.27 +        if (cnt++ != 0) {
   50.28 +            throw new IllegalStateException("Multiple initialization of a <cinit>");
   50.29 +        }
   50.30 +    }
   50.31 +    
   50.32 +    StaticUse() {
   50.33 +    }
   50.34 +    
   50.35 +    public void instanceMethod() {
   50.36 +        throw new IllegalStateException();
   50.37 +    }
   50.38 +
   50.39 +    public static int plus(int a, int b) {
   50.40 +        return a + b;
   50.41 +    }
   50.42 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/StaticUseSub.java	Mon Apr 29 16:32:14 2013 +0200
    51.3 @@ -0,0 +1,30 @@
    51.4 +/**
    51.5 + * Back 2 Browser Bytecode Translator
    51.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    51.7 + *
    51.8 + * This program is free software: you can redistribute it and/or modify
    51.9 + * it under the terms of the GNU General Public License as published by
   51.10 + * the Free Software Foundation, version 2 of the License.
   51.11 + *
   51.12 + * This program is distributed in the hope that it will be useful,
   51.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   51.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   51.15 + * GNU General Public License for more details.
   51.16 + *
   51.17 + * You should have received a copy of the GNU General Public License
   51.18 + * along with this program. Look for COPYING file in the top folder.
   51.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   51.20 + */
   51.21 +package org.apidesign.bck2brwsr.tck;
   51.22 +
   51.23 +public class StaticUseSub extends StaticUse {
   51.24 +    private StaticUseSub() {
   51.25 +    }
   51.26 +    
   51.27 +    public static Object getNonNull() {
   51.28 +        return NON_NULL;
   51.29 +    }
   51.30 +    static Object getNull() {
   51.31 +        return null;
   51.32 +    }
   51.33 +}
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/StaticUseSubTest.java	Mon Apr 29 16:32:14 2013 +0200
    52.3 @@ -0,0 +1,45 @@
    52.4 +/**
    52.5 + * Back 2 Browser Bytecode Translator
    52.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    52.7 + *
    52.8 + * This program is free software: you can redistribute it and/or modify
    52.9 + * it under the terms of the GNU General Public License as published by
   52.10 + * the Free Software Foundation, version 2 of the License.
   52.11 + *
   52.12 + * This program is distributed in the hope that it will be useful,
   52.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   52.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   52.15 + * GNU General Public License for more details.
   52.16 + *
   52.17 + * You should have received a copy of the GNU General Public License
   52.18 + * along with this program. Look for COPYING file in the top folder.
   52.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   52.20 + */
   52.21 +package org.apidesign.bck2brwsr.tck;
   52.22 +
   52.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   52.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   52.25 +import org.testng.annotations.Factory;
   52.26 +
   52.27 +/**
   52.28 + *
   52.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   52.30 + */
   52.31 +public class StaticUseSubTest {
   52.32 +    @Compare public String staticFieldInitializationInSuperClass() throws Exception {
   52.33 +        Object ret = StaticUseSub.getNonNull();
   52.34 +        return ret.getClass().getName();
   52.35 +    }
   52.36 +    
   52.37 +    @Compare public String isNullPointerTheSame() throws Exception {
   52.38 +        try {
   52.39 +            return StaticUseSub.getNull().getClass().toString();
   52.40 +        } catch (NullPointerException ex) {
   52.41 +            return ex.getClass().getName();
   52.42 +        }
   52.43 +    }
   52.44 +
   52.45 +    @Factory public static Object[] create() {
   52.46 +        return VMTest.create(StaticUseSubTest.class);
   52.47 +    }
   52.48 +}
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java	Mon Apr 29 16:32:14 2013 +0200
    53.3 @@ -0,0 +1,41 @@
    53.4 +/**
    53.5 + * Back 2 Browser Bytecode Translator
    53.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    53.7 + *
    53.8 + * This program is free software: you can redistribute it and/or modify
    53.9 + * it under the terms of the GNU General Public License as published by
   53.10 + * the Free Software Foundation, version 2 of the License.
   53.11 + *
   53.12 + * This program is distributed in the hope that it will be useful,
   53.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   53.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   53.15 + * GNU General Public License for more details.
   53.16 + *
   53.17 + * You should have received a copy of the GNU General Public License
   53.18 + * along with this program. Look for COPYING file in the top folder.
   53.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   53.20 + */
   53.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   53.22 +
   53.23 +import java.io.UnsupportedEncodingException;
   53.24 +import java.util.zip.CRC32;
   53.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
   53.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   53.27 +import org.testng.annotations.Factory;
   53.28 +
   53.29 +/**
   53.30 + *
   53.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   53.32 + */
   53.33 +public class CRC32Test {
   53.34 +
   53.35 +    @Compare public long crc1() throws UnsupportedEncodingException {
   53.36 +        CRC32 crc = new CRC32();
   53.37 +        crc.update("Hello World!".getBytes("UTF-8"));
   53.38 +        return crc.getValue();
   53.39 +    }
   53.40 +    
   53.41 +    @Factory public static Object[] create() {
   53.42 +        return VMTest.create(CRC32Test.class);
   53.43 +    }
   53.44 +}
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CallMeTwiceTest.java	Mon Apr 29 16:32:14 2013 +0200
    54.3 @@ -0,0 +1,43 @@
    54.4 +/**
    54.5 + * Back 2 Browser Bytecode Translator
    54.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    54.7 + *
    54.8 + * This program is free software: you can redistribute it and/or modify
    54.9 + * it under the terms of the GNU General Public License as published by
   54.10 + * the Free Software Foundation, version 2 of the License.
   54.11 + *
   54.12 + * This program is distributed in the hope that it will be useful,
   54.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   54.15 + * GNU General Public License for more details.
   54.16 + *
   54.17 + * You should have received a copy of the GNU General Public License
   54.18 + * along with this program. Look for COPYING file in the top folder.
   54.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   54.20 + */
   54.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   54.22 +
   54.23 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   54.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   54.25 +import org.testng.annotations.Factory;
   54.26 +
   54.27 +/**
   54.28 + *
   54.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   54.30 + */
   54.31 +public class CallMeTwiceTest {
   54.32 +    int cnt;
   54.33 +    
   54.34 +    @BrwsrTest public void callMeTwice() throws InterruptedException {
   54.35 +        if (cnt++ == 0) {
   54.36 +            throw new InterruptedException();
   54.37 +        }
   54.38 +        int prevCnt = cnt;
   54.39 +        cnt = 0;
   54.40 +        assert prevCnt == 2 : "We need to receive two calls " + prevCnt;
   54.41 +    }
   54.42 +    
   54.43 +    @Factory public static Object[] create() {
   54.44 +        return VMTest.create(CallMeTwiceTest.class);
   54.45 +    }
   54.46 +}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java	Mon Apr 29 16:32:14 2013 +0200
    55.3 @@ -0,0 +1,67 @@
    55.4 +/**
    55.5 + * Back 2 Browser Bytecode Translator
    55.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    55.7 + *
    55.8 + * This program is free software: you can redistribute it and/or modify
    55.9 + * it under the terms of the GNU General Public License as published by
   55.10 + * the Free Software Foundation, version 2 of the License.
   55.11 + *
   55.12 + * This program is distributed in the hope that it will be useful,
   55.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   55.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   55.15 + * GNU General Public License for more details.
   55.16 + *
   55.17 + * You should have received a copy of the GNU General Public License
   55.18 + * along with this program. Look for COPYING file in the top folder.
   55.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   55.20 + */
   55.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   55.22 +
   55.23 +import java.io.ByteArrayInputStream;
   55.24 +import java.io.IOException;
   55.25 +import java.io.InputStream;
   55.26 +import org.apidesign.bck2brwsr.emul.zip.FastJar;
   55.27 +import org.testng.annotations.Test;
   55.28 +import static org.testng.Assert.*;
   55.29 +
   55.30 +/**
   55.31 + *
   55.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   55.33 + */
   55.34 +@GenerateZip(name = "five.zip", contents = {
   55.35 +    "1.txt", "one",
   55.36 +    "2.txt", "duo",
   55.37 +    "3.txt", "three",
   55.38 +    "4.txt", "four",
   55.39 +    "5.txt", "five"
   55.40 +})
   55.41 +public class ZipEntryTest {
   55.42 +    @Test
   55.43 +    public void readEntriesEffectively() throws IOException {
   55.44 +        InputStream is = ZipEntryTest.class.getResourceAsStream("five.zip");
   55.45 +        byte[] arr = new byte[is.available()];
   55.46 +        int len = is.read(arr);
   55.47 +        assertEquals(len, arr.length, "Read fully");
   55.48 +        
   55.49 +        FastJar fj = new FastJar(arr);
   55.50 +        FastJar.Entry[] entrs = fj.list();
   55.51 +        
   55.52 +        assertEquals(5, entrs.length, "Five entries");
   55.53 +        
   55.54 +        for (int i = 1; i <= 5; i++) {
   55.55 +            FastJar.Entry en = entrs[i - 1];
   55.56 +            assertEquals(en.name, i + ".txt");
   55.57 +//            assertEquals(cis.cnt, 0, "Content of the file should be skipped, not read");
   55.58 +        }
   55.59 +        
   55.60 +        assertContent("three", fj.getInputStream(entrs[3 - 1]), "read OK");
   55.61 +        assertContent("five", fj.getInputStream(entrs[5 - 1]), "read OK");
   55.62 +    }
   55.63 +
   55.64 +    private static void assertContent(String exp, InputStream is, String msg) throws IOException {
   55.65 +        byte[] arr = new byte[512];
   55.66 +        int len = is.read(arr);
   55.67 +        String s = new String(arr, 0, len);
   55.68 +        assertEquals(exp, s, msg);
   55.69 +    }
   55.70 +}
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java	Mon Apr 29 16:32:14 2013 +0200
    56.3 @@ -0,0 +1,108 @@
    56.4 +/**
    56.5 + * Back 2 Browser Bytecode Translator
    56.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    56.7 + *
    56.8 + * This program is free software: you can redistribute it and/or modify
    56.9 + * it under the terms of the GNU General Public License as published by
   56.10 + * the Free Software Foundation, version 2 of the License.
   56.11 + *
   56.12 + * This program is distributed in the hope that it will be useful,
   56.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   56.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   56.15 + * GNU General Public License for more details.
   56.16 + *
   56.17 + * You should have received a copy of the GNU General Public License
   56.18 + * along with this program. Look for COPYING file in the top folder.
   56.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   56.20 + */
   56.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   56.22 +
   56.23 +import java.io.IOException;
   56.24 +import java.io.InputStream;
   56.25 +import java.util.Objects;
   56.26 +import java.util.zip.ZipEntry;
   56.27 +import java.util.zip.ZipInputStream;
   56.28 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   56.29 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   56.30 +import org.apidesign.bck2brwsr.vmtest.Compare;
   56.31 +import org.apidesign.bck2brwsr.vmtest.Http;
   56.32 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   56.33 +import org.testng.annotations.Factory;
   56.34 +
   56.35 +/**
   56.36 + *
   56.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   56.38 + */
   56.39 +@GenerateZip(name = "readAnEntry.zip", contents = { 
   56.40 +    "my/main/file.txt", "Hello World!"
   56.41 +})
   56.42 +public class ZipFileTest {
   56.43 +    
   56.44 +    @Compare public String readAnEntry() throws IOException {
   56.45 +        InputStream is = ZipFileTest.class.getResourceAsStream("readAnEntry.zip");
   56.46 +        ZipInputStream zip = new ZipInputStream(is);
   56.47 +        ZipEntry entry = zip.getNextEntry();
   56.48 +        assertEquals(entry.getName(), "my/main/file.txt", "Correct entry");
   56.49 +
   56.50 +        byte[] arr = new byte[4096];
   56.51 +        int len = zip.read(arr);
   56.52 +        
   56.53 +        assertEquals(zip.getNextEntry(), null, "No next entry");
   56.54 +        
   56.55 +        final String ret = new String(arr, 0, len, "UTF-8");
   56.56 +        return ret;
   56.57 +    }
   56.58 +    
   56.59 +    @JavaScriptBody(args = { "res", "path" }, body = 
   56.60 +          "var myvm = bck2brwsr.apply(null, path);\n"
   56.61 +        + "var cls = myvm.loadClass('java.lang.String');\n"
   56.62 +        + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n"
   56.63 +    )
   56.64 +    private static native Object loadVMResource(String res, String...path);
   56.65 +
   56.66 +    @Http({
   56.67 +        @Http.Resource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip")
   56.68 +    })
   56.69 +    @BrwsrTest  public void canVmLoadResourceFromZip() throws IOException {
   56.70 +        Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar");
   56.71 +        assert res instanceof InputStream : "Got array of bytes: " + res;
   56.72 +        InputStream is = (InputStream)res;
   56.73 +        
   56.74 +        byte[] arr = new byte[4096];
   56.75 +        int len = is.read(arr);
   56.76 +        
   56.77 +        final String ret = new String(arr, 0, len, "UTF-8");
   56.78 +
   56.79 +        assertEquals(ret, "Hello World!", "Can read the bytes");
   56.80 +    }
   56.81 +    
   56.82 +    @GenerateZip(name = "cpattr.zip", contents = { 
   56.83 +        "META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n"
   56.84 +        + "Created-By: hand\n"
   56.85 +        + "Class-Path: realJar.jar\n\n\n"
   56.86 +    })
   56.87 +    @Http({
   56.88 +        @Http.Resource(path = "/readComplexEntry.jar", mimeType = "x-application/zip", content = "", resource="cpattr.zip"),
   56.89 +        @Http.Resource(path = "/realJar.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip"),
   56.90 +    })
   56.91 +    @BrwsrTest  public void understandsClassPathAttr() throws IOException {
   56.92 +        Object res = loadVMResource("/my/main/file.txt", "/readComplexEntry.jar");
   56.93 +        assert res instanceof InputStream : "Got array of bytes: " + res;
   56.94 +        InputStream is = (InputStream)res;
   56.95 +        
   56.96 +        byte[] arr = new byte[4096];
   56.97 +        int len = is.read(arr);
   56.98 +        
   56.99 +        final String ret = new String(arr, 0, len, "UTF-8");
  56.100 +
  56.101 +        assertEquals(ret, "Hello World!", "Can read the bytes from secondary JAR");
  56.102 +    }
  56.103 +    
  56.104 +    private static void assertEquals(Object real, Object exp, String msg) {
  56.105 +        assert Objects.equals(exp, real) : msg + " exp: " + exp + " real: " + real;
  56.106 +    }
  56.107 +    
  56.108 +    @Factory public static Object[] create() {
  56.109 +        return VMTest.create(ZipFileTest.class);
  56.110 +    }
  56.111 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/rt/emul/compact/src/test/resources/org/apidesign/bck2brwsr/tck/0xfe	Mon Apr 29 16:32:14 2013 +0200
    57.3 @@ -0,0 +1,1 @@
    57.4    57.5 \ No newline at end of file
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/rt/emul/compact/src/test/resources/org/apidesign/bck2brwsr/tck/Resources.txt	Mon Apr 29 16:32:14 2013 +0200
    58.3 @@ -0,0 +1,1 @@
    58.4 +Ahoj
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/rt/emul/mini/src/main/java/java/lang/ArithmeticException.java	Mon Apr 29 16:32:14 2013 +0200
    59.3 @@ -0,0 +1,61 @@
    59.4 +/*
    59.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
    59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    59.7 + *
    59.8 + * This code is free software; you can redistribute it and/or modify it
    59.9 + * under the terms of the GNU General Public License version 2 only, as
   59.10 + * published by the Free Software Foundation.  Oracle designates this
   59.11 + * particular file as subject to the "Classpath" exception as provided
   59.12 + * by Oracle in the LICENSE file that accompanied this code.
   59.13 + *
   59.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   59.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   59.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   59.17 + * version 2 for more details (a copy is included in the LICENSE file that
   59.18 + * accompanied this code).
   59.19 + *
   59.20 + * You should have received a copy of the GNU General Public License version
   59.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   59.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   59.23 + *
   59.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   59.25 + * or visit www.oracle.com if you need additional information or have any
   59.26 + * questions.
   59.27 + */
   59.28 +
   59.29 +package java.lang;
   59.30 +
   59.31 +/**
   59.32 + * Thrown when an exceptional arithmetic condition has occurred. For
   59.33 + * example, an integer "divide by zero" throws an
   59.34 + * instance of this class.
   59.35 + *
   59.36 + * {@code ArithmeticException} objects may be constructed by the
   59.37 + * virtual machine as if {@linkplain Throwable#Throwable(String,
   59.38 + * Throwable, boolean, boolean) suppression were disabled and/or the
   59.39 + * stack trace was not writable}.
   59.40 + *
   59.41 + * @author  unascribed
   59.42 + * @since   JDK1.0
   59.43 + */
   59.44 +public class ArithmeticException extends RuntimeException {
   59.45 +    private static final long serialVersionUID = 2256477558314496007L;
   59.46 +
   59.47 +    /**
   59.48 +     * Constructs an {@code ArithmeticException} with no detail
   59.49 +     * message.
   59.50 +     */
   59.51 +    public ArithmeticException() {
   59.52 +        super();
   59.53 +    }
   59.54 +
   59.55 +    /**
   59.56 +     * Constructs an {@code ArithmeticException} with the specified
   59.57 +     * detail message.
   59.58 +     *
   59.59 +     * @param   s   the detail message.
   59.60 +     */
   59.61 +    public ArithmeticException(String s) {
   59.62 +        super(s);
   59.63 +    }
   59.64 +}
    60.1 --- a/rt/launcher/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    60.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.3 @@ -1,56 +0,0 @@
    60.4 -<?xml version="1.0"?>
    60.5 -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    60.6 -  <modelVersion>4.0.0</modelVersion>
    60.7 -  <parent>
    60.8 -    <groupId>org.apidesign.bck2brwsr</groupId>
    60.9 -    <artifactId>rt</artifactId>
   60.10 -    <version>0.7-SNAPSHOT</version>
   60.11 -  </parent>
   60.12 -  <groupId>org.apidesign.bck2brwsr</groupId>
   60.13 -  <artifactId>launcher</artifactId>
   60.14 -  <version>0.7-SNAPSHOT</version>
   60.15 -  <name>Bck2Brwsr Launcher</name>
   60.16 -  <url>http://maven.apache.org</url>
   60.17 -    <build>
   60.18 -        <plugins>
   60.19 -            <plugin>
   60.20 -                <groupId>org.apache.maven.plugins</groupId>
   60.21 -                <artifactId>maven-compiler-plugin</artifactId>
   60.22 -                <version>2.3.2</version>
   60.23 -                <configuration>
   60.24 -                    <source>1.7</source>
   60.25 -                    <target>1.7</target>
   60.26 -                </configuration>
   60.27 -            </plugin>
   60.28 -            <plugin>
   60.29 -                <groupId>org.apache.maven.plugins</groupId>
   60.30 -                <artifactId>maven-javadoc-plugin</artifactId>
   60.31 -                <configuration>
   60.32 -                    <excludePackageNames>org.apidesign.bck2brwsr.launcher.impl</excludePackageNames>
   60.33 -                    <skip>false</skip>
   60.34 -                </configuration>
   60.35 -            </plugin>
   60.36 -        </plugins>
   60.37 -    </build>
   60.38 -    <properties>
   60.39 -    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   60.40 -  </properties>
   60.41 -  <dependencies>
   60.42 -    <dependency>
   60.43 -      <groupId>junit</groupId>
   60.44 -      <artifactId>junit</artifactId>
   60.45 -      <version>3.8.1</version>
   60.46 -      <scope>test</scope>
   60.47 -    </dependency>
   60.48 -    <dependency>
   60.49 -      <groupId>org.glassfish.grizzly</groupId>
   60.50 -      <artifactId>grizzly-http-server</artifactId>
   60.51 -      <version>2.2.19</version>
   60.52 -    </dependency>
   60.53 -    <dependency>
   60.54 -      <groupId>${project.groupId}</groupId>
   60.55 -      <artifactId>vm4brwsr</artifactId>
   60.56 -      <version>${project.version}</version>
   60.57 -    </dependency>
   60.58 -  </dependencies>
   60.59 -</project>
    61.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Fri Apr 26 15:09:59 2013 +0200
    61.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.3 @@ -1,602 +0,0 @@
    61.4 -/**
    61.5 - * Back 2 Browser Bytecode Translator
    61.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    61.7 - *
    61.8 - * This program is free software: you can redistribute it and/or modify
    61.9 - * it under the terms of the GNU General Public License as published by
   61.10 - * the Free Software Foundation, version 2 of the License.
   61.11 - *
   61.12 - * This program is distributed in the hope that it will be useful,
   61.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   61.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   61.15 - * GNU General Public License for more details.
   61.16 - *
   61.17 - * You should have received a copy of the GNU General Public License
   61.18 - * along with this program. Look for COPYING file in the top folder.
   61.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   61.20 - */
   61.21 -package org.apidesign.bck2brwsr.launcher;
   61.22 -
   61.23 -import java.io.Closeable;
   61.24 -import java.io.File;
   61.25 -import java.io.IOException;
   61.26 -import java.io.InputStream;
   61.27 -import java.io.InterruptedIOException;
   61.28 -import java.io.OutputStream;
   61.29 -import java.io.UnsupportedEncodingException;
   61.30 -import java.io.Writer;
   61.31 -import java.net.URI;
   61.32 -import java.net.URISyntaxException;
   61.33 -import java.net.URL;
   61.34 -import java.util.ArrayList;
   61.35 -import java.util.Arrays;
   61.36 -import java.util.Enumeration;
   61.37 -import java.util.LinkedHashSet;
   61.38 -import java.util.List;
   61.39 -import java.util.Set;
   61.40 -import java.util.concurrent.BlockingQueue;
   61.41 -import java.util.concurrent.CountDownLatch;
   61.42 -import java.util.concurrent.LinkedBlockingQueue;
   61.43 -import java.util.concurrent.TimeUnit;
   61.44 -import java.util.logging.Level;
   61.45 -import java.util.logging.Logger;
   61.46 -import org.apidesign.bck2brwsr.launcher.InvocationContext.Resource;
   61.47 -import org.apidesign.vm4brwsr.Bck2Brwsr;
   61.48 -import org.glassfish.grizzly.PortRange;
   61.49 -import org.glassfish.grizzly.http.server.HttpHandler;
   61.50 -import org.glassfish.grizzly.http.server.HttpServer;
   61.51 -import org.glassfish.grizzly.http.server.NetworkListener;
   61.52 -import org.glassfish.grizzly.http.server.Request;
   61.53 -import org.glassfish.grizzly.http.server.Response;
   61.54 -import org.glassfish.grizzly.http.server.ServerConfiguration;
   61.55 -import org.glassfish.grizzly.http.util.HttpStatus;
   61.56 -
   61.57 -/**
   61.58 - * Lightweight server to launch Bck2Brwsr applications and tests.
   61.59 - * Supports execution in native browser as well as Java's internal 
   61.60 - * execution engine.
   61.61 - */
   61.62 -final class Bck2BrwsrLauncher extends Launcher implements Closeable {
   61.63 -    private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
   61.64 -    private static final InvocationContext END = new InvocationContext(null, null, null);
   61.65 -    private final Set<ClassLoader> loaders = new LinkedHashSet<>();
   61.66 -    private final BlockingQueue<InvocationContext> methods = new LinkedBlockingQueue<>();
   61.67 -    private long timeOut;
   61.68 -    private final Res resources = new Res();
   61.69 -    private final String cmd;
   61.70 -    private Object[] brwsr;
   61.71 -    private HttpServer server;
   61.72 -    private CountDownLatch wait;
   61.73 -    
   61.74 -    public Bck2BrwsrLauncher(String cmd) {
   61.75 -        this.cmd = cmd;
   61.76 -    }
   61.77 -    
   61.78 -    @Override
   61.79 -    InvocationContext runMethod(InvocationContext c) throws IOException {
   61.80 -        loaders.add(c.clazz.getClassLoader());
   61.81 -        methods.add(c);
   61.82 -        try {
   61.83 -            c.await(timeOut);
   61.84 -        } catch (InterruptedException ex) {
   61.85 -            throw new IOException(ex);
   61.86 -        }
   61.87 -        return c;
   61.88 -    }
   61.89 -    
   61.90 -    public void setTimeout(long ms) {
   61.91 -        timeOut = ms;
   61.92 -    }
   61.93 -    
   61.94 -    public void addClassLoader(ClassLoader url) {
   61.95 -        this.loaders.add(url);
   61.96 -    }
   61.97 -
   61.98 -    public void showURL(String startpage) throws IOException {
   61.99 -        if (!startpage.startsWith("/")) {
  61.100 -            startpage = "/" + startpage;
  61.101 -        }
  61.102 -        HttpServer s = initServer(".", true);
  61.103 -        int last = startpage.lastIndexOf('/');
  61.104 -        String prefix = startpage.substring(0, last);
  61.105 -        String simpleName = startpage.substring(last);
  61.106 -        s.getServerConfiguration().addHttpHandler(new SubTree(resources, prefix), "/");
  61.107 -        try {
  61.108 -            launchServerAndBrwsr(s, simpleName);
  61.109 -        } catch (URISyntaxException | InterruptedException ex) {
  61.110 -            throw new IOException(ex);
  61.111 -        }
  61.112 -    }
  61.113 -
  61.114 -    void showDirectory(File dir, String startpage) throws IOException {
  61.115 -        if (!startpage.startsWith("/")) {
  61.116 -            startpage = "/" + startpage;
  61.117 -        }
  61.118 -        HttpServer s = initServer(dir.getPath(), false);
  61.119 -        try {
  61.120 -            launchServerAndBrwsr(s, startpage);
  61.121 -        } catch (URISyntaxException | InterruptedException ex) {
  61.122 -            throw new IOException(ex);
  61.123 -        }
  61.124 -    }
  61.125 -
  61.126 -    @Override
  61.127 -    public void initialize() throws IOException {
  61.128 -        try {
  61.129 -            executeInBrowser();
  61.130 -        } catch (InterruptedException ex) {
  61.131 -            final InterruptedIOException iio = new InterruptedIOException(ex.getMessage());
  61.132 -            iio.initCause(ex);
  61.133 -            throw iio;
  61.134 -        } catch (Exception ex) {
  61.135 -            if (ex instanceof IOException) {
  61.136 -                throw (IOException)ex;
  61.137 -            }
  61.138 -            if (ex instanceof RuntimeException) {
  61.139 -                throw (RuntimeException)ex;
  61.140 -            }
  61.141 -            throw new IOException(ex);
  61.142 -        }
  61.143 -    }
  61.144 -    
  61.145 -    private HttpServer initServer(String path, boolean addClasses) throws IOException {
  61.146 -        HttpServer s = HttpServer.createSimpleServer(path, new PortRange(8080, 65535));
  61.147 -
  61.148 -        final ServerConfiguration conf = s.getServerConfiguration();
  61.149 -        if (addClasses) {
  61.150 -            conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
  61.151 -            conf.addHttpHandler(new Classes(resources), "/classes/");
  61.152 -        }
  61.153 -        return s;
  61.154 -    }
  61.155 -    
  61.156 -    private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
  61.157 -        wait = new CountDownLatch(1);
  61.158 -        server = initServer(".", true);
  61.159 -        final ServerConfiguration conf = server.getServerConfiguration();
  61.160 -        
  61.161 -        class DynamicResourceHandler extends HttpHandler {
  61.162 -            private final InvocationContext ic;
  61.163 -            public DynamicResourceHandler(InvocationContext ic) {
  61.164 -                if (ic == null || ic.resources.isEmpty()) {
  61.165 -                    throw new NullPointerException();
  61.166 -                }
  61.167 -                this.ic = ic;
  61.168 -                for (Resource r : ic.resources) {
  61.169 -                    conf.addHttpHandler(this, r.httpPath);
  61.170 -                }
  61.171 -            }
  61.172 -
  61.173 -            public void close() {
  61.174 -                conf.removeHttpHandler(this);
  61.175 -            }
  61.176 -            
  61.177 -            @Override
  61.178 -            public void service(Request request, Response response) throws Exception {
  61.179 -                for (Resource r : ic.resources) {
  61.180 -                    if (r.httpPath.equals(request.getRequestURI())) {
  61.181 -                        LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
  61.182 -                        response.setContentType(r.httpType);
  61.183 -                        r.httpContent.reset();
  61.184 -                        String[] params = null;
  61.185 -                        if (r.parameters.length != 0) {
  61.186 -                            params = new String[r.parameters.length];
  61.187 -                            for (int i = 0; i < r.parameters.length; i++) {
  61.188 -                                params[i] = request.getParameter(r.parameters[i]);
  61.189 -                            }
  61.190 -                        }
  61.191 -                        
  61.192 -                        copyStream(r.httpContent, response.getOutputStream(), null, params);
  61.193 -                    }
  61.194 -                }
  61.195 -            }
  61.196 -        }
  61.197 -        
  61.198 -        conf.addHttpHandler(new Page(resources, 
  61.199 -            "org/apidesign/bck2brwsr/launcher/harness.xhtml"
  61.200 -        ), "/execute");
  61.201 -        
  61.202 -        conf.addHttpHandler(new HttpHandler() {
  61.203 -            int cnt;
  61.204 -            List<InvocationContext> cases = new ArrayList<>();
  61.205 -            DynamicResourceHandler prev;
  61.206 -            @Override
  61.207 -            public void service(Request request, Response response) throws Exception {
  61.208 -                String id = request.getParameter("request");
  61.209 -                String value = request.getParameter("result");
  61.210 -                if (value != null && value.indexOf((char)0xC5) != -1) {
  61.211 -                    value = toUTF8(value);
  61.212 -                }
  61.213 -                
  61.214 -                
  61.215 -                InvocationContext mi = null;
  61.216 -                int caseNmbr = -1;
  61.217 -                
  61.218 -                if (id != null && value != null) {
  61.219 -                    LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
  61.220 -                    value = decodeURL(value);
  61.221 -                    int indx = Integer.parseInt(id);
  61.222 -                    cases.get(indx).result(value, null);
  61.223 -                    if (++indx < cases.size()) {
  61.224 -                        mi = cases.get(indx);
  61.225 -                        LOG.log(Level.INFO, "Re-executing case {0}", indx);
  61.226 -                        caseNmbr = indx;
  61.227 -                    }
  61.228 -                } else {
  61.229 -                    if (!cases.isEmpty()) {
  61.230 -                        LOG.info("Re-executing test cases");
  61.231 -                        mi = cases.get(0);
  61.232 -                        caseNmbr = 0;
  61.233 -                    }
  61.234 -                }
  61.235 -                
  61.236 -                if (prev != null) {
  61.237 -                    prev.close();
  61.238 -                    prev = null;
  61.239 -                }
  61.240 -                
  61.241 -                if (mi == null) {
  61.242 -                    mi = methods.take();
  61.243 -                    caseNmbr = cnt++;
  61.244 -                }
  61.245 -                if (mi == END) {
  61.246 -                    response.getWriter().write("");
  61.247 -                    wait.countDown();
  61.248 -                    cnt = 0;
  61.249 -                    LOG.log(Level.INFO, "End of data reached. Exiting.");
  61.250 -                    return;
  61.251 -                }
  61.252 -                
  61.253 -                if (!mi.resources.isEmpty()) {
  61.254 -                    prev = new DynamicResourceHandler(mi);
  61.255 -                }
  61.256 -                
  61.257 -                cases.add(mi);
  61.258 -                final String cn = mi.clazz.getName();
  61.259 -                final String mn = mi.methodName;
  61.260 -                LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{caseNmbr, cn, mn});
  61.261 -                response.getWriter().write("{"
  61.262 -                    + "className: '" + cn + "', "
  61.263 -                    + "methodName: '" + mn + "', "
  61.264 -                    + "request: " + caseNmbr
  61.265 -                );
  61.266 -                if (mi.html != null) {
  61.267 -                    response.getWriter().write(", html: '");
  61.268 -                    response.getWriter().write(encodeJSON(mi.html));
  61.269 -                    response.getWriter().write("'");
  61.270 -                }
  61.271 -                response.getWriter().write("}");
  61.272 -            }
  61.273 -        }, "/data");
  61.274 -
  61.275 -        this.brwsr = launchServerAndBrwsr(server, "/execute");
  61.276 -    }
  61.277 -    
  61.278 -    private static String encodeJSON(String in) {
  61.279 -        StringBuilder sb = new StringBuilder();
  61.280 -        for (int i = 0; i < in.length(); i++) {
  61.281 -            char ch = in.charAt(i);
  61.282 -            if (ch < 32 || ch == '\'' || ch == '"') {
  61.283 -                sb.append("\\u");
  61.284 -                String hs = "0000" + Integer.toHexString(ch);
  61.285 -                hs = hs.substring(hs.length() - 4);
  61.286 -                sb.append(hs);
  61.287 -            } else {
  61.288 -                sb.append(ch);
  61.289 -            }
  61.290 -        }
  61.291 -        return sb.toString();
  61.292 -    }
  61.293 -    
  61.294 -    @Override
  61.295 -    public void shutdown() throws IOException {
  61.296 -        methods.offer(END);
  61.297 -        for (;;) {
  61.298 -            int prev = methods.size();
  61.299 -            try {
  61.300 -                if (wait != null && wait.await(timeOut, TimeUnit.MILLISECONDS)) {
  61.301 -                    break;
  61.302 -                }
  61.303 -            } catch (InterruptedException ex) {
  61.304 -                throw new IOException(ex);
  61.305 -            }
  61.306 -            if (prev == methods.size()) {
  61.307 -                LOG.log(
  61.308 -                    Level.WARNING, 
  61.309 -                    "Timeout and no test has been executed meanwhile (at {0}). Giving up.", 
  61.310 -                    methods.size()
  61.311 -                );
  61.312 -                break;
  61.313 -            }
  61.314 -            LOG.log(Level.INFO, 
  61.315 -                "Timeout, but tests got from {0} to {1}. Trying again.", 
  61.316 -                new Object[]{prev, methods.size()}
  61.317 -            );
  61.318 -        }
  61.319 -        stopServerAndBrwsr(server, brwsr);
  61.320 -    }
  61.321 -    
  61.322 -    static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
  61.323 -        for (;;) {
  61.324 -            int ch = is.read();
  61.325 -            if (ch == -1) {
  61.326 -                break;
  61.327 -            }
  61.328 -            if (ch == '$' && params.length > 0) {
  61.329 -                int cnt = is.read() - '0';
  61.330 -                if (baseURL != null && cnt == 'U' - '0') {
  61.331 -                    os.write(baseURL.getBytes("UTF-8"));
  61.332 -                } else {
  61.333 -                    if (cnt >= 0 && cnt < params.length) {
  61.334 -                        os.write(params[cnt].getBytes("UTF-8"));
  61.335 -                    } else {
  61.336 -                        os.write('$');
  61.337 -                        os.write(cnt + '0');
  61.338 -                    }
  61.339 -                }
  61.340 -            } else {
  61.341 -                os.write(ch);
  61.342 -            }
  61.343 -        }
  61.344 -    }
  61.345 -
  61.346 -    private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
  61.347 -        server.start();
  61.348 -        NetworkListener listener = server.getListeners().iterator().next();
  61.349 -        int port = listener.getPort();
  61.350 -        
  61.351 -        URI uri = new URI("http://localhost:" + port + page);
  61.352 -        LOG.log(Level.INFO, "Showing {0}", uri);
  61.353 -        if (cmd == null) {
  61.354 -            try {
  61.355 -                LOG.log(Level.INFO, "Trying Desktop.browse on {0} {2} by {1}", new Object[] {
  61.356 -                    System.getProperty("java.vm.name"),
  61.357 -                    System.getProperty("java.vm.vendor"),
  61.358 -                    System.getProperty("java.vm.version"),
  61.359 -                });
  61.360 -                java.awt.Desktop.getDesktop().browse(uri);
  61.361 -                LOG.log(Level.INFO, "Desktop.browse successfully finished");
  61.362 -                return null;
  61.363 -            } catch (UnsupportedOperationException ex) {
  61.364 -                LOG.log(Level.INFO, "Desktop.browse not supported: {0}", ex.getMessage());
  61.365 -                LOG.log(Level.FINE, null, ex);
  61.366 -            }
  61.367 -        }
  61.368 -        {
  61.369 -            String cmdName = cmd == null ? "xdg-open" : cmd;
  61.370 -            String[] cmdArr = { 
  61.371 -                cmdName, uri.toString()
  61.372 -            };
  61.373 -            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmdArr));
  61.374 -            final Process process = Runtime.getRuntime().exec(cmdArr);
  61.375 -            return new Object[] { process, null };
  61.376 -        }
  61.377 -    }
  61.378 -    private static String toUTF8(String value) throws UnsupportedEncodingException {
  61.379 -        byte[] arr = new byte[value.length()];
  61.380 -        for (int i = 0; i < arr.length; i++) {
  61.381 -            arr[i] = (byte)value.charAt(i);
  61.382 -        }
  61.383 -        return new String(arr, "UTF-8");
  61.384 -    }
  61.385 -    
  61.386 -    private static String decodeURL(String s) {
  61.387 -        for (;;) {
  61.388 -            int pos = s.indexOf('%');
  61.389 -            if (pos == -1) {
  61.390 -                return s;
  61.391 -            }
  61.392 -            int i = Integer.parseInt(s.substring(pos + 1, pos + 2), 16);
  61.393 -            s = s.substring(0, pos) + (char)i + s.substring(pos + 2);
  61.394 -        }
  61.395 -    }
  61.396 -    
  61.397 -    private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException {
  61.398 -        if (brwsr == null) {
  61.399 -            return;
  61.400 -        }
  61.401 -        Process process = (Process)brwsr[0];
  61.402 -        
  61.403 -        server.stop();
  61.404 -        InputStream stdout = process.getInputStream();
  61.405 -        InputStream stderr = process.getErrorStream();
  61.406 -        drain("StdOut", stdout);
  61.407 -        drain("StdErr", stderr);
  61.408 -        process.destroy();
  61.409 -        int res;
  61.410 -        try {
  61.411 -            res = process.waitFor();
  61.412 -        } catch (InterruptedException ex) {
  61.413 -            throw new IOException(ex);
  61.414 -        }
  61.415 -        LOG.log(Level.INFO, "Exit code: {0}", res);
  61.416 -
  61.417 -        deleteTree((File)brwsr[1]);
  61.418 -    }
  61.419 -    
  61.420 -    private static void drain(String name, InputStream is) throws IOException {
  61.421 -        int av = is.available();
  61.422 -        if (av > 0) {
  61.423 -            StringBuilder sb = new StringBuilder();
  61.424 -            sb.append("v== ").append(name).append(" ==v\n");
  61.425 -            while (av-- > 0) {
  61.426 -                sb.append((char)is.read());
  61.427 -            }
  61.428 -            sb.append("\n^== ").append(name).append(" ==^");
  61.429 -            LOG.log(Level.INFO, sb.toString());
  61.430 -        }
  61.431 -    }
  61.432 -
  61.433 -    private void deleteTree(File file) {
  61.434 -        if (file == null) {
  61.435 -            return;
  61.436 -        }
  61.437 -        File[] arr = file.listFiles();
  61.438 -        if (arr != null) {
  61.439 -            for (File s : arr) {
  61.440 -                deleteTree(s);
  61.441 -            }
  61.442 -        }
  61.443 -        file.delete();
  61.444 -    }
  61.445 -
  61.446 -    @Override
  61.447 -    public void close() throws IOException {
  61.448 -        shutdown();
  61.449 -    }
  61.450 -
  61.451 -    private class Res implements Bck2Brwsr.Resources {
  61.452 -        @Override
  61.453 -        public InputStream get(String resource) throws IOException {
  61.454 -            for (ClassLoader l : loaders) {
  61.455 -                URL u = null;
  61.456 -                Enumeration<URL> en = l.getResources(resource);
  61.457 -                while (en.hasMoreElements()) {
  61.458 -                    u = en.nextElement();
  61.459 -                }
  61.460 -                if (u != null) {
  61.461 -                    return u.openStream();
  61.462 -                }
  61.463 -            }
  61.464 -            throw new IOException("Can't find " + resource);
  61.465 -        }
  61.466 -    }
  61.467 -
  61.468 -    private static class Page extends HttpHandler {
  61.469 -        final String resource;
  61.470 -        private final String[] args;
  61.471 -        private final Res res;
  61.472 -        
  61.473 -        public Page(Res res, String resource, String... args) {
  61.474 -            this.res = res;
  61.475 -            this.resource = resource;
  61.476 -            this.args = args.length == 0 ? new String[] { "$0" } : args;
  61.477 -        }
  61.478 -
  61.479 -        @Override
  61.480 -        public void service(Request request, Response response) throws Exception {
  61.481 -            String r = computePage(request);
  61.482 -            if (r.startsWith("/")) {
  61.483 -                r = r.substring(1);
  61.484 -            }
  61.485 -            String[] replace = {};
  61.486 -            if (r.endsWith(".html")) {
  61.487 -                response.setContentType("text/html");
  61.488 -                LOG.info("Content type text/html");
  61.489 -                replace = args;
  61.490 -            }
  61.491 -            if (r.endsWith(".xhtml")) {
  61.492 -                response.setContentType("application/xhtml+xml");
  61.493 -                LOG.info("Content type application/xhtml+xml");
  61.494 -                replace = args;
  61.495 -            }
  61.496 -            OutputStream os = response.getOutputStream();
  61.497 -            try (InputStream is = res.get(r)) {
  61.498 -                copyStream(is, os, request.getRequestURL().toString(), replace);
  61.499 -            } catch (IOException ex) {
  61.500 -                response.setDetailMessage(ex.getLocalizedMessage());
  61.501 -                response.setError();
  61.502 -                response.setStatus(404);
  61.503 -            }
  61.504 -        }
  61.505 -
  61.506 -        protected String computePage(Request request) {
  61.507 -            String r = resource;
  61.508 -            if (r == null) {
  61.509 -                r = request.getHttpHandlerPath();
  61.510 -            }
  61.511 -            return r;
  61.512 -        }
  61.513 -    }
  61.514 -    
  61.515 -    private static class SubTree extends Page {
  61.516 -
  61.517 -        public SubTree(Res res, String resource, String... args) {
  61.518 -            super(res, resource, args);
  61.519 -        }
  61.520 -
  61.521 -        @Override
  61.522 -        protected String computePage(Request request) {
  61.523 -            return resource + request.getHttpHandlerPath();
  61.524 -        }
  61.525 -        
  61.526 -        
  61.527 -    }
  61.528 -
  61.529 -    private static class VM extends HttpHandler {
  61.530 -        private final String bck2brwsr;
  61.531 -
  61.532 -        public VM(Res loader) throws IOException {
  61.533 -            StringBuilder sb = new StringBuilder();
  61.534 -            Bck2Brwsr.generate(sb, loader);
  61.535 -            sb.append(
  61.536 -                  "(function WrapperVM(global) {"
  61.537 -                + "  function ldCls(res) {\n"
  61.538 -                + "    var request = new XMLHttpRequest();\n"
  61.539 -                + "    request.open('GET', '/classes/' + res, false);\n"
  61.540 -                + "    request.send();\n"
  61.541 -                + "    if (request.status !== 200) return null;\n"
  61.542 -                + "    var arr = eval('(' + request.responseText + ')');\n"
  61.543 -                + "    return arr;\n"
  61.544 -                + "  }\n"
  61.545 -                + "  var prevvm = global.bck2brwsr;\n"
  61.546 -                + "  global.bck2brwsr = function() {\n"
  61.547 -                + "    var args = Array.prototype.slice.apply(arguments);\n"
  61.548 -                + "    args.unshift(ldCls);\n"
  61.549 -                + "    return prevvm.apply(null, args);\n"
  61.550 -                + "  };\n"
  61.551 -                + "})(this);\n"
  61.552 -            );
  61.553 -            this.bck2brwsr = sb.toString();
  61.554 -        }
  61.555 -
  61.556 -        @Override
  61.557 -        public void service(Request request, Response response) throws Exception {
  61.558 -            response.setCharacterEncoding("UTF-8");
  61.559 -            response.setContentType("text/javascript");
  61.560 -            response.getWriter().write(bck2brwsr);
  61.561 -        }
  61.562 -    }
  61.563 -
  61.564 -    private static class Classes extends HttpHandler {
  61.565 -        private final Res loader;
  61.566 -
  61.567 -        public Classes(Res loader) {
  61.568 -            this.loader = loader;
  61.569 -        }
  61.570 -
  61.571 -        @Override
  61.572 -        public void service(Request request, Response response) throws Exception {
  61.573 -            String res = request.getHttpHandlerPath();
  61.574 -            if (res.startsWith("/")) {
  61.575 -                res = res.substring(1);
  61.576 -            }
  61.577 -            try (InputStream is = loader.get(res)) {
  61.578 -                response.setContentType("text/javascript");
  61.579 -                Writer w = response.getWriter();
  61.580 -                w.append("[");
  61.581 -                for (int i = 0;; i++) {
  61.582 -                    int b = is.read();
  61.583 -                    if (b == -1) {
  61.584 -                        break;
  61.585 -                    }
  61.586 -                    if (i > 0) {
  61.587 -                        w.append(", ");
  61.588 -                    }
  61.589 -                    if (i % 20 == 0) {
  61.590 -                        w.write("\n");
  61.591 -                    }
  61.592 -                    if (b > 127) {
  61.593 -                        b = b - 256;
  61.594 -                    }
  61.595 -                    w.append(Integer.toString(b));
  61.596 -                }
  61.597 -                w.append("\n]");
  61.598 -            } catch (IOException ex) {
  61.599 -                response.setStatus(HttpStatus.NOT_FOUND_404);
  61.600 -                response.setError();
  61.601 -                response.setDetailMessage(ex.getMessage());
  61.602 -            }
  61.603 -        }
  61.604 -    }
  61.605 -}
    62.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java	Fri Apr 26 15:09:59 2013 +0200
    62.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.3 @@ -1,115 +0,0 @@
    62.4 -/**
    62.5 - * Back 2 Browser Bytecode Translator
    62.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    62.7 - *
    62.8 - * This program is free software: you can redistribute it and/or modify
    62.9 - * it under the terms of the GNU General Public License as published by
   62.10 - * the Free Software Foundation, version 2 of the License.
   62.11 - *
   62.12 - * This program is distributed in the hope that it will be useful,
   62.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   62.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   62.15 - * GNU General Public License for more details.
   62.16 - *
   62.17 - * You should have received a copy of the GNU General Public License
   62.18 - * along with this program. Look for COPYING file in the top folder.
   62.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   62.20 - */
   62.21 -package org.apidesign.bck2brwsr.launcher;
   62.22 -
   62.23 -import java.io.IOException;
   62.24 -import java.io.InputStream;
   62.25 -import java.util.ArrayList;
   62.26 -import java.util.List;
   62.27 -import java.util.concurrent.CountDownLatch;
   62.28 -import java.util.concurrent.TimeUnit;
   62.29 -
   62.30 -/** Represents individual method invocation, its context and its result.
   62.31 - *
   62.32 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   62.33 - */
   62.34 -public final class InvocationContext {
   62.35 -    final CountDownLatch wait = new CountDownLatch(1);
   62.36 -    final Class<?> clazz;
   62.37 -    final String methodName;
   62.38 -    private final Launcher launcher;
   62.39 -    private String result;
   62.40 -    private Throwable exception;
   62.41 -    String html;
   62.42 -    final List<Resource> resources = new ArrayList<>();
   62.43 -
   62.44 -    InvocationContext(Launcher launcher, Class<?> clazz, String methodName) {
   62.45 -        this.launcher = launcher;
   62.46 -        this.clazz = clazz;
   62.47 -        this.methodName = methodName;
   62.48 -    }
   62.49 -    
   62.50 -    /** An HTML fragment to be available for the execution. Useful primarily when
   62.51 -     * executing in a browser via {@link Launcher#createBrowser(java.lang.String)}.
   62.52 -     * @param html the html fragment
   62.53 -     */
   62.54 -    public void setHtmlFragment(String html) {
   62.55 -        this.html = html;
   62.56 -    }
   62.57 -    
   62.58 -    /** HTTP resource to be available during execution. An invocation may
   62.59 -     * perform an HTTP query and obtain a resource relative to the page.
   62.60 -     */
   62.61 -    public void addHttpResource(String relativePath, String mimeType, String[] parameters, InputStream content) {
   62.62 -        if (relativePath == null || mimeType == null || content == null || parameters == null) {
   62.63 -            throw new NullPointerException();
   62.64 -        }
   62.65 -        resources.add(new Resource(content, mimeType, relativePath, parameters));
   62.66 -    }
   62.67 -    
   62.68 -    /** Invokes the associated method. 
   62.69 -     * @return the textual result of the invocation
   62.70 -     */
   62.71 -    public String invoke() throws IOException {
   62.72 -        launcher.runMethod(this);
   62.73 -        return toString();
   62.74 -    }
   62.75 -    
   62.76 -    /** Obtains textual result of the invocation.
   62.77 -     * @return text representing the exception or result value
   62.78 -     */
   62.79 -    @Override
   62.80 -    public String toString() {
   62.81 -        if (exception != null) {
   62.82 -            return exception.toString();
   62.83 -        }
   62.84 -        return result;
   62.85 -    }
   62.86 -    
   62.87 -    /**
   62.88 -     * @param timeOut
   62.89 -     * @throws InterruptedException 
   62.90 -     */
   62.91 -    void await(long timeOut) throws InterruptedException {
   62.92 -        wait.await(timeOut, TimeUnit.MILLISECONDS);
   62.93 -    }
   62.94 -    
   62.95 -    void result(String r, Throwable e) {
   62.96 -        this.result = r;
   62.97 -        this.exception = e;
   62.98 -        wait.countDown();
   62.99 -    }
  62.100 -
  62.101 -
  62.102 -    static final class Resource {
  62.103 -        final InputStream httpContent;
  62.104 -        final String httpType;
  62.105 -        final String httpPath;
  62.106 -        final String[] parameters;
  62.107 -
  62.108 -        Resource(InputStream httpContent, String httpType, String httpPath,
  62.109 -            String[] parameters
  62.110 -        ) {
  62.111 -            httpContent.mark(Integer.MAX_VALUE);
  62.112 -            this.httpContent = httpContent;
  62.113 -            this.httpType = httpType;
  62.114 -            this.httpPath = httpPath;
  62.115 -            this.parameters = parameters;
  62.116 -        }
  62.117 -    }
  62.118 -}
    63.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Fri Apr 26 15:09:59 2013 +0200
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,132 +0,0 @@
    63.4 -/**
    63.5 - * Back 2 Browser Bytecode Translator
    63.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    63.7 - *
    63.8 - * This program is free software: you can redistribute it and/or modify
    63.9 - * it under the terms of the GNU General Public License as published by
   63.10 - * the Free Software Foundation, version 2 of the License.
   63.11 - *
   63.12 - * This program is distributed in the hope that it will be useful,
   63.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   63.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   63.15 - * GNU General Public License for more details.
   63.16 - *
   63.17 - * You should have received a copy of the GNU General Public License
   63.18 - * along with this program. Look for COPYING file in the top folder.
   63.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   63.20 - */
   63.21 -package org.apidesign.bck2brwsr.launcher;
   63.22 -
   63.23 -import org.apidesign.bck2brwsr.launcher.impl.Console;
   63.24 -import java.io.IOException;
   63.25 -import java.io.InputStream;
   63.26 -import java.net.URL;
   63.27 -import java.util.Enumeration;
   63.28 -import java.util.LinkedHashSet;
   63.29 -import java.util.Set;
   63.30 -import java.util.logging.Level;
   63.31 -import java.util.logging.Logger;
   63.32 -import javax.script.Invocable;
   63.33 -import javax.script.ScriptEngine;
   63.34 -import javax.script.ScriptEngineManager;
   63.35 -import javax.script.ScriptException;
   63.36 -import org.apidesign.vm4brwsr.Bck2Brwsr;
   63.37 -
   63.38 -/**
   63.39 - * Tests execution in Java's internal scripting engine.
   63.40 - */
   63.41 -final class JSLauncher extends Launcher {
   63.42 -    private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
   63.43 -    private Set<ClassLoader> loaders = new LinkedHashSet<>();
   63.44 -    private final Res resources = new Res();
   63.45 -    private Invocable code;
   63.46 -    private StringBuilder codeSeq;
   63.47 -    private Object console;
   63.48 -    
   63.49 -    
   63.50 -    @Override InvocationContext runMethod(InvocationContext mi) {
   63.51 -        loaders.add(mi.clazz.getClassLoader());
   63.52 -        try {
   63.53 -            long time = System.currentTimeMillis();
   63.54 -            LOG.log(Level.FINE, "Invoking {0}.{1}", new Object[]{mi.clazz.getName(), mi.methodName});
   63.55 -            String res = code.invokeMethod(
   63.56 -                console,
   63.57 -                "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
   63.58 -                mi.clazz.getName(), mi.methodName).toString();
   63.59 -            time = System.currentTimeMillis() - time;
   63.60 -            LOG.log(Level.FINE, "Resut of {0}.{1} = {2} in {3} ms", new Object[]{mi.clazz.getName(), mi.methodName, res, time});
   63.61 -            mi.result(res, null);
   63.62 -        } catch (ScriptException | NoSuchMethodException ex) {
   63.63 -            mi.result(null, ex);
   63.64 -        }
   63.65 -        return mi;
   63.66 -    }
   63.67 -    
   63.68 -    public void addClassLoader(ClassLoader url) {
   63.69 -        this.loaders.add(url);
   63.70 -    }
   63.71 -
   63.72 -    @Override
   63.73 -    public void initialize() throws IOException {
   63.74 -        try {
   63.75 -            initRhino();
   63.76 -        } catch (Exception ex) {
   63.77 -            if (ex instanceof IOException) {
   63.78 -                throw (IOException)ex;
   63.79 -            }
   63.80 -            if (ex instanceof RuntimeException) {
   63.81 -                throw (RuntimeException)ex;
   63.82 -            }
   63.83 -            throw new IOException(ex);
   63.84 -        }
   63.85 -    }
   63.86 -    
   63.87 -    private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
   63.88 -        StringBuilder sb = new StringBuilder();
   63.89 -        Bck2Brwsr.generate(sb, new Res());
   63.90 -
   63.91 -        ScriptEngineManager sem = new ScriptEngineManager();
   63.92 -        ScriptEngine mach = sem.getEngineByExtension("js");
   63.93 -
   63.94 -        sb.append(
   63.95 -              "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.impl.Console.read);"
   63.96 -            + "\nfunction initVM() { return vm; };"
   63.97 -            + "\n");
   63.98 -
   63.99 -        Object res = mach.eval(sb.toString());
  63.100 -        if (!(mach instanceof Invocable)) {
  63.101 -            throw new IOException("It is invocable object: " + res);
  63.102 -        }
  63.103 -        code = (Invocable) mach;
  63.104 -        codeSeq = sb;
  63.105 -        
  63.106 -        Object vm = code.invokeFunction("initVM");
  63.107 -        console = code.invokeMethod(vm, "loadClass", Console.class.getName());
  63.108 -    }
  63.109 -
  63.110 -    @Override
  63.111 -    public void shutdown() throws IOException {
  63.112 -    }
  63.113 -
  63.114 -    @Override
  63.115 -    public String toString() {
  63.116 -        return codeSeq.toString();
  63.117 -    }
  63.118 -    
  63.119 -    private class Res implements Bck2Brwsr.Resources {
  63.120 -        @Override
  63.121 -        public InputStream get(String resource) throws IOException {
  63.122 -            for (ClassLoader l : loaders) {
  63.123 -                URL u = null;
  63.124 -                Enumeration<URL> en = l.getResources(resource);
  63.125 -                while (en.hasMoreElements()) {
  63.126 -                    u = en.nextElement();
  63.127 -                }
  63.128 -                if (u != null) {
  63.129 -                    return u.openStream();
  63.130 -                }
  63.131 -            }
  63.132 -            throw new IOException("Can't find " + resource);
  63.133 -        }
  63.134 -    }
  63.135 -}
    64.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Fri Apr 26 15:09:59 2013 +0200
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,116 +0,0 @@
    64.4 -/**
    64.5 - * Back 2 Browser Bytecode Translator
    64.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    64.7 - *
    64.8 - * This program is free software: you can redistribute it and/or modify
    64.9 - * it under the terms of the GNU General Public License as published by
   64.10 - * the Free Software Foundation, version 2 of the License.
   64.11 - *
   64.12 - * This program is distributed in the hope that it will be useful,
   64.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   64.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   64.15 - * GNU General Public License for more details.
   64.16 - *
   64.17 - * You should have received a copy of the GNU General Public License
   64.18 - * along with this program. Look for COPYING file in the top folder.
   64.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   64.20 - */
   64.21 -package org.apidesign.bck2brwsr.launcher;
   64.22 -
   64.23 -import java.io.Closeable;
   64.24 -import java.io.File;
   64.25 -import java.io.IOException;
   64.26 -import org.apidesign.vm4brwsr.Bck2Brwsr;
   64.27 -
   64.28 -/** An abstraction for executing tests in a Bck2Brwsr virtual machine.
   64.29 - * Either in {@linkm Launcher#createJavaScript JavaScript engine}, 
   64.30 - * or in {@linkm Launcher#createBrowser external browser}.
   64.31 - * <p>
   64.32 - * There also are methods to {@link #showDir(java.io.File, java.lang.String) display pages} 
   64.33 - * in an external browser served by internal HTTP server.
   64.34 - *
   64.35 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   64.36 - */
   64.37 -public abstract class Launcher {
   64.38 -
   64.39 -    Launcher() {
   64.40 -    }
   64.41 -
   64.42 -    /** Initializes the launcher. This may mean starting a web browser or
   64.43 -     * initializing execution engine.
   64.44 -     * @throws IOException if something goes wrong
   64.45 -     */
   64.46 -    public abstract void initialize() throws IOException;
   64.47 -    
   64.48 -    /** Shuts down the launcher.
   64.49 -     * @throws IOException if something goes wrong
   64.50 -     */
   64.51 -    public abstract void shutdown() throws IOException;
   64.52 -    
   64.53 -    
   64.54 -    /** Builds an invocation context. The context can later be customized
   64.55 -     * and {@link InvocationContext#invoke() invoked}.
   64.56 -     * 
   64.57 -     * @param clazz the class to execute method from
   64.58 -     * @param method the method to execute
   64.59 -     * @return the context pointing to the selected method
   64.60 -     */
   64.61 -    public InvocationContext createInvocation(Class<?> clazz, String method) {
   64.62 -        return new InvocationContext(this, clazz, method);
   64.63 -    }
   64.64 -    
   64.65 -
   64.66 -    /** Creates launcher that uses internal JavaScript engine (Rhino).
   64.67 -     * @return the launcher
   64.68 -     */
   64.69 -    public static Launcher createJavaScript() {
   64.70 -        final JSLauncher l = new JSLauncher();
   64.71 -        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
   64.72 -        return l;
   64.73 -    }
   64.74 -    
   64.75 -    /** Creates launcher that is using external browser.
   64.76 -     * 
   64.77 -     * @param cmd <code>null</code> to use <code>java.awt.Desktop</code> to show the launcher
   64.78 -     *    or a string to execute in an external process (with a parameter to the URL)
   64.79 -     * @return launcher executing in external browser.
   64.80 -     */
   64.81 -    public static Launcher createBrowser(String cmd) {
   64.82 -        final Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(cmd);
   64.83 -        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
   64.84 -        l.setTimeout(180000);
   64.85 -        return l;
   64.86 -    }
   64.87 -    
   64.88 -    /** Starts an HTTP server which provides access to classes and resources
   64.89 -     * available in the <code>classes</code> URL and shows a start page
   64.90 -     * available as {@link ClassLoader#getResource(java.lang.String)} from the
   64.91 -     * provide classloader. Opens a browser with URL showing the start page.
   64.92 -     * 
   64.93 -     * @param classes classloader offering access to classes and resources
   64.94 -     * @param startpage page to show in the browser
   64.95 -     * @return interface that allows one to stop the server
   64.96 -     * @throws IOException if something goes wrong
   64.97 -     */
   64.98 -    public static Closeable showURL(ClassLoader classes, String startpage) throws IOException {
   64.99 -        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
  64.100 -        l.addClassLoader(classes);
  64.101 -        l.showURL(startpage);
  64.102 -        return l;
  64.103 -    }
  64.104 -    /** Starts an HTTP server which provides access to certain directory.
  64.105 -     * The <code>startpage</code> should be relative location inside the root 
  64.106 -     * directory. Opens a browser with URL showing the start page.
  64.107 -     * 
  64.108 -     * @param directory the root directory on disk
  64.109 -     * @param startpage relative path from the root to the page
  64.110 -     * @exception IOException if something goes wrong.
  64.111 -     */
  64.112 -    public static Closeable showDir(File directory, String startpage) throws IOException {
  64.113 -        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
  64.114 -        l.showDirectory(directory, startpage);
  64.115 -        return l;
  64.116 -    }
  64.117 -
  64.118 -    abstract InvocationContext runMethod(InvocationContext c) throws IOException; 
  64.119 -}
    65.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java	Fri Apr 26 15:09:59 2013 +0200
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,356 +0,0 @@
    65.4 -/**
    65.5 - * Back 2 Browser Bytecode Translator
    65.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    65.7 - *
    65.8 - * This program is free software: you can redistribute it and/or modify
    65.9 - * it under the terms of the GNU General Public License as published by
   65.10 - * the Free Software Foundation, version 2 of the License.
   65.11 - *
   65.12 - * This program is distributed in the hope that it will be useful,
   65.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   65.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   65.15 - * GNU General Public License for more details.
   65.16 - *
   65.17 - * You should have received a copy of the GNU General Public License
   65.18 - * along with this program. Look for COPYING file in the top folder.
   65.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   65.20 - */
   65.21 -package org.apidesign.bck2brwsr.launcher.impl;
   65.22 -
   65.23 -import java.io.IOException;
   65.24 -import java.io.InputStream;
   65.25 -import java.io.UnsupportedEncodingException;
   65.26 -import java.lang.reflect.InvocationTargetException;
   65.27 -import java.lang.reflect.Method;
   65.28 -import java.lang.reflect.Modifier;
   65.29 -import java.net.URL;
   65.30 -import java.util.Enumeration;
   65.31 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   65.32 -
   65.33 -/**
   65.34 - *
   65.35 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   65.36 - */
   65.37 -public class Console {
   65.38 -    private Console() {
   65.39 -    }
   65.40 -    static {
   65.41 -        turnAssetionStatusOn();
   65.42 -    }
   65.43 -    
   65.44 -    @JavaScriptBody(args = {"id", "attr"}, body = 
   65.45 -        "return window.document.getElementById(id)[attr].toString();")
   65.46 -    private static native Object getAttr(String id, String attr);
   65.47 -    @JavaScriptBody(args = {"elem", "attr"}, body = 
   65.48 -        "return elem[attr].toString();")
   65.49 -    private static native Object getAttr(Object elem, String attr);
   65.50 -
   65.51 -    @JavaScriptBody(args = {"id", "attr", "value"}, body = 
   65.52 -        "window.document.getElementById(id)[attr] = value;")
   65.53 -    private static native void setAttr(String id, String attr, Object value);
   65.54 -    @JavaScriptBody(args = {"elem", "attr", "value"}, body = 
   65.55 -        "elem[attr] = value;")
   65.56 -    private static native void setAttr(Object id, String attr, Object value);
   65.57 -    
   65.58 -    @JavaScriptBody(args = {}, body = "return; window.close();")
   65.59 -    private static native void closeWindow();
   65.60 -
   65.61 -    private static Object textArea;
   65.62 -    private static Object statusArea;
   65.63 -    
   65.64 -    private static void log(String newText) {
   65.65 -        if (textArea == null) {
   65.66 -            return;
   65.67 -        }
   65.68 -        String attr = "value";
   65.69 -        setAttr(textArea, attr, getAttr(textArea, attr) + "\n" + newText);
   65.70 -        setAttr(textArea, "scrollTop", getAttr(textArea, "scrollHeight"));
   65.71 -    }
   65.72 -    
   65.73 -    private static void beginTest(Case c) {
   65.74 -        Object[] arr = new Object[2];
   65.75 -        beginTest(c.getClassName() + "." + c.getMethodName(), c, arr);
   65.76 -        textArea = arr[0];
   65.77 -        statusArea = arr[1];
   65.78 -    }
   65.79 -    
   65.80 -    private static void finishTest(Case c, Object res) {
   65.81 -        if ("null".equals(res)) {
   65.82 -            setAttr(statusArea, "innerHTML", "Success");
   65.83 -        } else {
   65.84 -            setAttr(statusArea, "innerHTML", "Result " + res);
   65.85 -        }
   65.86 -        statusArea = null;
   65.87 -        textArea = null;
   65.88 -    }
   65.89 -
   65.90 -    @JavaScriptBody(args = { "test", "c", "arr" }, body = 
   65.91 -          "var ul = window.document.getElementById('bck2brwsr.result');\n"
   65.92 -        + "var li = window.document.createElement('li');\n"
   65.93 -        + "var span = window.document.createElement('span');"
   65.94 -        + "span.innerHTML = test + ' - ';\n"
   65.95 -        + "var details = window.document.createElement('a');\n"
   65.96 -        + "details.innerHTML = 'Details';\n"
   65.97 -        + "details.href = '#';\n"
   65.98 -        + "var p = window.document.createElement('p');\n"
   65.99 -        + "var status = window.document.createElement('a');\n"
  65.100 -        + "status.innerHTML = 'running';"
  65.101 -        + "details.onclick = function() { li.appendChild(p); li.removeChild(details); status.innerHTML = 'Run Again'; status.href = '#'; };\n"
  65.102 -        + "status.onclick = function() { c.again__V_3Ljava_lang_Object_2(arr); }\n"
  65.103 -        + "var pre = window.document.createElement('textarea');\n"
  65.104 -        + "pre.cols = 100;"
  65.105 -        + "pre.rows = 10;"
  65.106 -        + "li.appendChild(span);\n"
  65.107 -        + "li.appendChild(status);\n"
  65.108 -        + "var span = window.document.createElement('span');"
  65.109 -        + "span.innerHTML = ' ';\n"
  65.110 -        + "li.appendChild(span);\n"
  65.111 -        + "li.appendChild(details);\n"
  65.112 -        + "p.appendChild(pre);\n"
  65.113 -        + "ul.appendChild(li);\n"
  65.114 -        + "arr[0] = pre;\n"
  65.115 -        + "arr[1] = status;\n"
  65.116 -    )
  65.117 -    private static native void beginTest(String test, Case c, Object[] arr);
  65.118 -    
  65.119 -    @JavaScriptBody(args = { "url", "callback", "arr" }, body = ""
  65.120 -        + "var request = new XMLHttpRequest();\n"
  65.121 -        + "request.open('GET', url, true);\n"
  65.122 -        + "request.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');\n"
  65.123 -        + "request.onreadystatechange = function() {\n"
  65.124 -        + "  if (this.readyState!==4) return;\n"
  65.125 -        + "  arr[0] = this.responseText;\n"
  65.126 -        + "  callback.run__V();\n"
  65.127 -        + "};"
  65.128 -        + "request.send();"
  65.129 -    )
  65.130 -    private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
  65.131 -    
  65.132 -    public static void harness(String url) throws IOException {
  65.133 -        log("Connecting to " + url);
  65.134 -        Request r = new Request(url);
  65.135 -    }
  65.136 -    
  65.137 -    private static class Request implements Runnable {
  65.138 -        private final String[] arr = { null };
  65.139 -        private final String url;
  65.140 -        private Case c;
  65.141 -        private int retries;
  65.142 -
  65.143 -        private Request(String url) throws IOException {
  65.144 -            this.url = url;
  65.145 -            loadText(url, this, arr);
  65.146 -        }
  65.147 -        private Request(String url, String u) throws IOException {
  65.148 -            this.url = url;
  65.149 -            loadText(u, this, arr);
  65.150 -        }
  65.151 -        
  65.152 -        @Override
  65.153 -        public void run() {
  65.154 -            try {
  65.155 -                if (c == null) {
  65.156 -                    String data = arr[0];
  65.157 -
  65.158 -                    if (data == null) {
  65.159 -                        log("Some error exiting");
  65.160 -                        closeWindow();
  65.161 -                        return;
  65.162 -                    }
  65.163 -
  65.164 -                    if (data.isEmpty()) {
  65.165 -                        log("No data, exiting");
  65.166 -                        closeWindow();
  65.167 -                        return;
  65.168 -                    }
  65.169 -
  65.170 -                    c = Case.parseData(data);
  65.171 -                    beginTest(c);
  65.172 -                    log("Got \"" + data + "\"");
  65.173 -                } else {
  65.174 -                    log("Processing \"" + arr[0] + "\" for " + retries + " time");
  65.175 -                }
  65.176 -                Object result = retries++ >= 10 ? "java.lang.InterruptedException:timeout" : c.runTest();
  65.177 -                finishTest(c, result);
  65.178 -                
  65.179 -                String u = url + "?request=" + c.getRequestId() + "&result=" + result;
  65.180 -                new Request(url, u);
  65.181 -            } catch (Exception ex) {
  65.182 -                if (ex instanceof InterruptedException) {
  65.183 -                    log("Re-scheduling in 100ms");
  65.184 -                    schedule(this, 100);
  65.185 -                    return;
  65.186 -                }
  65.187 -                log(ex.getClass().getName() + ":" + ex.getMessage());
  65.188 -            }
  65.189 -        }
  65.190 -    }
  65.191 -    
  65.192 -    private static String encodeURL(String r) throws UnsupportedEncodingException {
  65.193 -        final String SPECIAL = "%$&+,/:;=?@";
  65.194 -        StringBuilder sb = new StringBuilder();
  65.195 -        byte[] utf8 = r.getBytes("UTF-8");
  65.196 -        for (int i = 0; i < utf8.length; i++) {
  65.197 -            int ch = utf8[i] & 0xff;
  65.198 -            if (ch < 32 || ch > 127 || SPECIAL.indexOf(ch) >= 0) {
  65.199 -                final String numbers = "0" + Integer.toHexString(ch);
  65.200 -                sb.append("%").append(numbers.substring(numbers.length() - 2));
  65.201 -            } else {
  65.202 -                if (ch == 32) {
  65.203 -                    sb.append("+");
  65.204 -                } else {
  65.205 -                    sb.append((char)ch);
  65.206 -                }
  65.207 -            }
  65.208 -        }
  65.209 -        return sb.toString();
  65.210 -    }
  65.211 -    
  65.212 -    static String invoke(String clazz, String method) throws 
  65.213 -    ClassNotFoundException, InvocationTargetException, IllegalAccessException, 
  65.214 -    InstantiationException, InterruptedException {
  65.215 -        final Object r = new Case(null).invokeMethod(clazz, method);
  65.216 -        return r == null ? "null" : r.toString().toString();
  65.217 -    }
  65.218 -
  65.219 -    /** Helper method that inspects the classpath and loads given resource
  65.220 -     * (usually a class file). Used while running tests in Rhino.
  65.221 -     * 
  65.222 -     * @param name resource name to find
  65.223 -     * @return the array of bytes in the given resource
  65.224 -     * @throws IOException I/O in case something goes wrong
  65.225 -     */
  65.226 -    public static byte[] read(String name) throws IOException {
  65.227 -        URL u = null;
  65.228 -        Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
  65.229 -        while (en.hasMoreElements()) {
  65.230 -            u = en.nextElement();
  65.231 -        }
  65.232 -        if (u == null) {
  65.233 -            throw new IOException("Can't find " + name);
  65.234 -        }
  65.235 -        try (InputStream is = u.openStream()) {
  65.236 -            byte[] arr;
  65.237 -            arr = new byte[is.available()];
  65.238 -            int offset = 0;
  65.239 -            while (offset < arr.length) {
  65.240 -                int len = is.read(arr, offset, arr.length - offset);
  65.241 -                if (len == -1) {
  65.242 -                    throw new IOException("Can't read " + name);
  65.243 -                }
  65.244 -                offset += len;
  65.245 -            }
  65.246 -            return arr;
  65.247 -        }
  65.248 -    }
  65.249 -   
  65.250 -    @JavaScriptBody(args = {}, body = "vm.desiredAssertionStatus = true;")
  65.251 -    private static void turnAssetionStatusOn() {
  65.252 -    }
  65.253 -
  65.254 -    @JavaScriptBody(args = {"r", "time"}, body =
  65.255 -        "return window.setTimeout(function() { r.run__V(); }, time);")
  65.256 -    private static native Object schedule(Runnable r, int time);
  65.257 -    
  65.258 -    private static final class Case {
  65.259 -        private final Object data;
  65.260 -        private Object inst;
  65.261 -
  65.262 -        private Case(Object data) {
  65.263 -            this.data = data;
  65.264 -        }
  65.265 -        
  65.266 -        public static Case parseData(String s) {
  65.267 -            return new Case(toJSON(s));
  65.268 -        }
  65.269 -        
  65.270 -        public String getMethodName() {
  65.271 -            return value("methodName", data);
  65.272 -        }
  65.273 -
  65.274 -        public String getClassName() {
  65.275 -            return value("className", data);
  65.276 -        }
  65.277 -        
  65.278 -        public String getRequestId() {
  65.279 -            return value("request", data);
  65.280 -        }
  65.281 -
  65.282 -        public String getHtmlFragment() {
  65.283 -            return value("html", data);
  65.284 -        }
  65.285 -        
  65.286 -        void again(Object[] arr) {
  65.287 -            try {
  65.288 -                textArea = arr[0];
  65.289 -                statusArea = arr[1];
  65.290 -                setAttr(textArea, "value", "");
  65.291 -                runTest();
  65.292 -            } catch (Exception ex) {
  65.293 -                log(ex.getClass().getName() + ":" + ex.getMessage());
  65.294 -            }
  65.295 -        }
  65.296 -
  65.297 -        private Object runTest() throws IllegalAccessException, 
  65.298 -        IllegalArgumentException, ClassNotFoundException, UnsupportedEncodingException, 
  65.299 -        InvocationTargetException, InstantiationException, InterruptedException {
  65.300 -            if (this.getHtmlFragment() != null) {
  65.301 -                setAttr("bck2brwsr.fragment", "innerHTML", this.getHtmlFragment());
  65.302 -            }
  65.303 -            log("Invoking " + this.getClassName() + '.' + this.getMethodName() + " as request: " + this.getRequestId());
  65.304 -            Object result = invokeMethod(this.getClassName(), this.getMethodName());
  65.305 -            setAttr("bck2brwsr.fragment", "innerHTML", "");
  65.306 -            log("Result: " + result);
  65.307 -            result = encodeURL("" + result);
  65.308 -            log("Sending back: ...?request=" + this.getRequestId() + "&result=" + result);
  65.309 -            return result;
  65.310 -        }
  65.311 -
  65.312 -        private Object invokeMethod(String clazz, String method)
  65.313 -        throws ClassNotFoundException, InvocationTargetException,
  65.314 -        InterruptedException, IllegalAccessException, IllegalArgumentException,
  65.315 -        InstantiationException {
  65.316 -            Method found = null;
  65.317 -            Class<?> c = Class.forName(clazz);
  65.318 -            for (Method m : c.getMethods()) {
  65.319 -                if (m.getName().equals(method)) {
  65.320 -                    found = m;
  65.321 -                }
  65.322 -            }
  65.323 -            Object res;
  65.324 -            if (found != null) {
  65.325 -                try {
  65.326 -                    if ((found.getModifiers() & Modifier.STATIC) != 0) {
  65.327 -                        res = found.invoke(null);
  65.328 -                    } else {
  65.329 -                        if (inst == null) {
  65.330 -                            inst = c.newInstance();
  65.331 -                        }
  65.332 -                        res = found.invoke(inst);
  65.333 -                    }
  65.334 -                } catch (Throwable ex) {
  65.335 -                    if (ex instanceof InvocationTargetException) {
  65.336 -                        ex = ((InvocationTargetException) ex).getTargetException();
  65.337 -                    }
  65.338 -                    if (ex instanceof InterruptedException) {
  65.339 -                        throw (InterruptedException)ex;
  65.340 -                    }
  65.341 -                    res = ex.getClass().getName() + ":" + ex.getMessage();
  65.342 -                }
  65.343 -            } else {
  65.344 -                res = "Can't find method " + method + " in " + clazz;
  65.345 -            }
  65.346 -            return res;
  65.347 -        }
  65.348 -        
  65.349 -        @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
  65.350 -        private static native Object toJSON(String s);
  65.351 -        
  65.352 -        @JavaScriptBody(args = {"p", "d"}, body = 
  65.353 -              "var v = d[p];\n"
  65.354 -            + "if (typeof v === 'undefined') return null;\n"
  65.355 -            + "return v.toString();"
  65.356 -        )
  65.357 -        private static native String value(String p, Object d);
  65.358 -    }
  65.359 -}
    66.1 --- a/rt/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Fri Apr 26 15:09:59 2013 +0200
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,43 +0,0 @@
    66.4 -<?xml version="1.0" encoding="UTF-8"?>
    66.5 -<!--
    66.6 -
    66.7 -    Back 2 Browser Bytecode Translator
    66.8 -    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    66.9 -
   66.10 -    This program is free software: you can redistribute it and/or modify
   66.11 -    it under the terms of the GNU General Public License as published by
   66.12 -    the Free Software Foundation, version 2 of the License.
   66.13 -
   66.14 -    This program is distributed in the hope that it will be useful,
   66.15 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   66.16 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   66.17 -    GNU General Public License for more details.
   66.18 -
   66.19 -    You should have received a copy of the GNU General Public License
   66.20 -    along with this program. Look for COPYING file in the top folder.
   66.21 -    If not, see http://opensource.org/licenses/GPL-2.0.
   66.22 -
   66.23 --->
   66.24 -<!DOCTYPE html>
   66.25 -<html xmlns="http://www.w3.org/1999/xhtml">
   66.26 -    <head>
   66.27 -        <title>Bck2Brwsr Harness</title>
   66.28 -    </head>
   66.29 -    <body>
   66.30 -        <script src="/bck2brwsr.js"></script>
   66.31 -        <script>
   66.32 -            var vm = bck2brwsr();
   66.33 -        </script>
   66.34 -        
   66.35 -        <h1>Bck2Brwsr Execution Harness</h1>
   66.36 -        
   66.37 -        <ul id="bck2brwsr.result" style="width: 100%;" >
   66.38 -        </ul>
   66.39 -
   66.40 -        <div id="bck2brwsr.fragment"/>
   66.41 -        
   66.42 -        <script type="text/javascript">
   66.43 -            vm.loadClass('org.apidesign.bck2brwsr.launcher.impl.Console').harness__VLjava_lang_String_2('$U/../data');
   66.44 -        </script>
   66.45 -    </body>
   66.46 -</html>
    67.1 --- a/rt/mojo/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    67.2 +++ b/rt/mojo/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    67.3 @@ -81,5 +81,15 @@
    67.4          <artifactId>launcher</artifactId>
    67.5        <version>${project.version}</version>
    67.6      </dependency>
    67.7 +    <dependency>
    67.8 +        <groupId>${project.groupId}</groupId>
    67.9 +        <artifactId>launcher.http</artifactId>
   67.10 +      <version>${project.version}</version>
   67.11 +    </dependency>
   67.12 +    <dependency>
   67.13 +        <groupId>${project.groupId}</groupId>
   67.14 +        <artifactId>launcher.fx</artifactId>
   67.15 +      <version>${project.version}</version>
   67.16 +    </dependency>
   67.17  </dependencies>
   67.18  </project>
    68.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Fri Apr 26 15:09:59 2013 +0200
    68.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.3 @@ -1,99 +0,0 @@
    68.4 -/**
    68.5 - * Back 2 Browser Bytecode Translator
    68.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    68.7 - *
    68.8 - * This program is free software: you can redistribute it and/or modify
    68.9 - * it under the terms of the GNU General Public License as published by
   68.10 - * the Free Software Foundation, version 2 of the License.
   68.11 - *
   68.12 - * This program is distributed in the hope that it will be useful,
   68.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   68.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   68.15 - * GNU General Public License for more details.
   68.16 - *
   68.17 - * You should have received a copy of the GNU General Public License
   68.18 - * along with this program. Look for COPYING file in the top folder.
   68.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   68.20 - */
   68.21 -package org.apidesign.bck2brwsr.mojo;
   68.22 -
   68.23 -import java.io.Closeable;
   68.24 -import org.apache.maven.plugin.AbstractMojo;
   68.25 -
   68.26 -import java.io.File;
   68.27 -import java.io.IOException;
   68.28 -import java.net.MalformedURLException;
   68.29 -import java.net.URL;
   68.30 -import java.net.URLClassLoader;
   68.31 -import java.util.ArrayList;
   68.32 -import java.util.Collection;
   68.33 -import java.util.List;
   68.34 -import org.apache.maven.artifact.Artifact;
   68.35 -import org.apache.maven.plugin.MojoExecutionException;
   68.36 -import org.apache.maven.plugins.annotations.LifecyclePhase;
   68.37 -import org.apache.maven.plugins.annotations.Mojo;
   68.38 -import org.apache.maven.plugins.annotations.Parameter;
   68.39 -import org.apache.maven.project.MavenProject;
   68.40 -import org.apidesign.bck2brwsr.launcher.Launcher;
   68.41 -
   68.42 -/** Executes given HTML page in a browser. */
   68.43 -@Mojo(name="brwsr", defaultPhase=LifecyclePhase.NONE)
   68.44 -public class BrswrMojo extends AbstractMojo {
   68.45 -    public BrswrMojo() {
   68.46 -    }
   68.47 -    /** Resource to show as initial page */
   68.48 -    @Parameter
   68.49 -    private String startpage;
   68.50 -
   68.51 -    @Parameter(defaultValue="${project}")
   68.52 -    private MavenProject prj;
   68.53 -    
   68.54 -    /** Root of the class files */
   68.55 -    @Parameter(defaultValue="${project.build.directory}/classes")
   68.56 -    private File classes;
   68.57 -    
   68.58 -    /** Root of all pages, and files, etc. */
   68.59 -    @Parameter
   68.60 -    private File directory;
   68.61 -
   68.62 -    @Override
   68.63 -    public void execute() throws MojoExecutionException {
   68.64 -        if (startpage == null) {
   68.65 -            throw new MojoExecutionException("You have to provide a start page");
   68.66 -        }
   68.67 -        
   68.68 -        try {
   68.69 -            Closeable httpServer;
   68.70 -            if (directory != null) {
   68.71 -                httpServer = Launcher.showDir(directory, startpage);
   68.72 -            } else {
   68.73 -                URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
   68.74 -                try {
   68.75 -                    httpServer = Launcher.showURL(url, startpage());
   68.76 -                } catch (Exception ex) {
   68.77 -                    throw new MojoExecutionException("Can't open " + startpage(), ex);
   68.78 -                }
   68.79 -            }
   68.80 -            System.in.read();
   68.81 -            httpServer.close();
   68.82 -        } catch (IOException ex) {
   68.83 -            throw new MojoExecutionException("Can't show the browser", ex);
   68.84 -        }
   68.85 -    }
   68.86 -    
   68.87 -    private String startpage() {
   68.88 -        return startpage;
   68.89 -    }
   68.90 -
   68.91 -    private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
   68.92 -        List<URL> arr = new ArrayList<URL>();
   68.93 -        arr.add(root.toURI().toURL());
   68.94 -        for (Artifact a : deps) {
   68.95 -            final File f = a.getFile();
   68.96 -            if (f != null) {
   68.97 -                arr.add(f.toURI().toURL());
   68.98 -            }
   68.99 -        }
  68.100 -        return new URLClassLoader(arr.toArray(new URL[0]), BrswrMojo.class.getClassLoader());
  68.101 -    }
  68.102 -}
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrwsrMojo.java	Mon Apr 29 16:32:14 2013 +0200
    69.3 @@ -0,0 +1,108 @@
    69.4 +/**
    69.5 + * Back 2 Browser Bytecode Translator
    69.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    69.7 + *
    69.8 + * This program is free software: you can redistribute it and/or modify
    69.9 + * it under the terms of the GNU General Public License as published by
   69.10 + * the Free Software Foundation, version 2 of the License.
   69.11 + *
   69.12 + * This program is distributed in the hope that it will be useful,
   69.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   69.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   69.15 + * GNU General Public License for more details.
   69.16 + *
   69.17 + * You should have received a copy of the GNU General Public License
   69.18 + * along with this program. Look for COPYING file in the top folder.
   69.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   69.20 + */
   69.21 +package org.apidesign.bck2brwsr.mojo;
   69.22 +
   69.23 +import java.io.Closeable;
   69.24 +import org.apache.maven.plugin.AbstractMojo;
   69.25 +
   69.26 +import java.io.File;
   69.27 +import java.io.IOException;
   69.28 +import java.net.MalformedURLException;
   69.29 +import java.net.URL;
   69.30 +import java.net.URLClassLoader;
   69.31 +import java.util.ArrayList;
   69.32 +import java.util.Collection;
   69.33 +import java.util.List;
   69.34 +import org.apache.maven.artifact.Artifact;
   69.35 +import org.apache.maven.plugin.MojoExecutionException;
   69.36 +import org.apache.maven.plugins.annotations.LifecyclePhase;
   69.37 +import org.apache.maven.plugins.annotations.Mojo;
   69.38 +import org.apache.maven.plugins.annotations.Parameter;
   69.39 +import org.apache.maven.project.MavenProject;
   69.40 +import org.apidesign.bck2brwsr.launcher.Launcher;
   69.41 +
   69.42 +/** Executes given HTML page in a browser. */
   69.43 +@Mojo(name="brwsr", defaultPhase=LifecyclePhase.NONE)
   69.44 +public class BrwsrMojo extends AbstractMojo {
   69.45 +    public BrwsrMojo() {
   69.46 +    }
   69.47 +    
   69.48 +    /** The identification of a launcher to use. Known values <code>fxbrwsr</code>, 
   69.49 +     * <code>bck2brwsr</code>, or 
   69.50 +     * name of an external process to execute.
   69.51 +     */
   69.52 +    @Parameter
   69.53 +    private String launcher;
   69.54 +    
   69.55 +    
   69.56 +    /** Resource to show as initial page */
   69.57 +    @Parameter
   69.58 +    private String startpage;
   69.59 +
   69.60 +    @Parameter(defaultValue="${project}")
   69.61 +    private MavenProject prj;
   69.62 +    
   69.63 +    /** Root of the class files */
   69.64 +    @Parameter(defaultValue="${project.build.directory}/classes")
   69.65 +    private File classes;
   69.66 +    
   69.67 +    /** Root of all pages, and files, etc. */
   69.68 +    @Parameter
   69.69 +    private File directory;
   69.70 +
   69.71 +    @Override
   69.72 +    public void execute() throws MojoExecutionException {
   69.73 +        if (startpage == null) {
   69.74 +            throw new MojoExecutionException("You have to provide a start page");
   69.75 +        }
   69.76 +        
   69.77 +        try {
   69.78 +            Closeable httpServer;
   69.79 +            if (directory != null) {
   69.80 +                httpServer = Launcher.showDir(directory, startpage);
   69.81 +            } else {
   69.82 +                URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
   69.83 +                try {
   69.84 +                    httpServer = Launcher.showURL(launcher, url, startpage());
   69.85 +                } catch (Exception ex) {
   69.86 +                    throw new MojoExecutionException("Can't open " + startpage(), ex);
   69.87 +                }
   69.88 +            }
   69.89 +            System.in.read();
   69.90 +            httpServer.close();
   69.91 +        } catch (IOException ex) {
   69.92 +            throw new MojoExecutionException("Can't show the browser", ex);
   69.93 +        }
   69.94 +    }
   69.95 +    
   69.96 +    private String startpage() {
   69.97 +        return startpage;
   69.98 +    }
   69.99 +
  69.100 +    private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
  69.101 +        List<URL> arr = new ArrayList<URL>();
  69.102 +        arr.add(root.toURI().toURL());
  69.103 +        for (Artifact a : deps) {
  69.104 +            final File f = a.getFile();
  69.105 +            if (f != null) {
  69.106 +                arr.add(f.toURI().toURL());
  69.107 +            }
  69.108 +        }
  69.109 +        return new URLClassLoader(arr.toArray(new URL[0]), BrwsrMojo.class.getClassLoader());
  69.110 +    }
  69.111 +}
    70.1 --- a/rt/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    70.2 +++ b/rt/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    70.3 @@ -14,7 +14,6 @@
    70.4    <modules>
    70.5      <module>core</module>
    70.6      <module>emul</module>
    70.7 -    <module>launcher</module>
    70.8      <module>archetype</module>
    70.9      <module>mojo</module>
   70.10      <module>vm</module>
    71.1 --- a/rt/vm/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    71.2 +++ b/rt/vm/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    71.3 @@ -86,6 +86,7 @@
    71.4                       <configuration>
    71.5                           <executable>java</executable>
    71.6                          <arguments>
    71.7 +                            <argument>-Dskip.if.exists=true</argument>
    71.8                              <argument>-cp</argument>
    71.9                              <classpath />
   71.10                              <argument>org.apidesign.vm4brwsr.Main</argument>
    72.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java	Fri Apr 26 15:09:59 2013 +0200
    72.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java	Mon Apr 29 16:32:14 2013 +0200
    72.3 @@ -18,6 +18,7 @@
    72.4  package org.apidesign.vm4brwsr;
    72.5  
    72.6  import java.io.BufferedWriter;
    72.7 +import java.io.File;
    72.8  import java.io.FileWriter;
    72.9  import java.io.IOException;
   72.10  import java.io.Writer;
   72.11 @@ -81,7 +82,14 @@
   72.12                  classes = classes.addAndNew(args[i]);
   72.13              }
   72.14          }
   72.15 -        try (Writer w = new BufferedWriter(new FileWriter(generateTo))) {
   72.16 +        
   72.17 +        File gt = new File(generateTo);
   72.18 +        if (Boolean.getBoolean("skip.if.exists") && gt.isFile()) {
   72.19 +            System.err.println("Skipping as " + gt + " exists.");
   72.20 +            System.exit(0);
   72.21 +        }
   72.22 +        
   72.23 +        try (Writer w = new BufferedWriter(new FileWriter(gt))) {
   72.24              Bck2Brwsr.newCompiler().
   72.25                  obfuscation(obfLevel).
   72.26                  addRootClasses(classes.toArray()).
    73.1 --- a/rt/vmtest/pom.xml	Fri Apr 26 15:09:59 2013 +0200
    73.2 +++ b/rt/vmtest/pom.xml	Mon Apr 29 16:32:14 2013 +0200
    73.3 @@ -50,18 +50,6 @@
    73.4      </dependency>
    73.5      <dependency>
    73.6        <groupId>${project.groupId}</groupId>
    73.7 -      <artifactId>vm4brwsr</artifactId>
    73.8 -      <version>${project.version}</version>
    73.9 -      <type>jar</type>
   73.10 -    </dependency>
   73.11 -    <dependency>
   73.12 -      <groupId>${project.groupId}</groupId>
   73.13 -      <artifactId>emul.mini</artifactId>
   73.14 -      <version>${project.version}</version>
   73.15 -      <scope>test</scope>
   73.16 -    </dependency>
   73.17 -    <dependency>
   73.18 -      <groupId>${project.groupId}</groupId>
   73.19        <artifactId>launcher</artifactId>
   73.20        <version>${project.version}</version>
   73.21      </dependency>
    74.1 --- a/rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/VMTest.java	Fri Apr 26 15:09:59 2013 +0200
    74.2 +++ b/rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/VMTest.java	Mon Apr 29 16:32:14 2013 +0200
    74.3 @@ -17,6 +17,9 @@
    74.4   */
    74.5  package org.apidesign.bck2brwsr.vmtest;
    74.6  
    74.7 +import java.util.ArrayList;
    74.8 +import java.util.Arrays;
    74.9 +import java.util.List;
   74.10  import org.apidesign.bck2brwsr.launcher.Launcher;
   74.11  import org.apidesign.bck2brwsr.vmtest.impl.CompareCase;
   74.12  import org.testng.annotations.Factory;
   74.13 @@ -34,6 +37,9 @@
   74.14   * @author Jaroslav Tulach <jtulach@netbeans.org>
   74.15   */
   74.16  public final class VMTest {
   74.17 +    private final List<Class> classes = new ArrayList<>();
   74.18 +    private final List<String> launcher = new ArrayList<>();
   74.19 +    
   74.20      private VMTest() {
   74.21      }
   74.22      
   74.23 @@ -47,10 +53,66 @@
   74.24       * Each {@link BrwsrTest} annotated method is executed once in {@link Launcher started
   74.25       * browser}.
   74.26       * 
   74.27 -     * @param clazz the class to inspect
   74.28 +     * @param clazz the class (or classes) to inspect
   74.29       * @return the set of created tests
   74.30       */
   74.31 -    public static Object[] create(Class<?> clazz) {
   74.32 -        return CompareCase.create(clazz);
   74.33 +    public static Object[] create(Class clazz) {
   74.34 +        return newTests().withClasses(clazz).build();
   74.35 +    }
   74.36 +    
   74.37 +    /** Creates new builder for test execution. Continue with methods
   74.38 +     * like {@link #withClasses(java.lang.Class[])} or {@link #withLaunchers(java.lang.String[])}.
   74.39 +     * Finish the process by calling {@link #build()}.
   74.40 +     * 
   74.41 +     * @return new instance of a builder
   74.42 +     * @since 0.7
   74.43 +     */
   74.44 +    public static VMTest newTests() {
   74.45 +        return new VMTest();
   74.46 +    }
   74.47 +    
   74.48 +    /** Adds class (or classes) to the test execution. The classes are inspected
   74.49 +     * to contain methods annotated by
   74.50 +     * {@link Compare} or {@link BrwsrTest}. Appropriate set of TestNG test
   74.51 +     * cases is then created.
   74.52 +     * <p>
   74.53 +     * Each {@link Compare} instance runs the test in different virtual
   74.54 +     * machine and at the end they compare the results.
   74.55 +     * <p>
   74.56 +     * Each {@link BrwsrTest} annotated method is executed once in {@link Launcher started
   74.57 +     * browser}.
   74.58 +     * 
   74.59 +     * @param classes one or more classes to inspect
   74.60 +     * @since 0.7
   74.61 +     */
   74.62 +    public final VMTest withClasses(Class... classes) {
   74.63 +        this.classes.addAll(Arrays.asList(classes));
   74.64 +        return this;
   74.65 +    }
   74.66 +
   74.67 +    /** Adds list of launchers that should be used to execute tests defined
   74.68 +     * by {@link Compare} and {@link BrwsrTest} annotations. This value 
   74.69 +     * can be overrided by using <code>vmtest.brwsrs</code> property.
   74.70 +     * List of supported launchers is available in the documentation of
   74.71 +     * {@link Launcher}.
   74.72 +     * 
   74.73 +     * @param launcher names of one or more launchers to use for the execution
   74.74 +     *   of tests
   74.75 +     * @since 0.7
   74.76 +     */
   74.77 +    public final VMTest withLaunchers(String... launcher) {
   74.78 +        this.launcher.addAll(Arrays.asList(launcher));
   74.79 +        return this;
   74.80 +    }
   74.81 +    
   74.82 +    /** Assembles the provided information into the final array of tests.
   74.83 +     * @return array of TestNG tests
   74.84 +     * @since 0.7
   74.85 +     */
   74.86 +    public final Object[] build() {
   74.87 +        return CompareCase.create(
   74.88 +            launcher.toArray(new String[0]), 
   74.89 +            classes.toArray(new Class[0])
   74.90 +        );
   74.91      }
   74.92  }
    75.1 --- a/rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java	Fri Apr 26 15:09:59 2013 +0200
    75.2 +++ b/rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java	Mon Apr 29 16:32:14 2013 +0200
    75.3 @@ -53,26 +53,25 @@
    75.4       * @param clazz the class to inspect
    75.5       * @return the set of created tests
    75.6       */
    75.7 -    public static Object[] create(Class<?> clazz) {
    75.8 -        Method[] arr = clazz.getMethods();
    75.9 +    public static Object[] create(String[] brwsr, Class[] classes) {
   75.10          List<Object> ret = new ArrayList<>();
   75.11          
   75.12          final LaunchSetup l = LaunchSetup.INSTANCE;
   75.13          ret.add(l);
   75.14          
   75.15 -        String[] brwsr;
   75.16          {
   75.17              String p = System.getProperty("vmtest.brwsrs");
   75.18              if (p != null) {
   75.19                  brwsr = p.split(",");
   75.20 -            } else {
   75.21 -                brwsr = new String[0];
   75.22              }
   75.23          }
   75.24          
   75.25 -        for (Method m : arr) {
   75.26 -            registerCompareCases(m, l, ret, brwsr);
   75.27 -            registerBrwsrCases(m, l, ret, brwsr);
   75.28 +        for (Class clazz : classes) {
   75.29 +            Method[] arr = clazz.getMethods();
   75.30 +            for (Method m : arr) {
   75.31 +                registerCompareCases(m, l, ret, brwsr);
   75.32 +                registerBrwsrCases(m, l, ret, brwsr);
   75.33 +            }
   75.34          }
   75.35          return ret.toArray();
   75.36      }
    76.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java	Fri Apr 26 15:09:59 2013 +0200
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,43 +0,0 @@
    76.4 -/**
    76.5 - * Back 2 Browser Bytecode Translator
    76.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    76.7 - *
    76.8 - * This program is free software: you can redistribute it and/or modify
    76.9 - * it under the terms of the GNU General Public License as published by
   76.10 - * the Free Software Foundation, version 2 of the License.
   76.11 - *
   76.12 - * This program is distributed in the hope that it will be useful,
   76.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   76.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   76.15 - * GNU General Public License for more details.
   76.16 - *
   76.17 - * You should have received a copy of the GNU General Public License
   76.18 - * along with this program. Look for COPYING file in the top folder.
   76.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   76.20 - */
   76.21 -package org.apidesign.bck2brwsr.tck;
   76.22 -
   76.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   76.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   76.25 -import org.testng.annotations.Factory;
   76.26 -
   76.27 -/**
   76.28 - *
   76.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   76.30 - */
   76.31 -public class AssertionTest {
   76.32 -
   76.33 -    @Compare public Object checkAssert() throws ClassNotFoundException {
   76.34 -        try {
   76.35 -            assert false : "Is assertion status on?";
   76.36 -            return null;
   76.37 -        } catch (AssertionError ex) {
   76.38 -            return ex.getClass().getName();
   76.39 -        }
   76.40 -    }
   76.41 -    
   76.42 -    @Factory
   76.43 -    public static Object[] create() {
   76.44 -        return VMTest.create(AssertionTest.class);
   76.45 -    }
   76.46 -}
    77.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/BrwsrCheckTest.java	Fri Apr 26 15:09:59 2013 +0200
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,57 +0,0 @@
    77.4 -/**
    77.5 - * Back 2 Browser Bytecode Translator
    77.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    77.7 - *
    77.8 - * This program is free software: you can redistribute it and/or modify
    77.9 - * it under the terms of the GNU General Public License as published by
   77.10 - * the Free Software Foundation, version 2 of the License.
   77.11 - *
   77.12 - * This program is distributed in the hope that it will be useful,
   77.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   77.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   77.15 - * GNU General Public License for more details.
   77.16 - *
   77.17 - * You should have received a copy of the GNU General Public License
   77.18 - * along with this program. Look for COPYING file in the top folder.
   77.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   77.20 - */
   77.21 -package org.apidesign.bck2brwsr.tck;
   77.22 -
   77.23 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   77.24 -import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   77.25 -import org.apidesign.bck2brwsr.vmtest.HtmlFragment;
   77.26 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   77.27 -import org.testng.annotations.Factory;
   77.28 -
   77.29 -/**
   77.30 - *
   77.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   77.32 - */
   77.33 -public class BrwsrCheckTest {
   77.34 -
   77.35 -    @BrwsrTest public void assertWindowObjectIsDefined() {
   77.36 -        assert window() != null : "No window object found!";
   77.37 -    }
   77.38 -
   77.39 -    
   77.40 -    
   77.41 -    
   77.42 -    @HtmlFragment("<h1 id='hello'>\n"
   77.43 -        + "Hello!\n"
   77.44 -        + "</h1>\n")
   77.45 -    @BrwsrTest public void accessProvidedFragment() {
   77.46 -        assert getElementById("hello") != null : "Element with 'hello' ID found";
   77.47 -    }
   77.48 -    
   77.49 -    @Factory
   77.50 -    public static Object[] create() {
   77.51 -        return VMTest.create(BrwsrCheckTest.class);
   77.52 -    }
   77.53 -    
   77.54 -
   77.55 -    @JavaScriptBody(args = {}, body = "return window;")
   77.56 -    private static native Object window();
   77.57 -
   77.58 -    @JavaScriptBody(args = { "id" }, body = "return window.document.getElementById(id);")
   77.59 -    private static native Object getElementById(String id);
   77.60 -}
    78.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java	Fri Apr 26 15:09:59 2013 +0200
    78.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.3 @@ -1,147 +0,0 @@
    78.4 -/**
    78.5 - * Back 2 Browser Bytecode Translator
    78.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    78.7 - *
    78.8 - * This program is free software: you can redistribute it and/or modify
    78.9 - * it under the terms of the GNU General Public License as published by
   78.10 - * the Free Software Foundation, version 2 of the License.
   78.11 - *
   78.12 - * This program is distributed in the hope that it will be useful,
   78.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   78.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   78.15 - * GNU General Public License for more details.
   78.16 - *
   78.17 - * You should have received a copy of the GNU General Public License
   78.18 - * along with this program. Look for COPYING file in the top folder.
   78.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   78.20 - */
   78.21 -package org.apidesign.bck2brwsr.tck;
   78.22 -
   78.23 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   78.24 -import org.apidesign.bck2brwsr.vmtest.Compare;
   78.25 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   78.26 -import org.testng.annotations.Factory;
   78.27 -
   78.28 -/**
   78.29 - *
   78.30 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   78.31 - */
   78.32 -public class ByteArithmeticTest {
   78.33 -    
   78.34 -    private static byte add(byte x, byte y) {
   78.35 -        return (byte)(x + y);
   78.36 -    }
   78.37 -    
   78.38 -    private static byte sub(byte x, byte y) {
   78.39 -        return (byte)(x - y);
   78.40 -    }
   78.41 -    
   78.42 -    private static byte mul(byte x, byte y) {
   78.43 -        return (byte)(x * y);
   78.44 -    }
   78.45 -    
   78.46 -    private static byte div(byte x, byte y) {
   78.47 -        return (byte)(x / y);
   78.48 -    }
   78.49 -    
   78.50 -    private static byte mod(byte x, byte y) {
   78.51 -        return (byte)(x % y);
   78.52 -    }
   78.53 -    
   78.54 -    @Compare public byte conversion() {
   78.55 -        return (byte)123456;
   78.56 -    }
   78.57 -    
   78.58 -    @Compare public byte addOverflow() {
   78.59 -        return add(Byte.MAX_VALUE, (byte)1);
   78.60 -    }
   78.61 -    
   78.62 -    @Compare public byte subUnderflow() {
   78.63 -        return sub(Byte.MIN_VALUE, (byte)1);
   78.64 -    }
   78.65 -    
   78.66 -    @Compare public byte addMaxByteAndMaxByte() {
   78.67 -        return add(Byte.MAX_VALUE, Byte.MAX_VALUE);
   78.68 -    }
   78.69 -    
   78.70 -    @Compare public byte subMinByteAndMinByte() {
   78.71 -        return sub(Byte.MIN_VALUE, Byte.MIN_VALUE);
   78.72 -    }
   78.73 -    
   78.74 -    @Compare public byte multiplyMaxByte() {
   78.75 -        return mul(Byte.MAX_VALUE, (byte)2);
   78.76 -    }
   78.77 -    
   78.78 -    @Compare public byte multiplyMaxByteAndMaxByte() {
   78.79 -        return mul(Byte.MAX_VALUE, Byte.MAX_VALUE);
   78.80 -    }
   78.81 -    
   78.82 -    @Compare public byte multiplyMinByte() {
   78.83 -        return mul(Byte.MIN_VALUE, (byte)2);
   78.84 -    }
   78.85 -    
   78.86 -    @Compare public byte multiplyMinByteAndMinByte() {
   78.87 -        return mul(Byte.MIN_VALUE, Byte.MIN_VALUE);
   78.88 -    }
   78.89 -    
   78.90 -    @Compare public byte multiplyPrecision() {
   78.91 -        return mul((byte)17638, (byte)1103);
   78.92 -    }
   78.93 -    
   78.94 -    @Compare public byte division() {
   78.95 -        return div((byte)1, (byte)2);
   78.96 -    }
   78.97 -    
   78.98 -    @Compare public byte divisionReminder() {
   78.99 -        return mod((byte)1, (byte)2);
  78.100 -    }
  78.101 -
  78.102 -    private static int readShort(byte[] byteCodes, int offset) {
  78.103 -        int signed = byteCodes[offset];
  78.104 -        byte b0 = (byte)signed;
  78.105 -        return (b0 << 8) | (byteCodes[offset + 1] & 0xff);
  78.106 -    }
  78.107 -    
  78.108 -    private static int readShortArg(byte[] byteCodes, int offsetInstruction) {
  78.109 -        return readShort(byteCodes, offsetInstruction + 1);
  78.110 -    }
  78.111 -    
  78.112 -    @Compare public int readIntArgs255and156() {
  78.113 -        final byte[] arr = new byte[] { (byte)0, (byte)255, (byte)156 };
  78.114 -        
  78.115 -        assert arr[1] == -1 : "First byte: " + arr[1];
  78.116 -        assert arr[2] == -100 : "Second byte: " + arr[2];
  78.117 -        final int ret = readShortArg(arr, 0);
  78.118 -        assert ret < 65000: "Value: " + ret;
  78.119 -        return ret;
  78.120 -    }
  78.121 -    
  78.122 -    @JavaScriptBody(args = { "arr" }, body = "arr[1] = 255; arr[2] = 156; return arr;")
  78.123 -    private static byte[] fill255and156(byte[] arr) {
  78.124 -        arr[1] = (byte)255;
  78.125 -        arr[2] = (byte)156;
  78.126 -        return arr;
  78.127 -    }
  78.128 -
  78.129 -    @Compare public int readIntArgs255and156JSArray() {
  78.130 -        final byte[] arr = fill255and156(new byte[] { 0, 0, 0 });
  78.131 -        
  78.132 -        final int ret = readShortArg(arr, 0);
  78.133 -        assert ret < 65000: "Value: " + ret;
  78.134 -        return ret;
  78.135 -    }
  78.136 -    
  78.137 -    @Compare public int readIntArgsMinus1andMinus100() {
  78.138 -        final byte[] arr = new byte[] { (byte)0, (byte)-1, (byte)-100 };
  78.139 -        
  78.140 -        assert arr[1] == -1 : "First byte: " + arr[1];
  78.141 -        assert arr[2] == -100 : "Second byte: " + arr[2];
  78.142 -        
  78.143 -        return readShortArg(arr, 0);
  78.144 -    }
  78.145 -    
  78.146 -    @Factory
  78.147 -    public static Object[] create() {
  78.148 -        return VMTest.create(ByteArithmeticTest.class);
  78.149 -    }
  78.150 -}
    79.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CloneTest.java	Fri Apr 26 15:09:59 2013 +0200
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,73 +0,0 @@
    79.4 -/**
    79.5 - * Back 2 Browser Bytecode Translator
    79.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    79.7 - *
    79.8 - * This program is free software: you can redistribute it and/or modify
    79.9 - * it under the terms of the GNU General Public License as published by
   79.10 - * the Free Software Foundation, version 2 of the License.
   79.11 - *
   79.12 - * This program is distributed in the hope that it will be useful,
   79.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   79.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   79.15 - * GNU General Public License for more details.
   79.16 - *
   79.17 - * You should have received a copy of the GNU General Public License
   79.18 - * along with this program. Look for COPYING file in the top folder.
   79.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   79.20 - */
   79.21 -package org.apidesign.bck2brwsr.tck;
   79.22 -
   79.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   79.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   79.25 -import org.testng.annotations.Factory;
   79.26 -
   79.27 -/**
   79.28 - *
   79.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   79.30 - */
   79.31 -public class CloneTest {
   79.32 -    private int value;
   79.33 -    
   79.34 -    @Compare
   79.35 -    public Object notSupported() throws CloneNotSupportedException {
   79.36 -        return this.clone();
   79.37 -    }
   79.38 -
   79.39 -    @Compare public String sameClass() throws CloneNotSupportedException {
   79.40 -        return new Clnbl().clone().getClass().getName();
   79.41 -    }
   79.42 -
   79.43 -    @Compare public boolean differentInstance() throws CloneNotSupportedException {
   79.44 -        Clnbl orig = new Clnbl();
   79.45 -        return orig == orig.clone();
   79.46 -    }
   79.47 -
   79.48 -    @Compare public int sameReference() throws CloneNotSupportedException {
   79.49 -        CloneTest self = this;
   79.50 -        Clnbl orig = new Clnbl();
   79.51 -        self.value = 33;
   79.52 -        orig.ref = self;
   79.53 -        return ((Clnbl)orig.clone()).ref.value;
   79.54 -    }
   79.55 -
   79.56 -    @Compare public int sameValue() throws CloneNotSupportedException {
   79.57 -        Clnbl orig = new Clnbl();
   79.58 -        orig.value = 10;
   79.59 -        return ((Clnbl)orig.clone()).value;
   79.60 -    }
   79.61 -    
   79.62 -    @Factory
   79.63 -    public static Object[] create() {
   79.64 -        return VMTest.create(CloneTest.class);
   79.65 -    }
   79.66 -    
   79.67 -    public static final class Clnbl implements Cloneable {
   79.68 -        public CloneTest ref;
   79.69 -        private int value;
   79.70 -
   79.71 -        @Override
   79.72 -        public Object clone() throws CloneNotSupportedException {
   79.73 -            return super.clone();
   79.74 -        }
   79.75 -    }
   79.76 -}
    80.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Fri Apr 26 15:09:59 2013 +0200
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,103 +0,0 @@
    80.4 -/**
    80.5 - * Back 2 Browser Bytecode Translator
    80.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    80.7 - *
    80.8 - * This program is free software: you can redistribute it and/or modify
    80.9 - * it under the terms of the GNU General Public License as published by
   80.10 - * the Free Software Foundation, version 2 of the License.
   80.11 - *
   80.12 - * This program is distributed in the hope that it will be useful,
   80.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   80.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   80.15 - * GNU General Public License for more details.
   80.16 - *
   80.17 - * You should have received a copy of the GNU General Public License
   80.18 - * along with this program. Look for COPYING file in the top folder.
   80.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   80.20 - */
   80.21 -package org.apidesign.bck2brwsr.tck;
   80.22 -
   80.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   80.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   80.25 -import org.testng.annotations.Factory;
   80.26 -
   80.27 -/**
   80.28 - *
   80.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   80.30 - */
   80.31 -public class CompareByteArrayTest {
   80.32 -    @Compare public int byteArraySum() {
   80.33 -        byte[] arr = createArray();
   80.34 -        return sumByteArr(arr);
   80.35 -    }
   80.36 -    
   80.37 -    @Compare public int countZeros() {
   80.38 -        int zeros = 0;
   80.39 -        for (Byte b : createArray()) {
   80.40 -            if (b == 0) {
   80.41 -                zeros++;
   80.42 -            }
   80.43 -        }
   80.44 -        return zeros;
   80.45 -    }
   80.46 -    
   80.47 -    private static int sumByteArr(byte[] arr) {
   80.48 -        int sum = 0;
   80.49 -        for (int i = 0; i < arr.length; i++) {
   80.50 -            sum += arr[i];
   80.51 -        }
   80.52 -        return sum;
   80.53 -    }
   80.54 -    
   80.55 -    @Compare public String noOutOfBounds() {
   80.56 -        return atIndex(1);
   80.57 -    }
   80.58 -
   80.59 -    @Compare public String outOfBounds() {
   80.60 -        return atIndex(5);
   80.61 -    }
   80.62 -
   80.63 -    @Compare public String outOfBoundsMinus() {
   80.64 -        return atIndex(-1);
   80.65 -    }
   80.66 -
   80.67 -    @Compare public String toOfBounds() {
   80.68 -        return toIndex(5);
   80.69 -    }
   80.70 -
   80.71 -    @Compare public String toOfBoundsMinus() {
   80.72 -        return toIndex(-1);
   80.73 -    }
   80.74 -    
   80.75 -    @Compare public int multiArrayLength() {
   80.76 -         int[][] arr = new int[1][0];
   80.77 -         return arr[0].length;
   80.78 -    }
   80.79 -
   80.80 -    @Compare public int multiObjectArrayLength() {
   80.81 -         Object[][] arr = new Object[1][0];
   80.82 -         return arr[0].length;
   80.83 -    }
   80.84 -
   80.85 -    private static final int[] arr = { 0, 1, 2 };
   80.86 -    public static String atIndex(int at) {
   80.87 -        return "at@" + arr[at];
   80.88 -    }
   80.89 -    public static String toIndex(int at) {
   80.90 -        arr[at] = 10;
   80.91 -        return "ok";
   80.92 -    }
   80.93 -    
   80.94 -    
   80.95 -    @Factory
   80.96 -    public static Object[] create() {
   80.97 -        return VMTest.create(CompareByteArrayTest.class);
   80.98 -    }
   80.99 -
  80.100 -    private byte[] createArray() {
  80.101 -        byte[] arr = new byte[10];
  80.102 -        arr[5] = 3;
  80.103 -        arr[7] = 8;
  80.104 -        return arr;
  80.105 -    }
  80.106 -}
    81.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Fri Apr 26 15:09:59 2013 +0200
    81.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.3 @@ -1,50 +0,0 @@
    81.4 -/**
    81.5 - * Back 2 Browser Bytecode Translator
    81.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    81.7 - *
    81.8 - * This program is free software: you can redistribute it and/or modify
    81.9 - * it under the terms of the GNU General Public License as published by
   81.10 - * the Free Software Foundation, version 2 of the License.
   81.11 - *
   81.12 - * This program is distributed in the hope that it will be useful,
   81.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   81.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   81.15 - * GNU General Public License for more details.
   81.16 - *
   81.17 - * You should have received a copy of the GNU General Public License
   81.18 - * along with this program. Look for COPYING file in the top folder.
   81.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   81.20 - */
   81.21 -package org.apidesign.bck2brwsr.tck;
   81.22 -
   81.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   81.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   81.25 -import org.testng.annotations.Factory;
   81.26 -
   81.27 -/**
   81.28 - *
   81.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   81.30 - */
   81.31 -public class CompareHashTest {
   81.32 -    @Compare public int hashOfString() {
   81.33 -        return "Ahoj".hashCode();
   81.34 -    }
   81.35 -    
   81.36 -    @Compare public int hashRemainsYieldsZero() {
   81.37 -        Object o = new Object();
   81.38 -        return o.hashCode() - o.hashCode();
   81.39 -    }
   81.40 -    
   81.41 -    @Compare public int initializeInStatic() {
   81.42 -        return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
   81.43 -    }
   81.44 -    
   81.45 -    @Compare public int hashOfInt() {
   81.46 -        return Integer.valueOf(Integer.MAX_VALUE).hashCode();
   81.47 -    }
   81.48 -    
   81.49 -    @Factory
   81.50 -    public static Object[] create() {
   81.51 -        return VMTest.create(CompareHashTest.class);
   81.52 -    }
   81.53 -}
    82.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareIntArrayTest.java	Fri Apr 26 15:09:59 2013 +0200
    82.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.3 @@ -1,63 +0,0 @@
    82.4 -/**
    82.5 - * Back 2 Browser Bytecode Translator
    82.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    82.7 - *
    82.8 - * This program is free software: you can redistribute it and/or modify
    82.9 - * it under the terms of the GNU General Public License as published by
   82.10 - * the Free Software Foundation, version 2 of the License.
   82.11 - *
   82.12 - * This program is distributed in the hope that it will be useful,
   82.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   82.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   82.15 - * GNU General Public License for more details.
   82.16 - *
   82.17 - * You should have received a copy of the GNU General Public License
   82.18 - * along with this program. Look for COPYING file in the top folder.
   82.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   82.20 - */
   82.21 -package org.apidesign.bck2brwsr.tck;
   82.22 -
   82.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   82.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   82.25 -import org.testng.annotations.Factory;
   82.26 -
   82.27 -/**
   82.28 - *
   82.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   82.30 - */
   82.31 -public class CompareIntArrayTest {
   82.32 -    @Compare public int integerArraySum() {
   82.33 -        int[] arr = createArray();
   82.34 -        return sumIntArr(arr);
   82.35 -    }
   82.36 -    
   82.37 -    @Compare public int countZeros() {
   82.38 -        int zeros = 0;
   82.39 -        for (Integer i : createArray()) {
   82.40 -            if (i == 0) {
   82.41 -                zeros++;
   82.42 -            }
   82.43 -        }
   82.44 -        return zeros;
   82.45 -    }
   82.46 -    
   82.47 -    private static int sumIntArr(int[] arr) {
   82.48 -        int sum = 0;
   82.49 -        for (int i = 0; i < arr.length; i++) {
   82.50 -            sum += arr[i];
   82.51 -        }
   82.52 -        return sum;
   82.53 -    }
   82.54 -    
   82.55 -    @Factory
   82.56 -    public static Object[] create() {
   82.57 -        return VMTest.create(CompareIntArrayTest.class);
   82.58 -    }
   82.59 -
   82.60 -    private int[] createArray() {
   82.61 -        int[] arr = new int[10];
   82.62 -        arr[5] = 3;
   82.63 -        arr[7] = 8;
   82.64 -        return arr;
   82.65 -    }
   82.66 -}
    83.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Fri Apr 26 15:09:59 2013 +0200
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,174 +0,0 @@
    83.4 -/**
    83.5 - * Back 2 Browser Bytecode Translator
    83.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    83.7 - *
    83.8 - * This program is free software: you can redistribute it and/or modify
    83.9 - * it under the terms of the GNU General Public License as published by
   83.10 - * the Free Software Foundation, version 2 of the License.
   83.11 - *
   83.12 - * This program is distributed in the hope that it will be useful,
   83.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   83.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   83.15 - * GNU General Public License for more details.
   83.16 - *
   83.17 - * You should have received a copy of the GNU General Public License
   83.18 - * along with this program. Look for COPYING file in the top folder.
   83.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   83.20 - */
   83.21 -package org.apidesign.bck2brwsr.tck;
   83.22 -
   83.23 -import java.io.UnsupportedEncodingException;
   83.24 -import java.net.MalformedURLException;
   83.25 -import java.net.URL;
   83.26 -import org.apidesign.bck2brwsr.vmtest.Compare;
   83.27 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   83.28 -import org.testng.annotations.Factory;
   83.29 -
   83.30 -/**
   83.31 - *
   83.32 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   83.33 - */
   83.34 -public class CompareStringsTest {
   83.35 -    @Compare public String firstChar() {
   83.36 -        return "" + ("Hello".toCharArray()[0]);
   83.37 -    }
   83.38 -    
   83.39 -    @Compare public String classCast() {
   83.40 -        Object o = firstChar();
   83.41 -        return String.class.cast(o);
   83.42 -    }
   83.43 -
   83.44 -    @Compare public String classCastThrown() {
   83.45 -        Object o = null;
   83.46 -        return String.class.cast(o);
   83.47 -    }
   83.48 -    
   83.49 -    @Compare public boolean equalToNull() {
   83.50 -        return "Ahoj".equals(null);
   83.51 -    }
   83.52 -    
   83.53 -    @Compare public int highByteLenght() {
   83.54 -        byte[] arr= { 77,97,110,105,102,101,115,116,45,86,101,114,115,105,111,110 };
   83.55 -        return new String(arr, 0).length();
   83.56 -    }
   83.57 -    
   83.58 -    @Compare public String highByte() {
   83.59 -        byte[] arr= { 77,97,110,105,102,101,115,116,45,86,101,114,115,105,111,110 };
   83.60 -        StringBuilder sb = new StringBuilder();
   83.61 -        sb.append("pref:");
   83.62 -        sb.append(new String(arr, 0));
   83.63 -        return sb.toString();
   83.64 -    }
   83.65 -    
   83.66 -    @Compare public static Object compareURLs() throws MalformedURLException {
   83.67 -        return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
   83.68 -    }
   83.69 -    
   83.70 -    @Compare public String deleteLastTwoCharacters() {
   83.71 -        StringBuilder sb = new StringBuilder();
   83.72 -        sb.append("453.0");
   83.73 -        if (sb.toString().endsWith(".0")) {
   83.74 -            final int l = sb.length();
   83.75 -            sb.delete(l - 2, l);
   83.76 -        }
   83.77 -        return sb.toString().toString();
   83.78 -    }
   83.79 -    
   83.80 -    @Compare public String nameOfStringClass() throws Exception {
   83.81 -        return Class.forName("java.lang.String").getName();
   83.82 -    }
   83.83 -    @Compare public String nameOfArrayClass() throws Exception {
   83.84 -        return Class.forName("org.apidesign.bck2brwsr.tck.CompareHashTest").getName();
   83.85 -    }
   83.86 -    
   83.87 -    @Compare public String lowerHello() {
   83.88 -        return "HeLlO".toLowerCase();
   83.89 -    }
   83.90 -    
   83.91 -    @Compare public String lowerA() {
   83.92 -        return String.valueOf(Character.toLowerCase('A')).toString();
   83.93 -    }
   83.94 -    @Compare public String upperHello() {
   83.95 -        return "hello".toUpperCase();
   83.96 -    }
   83.97 -    
   83.98 -    @Compare public String upperA() {
   83.99 -        return String.valueOf(Character.toUpperCase('a')).toString();
  83.100 -    }
  83.101 -    
  83.102 -    @Compare public boolean matchRegExp() throws Exception {
  83.103 -        return "58038503".matches("\\d*");
  83.104 -    }
  83.105 -
  83.106 -    @Compare public boolean doesNotMatchRegExp() throws Exception {
  83.107 -        return "58038503GH".matches("\\d*");
  83.108 -    }
  83.109 -
  83.110 -    @Compare public boolean doesNotMatchRegExpFully() throws Exception {
  83.111 -        return "Hello".matches("Hell");
  83.112 -    }
  83.113 -    
  83.114 -    @Compare public String emptyCharArray() {
  83.115 -        char[] arr = new char[10];
  83.116 -        return new String(arr);
  83.117 -    }
  83.118 -    
  83.119 -    @Compare public String variousCharacterTests() throws Exception {
  83.120 -        StringBuilder sb = new StringBuilder();
  83.121 -        
  83.122 -        sb.append(Character.isUpperCase('a'));
  83.123 -        sb.append(Character.isUpperCase('A'));
  83.124 -        sb.append(Character.isLowerCase('a'));
  83.125 -        sb.append(Character.isLowerCase('A'));
  83.126 -        
  83.127 -        sb.append(Character.isLetter('A'));
  83.128 -        sb.append(Character.isLetterOrDigit('9'));
  83.129 -        sb.append(Character.isLetterOrDigit('A'));
  83.130 -        sb.append(Character.isLetter('0'));
  83.131 -        
  83.132 -        return sb.toString().toString();
  83.133 -    }
  83.134 -        
  83.135 -    @Compare
  83.136 -    public String nullFieldInitialized() {
  83.137 -        NullField nf = new NullField();
  83.138 -        return ("" + nf.name).toString();
  83.139 -    }
  83.140 -    @Compare
  83.141 -    public String toUTFString() throws UnsupportedEncodingException {
  83.142 -        byte[] arr = {
  83.143 -            (byte) -59, (byte) -67, (byte) 108, (byte) 117, (byte) -59, (byte) -91,
  83.144 -            (byte) 111, (byte) 117, (byte) -60, (byte) -115, (byte) 107, (byte) -61,
  83.145 -            (byte) -67, (byte) 32, (byte) 107, (byte) -59, (byte) -81, (byte) -59,
  83.146 -            (byte) -120
  83.147 -        };
  83.148 -        return new String(arr, "utf-8");
  83.149 -    }
  83.150 -
  83.151 -    @Compare
  83.152 -    public int stringToBytesLenght() throws UnsupportedEncodingException {
  83.153 -        return "\u017dlu\u0165ou\u010dk\u00fd k\u016f\u0148".getBytes("utf8").length;
  83.154 -    }
  83.155 -    
  83.156 -    @Compare public String replaceSeq() {
  83.157 -        return "Hello World.".replace(".", "!");
  83.158 -    }
  83.159 -    @Compare public String replaceSeqAll() {
  83.160 -        return "Hello World! Hello World.".replace("World", "Jarda");
  83.161 -    }
  83.162 -    @Compare public String replaceSeqAA() {
  83.163 -        String res = "aaa".replace("aa", "b");
  83.164 -        assert res.equals("ba") : "Expecting ba: " + res;
  83.165 -        return res;
  83.166 -    }
  83.167 -
  83.168 -    @Factory
  83.169 -    public static Object[] create() {
  83.170 -        return VMTest.create(CompareStringsTest.class);
  83.171 -    }
  83.172 -
  83.173 -    private static final class NullField {
  83.174 -
  83.175 -        String name;
  83.176 -    }
  83.177 -}
    84.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/DoubleTest.java	Fri Apr 26 15:09:59 2013 +0200
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,65 +0,0 @@
    84.4 -/**
    84.5 - * Back 2 Browser Bytecode Translator
    84.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    84.7 - *
    84.8 - * This program is free software: you can redistribute it and/or modify
    84.9 - * it under the terms of the GNU General Public License as published by
   84.10 - * the Free Software Foundation, version 2 of the License.
   84.11 - *
   84.12 - * This program is distributed in the hope that it will be useful,
   84.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   84.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   84.15 - * GNU General Public License for more details.
   84.16 - *
   84.17 - * You should have received a copy of the GNU General Public License
   84.18 - * along with this program. Look for COPYING file in the top folder.
   84.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   84.20 - */
   84.21 -package org.apidesign.bck2brwsr.tck;
   84.22 -
   84.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   84.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   84.25 -import org.testng.annotations.Factory;
   84.26 -
   84.27 -/**
   84.28 - *
   84.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   84.30 - */
   84.31 -public class DoubleTest {
   84.32 -    @Compare public String integerToString() {
   84.33 -        return toStr(1);
   84.34 -    }
   84.35 -
   84.36 -    @Compare public String integerAndHalfToString() {
   84.37 -        return toStr(1.5);
   84.38 -    }
   84.39 -
   84.40 -    @Compare public double longToAndBack() {
   84.41 -        return Double.parseDouble(toStr(Long.MAX_VALUE / 10));
   84.42 -    }
   84.43 -
   84.44 -    @Compare public String negativeIntToString() {
   84.45 -        return toStr(-10);
   84.46 -    }
   84.47 -
   84.48 -    @Compare public String negativeIntAndHalfToString() {
   84.49 -        return toStr(-10.5);
   84.50 -    }
   84.51 -
   84.52 -    @Compare public double negativeLongAndBack() {
   84.53 -        return Double.parseDouble(toStr(Long.MIN_VALUE / 10));
   84.54 -    }
   84.55 -    
   84.56 -    @Compare public double canParseExp() {
   84.57 -        return Double.parseDouble(toStr(1.7976931348623157e+308));
   84.58 -    }
   84.59 -    
   84.60 -    private static String toStr(double d) {
   84.61 -        return Double.toString(d);
   84.62 -    }
   84.63 -    
   84.64 -    @Factory 
   84.65 -    public static Object[] create() {
   84.66 -        return VMTest.create(DoubleTest.class);
   84.67 -    }
   84.68 -}
    85.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java	Fri Apr 26 15:09:59 2013 +0200
    85.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.3 @@ -1,106 +0,0 @@
    85.4 -/**
    85.5 - * Back 2 Browser Bytecode Translator
    85.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    85.7 - *
    85.8 - * This program is free software: you can redistribute it and/or modify
    85.9 - * it under the terms of the GNU General Public License as published by
   85.10 - * the Free Software Foundation, version 2 of the License.
   85.11 - *
   85.12 - * This program is distributed in the hope that it will be useful,
   85.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   85.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   85.15 - * GNU General Public License for more details.
   85.16 - *
   85.17 - * You should have received a copy of the GNU General Public License
   85.18 - * along with this program. Look for COPYING file in the top folder.
   85.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   85.20 - */
   85.21 -package org.apidesign.bck2brwsr.tck;
   85.22 -
   85.23 -import java.io.InputStream;
   85.24 -import java.net.URL;
   85.25 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   85.26 -import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   85.27 -import org.apidesign.bck2brwsr.vmtest.Http;
   85.28 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   85.29 -import org.testng.annotations.Factory;
   85.30 -
   85.31 -/**
   85.32 - *
   85.33 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   85.34 - */
   85.35 -public class HttpResourceTest {
   85.36 -    
   85.37 -    @Http({
   85.38 -        @Http.Resource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain")
   85.39 -    })
   85.40 -    @BrwsrTest
   85.41 -    
   85.42 -    
   85.43 -    public String testReadContentViaXHR() throws Exception {
   85.44 -        String msg = read("/xhr");
   85.45 -        assert "Hello Brwsr!".equals(msg) : "The message was " + msg;
   85.46 -        return msg;
   85.47 -    }
   85.48 -
   85.49 -    @Http({
   85.50 -        @Http.Resource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
   85.51 -    })
   85.52 -    @BrwsrTest
   85.53 -    public String testReadContentViaURL() throws Exception {
   85.54 -        URL url = new URL("http:/url");
   85.55 -        String msg = (String) url.getContent();
   85.56 -        assert "Hello via URL!".equals(msg) : "The message was " + msg;
   85.57 -        return msg;
   85.58 -    }
   85.59 -    @Http({
   85.60 -        @Http.Resource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
   85.61 -    })
   85.62 -    @BrwsrTest
   85.63 -    public String testReadContentViaURLWithStringParam() throws Exception {
   85.64 -        URL url = new URL("http:/url");
   85.65 -        String msg = (String) url.getContent(new Class[] { String.class });
   85.66 -        assert "Hello via URL!".equals(msg) : "The message was " + msg;
   85.67 -        return msg;
   85.68 -    }
   85.69 -
   85.70 -    @Http({
   85.71 -        @Http.Resource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
   85.72 -    })
   85.73 -    @BrwsrTest
   85.74 -    public void testReadByte() throws Exception {
   85.75 -        URL url = new URL("http:/bytes");
   85.76 -        final Object res = url.getContent(new Class[] { byte[].class });
   85.77 -        assert res instanceof byte[] : "Expecting byte[]: " + res;
   85.78 -        byte[] arr = (byte[]) res;
   85.79 -        assert arr.length == 1 : "One byte " + arr.length;
   85.80 -        assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
   85.81 -    }
   85.82 -
   85.83 -    @Http({
   85.84 -        @Http.Resource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
   85.85 -    })
   85.86 -    @BrwsrTest
   85.87 -    public void testReadByteViaInputStream() throws Exception {
   85.88 -        URL url = new URL("http:/bytes");
   85.89 -        InputStream is = url.openStream();
   85.90 -        byte[] arr = new byte[10];
   85.91 -        int len = is.read(arr);
   85.92 -        assert len == 1 : "One byte " + len;
   85.93 -        assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
   85.94 -    }
   85.95 -    
   85.96 -    @JavaScriptBody(args = { "url" }, body = 
   85.97 -          "var req = new XMLHttpRequest();\n"
   85.98 -        + "req.open('GET', url, false);\n"
   85.99 -        + "req.send();\n"
  85.100 -        + "return req.responseText;"
  85.101 -    )
  85.102 -    private static native String read(String url);
  85.103 -    
  85.104 -    
  85.105 -    @Factory
  85.106 -    public static Object[] create() {
  85.107 -        return VMTest.create(HttpResourceTest.class);
  85.108 -    }
  85.109 -}
    86.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceA.java	Fri Apr 26 15:09:59 2013 +0200
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,34 +0,0 @@
    86.4 -/**
    86.5 - * Back 2 Browser Bytecode Translator
    86.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    86.7 - *
    86.8 - * This program is free software: you can redistribute it and/or modify
    86.9 - * it under the terms of the GNU General Public License as published by
   86.10 - * the Free Software Foundation, version 2 of the License.
   86.11 - *
   86.12 - * This program is distributed in the hope that it will be useful,
   86.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   86.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   86.15 - * GNU General Public License for more details.
   86.16 - *
   86.17 - * You should have received a copy of the GNU General Public License
   86.18 - * along with this program. Look for COPYING file in the top folder.
   86.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   86.20 - */
   86.21 -package org.apidesign.bck2brwsr.tck;
   86.22 -
   86.23 -/**
   86.24 - *
   86.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   86.26 - */
   86.27 -public class InheritanceA {
   86.28 -    private String name;
   86.29 -    
   86.30 -    public void setA(String n) {
   86.31 -        this.name = n;
   86.32 -    }
   86.33 -    
   86.34 -    public String getA() {
   86.35 -        return name;
   86.36 -    }
   86.37 -}
    87.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceB.java	Fri Apr 26 15:09:59 2013 +0200
    87.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.3 @@ -1,34 +0,0 @@
    87.4 -/**
    87.5 - * Back 2 Browser Bytecode Translator
    87.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    87.7 - *
    87.8 - * This program is free software: you can redistribute it and/or modify
    87.9 - * it under the terms of the GNU General Public License as published by
   87.10 - * the Free Software Foundation, version 2 of the License.
   87.11 - *
   87.12 - * This program is distributed in the hope that it will be useful,
   87.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   87.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   87.15 - * GNU General Public License for more details.
   87.16 - *
   87.17 - * You should have received a copy of the GNU General Public License
   87.18 - * along with this program. Look for COPYING file in the top folder.
   87.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   87.20 - */
   87.21 -package org.apidesign.bck2brwsr.tck;
   87.22 -
   87.23 -/**
   87.24 - *
   87.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   87.26 - */
   87.27 -public class InheritanceB extends InheritanceA {
   87.28 -    private String name;
   87.29 -    
   87.30 -    public void setB(String n) {
   87.31 -        this.name = n;
   87.32 -    }
   87.33 -    
   87.34 -    public String getB() {
   87.35 -        return name;
   87.36 -    }
   87.37 -}
    88.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/InheritanceTest.java	Fri Apr 26 15:09:59 2013 +0200
    88.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.3 @@ -1,41 +0,0 @@
    88.4 -/**
    88.5 - * Back 2 Browser Bytecode Translator
    88.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    88.7 - *
    88.8 - * This program is free software: you can redistribute it and/or modify
    88.9 - * it under the terms of the GNU General Public License as published by
   88.10 - * the Free Software Foundation, version 2 of the License.
   88.11 - *
   88.12 - * This program is distributed in the hope that it will be useful,
   88.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   88.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   88.15 - * GNU General Public License for more details.
   88.16 - *
   88.17 - * You should have received a copy of the GNU General Public License
   88.18 - * along with this program. Look for COPYING file in the top folder.
   88.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   88.20 - */
   88.21 -package org.apidesign.bck2brwsr.tck;
   88.22 -
   88.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   88.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   88.25 -import org.testng.annotations.Factory;
   88.26 -
   88.27 -/**
   88.28 - *
   88.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   88.30 - */
   88.31 -public class InheritanceTest {
   88.32 -
   88.33 -    @Compare public String checkFieldsIndependent() throws ClassNotFoundException {
   88.34 -        InheritanceB ib = new InheritanceB();
   88.35 -        ib.setA("A");
   88.36 -        ib.setB("B");
   88.37 -        return "A: " + ib.getA() + " B: " + ib.getB();
   88.38 -    }
   88.39 -    
   88.40 -    @Factory
   88.41 -    public static Object[] create() {
   88.42 -        return VMTest.create(InheritanceTest.class);
   88.43 -    }
   88.44 -}
    89.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java	Fri Apr 26 15:09:59 2013 +0200
    89.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.3 @@ -1,166 +0,0 @@
    89.4 -/**
    89.5 - * Back 2 Browser Bytecode Translator
    89.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    89.7 - *
    89.8 - * This program is free software: you can redistribute it and/or modify
    89.9 - * it under the terms of the GNU General Public License as published by
   89.10 - * the Free Software Foundation, version 2 of the License.
   89.11 - *
   89.12 - * This program is distributed in the hope that it will be useful,
   89.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   89.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   89.15 - * GNU General Public License for more details.
   89.16 - *
   89.17 - * You should have received a copy of the GNU General Public License
   89.18 - * along with this program. Look for COPYING file in the top folder.
   89.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   89.20 - */
   89.21 -package org.apidesign.bck2brwsr.tck;
   89.22 -
   89.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   89.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   89.25 -import org.testng.annotations.Factory;
   89.26 -
   89.27 -/**
   89.28 - *
   89.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   89.30 - */
   89.31 -public class IntegerArithmeticTest {
   89.32 -    
   89.33 -    private static int add(int x, int y) {
   89.34 -        return x + y;
   89.35 -    }
   89.36 -    
   89.37 -    private static int sub(int x, int y) {
   89.38 -        return x - y;
   89.39 -    }
   89.40 -    
   89.41 -    private static int mul(int x, int y) {
   89.42 -        return x * y;
   89.43 -    }
   89.44 -    
   89.45 -    private static int div(int x, int y) {
   89.46 -        return x / y;
   89.47 -    }
   89.48 -    
   89.49 -    private static int mod(int x, int y) {
   89.50 -        return x % y;
   89.51 -    }
   89.52 -    
   89.53 -    private static int neg(int x) {
   89.54 -        return (-x);
   89.55 -    }
   89.56 -
   89.57 -    private static float fadd(float x, float y) {
   89.58 -        return x + y;
   89.59 -    }
   89.60 -
   89.61 -    private static double dadd(double x, double y) {
   89.62 -        return x + y;
   89.63 -    }
   89.64 -    
   89.65 -    @Compare public int addOverflow() {
   89.66 -        return add(Integer.MAX_VALUE, 1);
   89.67 -    }
   89.68 -    
   89.69 -    @Compare public int subUnderflow() {
   89.70 -        return sub(Integer.MIN_VALUE, 1);
   89.71 -    }
   89.72 -    
   89.73 -    @Compare public int addMaxIntAndMaxInt() {
   89.74 -        return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
   89.75 -    }
   89.76 -    
   89.77 -    @Compare public int subMinIntAndMinInt() {
   89.78 -        return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
   89.79 -    }
   89.80 -    
   89.81 -    @Compare public int multiplyMaxInt() {
   89.82 -        return mul(Integer.MAX_VALUE, 2);
   89.83 -    }
   89.84 -    
   89.85 -    @Compare public int multiplyMaxIntAndMaxInt() {
   89.86 -        return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
   89.87 -    }
   89.88 -    
   89.89 -    @Compare public int multiplyMinInt() {
   89.90 -        return mul(Integer.MIN_VALUE, 2);
   89.91 -    }
   89.92 -    
   89.93 -    @Compare public int multiplyMinIntAndMinInt() {
   89.94 -        return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
   89.95 -    }
   89.96 -    
   89.97 -    @Compare public int multiplyPrecision() {
   89.98 -        return mul(119106029, 1103515245);
   89.99 -    }
  89.100 -    
  89.101 -    @Compare public int division() {
  89.102 -        return div(1, 2);
  89.103 -    }
  89.104 -
  89.105 -    @Compare public int divisionReminder() {
  89.106 -        return mod(1, 2);
  89.107 -    }
  89.108 -
  89.109 -    @Compare public int negativeDivision() {
  89.110 -        return div(-7, 3);
  89.111 -    }
  89.112 -
  89.113 -    @Compare public int negativeDivisionReminder() {
  89.114 -        return mod(-7, 3);
  89.115 -    }
  89.116 -
  89.117 -    @Compare public int conversionFromFloat() {
  89.118 -        return (int) fadd(-2, -0.6f);
  89.119 -    }
  89.120 -
  89.121 -    @Compare public int conversionFromDouble() {
  89.122 -        return (int) dadd(-2, -0.6);
  89.123 -    }
  89.124 -
  89.125 -    @Compare public boolean divByZeroThrowsArithmeticException() {
  89.126 -        try {
  89.127 -            div(1, 0);
  89.128 -            return false;
  89.129 -        } catch (final ArithmeticException e) {
  89.130 -            return true;
  89.131 -        }
  89.132 -    }
  89.133 -
  89.134 -    @Compare public boolean modByZeroThrowsArithmeticException() {
  89.135 -        try {
  89.136 -            mod(1, 0);
  89.137 -            return false;
  89.138 -        } catch (final ArithmeticException e) {
  89.139 -            return true;
  89.140 -        }
  89.141 -    }
  89.142 -
  89.143 -    @Compare public int negate() {
  89.144 -        return neg(123456);
  89.145 -    }
  89.146 -    
  89.147 -    @Compare public int negateMaxInt() {
  89.148 -        return neg(Integer.MAX_VALUE);
  89.149 -    }
  89.150 -    
  89.151 -    @Compare public int negateMinInt() {
  89.152 -        return neg(Integer.MIN_VALUE);
  89.153 -    }
  89.154 -    
  89.155 -    @Compare public int sumTwoDimensions() {
  89.156 -        int[][] matrix = createMatrix(4, 3);
  89.157 -        matrix[0][0] += 10;
  89.158 -        return matrix[0][0];
  89.159 -    }
  89.160 -    
  89.161 -    static int[][] createMatrix(int x, int y) {
  89.162 -        return new int[x][y];
  89.163 -    }
  89.164 -    
  89.165 -    @Factory
  89.166 -    public static Object[] create() {
  89.167 -        return VMTest.create(IntegerArithmeticTest.class);
  89.168 -    }
  89.169 -}
    90.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java	Fri Apr 26 15:09:59 2013 +0200
    90.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.3 @@ -1,376 +0,0 @@
    90.4 -/**
    90.5 - * Back 2 Browser Bytecode Translator
    90.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    90.7 - *
    90.8 - * This program is free software: you can redistribute it and/or modify
    90.9 - * it under the terms of the GNU General Public License as published by
   90.10 - * the Free Software Foundation, version 2 of the License.
   90.11 - *
   90.12 - * This program is distributed in the hope that it will be useful,
   90.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   90.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   90.15 - * GNU General Public License for more details.
   90.16 - *
   90.17 - * You should have received a copy of the GNU General Public License
   90.18 - * along with this program. Look for COPYING file in the top folder.
   90.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   90.20 - */
   90.21 -package org.apidesign.bck2brwsr.tck;
   90.22 -
   90.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   90.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   90.25 -import org.testng.annotations.Factory;
   90.26 -
   90.27 -/**
   90.28 - *
   90.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   90.30 - */
   90.31 -public class LongArithmeticTest {
   90.32 -
   90.33 -    private static long add(long x, long y) {
   90.34 -        return (x + y);
   90.35 -    }
   90.36 -
   90.37 -    private static long sub(long x, long y) {
   90.38 -        return (x - y);
   90.39 -    }
   90.40 -
   90.41 -    private static long mul(long x, long y) {
   90.42 -        return (x * y);
   90.43 -    }
   90.44 -
   90.45 -    private static long div(long x, long y) {
   90.46 -        return (x / y);
   90.47 -    }
   90.48 -
   90.49 -    private static long mod(long x, long y) {
   90.50 -        return (x % y);
   90.51 -    }
   90.52 -
   90.53 -    private static long neg(long x) {
   90.54 -        return (-x);
   90.55 -    }
   90.56 -
   90.57 -    private static long shl(long x, int b) {
   90.58 -        return (x << b);
   90.59 -    }
   90.60 -
   90.61 -    private static long shr(long x, int b) {
   90.62 -        return (x >> b);
   90.63 -    }
   90.64 -
   90.65 -    private static long ushr(long x, int b) {
   90.66 -        return (x >>> b);
   90.67 -    }
   90.68 -
   90.69 -    private static long and(long x, long y) {
   90.70 -        return (x & y);
   90.71 -    }
   90.72 -
   90.73 -    private static long or(long x, long y) {
   90.74 -        return (x | y);
   90.75 -    }
   90.76 -
   90.77 -    private static long xor(long x, long y) {
   90.78 -        return (x ^ y);
   90.79 -    }
   90.80 -
   90.81 -    private static float fadd(float x, float y) {
   90.82 -        return x + y;
   90.83 -    }
   90.84 -
   90.85 -    private static double dadd(double x, double y) {
   90.86 -        return x + y;
   90.87 -    }
   90.88 -
   90.89 -    public static int compare(long x, long y, int zero) {
   90.90 -        final int xyResult = compareL(x, y, zero);
   90.91 -        final int yxResult = compareL(y, x, zero);
   90.92 -
   90.93 -        return ((xyResult + yxResult) == 0) ? xyResult : -2;
   90.94 -    }
   90.95 -
   90.96 -    private static int compareL(long x, long y, int zero) {
   90.97 -        int result = -2;
   90.98 -        int trueCount = 0;
   90.99 -
  90.100 -        x += zero;
  90.101 -        if (x == y) {
  90.102 -            result = 0;
  90.103 -            ++trueCount;
  90.104 -        }
  90.105 -
  90.106 -        x += zero;
  90.107 -        if (x < y) {
  90.108 -            result = -1;
  90.109 -            ++trueCount;
  90.110 -        }
  90.111 -
  90.112 -        x += zero;
  90.113 -        if (x > y) {
  90.114 -            result = 1;
  90.115 -            ++trueCount;
  90.116 -        }
  90.117 -
  90.118 -        return (trueCount == 1) ? result : -2;
  90.119 -    }
  90.120 -
  90.121 -    @Compare public long conversion() {
  90.122 -        return Long.MAX_VALUE;
  90.123 -    }
  90.124 -
  90.125 -    @Compare public long negate1() {
  90.126 -        return neg(0x00fa37d7763e0ca1l);
  90.127 -    }
  90.128 -
  90.129 -    @Compare public long negate2() {
  90.130 -        return neg(0x80fa37d7763e0ca1l);
  90.131 -    }
  90.132 -
  90.133 -    @Compare public long negate3() {
  90.134 -        return neg(0xfffffffffffffeddl);
  90.135 -    }
  90.136 -
  90.137 -    @Compare public long addOverflow() {
  90.138 -        return add(Long.MAX_VALUE, 1l);
  90.139 -    }
  90.140 -
  90.141 -    @Compare public long subUnderflow() {
  90.142 -        return sub(Long.MIN_VALUE, 1l);
  90.143 -    }
  90.144 -
  90.145 -    @Compare public long addMaxLongAndMaxLong() {
  90.146 -        return add(Long.MAX_VALUE, Long.MAX_VALUE);
  90.147 -    }
  90.148 -
  90.149 -    @Compare public long subMinLongAndMinLong() {
  90.150 -        return sub(Long.MIN_VALUE, Long.MIN_VALUE);
  90.151 -    }
  90.152 -
  90.153 -    @Compare public long subMinLongAndMaxLong() {
  90.154 -        return sub(Long.MIN_VALUE, Long.MAX_VALUE);
  90.155 -    }
  90.156 -
  90.157 -    @Compare public long multiplyMaxLong() {
  90.158 -        return mul(Long.MAX_VALUE, 2l);
  90.159 -    }
  90.160 -
  90.161 -    @Compare public long multiplyMaxLongAndMaxLong() {
  90.162 -        return mul(Long.MAX_VALUE, Long.MAX_VALUE);
  90.163 -    }
  90.164 -
  90.165 -    @Compare public long multiplyMinLong() {
  90.166 -        return mul(Long.MIN_VALUE, 2l);
  90.167 -    }
  90.168 -
  90.169 -    @Compare public long multiplyMinLongAndMinLong() {
  90.170 -        return mul(Long.MIN_VALUE, Long.MIN_VALUE);
  90.171 -    }
  90.172 -
  90.173 -    @Compare public long multiplyPrecision() {
  90.174 -        return mul(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  90.175 -    }
  90.176 -
  90.177 -    @Compare public long divideSmallPositiveNumbers() {
  90.178 -        return div(0xabcdef, 0x123);
  90.179 -    }
  90.180 -
  90.181 -    @Compare public long divideSmallNegativeNumbers() {
  90.182 -        return div(-0xabcdef, -0x123);
  90.183 -    }
  90.184 -
  90.185 -    @Compare public long divideSmallMixedNumbers() {
  90.186 -        return div(0xabcdef, -0x123);
  90.187 -    }
  90.188 -
  90.189 -    @Compare public long dividePositiveNumbersOneDigitDenom() {
  90.190 -        return div(0xabcdef0102ffffl, 0x654);
  90.191 -    }
  90.192 -
  90.193 -    @Compare public long divideNegativeNumbersOneDigitDenom() {
  90.194 -        return div(-0xabcdef0102ffffl, -0x654);
  90.195 -    }
  90.196 -
  90.197 -    @Compare public long divideMixedNumbersOneDigitDenom() {
  90.198 -        return div(-0xabcdef0102ffffl, 0x654);
  90.199 -    }
  90.200 -
  90.201 -    @Compare public long dividePositiveNumbersMultiDigitDenom() {
  90.202 -        return div(0x7ffefc003322aabbl, 0x89ab1000l);
  90.203 -    }
  90.204 -
  90.205 -    @Compare public long divideNegativeNumbersMultiDigitDenom() {
  90.206 -        return div(-0x7ffefc003322aabbl, -0x123489ab1001l);
  90.207 -    }
  90.208 -
  90.209 -    @Compare public long divideMixedNumbersMultiDigitDenom() {
  90.210 -        return div(0x7ffefc003322aabbl, -0x38f49b0b7574e36l);
  90.211 -    }
  90.212 -
  90.213 -    @Compare public long divideWithOverflow() {
  90.214 -        return div(0x8000fffe0000l, 0x8000ffffl);
  90.215 -    }
  90.216 -
  90.217 -    @Compare public long divideWithCorrection() {
  90.218 -        return div(0x7fff800000000000l, 0x800000000001l);
  90.219 -    }
  90.220 -
  90.221 -    @Compare public long moduloSmallPositiveNumbers() {
  90.222 -        return mod(0xabcdef, 0x123);
  90.223 -    }
  90.224 -
  90.225 -    @Compare public long moduloSmallNegativeNumbers() {
  90.226 -        return mod(-0xabcdef, -0x123);
  90.227 -    }
  90.228 -
  90.229 -    @Compare public long moduloSmallMixedNumbers() {
  90.230 -        return mod(0xabcdef, -0x123);
  90.231 -    }
  90.232 -
  90.233 -    @Compare public long moduloPositiveNumbersOneDigitDenom() {
  90.234 -        return mod(0xabcdef0102ffffl, 0x654);
  90.235 -    }
  90.236 -
  90.237 -    @Compare public long moduloNegativeNumbersOneDigitDenom() {
  90.238 -        return mod(-0xabcdef0102ffffl, -0x654);
  90.239 -    }
  90.240 -
  90.241 -    @Compare public long moduloMixedNumbersOneDigitDenom() {
  90.242 -        return mod(-0xabcdef0102ffffl, 0x654);
  90.243 -    }
  90.244 -
  90.245 -    @Compare public long moduloPositiveNumbersMultiDigitDenom() {
  90.246 -        return mod(0x7ffefc003322aabbl, 0x89ab1000l);
  90.247 -    }
  90.248 -
  90.249 -    @Compare public long moduloNegativeNumbersMultiDigitDenom() {
  90.250 -        return mod(-0x7ffefc003322aabbl, -0x123489ab1001l);
  90.251 -    }
  90.252 -
  90.253 -    @Compare public long moduloMixedNumbersMultiDigitDenom() {
  90.254 -        return mod(0x7ffefc003322aabbl, -0x38f49b0b7574e36l);
  90.255 -    }
  90.256 -
  90.257 -    @Compare public long moduloWithOverflow() {
  90.258 -        return mod(0x8000fffe0000l, 0x8000ffffl);
  90.259 -    }
  90.260 -
  90.261 -    @Compare public long moduloWithCorrection() {
  90.262 -        return mod(0x7fff800000000000l, 0x800000000001l);
  90.263 -    }
  90.264 -
  90.265 -    @Compare public long conversionFromFloatPositive() {
  90.266 -        return (long) fadd(2, 0.6f);
  90.267 -    }
  90.268 -
  90.269 -    @Compare public long conversionFromFloatNegative() {
  90.270 -        return (long) fadd(-2, -0.6f);
  90.271 -    }
  90.272 -
  90.273 -    @Compare public long conversionFromDoublePositive() {
  90.274 -        return (long) dadd(0x20ffff0000L, 0.6);
  90.275 -    }
  90.276 -
  90.277 -    @Compare public long conversionFromDoubleNegative() {
  90.278 -        return (long) dadd(-0x20ffff0000L, -0.6);
  90.279 -    }
  90.280 -
  90.281 -    @Compare public boolean divByZeroThrowsArithmeticException() {
  90.282 -        try {
  90.283 -            div(1, 0);
  90.284 -            return false;
  90.285 -        } catch (final ArithmeticException e) {
  90.286 -            return true;
  90.287 -        }
  90.288 -    }
  90.289 -
  90.290 -    @Compare public boolean modByZeroThrowsArithmeticException() {
  90.291 -        try {
  90.292 -            mod(1, 0);
  90.293 -            return false;
  90.294 -        } catch (final ArithmeticException e) {
  90.295 -            return true;
  90.296 -        }
  90.297 -    }
  90.298 -
  90.299 -    @Compare public long shiftL1() {
  90.300 -        return shl(0x00fa37d7763e0ca1l, 5);
  90.301 -    }
  90.302 -
  90.303 -    @Compare public long shiftL2() {
  90.304 -        return shl(0x00fa37d7763e0ca1l, 32);
  90.305 -    }
  90.306 -
  90.307 -    @Compare public long shiftL3() {
  90.308 -        return shl(0x00fa37d7763e0ca1l, 45);
  90.309 -    }
  90.310 -
  90.311 -    @Compare public long shiftR1() {
  90.312 -        return shr(0x00fa37d7763e0ca1l, 5);
  90.313 -    }
  90.314 -
  90.315 -    @Compare public long shiftR2() {
  90.316 -        return shr(0x00fa37d7763e0ca1l, 32);
  90.317 -    }
  90.318 -
  90.319 -    @Compare public long shiftR3() {
  90.320 -        return shr(0x00fa37d7763e0ca1l, 45);
  90.321 -    }
  90.322 -
  90.323 -    @Compare public long uShiftR1() {
  90.324 -        return ushr(0x00fa37d7763e0ca1l, 5);
  90.325 -    }
  90.326 -
  90.327 -    @Compare public long uShiftR2() {
  90.328 -        return ushr(0x00fa37d7763e0ca1l, 45);
  90.329 -    }
  90.330 -
  90.331 -    @Compare public long uShiftR3() {
  90.332 -        return ushr(0xf0fa37d7763e0ca1l, 5);
  90.333 -    }
  90.334 -
  90.335 -    @Compare public long uShiftR4() {
  90.336 -        return ushr(0xf0fa37d7763e0ca1l, 45);
  90.337 -    }
  90.338 -
  90.339 -    @Compare public long and1() {
  90.340 -        return and(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  90.341 -    }
  90.342 -
  90.343 -    @Compare public long or1() {
  90.344 -        return or(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  90.345 -    }
  90.346 -
  90.347 -    @Compare public long xor1() {
  90.348 -        return xor(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
  90.349 -    }
  90.350 -
  90.351 -    @Compare public long xor2() {
  90.352 -        return xor(0x00fa37d7763e0ca1l, 0x00000000ff00123el);
  90.353 -    }
  90.354 -
  90.355 -    @Compare public long xor3() {
  90.356 -        return xor(0x00000000763e0ca1l, 0x00000000ff00123el);
  90.357 -    }
  90.358 -
  90.359 -    @Compare public int compareSameNumbers() {
  90.360 -        return compare(0x0000000000000000l, 0x0000000000000000l, 0);
  90.361 -    }
  90.362 -
  90.363 -    @Compare public int comparePositiveNumbers() {
  90.364 -        return compare(0x0000000000200000l, 0x0000000010000000l, 0);
  90.365 -    }
  90.366 -
  90.367 -    @Compare public int compareNegativeNumbers() {
  90.368 -        return compare(0xffffffffffffffffl, 0xffffffff00000000l, 0);
  90.369 -    }
  90.370 -
  90.371 -    @Compare public int compareMixedNumbers() {
  90.372 -        return compare(0x8000000000000000l, 0x7fffffffffffffffl, 0);
  90.373 -    }
  90.374 -    
  90.375 -    @Factory
  90.376 -    public static Object[] create() {
  90.377 -        return VMTest.create(LongArithmeticTest.class);
  90.378 -    }
  90.379 -}
    91.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionArrayTest.java	Fri Apr 26 15:09:59 2013 +0200
    91.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.3 @@ -1,161 +0,0 @@
    91.4 -/**
    91.5 - * Back 2 Browser Bytecode Translator
    91.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    91.7 - *
    91.8 - * This program is free software: you can redistribute it and/or modify
    91.9 - * it under the terms of the GNU General Public License as published by
   91.10 - * the Free Software Foundation, version 2 of the License.
   91.11 - *
   91.12 - * This program is distributed in the hope that it will be useful,
   91.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   91.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   91.15 - * GNU General Public License for more details.
   91.16 - *
   91.17 - * You should have received a copy of the GNU General Public License
   91.18 - * along with this program. Look for COPYING file in the top folder.
   91.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   91.20 - */
   91.21 -package org.apidesign.bck2brwsr.tck;
   91.22 -
   91.23 -import java.lang.reflect.Array;
   91.24 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   91.25 -import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   91.26 -import org.apidesign.bck2brwsr.vmtest.Compare;
   91.27 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   91.28 -import org.testng.annotations.Factory;
   91.29 -
   91.30 -/**
   91.31 - *
   91.32 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   91.33 - */
   91.34 -public class ReflectionArrayTest {
   91.35 -    @Compare public int lengthOfStringArray() {
   91.36 -        String[] arr = (String[]) Array.newInstance(String.class, 10);
   91.37 -        return arr.length;
   91.38 -    }
   91.39 -    
   91.40 -    @Compare public int reflectiveLengthOfStringArray() {
   91.41 -        Object arr = Array.newInstance(String.class, 10);
   91.42 -        return Array.getLength(arr);
   91.43 -    }
   91.44 -
   91.45 -    @Compare public int reflectiveLengthOneNonArray() {
   91.46 -        Object arr = "non-array";
   91.47 -        return Array.getLength(arr);
   91.48 -    }
   91.49 -
   91.50 -    @Compare public String compTypeOfStringArray() {
   91.51 -        String[] arr = (String[]) Array.newInstance(String.class, 10);
   91.52 -        return arr.getClass().getComponentType().getName();
   91.53 -    }
   91.54 -
   91.55 -    @Compare public Object negativeArrayExcp() {
   91.56 -        return Array.newInstance(String.class, -5);
   91.57 -    }
   91.58 -    
   91.59 -    @Compare public int lengthOfIntArray() {
   91.60 -        int[] arr = (int[]) Array.newInstance(Integer.TYPE, 10);
   91.61 -        return arr.length;
   91.62 -    }
   91.63 -
   91.64 -    @Compare public int reflectiveLengthOfIntArray() {
   91.65 -        Object arr = Array.newInstance(Integer.TYPE, 10);
   91.66 -        return Array.getLength(arr);
   91.67 -    }
   91.68 -
   91.69 -    @Compare public String compTypeOfIntArray() {
   91.70 -        int[] arr = (int[]) Array.newInstance(int.class, 10);
   91.71 -        return arr.getClass().getComponentType().getName();
   91.72 -    }
   91.73 -
   91.74 -    @Compare public Object intNegativeArrayExcp() {
   91.75 -        return Array.newInstance(int.class, -5);
   91.76 -    }
   91.77 -
   91.78 -    @Compare public Integer verifyAutobox() {
   91.79 -        int[] arr = (int[]) Array.newInstance(int.class, 5);
   91.80 -        return (Integer) Array.get(arr, 0);
   91.81 -    }
   91.82 -    @Compare public String verifyObjectArray() {
   91.83 -        String[] arr = (String[]) Array.newInstance(String.class, 5);
   91.84 -        Array.set(arr, 0, "Hello");
   91.85 -        return (String) Array.get(arr, 0);
   91.86 -    }
   91.87 -    @Compare public int verifyInt() {
   91.88 -        int[] arr = (int[]) Array.newInstance(int.class, 5);
   91.89 -        return Array.getInt(arr, 0);
   91.90 -    }
   91.91 -    @Compare public long verifyConvertToLong() {
   91.92 -        int[] arr = (int[]) Array.newInstance(int.class, 5);
   91.93 -        return Array.getLong(arr, 0);
   91.94 -    }
   91.95 -
   91.96 -    @Compare public Object verifySetIntToObject() {
   91.97 -        try {
   91.98 -            Object[] arr = (Object[]) Array.newInstance(Object.class, 5);
   91.99 -            Array.setInt(arr, 0, 10);
  91.100 -            return Array.get(arr, 0);
  91.101 -        } catch (Exception exception) {
  91.102 -            return exception.getClass().getName();
  91.103 -        }
  91.104 -    }
  91.105 -    @Compare public long verifySetShort() {
  91.106 -        int[] arr = (int[]) Array.newInstance(int.class, 5);
  91.107 -        Array.setShort(arr, 0, (short)10);
  91.108 -        return Array.getLong(arr, 0);
  91.109 -    }
  91.110 -    @Compare public long verifyCantSetLong() {
  91.111 -        int[] arr = (int[]) Array.newInstance(int.class, 5);
  91.112 -        Array.setLong(arr, 0, 10);
  91.113 -        return Array.getLong(arr, 0);
  91.114 -    }
  91.115 -    @Compare public float verifyLongToFloat() {
  91.116 -        Object arr = Array.newInstance(float.class, 5);
  91.117 -        Array.setLong(arr, 0, 10);
  91.118 -        return Array.getFloat(arr, 0);
  91.119 -    }
  91.120 -
  91.121 -    @Compare public double verifyConvertToDouble() {
  91.122 -        int[] arr = (int[]) Array.newInstance(int.class, 5);
  91.123 -        return Array.getDouble(arr, 0);
  91.124 -    }
  91.125 -    
  91.126 -    @Compare public int multiIntArray() {
  91.127 -        int[][][] arr = (int[][][]) Array.newInstance(int.class, 3, 3, 3);
  91.128 -        return arr[0][1][2] + 5 + arr[2][2][0];
  91.129 -    }
  91.130 -
  91.131 -    @Compare public String multiIntArrayCompType() {
  91.132 -        return Array.newInstance(int.class, 3, 3, 3).getClass().getName();
  91.133 -    }
  91.134 -    
  91.135 -    @JavaScriptBody(args = {}, body = "return [1, 2];")
  91.136 -    private static native Object crtarr();
  91.137 -
  91.138 -    @JavaScriptBody(args = {}, body = "return new Object();")
  91.139 -    private static native Object newobj();
  91.140 -
  91.141 -    @BrwsrTest
  91.142 -    public static void toStringArray() {
  91.143 -        final Object arr = crtarr();
  91.144 -        final Object real = new Object[2];
  91.145 -        assert arr instanceof Object[] : "Any array is Java array: " + arr;
  91.146 -        assert arr.getClass() == real.getClass() : "Same classes " + arr + " and " + real.getClass();
  91.147 -        final String str = arr.toString();
  91.148 -        assert str != null;
  91.149 -        assert str.startsWith("[Ljava.lang.Object;@") : str;
  91.150 -    }
  91.151 -    
  91.152 -    @BrwsrTest
  91.153 -    public static void objectToString() {
  91.154 -        String s = newobj().toString();
  91.155 -        assert s != null : "Some string computed";
  91.156 -        assert s.startsWith("java.lang.Object@") : "Regular object toString(): " + s;
  91.157 -    }
  91.158 -
  91.159 -    
  91.160 -    @Factory
  91.161 -    public static Object[] create() {
  91.162 -        return VMTest.create(ReflectionArrayTest.class);
  91.163 -    }
  91.164 -}
    92.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Fri Apr 26 15:09:59 2013 +0200
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,272 +0,0 @@
    92.4 -/**
    92.5 - * Back 2 Browser Bytecode Translator
    92.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    92.7 - *
    92.8 - * This program is free software: you can redistribute it and/or modify
    92.9 - * it under the terms of the GNU General Public License as published by
   92.10 - * the Free Software Foundation, version 2 of the License.
   92.11 - *
   92.12 - * This program is distributed in the hope that it will be useful,
   92.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   92.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   92.15 - * GNU General Public License for more details.
   92.16 - *
   92.17 - * You should have received a copy of the GNU General Public License
   92.18 - * along with this program. Look for COPYING file in the top folder.
   92.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   92.20 - */
   92.21 -package org.apidesign.bck2brwsr.tck;
   92.22 -
   92.23 -import java.lang.annotation.Retention;
   92.24 -import java.lang.annotation.RetentionPolicy;
   92.25 -import java.lang.reflect.Method;
   92.26 -import java.util.Arrays;
   92.27 -import java.util.Collections;
   92.28 -import java.util.List;
   92.29 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   92.30 -import org.apidesign.bck2brwsr.vmtest.Compare;
   92.31 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   92.32 -import org.testng.annotations.Factory;
   92.33 -
   92.34 -/**
   92.35 - *
   92.36 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   92.37 - */
   92.38 -public class ReflectionTest {
   92.39 -    @Compare public boolean nonNullThis() {
   92.40 -        return this == null;
   92.41 -    }
   92.42 -    
   92.43 -    @Compare public String intType() {
   92.44 -        return Integer.TYPE.toString();
   92.45 -    }
   92.46 -
   92.47 -    @Compare public String voidType() throws Exception {
   92.48 -        return void.class.toString();
   92.49 -    }
   92.50 -
   92.51 -    @Compare public String longClass() {
   92.52 -        return long.class.toString();
   92.53 -    }
   92.54 -    
   92.55 -    @Compare public boolean isRunnableInterface() {
   92.56 -        return Runnable.class.isInterface();
   92.57 -    }
   92.58 -
   92.59 -    @Compare public boolean isAssignableToPrimitiveType() {
   92.60 -        return boolean.class.isAssignableFrom(Runnable.class);
   92.61 -    }
   92.62 -
   92.63 -    @Compare public boolean isAssignableFromPrimitiveType() {
   92.64 -        return Runnable.class.isAssignableFrom(boolean.class);
   92.65 -    }
   92.66 -
   92.67 -    @Compare public boolean isAssignableLongFromInt() {
   92.68 -        return long.class.isAssignableFrom(int.class);
   92.69 -    }
   92.70 -
   92.71 -    @Compare public boolean isAssignableIntFromLong() {
   92.72 -        return int.class.isAssignableFrom(long.class);
   92.73 -    }
   92.74 -
   92.75 -    @Compare public String isRunnableHasRunMethod() throws NoSuchMethodException {
   92.76 -        return Runnable.class.getMethod("run").getName();
   92.77 -    }
   92.78 -    
   92.79 -    @Compare public String namesOfMethods() {
   92.80 -        StringBuilder sb = new StringBuilder();
   92.81 -        String[] arr = new String[20];
   92.82 -        int i = 0;
   92.83 -        for (Method m : StaticUse.class.getMethods()) {
   92.84 -            arr[i++] = m.getName();
   92.85 -        }
   92.86 -        for (String s : sort(arr, i)) {
   92.87 -            sb.append(s).append("\n");
   92.88 -        }
   92.89 -        return sb.toString();
   92.90 -    }
   92.91 -
   92.92 -    @Compare public String namesOfDeclaringClassesOfMethods() {
   92.93 -        StringBuilder sb = new StringBuilder();
   92.94 -        String[] arr = new String[20];
   92.95 -        int i = 0;
   92.96 -        for (Method m : StaticUse.class.getMethods()) {
   92.97 -            arr[i++] = m.getName() + "@" + m.getDeclaringClass().getName();
   92.98 -        }
   92.99 -        for (String s : sort(arr, i)) {
  92.100 -            sb.append(s).append("\n");
  92.101 -        }
  92.102 -        return sb.toString();
  92.103 -    }
  92.104 -    
  92.105 -    @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
  92.106 -        StaticUse.class.getMethod("instanceMethod").invoke(null);
  92.107 -        return "should not happen";
  92.108 -    }
  92.109 -    
  92.110 -    @Compare public String classCastException() {
  92.111 -        try {
  92.112 -            Integer i = (Integer)StaticUseSub.getNonNull();
  92.113 -            return "" + i.intValue();
  92.114 -        } catch (ClassCastException ex) {
  92.115 -            return ex.getClass().getName();
  92.116 -        }
  92.117 -    }
  92.118 -
  92.119 -    @Compare public String methodThatThrowsException() throws Exception {
  92.120 -        StaticUse.class.getMethod("instanceMethod").invoke(new StaticUse());
  92.121 -        return "should not happen";
  92.122 -    }
  92.123 -
  92.124 -    @Compare public Object voidReturnType() throws Exception {
  92.125 -        return StaticUse.class.getMethod("instanceMethod").getReturnType();
  92.126 -    }
  92.127 -    
  92.128 -    @Retention(RetentionPolicy.RUNTIME)
  92.129 -    @interface Ann {
  92.130 -    }
  92.131 -    
  92.132 -    @Compare public String annoClass() throws Exception {
  92.133 -        Retention r = Ann.class.getAnnotation(Retention.class);
  92.134 -        assert r != null : "Annotation is present";
  92.135 -        assert r.value() == RetentionPolicy.RUNTIME : "Policy value is OK: " + r.value();
  92.136 -        return r.annotationType().getName();
  92.137 -    }
  92.138 -    
  92.139 -    @Compare public boolean isAnnotation() {
  92.140 -        return Ann.class.isAnnotation();
  92.141 -    }
  92.142 -    @Compare public boolean isNotAnnotation() {
  92.143 -        return String.class.isAnnotation();
  92.144 -    }
  92.145 -    @Compare public boolean isNotAnnotationEnum() {
  92.146 -        return E.class.isAnnotation();
  92.147 -    }
  92.148 -    enum E { A, B };
  92.149 -    @Compare public boolean isEnum() {
  92.150 -        return E.A.getClass().isEnum();
  92.151 -    }
  92.152 -
  92.153 -    @Compare public boolean isNotEnum() {
  92.154 -        return "".getClass().isEnum();
  92.155 -    }
  92.156 -    
  92.157 -    @Compare public String newInstanceFails() throws InstantiationException {
  92.158 -        try {
  92.159 -            return "success: " + StaticUseSub.class.newInstance();
  92.160 -        } catch (IllegalAccessException ex) {
  92.161 -            return ex.getClass().getName();
  92.162 -        }
  92.163 -    }
  92.164 -    
  92.165 -    @Compare public String paramTypes() throws Exception {
  92.166 -        Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
  92.167 -        final Class[] pt = plus.getParameterTypes();
  92.168 -        return pt[0].getName();
  92.169 -    }
  92.170 -    @Compare public String paramTypesNotFound() throws Exception {
  92.171 -        return StaticUse.class.getMethod("plus", int.class, double.class).toString();
  92.172 -    }
  92.173 -    @Compare public int methodWithArgs() throws Exception {
  92.174 -        Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
  92.175 -        return (Integer)plus.invoke(null, 2, 3);
  92.176 -    }
  92.177 -    
  92.178 -    @Compare public String classGetNameForByte() {
  92.179 -         return byte.class.getName();
  92.180 -    }
  92.181 -    @Compare public String classGetNameForBaseObject() {
  92.182 -        return newObject().getClass().getName();
  92.183 -    }
  92.184 -    @Compare public String classGetNameForJavaObject() {
  92.185 -        return new Object().getClass().getName();
  92.186 -    }
  92.187 -    @Compare public String classGetNameForObjectArray() {
  92.188 -        return (new Object[3]).getClass().getName();
  92.189 -    }
  92.190 -    @Compare public String classGetNameForSimpleIntArray() {
  92.191 -        return (new int[3]).getClass().getName();
  92.192 -    }
  92.193 -    @Compare public boolean sameClassGetNameForSimpleCharArray() {
  92.194 -        return (new char[3]).getClass() == (new char[34]).getClass();
  92.195 -    }
  92.196 -    @Compare public String classGetNameForMultiIntArray() {
  92.197 -        return (new int[3][4][5][6][7][8][9]).getClass().getName();
  92.198 -    }
  92.199 -    @Compare public String classGetNameForMultiIntArrayInner() {
  92.200 -        final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
  92.201 -        int[][][][][][] subarr = arr[0];
  92.202 -        int[][][][][] subsubarr = subarr[0];
  92.203 -        return subsubarr.getClass().getName();
  92.204 -    }
  92.205 -    @Compare public String classGetNameForMultiStringArray() {
  92.206 -        return (new String[3][4][5][6][7][8][9]).getClass().getName();
  92.207 -    }
  92.208 -    
  92.209 -    @Compare public String classForByte() throws Exception {
  92.210 -        return Class.forName("[Z").getName();
  92.211 -    }
  92.212 -
  92.213 -    @Compare public String classForUnknownArray() {
  92.214 -        try {
  92.215 -            return Class.forName("[W").getName();
  92.216 -        } catch (Exception ex) {
  92.217 -            return ex.getClass().getName();
  92.218 -        }
  92.219 -    }
  92.220 -    
  92.221 -    @Compare public String classForUnknownDeepArray() {
  92.222 -        try {
  92.223 -            return Class.forName("[[[[[W").getName();
  92.224 -        } catch (Exception ex) {
  92.225 -            return ex.getClass().getName();
  92.226 -        }
  92.227 -    }
  92.228 -    
  92.229 -    @Compare public String componentGetNameForObjectArray() {
  92.230 -        return (new Object[3]).getClass().getComponentType().getName();
  92.231 -    }
  92.232 -    @Compare public boolean sameComponentGetNameForObjectArray() {
  92.233 -        return (new Object[3]).getClass().getComponentType() == Object.class;
  92.234 -    }
  92.235 -    @Compare public String componentGetNameForSimpleIntArray() {
  92.236 -        return (new int[3]).getClass().getComponentType().getName();
  92.237 -    }
  92.238 -    @Compare public String componentGetNameForMultiIntArray() {
  92.239 -        return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
  92.240 -    }
  92.241 -    @Compare public String componentGetNameForMultiStringArray() {
  92.242 -        Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
  92.243 -        StringBuilder sb = new StringBuilder();
  92.244 -        for (;;) {
  92.245 -            sb.append(c.getName()).append("\n");
  92.246 -            c = c.getComponentType();
  92.247 -            if (c == null) {
  92.248 -                break;
  92.249 -            }
  92.250 -        }
  92.251 -        return sb.toString();
  92.252 -    }
  92.253 -    
  92.254 -    @Compare public boolean isArray() {
  92.255 -        return new Object[0].getClass().isArray();
  92.256 -    }
  92.257 -    
  92.258 -    @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
  92.259 -    private static String[] sort(String[] arr, int len) {
  92.260 -        List<String> list = Arrays.asList(arr).subList(0, len);
  92.261 -        Collections.sort(list);
  92.262 -        return list.toArray(new String[0]);
  92.263 -    }
  92.264 -    
  92.265 -    @JavaScriptBody(args = {}, body = "return new Object();")
  92.266 -    private static Object newObject() {
  92.267 -        return new Object();
  92.268 -    }
  92.269 -    
  92.270 -    @Factory
  92.271 -    public static Object[] create() {
  92.272 -        return VMTest.create(ReflectionTest.class);
  92.273 -    }
  92.274 -    
  92.275 -}
    93.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java	Fri Apr 26 15:09:59 2013 +0200
    93.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.3 @@ -1,45 +0,0 @@
    93.4 -/**
    93.5 - * Back 2 Browser Bytecode Translator
    93.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    93.7 - *
    93.8 - * This program is free software: you can redistribute it and/or modify
    93.9 - * it under the terms of the GNU General Public License as published by
   93.10 - * the Free Software Foundation, version 2 of the License.
   93.11 - *
   93.12 - * This program is distributed in the hope that it will be useful,
   93.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   93.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   93.15 - * GNU General Public License for more details.
   93.16 - *
   93.17 - * You should have received a copy of the GNU General Public License
   93.18 - * along with this program. Look for COPYING file in the top folder.
   93.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   93.20 - */
   93.21 -package org.apidesign.bck2brwsr.tck;
   93.22 -
   93.23 -import java.io.InputStream;
   93.24 -import org.apidesign.bck2brwsr.vmtest.Compare;
   93.25 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   93.26 -import org.testng.annotations.Factory;
   93.27 -
   93.28 -/**
   93.29 - *
   93.30 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   93.31 - */
   93.32 -public class ResourcesTest {
   93.33 -    
   93.34 -    @Compare public String readResourceAsStream() throws Exception {
   93.35 -        InputStream is = getClass().getResourceAsStream("Resources.txt");
   93.36 -        byte[] b = new byte[30];
   93.37 -        int len = is.read(b);
   93.38 -        StringBuilder sb = new StringBuilder();
   93.39 -        for (int i = 0; i < len; i++) {
   93.40 -            sb.append((char)b[i]);
   93.41 -        }
   93.42 -        return sb.toString();
   93.43 -    }
   93.44 -    
   93.45 -    @Factory public static Object[] create() {
   93.46 -        return VMTest.create(ResourcesTest.class);
   93.47 -    }
   93.48 -}
    94.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ShortArithmeticTest.java	Fri Apr 26 15:09:59 2013 +0200
    94.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.3 @@ -1,102 +0,0 @@
    94.4 -/**
    94.5 - * Back 2 Browser Bytecode Translator
    94.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    94.7 - *
    94.8 - * This program is free software: you can redistribute it and/or modify
    94.9 - * it under the terms of the GNU General Public License as published by
   94.10 - * the Free Software Foundation, version 2 of the License.
   94.11 - *
   94.12 - * This program is distributed in the hope that it will be useful,
   94.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   94.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   94.15 - * GNU General Public License for more details.
   94.16 - *
   94.17 - * You should have received a copy of the GNU General Public License
   94.18 - * along with this program. Look for COPYING file in the top folder.
   94.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   94.20 - */
   94.21 -package org.apidesign.bck2brwsr.tck;
   94.22 -
   94.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   94.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   94.25 -import org.testng.annotations.Factory;
   94.26 -
   94.27 -/**
   94.28 - *
   94.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   94.30 - */
   94.31 -public class ShortArithmeticTest {
   94.32 -    
   94.33 -    private static short add(short x, short y) {
   94.34 -        return (short)(x + y);
   94.35 -    }
   94.36 -    
   94.37 -    private static short sub(short x, short y) {
   94.38 -        return (short)(x - y);
   94.39 -    }
   94.40 -    
   94.41 -    private static short mul(short x, short y) {
   94.42 -        return (short)(x * y);
   94.43 -    }
   94.44 -    
   94.45 -    private static short div(short x, short y) {
   94.46 -        return (short)(x / y);
   94.47 -    }
   94.48 -    
   94.49 -    private static short mod(short x, short y) {
   94.50 -        return (short)(x % y);
   94.51 -    }
   94.52 -    
   94.53 -    @Compare public short conversion() {
   94.54 -        return (short)123456;
   94.55 -    }
   94.56 -    
   94.57 -    @Compare public short addOverflow() {
   94.58 -        return add(Short.MAX_VALUE, (short)1);
   94.59 -    }
   94.60 -    
   94.61 -    @Compare public short subUnderflow() {
   94.62 -        return sub(Short.MIN_VALUE, (short)1);
   94.63 -    }
   94.64 -    
   94.65 -    @Compare public short addMaxShortAndMaxShort() {
   94.66 -        return add(Short.MAX_VALUE, Short.MAX_VALUE);
   94.67 -    }
   94.68 -    
   94.69 -    @Compare public short subMinShortAndMinShort() {
   94.70 -        return sub(Short.MIN_VALUE, Short.MIN_VALUE);
   94.71 -    }
   94.72 -    
   94.73 -    @Compare public short multiplyMaxShort() {
   94.74 -        return mul(Short.MAX_VALUE, (short)2);
   94.75 -    }
   94.76 -    
   94.77 -    @Compare public short multiplyMaxShortAndMaxShort() {
   94.78 -        return mul(Short.MAX_VALUE, Short.MAX_VALUE);
   94.79 -    }
   94.80 -    
   94.81 -    @Compare public short multiplyMinShort() {
   94.82 -        return mul(Short.MIN_VALUE, (short)2);
   94.83 -    }
   94.84 -    
   94.85 -    @Compare public short multiplyMinShortAndMinShort() {
   94.86 -        return mul(Short.MIN_VALUE, Short.MIN_VALUE);
   94.87 -    }
   94.88 -    
   94.89 -    @Compare public short multiplyPrecision() {
   94.90 -        return mul((short)17638, (short)1103);
   94.91 -    }
   94.92 -    
   94.93 -    @Compare public short division() {
   94.94 -        return div((short)1, (short)2);
   94.95 -    }
   94.96 -    
   94.97 -    @Compare public short divisionReminder() {
   94.98 -        return mod((short)1, (short)2);
   94.99 -    }
  94.100 -    
  94.101 -    @Factory
  94.102 -    public static Object[] create() {
  94.103 -        return VMTest.create(ShortArithmeticTest.class);
  94.104 -    }
  94.105 -}
    95.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java	Fri Apr 26 15:09:59 2013 +0200
    95.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.3 @@ -1,39 +0,0 @@
    95.4 -/**
    95.5 - * Back 2 Browser Bytecode Translator
    95.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    95.7 - *
    95.8 - * This program is free software: you can redistribute it and/or modify
    95.9 - * it under the terms of the GNU General Public License as published by
   95.10 - * the Free Software Foundation, version 2 of the License.
   95.11 - *
   95.12 - * This program is distributed in the hope that it will be useful,
   95.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   95.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   95.15 - * GNU General Public License for more details.
   95.16 - *
   95.17 - * You should have received a copy of the GNU General Public License
   95.18 - * along with this program. Look for COPYING file in the top folder.
   95.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   95.20 - */
   95.21 -package org.apidesign.bck2brwsr.tck;
   95.22 -
   95.23 -class StaticUse {
   95.24 -    public static final Object NON_NULL = new Object();
   95.25 -    public static int cnt;
   95.26 -    static {
   95.27 -        if (cnt++ != 0) {
   95.28 -            throw new IllegalStateException("Multiple initialization of a <cinit>");
   95.29 -        }
   95.30 -    }
   95.31 -    
   95.32 -    StaticUse() {
   95.33 -    }
   95.34 -    
   95.35 -    public void instanceMethod() {
   95.36 -        throw new IllegalStateException();
   95.37 -    }
   95.38 -
   95.39 -    public static int plus(int a, int b) {
   95.40 -        return a + b;
   95.41 -    }
   95.42 -}
    96.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUseSub.java	Fri Apr 26 15:09:59 2013 +0200
    96.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.3 @@ -1,30 +0,0 @@
    96.4 -/**
    96.5 - * Back 2 Browser Bytecode Translator
    96.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    96.7 - *
    96.8 - * This program is free software: you can redistribute it and/or modify
    96.9 - * it under the terms of the GNU General Public License as published by
   96.10 - * the Free Software Foundation, version 2 of the License.
   96.11 - *
   96.12 - * This program is distributed in the hope that it will be useful,
   96.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   96.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   96.15 - * GNU General Public License for more details.
   96.16 - *
   96.17 - * You should have received a copy of the GNU General Public License
   96.18 - * along with this program. Look for COPYING file in the top folder.
   96.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   96.20 - */
   96.21 -package org.apidesign.bck2brwsr.tck;
   96.22 -
   96.23 -public class StaticUseSub extends StaticUse {
   96.24 -    private StaticUseSub() {
   96.25 -    }
   96.26 -    
   96.27 -    public static Object getNonNull() {
   96.28 -        return NON_NULL;
   96.29 -    }
   96.30 -    static Object getNull() {
   96.31 -        return null;
   96.32 -    }
   96.33 -}
    97.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUseSubTest.java	Fri Apr 26 15:09:59 2013 +0200
    97.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.3 @@ -1,45 +0,0 @@
    97.4 -/**
    97.5 - * Back 2 Browser Bytecode Translator
    97.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    97.7 - *
    97.8 - * This program is free software: you can redistribute it and/or modify
    97.9 - * it under the terms of the GNU General Public License as published by
   97.10 - * the Free Software Foundation, version 2 of the License.
   97.11 - *
   97.12 - * This program is distributed in the hope that it will be useful,
   97.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   97.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   97.15 - * GNU General Public License for more details.
   97.16 - *
   97.17 - * You should have received a copy of the GNU General Public License
   97.18 - * along with this program. Look for COPYING file in the top folder.
   97.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   97.20 - */
   97.21 -package org.apidesign.bck2brwsr.tck;
   97.22 -
   97.23 -import org.apidesign.bck2brwsr.vmtest.Compare;
   97.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   97.25 -import org.testng.annotations.Factory;
   97.26 -
   97.27 -/**
   97.28 - *
   97.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   97.30 - */
   97.31 -public class StaticUseSubTest {
   97.32 -    @Compare public String staticFieldInitializationInSuperClass() throws Exception {
   97.33 -        Object ret = StaticUseSub.getNonNull();
   97.34 -        return ret.getClass().getName();
   97.35 -    }
   97.36 -    
   97.37 -    @Compare public String isNullPointerTheSame() throws Exception {
   97.38 -        try {
   97.39 -            return StaticUseSub.getNull().getClass().toString();
   97.40 -        } catch (NullPointerException ex) {
   97.41 -            return ex.getClass().getName();
   97.42 -        }
   97.43 -    }
   97.44 -
   97.45 -    @Factory public static Object[] create() {
   97.46 -        return VMTest.create(StaticUseSubTest.class);
   97.47 -    }
   97.48 -}
    98.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java	Fri Apr 26 15:09:59 2013 +0200
    98.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.3 @@ -1,41 +0,0 @@
    98.4 -/**
    98.5 - * Back 2 Browser Bytecode Translator
    98.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    98.7 - *
    98.8 - * This program is free software: you can redistribute it and/or modify
    98.9 - * it under the terms of the GNU General Public License as published by
   98.10 - * the Free Software Foundation, version 2 of the License.
   98.11 - *
   98.12 - * This program is distributed in the hope that it will be useful,
   98.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   98.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   98.15 - * GNU General Public License for more details.
   98.16 - *
   98.17 - * You should have received a copy of the GNU General Public License
   98.18 - * along with this program. Look for COPYING file in the top folder.
   98.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   98.20 - */
   98.21 -package org.apidesign.bck2brwsr.vmtest.impl;
   98.22 -
   98.23 -import java.io.UnsupportedEncodingException;
   98.24 -import java.util.zip.CRC32;
   98.25 -import org.apidesign.bck2brwsr.vmtest.Compare;
   98.26 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   98.27 -import org.testng.annotations.Factory;
   98.28 -
   98.29 -/**
   98.30 - *
   98.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   98.32 - */
   98.33 -public class CRC32Test {
   98.34 -
   98.35 -    @Compare public long crc1() throws UnsupportedEncodingException {
   98.36 -        CRC32 crc = new CRC32();
   98.37 -        crc.update("Hello World!".getBytes("UTF-8"));
   98.38 -        return crc.getValue();
   98.39 -    }
   98.40 -    
   98.41 -    @Factory public static Object[] create() {
   98.42 -        return VMTest.create(CRC32Test.class);
   98.43 -    }
   98.44 -}
    99.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CallMeTwiceTest.java	Fri Apr 26 15:09:59 2013 +0200
    99.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.3 @@ -1,43 +0,0 @@
    99.4 -/**
    99.5 - * Back 2 Browser Bytecode Translator
    99.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    99.7 - *
    99.8 - * This program is free software: you can redistribute it and/or modify
    99.9 - * it under the terms of the GNU General Public License as published by
   99.10 - * the Free Software Foundation, version 2 of the License.
   99.11 - *
   99.12 - * This program is distributed in the hope that it will be useful,
   99.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   99.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   99.15 - * GNU General Public License for more details.
   99.16 - *
   99.17 - * You should have received a copy of the GNU General Public License
   99.18 - * along with this program. Look for COPYING file in the top folder.
   99.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   99.20 - */
   99.21 -package org.apidesign.bck2brwsr.vmtest.impl;
   99.22 -
   99.23 -import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
   99.24 -import org.apidesign.bck2brwsr.vmtest.VMTest;
   99.25 -import org.testng.annotations.Factory;
   99.26 -
   99.27 -/**
   99.28 - *
   99.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   99.30 - */
   99.31 -public class CallMeTwiceTest {
   99.32 -    int cnt;
   99.33 -    
   99.34 -    @BrwsrTest public void callMeTwice() throws InterruptedException {
   99.35 -        if (cnt++ == 0) {
   99.36 -            throw new InterruptedException();
   99.37 -        }
   99.38 -        int prevCnt = cnt;
   99.39 -        cnt = 0;
   99.40 -        assert prevCnt == 2 : "We need to receive two calls " + prevCnt;
   99.41 -    }
   99.42 -    
   99.43 -    @Factory public static Object[] create() {
   99.44 -        return VMTest.create(CallMeTwiceTest.class);
   99.45 -    }
   99.46 -}
   100.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java	Fri Apr 26 15:09:59 2013 +0200
   100.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.3 @@ -1,67 +0,0 @@
   100.4 -/**
   100.5 - * Back 2 Browser Bytecode Translator
   100.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   100.7 - *
   100.8 - * This program is free software: you can redistribute it and/or modify
   100.9 - * it under the terms of the GNU General Public License as published by
  100.10 - * the Free Software Foundation, version 2 of the License.
  100.11 - *
  100.12 - * This program is distributed in the hope that it will be useful,
  100.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  100.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  100.15 - * GNU General Public License for more details.
  100.16 - *
  100.17 - * You should have received a copy of the GNU General Public License
  100.18 - * along with this program. Look for COPYING file in the top folder.
  100.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
  100.20 - */
  100.21 -package org.apidesign.bck2brwsr.vmtest.impl;
  100.22 -
  100.23 -import java.io.ByteArrayInputStream;
  100.24 -import java.io.IOException;
  100.25 -import java.io.InputStream;
  100.26 -import org.apidesign.bck2brwsr.emul.zip.FastJar;
  100.27 -import org.testng.annotations.Test;
  100.28 -import static org.testng.Assert.*;
  100.29 -
  100.30 -/**
  100.31 - *
  100.32 - * @author Jaroslav Tulach <jtulach@netbeans.org>
  100.33 - */
  100.34 -@GenerateZip(name = "five.zip", contents = {
  100.35 -    "1.txt", "one",
  100.36 -    "2.txt", "duo",
  100.37 -    "3.txt", "three",
  100.38 -    "4.txt", "four",
  100.39 -    "5.txt", "five"
  100.40 -})
  100.41 -public class ZipEntryTest {
  100.42 -    @Test
  100.43 -    public void readEntriesEffectively() throws IOException {
  100.44 -        InputStream is = ZipEntryTest.class.getResourceAsStream("five.zip");
  100.45 -        byte[] arr = new byte[is.available()];
  100.46 -        int len = is.read(arr);
  100.47 -        assertEquals(len, arr.length, "Read fully");
  100.48 -        
  100.49 -        FastJar fj = new FastJar(arr);
  100.50 -        FastJar.Entry[] entrs = fj.list();
  100.51 -        
  100.52 -        assertEquals(5, entrs.length, "Five entries");
  100.53 -        
  100.54 -        for (int i = 1; i <= 5; i++) {
  100.55 -            FastJar.Entry en = entrs[i - 1];
  100.56 -            assertEquals(en.name, i + ".txt");
  100.57 -//            assertEquals(cis.cnt, 0, "Content of the file should be skipped, not read");
  100.58 -        }
  100.59 -        
  100.60 -        assertContent("three", fj.getInputStream(entrs[3 - 1]), "read OK");
  100.61 -        assertContent("five", fj.getInputStream(entrs[5 - 1]), "read OK");
  100.62 -    }
  100.63 -
  100.64 -    private static void assertContent(String exp, InputStream is, String msg) throws IOException {
  100.65 -        byte[] arr = new byte[512];
  100.66 -        int len = is.read(arr);
  100.67 -        String s = new String(arr, 0, len);
  100.68 -        assertEquals(exp, s, msg);
  100.69 -    }
  100.70 -}
   101.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java	Fri Apr 26 15:09:59 2013 +0200
   101.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.3 @@ -1,108 +0,0 @@
   101.4 -/**
   101.5 - * Back 2 Browser Bytecode Translator
   101.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   101.7 - *
   101.8 - * This program is free software: you can redistribute it and/or modify
   101.9 - * it under the terms of the GNU General Public License as published by
  101.10 - * the Free Software Foundation, version 2 of the License.
  101.11 - *
  101.12 - * This program is distributed in the hope that it will be useful,
  101.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  101.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  101.15 - * GNU General Public License for more details.
  101.16 - *
  101.17 - * You should have received a copy of the GNU General Public License
  101.18 - * along with this program. Look for COPYING file in the top folder.
  101.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
  101.20 - */
  101.21 -package org.apidesign.bck2brwsr.vmtest.impl;
  101.22 -
  101.23 -import java.io.IOException;
  101.24 -import java.io.InputStream;
  101.25 -import java.util.Objects;
  101.26 -import java.util.zip.ZipEntry;
  101.27 -import java.util.zip.ZipInputStream;
  101.28 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
  101.29 -import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
  101.30 -import org.apidesign.bck2brwsr.vmtest.Compare;
  101.31 -import org.apidesign.bck2brwsr.vmtest.Http;
  101.32 -import org.apidesign.bck2brwsr.vmtest.VMTest;
  101.33 -import org.testng.annotations.Factory;
  101.34 -
  101.35 -/**
  101.36 - *
  101.37 - * @author Jaroslav Tulach <jtulach@netbeans.org>
  101.38 - */
  101.39 -@GenerateZip(name = "readAnEntry.zip", contents = { 
  101.40 -    "my/main/file.txt", "Hello World!"
  101.41 -})
  101.42 -public class ZipFileTest {
  101.43 -    
  101.44 -    @Compare public String readAnEntry() throws IOException {
  101.45 -        InputStream is = ZipFileTest.class.getResourceAsStream("readAnEntry.zip");
  101.46 -        ZipInputStream zip = new ZipInputStream(is);
  101.47 -        ZipEntry entry = zip.getNextEntry();
  101.48 -        assertEquals(entry.getName(), "my/main/file.txt", "Correct entry");
  101.49 -
  101.50 -        byte[] arr = new byte[4096];
  101.51 -        int len = zip.read(arr);
  101.52 -        
  101.53 -        assertEquals(zip.getNextEntry(), null, "No next entry");
  101.54 -        
  101.55 -        final String ret = new String(arr, 0, len, "UTF-8");
  101.56 -        return ret;
  101.57 -    }
  101.58 -    
  101.59 -    @JavaScriptBody(args = { "res", "path" }, body = 
  101.60 -          "var myvm = bck2brwsr.apply(null, path);\n"
  101.61 -        + "var cls = myvm.loadClass('java.lang.String');\n"
  101.62 -        + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n"
  101.63 -    )
  101.64 -    private static native Object loadVMResource(String res, String...path);
  101.65 -
  101.66 -    @Http({
  101.67 -        @Http.Resource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip")
  101.68 -    })
  101.69 -    @BrwsrTest  public void canVmLoadResourceFromZip() throws IOException {
  101.70 -        Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar");
  101.71 -        assert res instanceof InputStream : "Got array of bytes: " + res;
  101.72 -        InputStream is = (InputStream)res;
  101.73 -        
  101.74 -        byte[] arr = new byte[4096];
  101.75 -        int len = is.read(arr);
  101.76 -        
  101.77 -        final String ret = new String(arr, 0, len, "UTF-8");
  101.78 -
  101.79 -        assertEquals(ret, "Hello World!", "Can read the bytes");
  101.80 -    }
  101.81 -    
  101.82 -    @GenerateZip(name = "cpattr.zip", contents = { 
  101.83 -        "META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n"
  101.84 -        + "Created-By: hand\n"
  101.85 -        + "Class-Path: realJar.jar\n\n\n"
  101.86 -    })
  101.87 -    @Http({
  101.88 -        @Http.Resource(path = "/readComplexEntry.jar", mimeType = "x-application/zip", content = "", resource="cpattr.zip"),
  101.89 -        @Http.Resource(path = "/realJar.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip"),
  101.90 -    })
  101.91 -    @BrwsrTest  public void understandsClassPathAttr() throws IOException {
  101.92 -        Object res = loadVMResource("/my/main/file.txt", "/readComplexEntry.jar");
  101.93 -        assert res instanceof InputStream : "Got array of bytes: " + res;
  101.94 -        InputStream is = (InputStream)res;
  101.95 -        
  101.96 -        byte[] arr = new byte[4096];
  101.97 -        int len = is.read(arr);
  101.98 -        
  101.99 -        final String ret = new String(arr, 0, len, "UTF-8");
 101.100 -
 101.101 -        assertEquals(ret, "Hello World!", "Can read the bytes from secondary JAR");
 101.102 -    }
 101.103 -    
 101.104 -    private static void assertEquals(Object real, Object exp, String msg) {
 101.105 -        assert Objects.equals(exp, real) : msg + " exp: " + exp + " real: " + real;
 101.106 -    }
 101.107 -    
 101.108 -    @Factory public static Object[] create() {
 101.109 -        return VMTest.create(ZipFileTest.class);
 101.110 -    }
 101.111 -}
   102.1 --- a/rt/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/0xfe	Fri Apr 26 15:09:59 2013 +0200
   102.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.3 @@ -1,1 +0,0 @@
   102.4   102.5 \ No newline at end of file
   103.1 --- a/rt/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/Resources.txt	Fri Apr 26 15:09:59 2013 +0200
   103.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.3 @@ -1,1 +0,0 @@
   103.4 -Ahoj