1.1 --- a/boot/src/main/java/net/java/html/boot/BrowserBuilder.java Mon Jun 24 15:32:43 2013 +0200
1.2 +++ b/boot/src/main/java/net/java/html/boot/BrowserBuilder.java Mon Jun 24 15:34:25 2013 +0200
1.3 @@ -36,6 +36,8 @@
1.4 public final class BrowserBuilder {
1.5 private String resource;
1.6 private Class<?> clazz;
1.7 + private Class[] browserClass;
1.8 + private Runnable onLoad;
1.9 private BrowserBuilder() {
1.10 }
1.11
1.12 @@ -54,6 +56,10 @@
1.13 }
1.14
1.15 public void showAndWait() {
1.16 + if (resource == null) {
1.17 + throw new IllegalStateException("Need to specify resource via loadPage method");
1.18 + }
1.19 +
1.20 FImpl impl = new FImpl(clazz.getClassLoader());
1.21 URL url = clazz.getResource(resource);
1.22 if (url == null) {
1.23 @@ -68,6 +74,12 @@
1.24 public void run() {
1.25 try {
1.26 Class<?> newClazz = Class.forName(clazz.getName(), true, loader);
1.27 + if (browserClass != null) {
1.28 + browserClass[0] = newClazz;
1.29 + }
1.30 + if (onLoad != null) {
1.31 + onLoad.run();
1.32 + }
1.33 } catch (ClassNotFoundException ex) {
1.34 throw new IllegalStateException(ex);
1.35 }
1.36 @@ -78,6 +90,20 @@
1.37 }
1.38 throw new IllegalStateException("Can't find any Fn.Definer");
1.39 }
1.40 +
1.41 + public BrowserBuilder onClassReady(Class[] browserClass) {
1.42 + if (browserClass.length != 1) {
1.43 + throw new IllegalStateException("Expecting array of size one");
1.44 + }
1.45 + this.browserClass = browserClass;
1.46 + return this;
1.47 + }
1.48 +
1.49 + // callback happens on browser thread
1.50 + public BrowserBuilder onLoad(Runnable r) {
1.51 + this.onLoad = r;
1.52 + return this;
1.53 + }
1.54
1.55 private static final class FImpl implements FindResources {
1.56 final ClassLoader l;
2.1 --- a/ko-fx/pom.xml Mon Jun 24 15:32:43 2013 +0200
2.2 +++ b/ko-fx/pom.xml Mon Jun 24 15:34:25 2013 +0200
2.3 @@ -62,23 +62,16 @@
2.4 <scope>provided</scope>
2.5 </dependency>
2.6 <dependency>
2.7 - <groupId>org.apidesign.bck2brwsr</groupId>
2.8 - <artifactId>launcher.fx</artifactId>
2.9 - <version>${bck2brwsr.launcher.version}</version>
2.10 - <scope>test</scope>
2.11 - </dependency>
2.12 - <dependency>
2.13 <groupId>org.apidesign.html</groupId>
2.14 <artifactId>net.java.html.boot</artifactId>
2.15 <version>${project.version}</version>
2.16 <type>jar</type>
2.17 </dependency>
2.18 <dependency>
2.19 - <groupId>org.apidesign.bck2brwsr</groupId>
2.20 - <artifactId>vmtest</artifactId>
2.21 - <version>0.8-SNAPSHOT</version>
2.22 + <groupId>${project.groupId}</groupId>
2.23 + <artifactId>boot-fx</artifactId>
2.24 + <version>${project.version}</version>
2.25 <scope>test</scope>
2.26 - <type>jar</type>
2.27 </dependency>
2.28 </dependencies>
2.29 </project>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/ko-fx/src/test/java/org/apidesign/html/kofx/KOFx.java Mon Jun 24 15:34:25 2013 +0200
3.3 @@ -0,0 +1,74 @@
3.4 +/**
3.5 + * HTML via Java(tm) Language Bindings
3.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.7 + *
3.8 + * This program is free software: you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License as published by
3.10 + * the Free Software Foundation, version 2 of the License.
3.11 + *
3.12 + * This program is distributed in the hope that it will be useful,
3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 + * GNU General Public License for more details. apidesign.org
3.16 + * designates this particular file as subject to the
3.17 + * "Classpath" exception as provided by apidesign.org
3.18 + * in the License file that accompanied this code.
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License
3.21 + * along with this program. Look for COPYING file in the top folder.
3.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
3.23 + */
3.24 +package org.apidesign.html.kofx;
3.25 +
3.26 +import java.lang.reflect.Method;
3.27 +import javafx.application.Platform;
3.28 +import org.testng.ITest;
3.29 +import org.testng.annotations.Test;
3.30 +
3.31 +/**
3.32 + *
3.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.34 + */
3.35 +public final class KOFx implements ITest, Runnable {
3.36 + private final Method m;
3.37 + private Object result;
3.38 +
3.39 + KOFx(Method m) {
3.40 + this.m = m;
3.41 + }
3.42 +
3.43 + @Override
3.44 + public String getTestName() {
3.45 + return m.getDeclaringClass().getName() + "." + m.getName();
3.46 + }
3.47 +
3.48 + @Test
3.49 + public synchronized void executeTest() throws Exception {
3.50 + if (result == null) {
3.51 + Platform.runLater(this);
3.52 + wait();
3.53 + }
3.54 + if (result instanceof Exception) {
3.55 + throw (Exception)result;
3.56 + }
3.57 + if (result instanceof Error) {
3.58 + throw (Error)result;
3.59 + }
3.60 + }
3.61 +
3.62 + @Override
3.63 + public synchronized void run() {
3.64 + try {
3.65 + Object inst = m.getDeclaringClass().newInstance();
3.66 + result = m.invoke(inst);
3.67 + if (result == null) {
3.68 + result = this;
3.69 + }
3.70 + } catch (Throwable ex) {
3.71 + result = ex;
3.72 + } finally {
3.73 + notifyAll();
3.74 + }
3.75 + }
3.76 +
3.77 +}
4.1 --- a/ko-fx/src/test/java/org/apidesign/html/kofx/KnockoutFXTest.java Mon Jun 24 15:32:43 2013 +0200
4.2 +++ b/ko-fx/src/test/java/org/apidesign/html/kofx/KnockoutFXTest.java Mon Jun 24 15:34:25 2013 +0200
4.3 @@ -24,15 +24,20 @@
4.4 import java.io.IOException;
4.5 import java.io.InputStreamReader;
4.6 import java.io.PrintWriter;
4.7 +import java.lang.annotation.Annotation;
4.8 +import java.lang.reflect.Method;
4.9 import java.net.HttpURLConnection;
4.10 import java.net.URI;
4.11 import java.net.URISyntaxException;
4.12 import java.net.URL;
4.13 import java.net.URLConnection;
4.14 +import java.util.ArrayList;
4.15 +import java.util.List;
4.16 import java.util.Map;
4.17 +import java.util.concurrent.Executors;
4.18 import net.java.html.BrwsrCtx;
4.19 +import net.java.html.boot.BrowserBuilder;
4.20 import net.java.html.js.JavaScriptBody;
4.21 -import org.apidesign.bck2brwsr.vmtest.VMTest;
4.22 import org.apidesign.html.context.spi.Contexts;
4.23 import org.apidesign.html.json.spi.Technology;
4.24 import org.apidesign.html.json.spi.Transfer;
4.25 @@ -42,6 +47,9 @@
4.26 import org.json.JSONObject;
4.27 import org.openide.util.lookup.ServiceProvider;
4.28 import org.testng.annotations.Factory;
4.29 +import static org.testng.Assert.*;
4.30 +import org.testng.ITest;
4.31 +import org.testng.annotations.Test;
4.32
4.33 /**
4.34 *
4.35 @@ -52,11 +60,55 @@
4.36 public KnockoutFXTest() {
4.37 }
4.38
4.39 - @Factory public static Object[] compatibilityTests() {
4.40 - return VMTest.newTests().
4.41 - withClasses(testClasses()).
4.42 - withTestAnnotation(KOTest.class).
4.43 - withLaunchers("fxbrwsr").build();
4.44 + @Factory public static Object[] compatibilityTests() throws Exception {
4.45 + Class[] arr = testClasses();
4.46 + ClassLoader l = KnockoutFXTest.class.getClassLoader();
4.47 + for (int i = 0; i < arr.length; i++) {
4.48 + assertEquals(arr[i].getClassLoader(), l, "All classes loaded by the same classloader");
4.49 + }
4.50 + assertNotNull(l, "At least one class provided");
4.51 +
4.52 + class R implements Runnable {
4.53 + final Class[] browserClass = { null };
4.54 + @Override
4.55 + public synchronized void run() {
4.56 + notifyAll();
4.57 + }
4.58 +
4.59 + synchronized ClassLoader getClassLoader() throws InterruptedException {
4.60 + while (browserClass[0] == null) {
4.61 + wait();
4.62 + }
4.63 + return browserClass[0].getClassLoader();
4.64 + }
4.65 + }
4.66 + R r = new R();
4.67 +
4.68 + final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(KnockoutFXTest.class).
4.69 + loadPage("test.html").
4.70 + onClassReady(r.browserClass).
4.71 + onLoad(r);
4.72 + Executors.newSingleThreadExecutor().submit(new Runnable() {
4.73 + @Override
4.74 + public void run() {
4.75 + bb.showAndWait();
4.76 + }
4.77 + });
4.78 +
4.79 + l = r.getClassLoader();
4.80 + List<Object> res = new ArrayList<Object>();
4.81 + for (int i = 0; i < arr.length; i++) {
4.82 + Class<?> c = Class.forName(arr[i].getName(), true, l);
4.83 + Class<? extends Annotation> koTest =
4.84 + c.getClassLoader().loadClass(KOTest.class.getName()).
4.85 + asSubclass(Annotation.class);
4.86 + for (Method m : c.getMethods()) {
4.87 + if (m.getAnnotation(koTest) != null) {
4.88 + res.add(new KOFx(m));
4.89 + }
4.90 + }
4.91 + }
4.92 + return res.toArray();
4.93 }
4.94
4.95 @Override
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/ko-fx/src/test/resources/org/apidesign/html/kofx/test.html Mon Jun 24 15:34:25 2013 +0200
5.3 @@ -0,0 +1,33 @@
5.4 +<!--
5.5 +
5.6 + HTML via Java(tm) Language Bindings
5.7 + Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.8 +
5.9 + This program is free software: you can redistribute it and/or modify
5.10 + it under the terms of the GNU General Public License as published by
5.11 + the Free Software Foundation, version 2 of the License.
5.12 +
5.13 + This program is distributed in the hope that it will be useful,
5.14 + but WITHOUT ANY WARRANTY; without even the implied warranty of
5.15 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.16 + GNU General Public License for more details. apidesign.org
5.17 + designates this particular file as subject to the
5.18 + "Classpath" exception as provided by apidesign.org
5.19 + in the License file that accompanied this code.
5.20 +
5.21 + You should have received a copy of the GNU General Public License
5.22 + along with this program. Look for COPYING file in the top folder.
5.23 + If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
5.24 +
5.25 +-->
5.26 +<!DOCTYPE html>
5.27 +<html>
5.28 + <head>
5.29 + <title>Knockout.fx Execution Harness</title>
5.30 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5.31 + <meta name="viewport" content="width=device-width">
5.32 + </head>
5.33 + <body>
5.34 + <h1>Knockout.fx Execution Harness</h1>
5.35 + </body>
5.36 +</html>