1.1 --- a/boot/src/main/java/net/java/html/boot/BrowserBuilder.java Mon Jun 24 16:51:33 2013 +0200
1.2 +++ b/boot/src/main/java/net/java/html/boot/BrowserBuilder.java Mon Jun 24 16:51:38 2013 +0200
1.3 @@ -21,6 +21,7 @@
1.4 package net.java.html.boot;
1.5
1.6 import java.io.IOException;
1.7 +import java.net.MalformedURLException;
1.8 import java.net.URL;
1.9 import java.util.Collection;
1.10 import java.util.Enumeration;
1.11 @@ -61,9 +62,22 @@
1.12 }
1.13
1.14 FImpl impl = new FImpl(clazz.getClassLoader());
1.15 - URL url = clazz.getResource(resource);
1.16 + URL url = null;
1.17 + MalformedURLException mal = null;
1.18 + try {
1.19 + url = new URL(resource);
1.20 + } catch (MalformedURLException ex) {
1.21 + mal = ex;
1.22 + }
1.23 if (url == null) {
1.24 - throw new IllegalStateException("Can't find resouce: " + resource + " relative to " + clazz);
1.25 + url = clazz.getResource(resource);
1.26 + }
1.27 + if (url == null) {
1.28 + IllegalStateException ise = new IllegalStateException("Can't find resouce: " + resource + " relative to " + clazz);
1.29 + if (mal != null) {
1.30 + ise.initCause(mal);
1.31 + }
1.32 + throw ise;
1.33 }
1.34
1.35 for (Fn.Presenter dfnr : ServiceLoader.load(Fn.Presenter.class)) {
2.1 --- a/ko-fx/pom.xml Mon Jun 24 16:51:33 2013 +0200
2.2 +++ b/ko-fx/pom.xml Mon Jun 24 16:51:38 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>org.glassfish.grizzly</groupId>
2.9 + <artifactId>grizzly-http-server</artifactId>
2.10 + <version>2.3.3</version>
2.11 + <scope>test</scope>
2.12 + </dependency>
2.13 </dependencies>
2.14 </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/DynamicHTTP.java Mon Jun 24 16:51:38 2013 +0200
3.3 @@ -0,0 +1,190 @@
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.io.ByteArrayInputStream;
3.27 +import java.io.IOException;
3.28 +import java.io.InputStream;
3.29 +import java.io.OutputStream;
3.30 +import java.io.Reader;
3.31 +import java.net.URI;
3.32 +import java.net.URISyntaxException;
3.33 +import java.util.ArrayList;
3.34 +import java.util.List;
3.35 +import org.glassfish.grizzly.PortRange;
3.36 +import org.glassfish.grizzly.http.server.HttpHandler;
3.37 +import org.glassfish.grizzly.http.server.HttpServer;
3.38 +import org.glassfish.grizzly.http.server.NetworkListener;
3.39 +import org.glassfish.grizzly.http.server.Request;
3.40 +import org.glassfish.grizzly.http.server.Response;
3.41 +import org.glassfish.grizzly.http.server.ServerConfiguration;
3.42 +import org.glassfish.grizzly.threadpool.ThreadPoolConfig;
3.43 +
3.44 +/**
3.45 + *
3.46 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.47 + */
3.48 +final class DynamicHTTP extends HttpHandler {
3.49 + private static int resourcesCount;
3.50 + private static List<Resource> resources;
3.51 + private static ServerConfiguration conf;
3.52 + private static HttpServer server;
3.53 +
3.54 + private DynamicHTTP() {
3.55 + }
3.56 +
3.57 + static URI initServer() throws Exception {
3.58 + server = HttpServer.createSimpleServer(null, new PortRange(8080, 65535));
3.59 + resources = new ArrayList<Resource>();
3.60 +
3.61 + conf = server.getServerConfiguration();
3.62 + final DynamicHTTP dh = new DynamicHTTP();
3.63 +
3.64 + conf.addHttpHandler(dh, "/");
3.65 +
3.66 + server.start();
3.67 +
3.68 + return pageURL(server, "/test.html");
3.69 + }
3.70 +
3.71 + @Override
3.72 + public void service(Request request, Response response) throws Exception {
3.73 + if ("/test.html".equals(request.getRequestURI())) {
3.74 + response.setContentType("text/html");
3.75 + final InputStream is = DynamicHTTP.class.getResourceAsStream("test.html");
3.76 + copyStream(is, response.getOutputStream(), null);
3.77 + return;
3.78 + }
3.79 + if ("/dynamic".equals(request.getRequestURI())) {
3.80 + String mimeType = request.getParameter("mimeType");
3.81 + List<String> params = new ArrayList<String>();
3.82 + for (int i = 0;; i++) {
3.83 + String p = request.getParameter("param" + i);
3.84 + if (p == null) {
3.85 + break;
3.86 + }
3.87 + params.add(p);
3.88 + }
3.89 + final String cnt = request.getParameter("content");
3.90 + String mangle = cnt.replace("%20", " ").replace("%0A", "\n");
3.91 + ByteArrayInputStream is = new ByteArrayInputStream(mangle.getBytes("UTF-8"));
3.92 + URI url = registerResource(new Resource(is, mimeType, "/dynamic/res" + ++resourcesCount, params.toArray(new String[params.size()])));
3.93 + response.getWriter().write(url.toString());
3.94 + response.getWriter().write("\n");
3.95 + return;
3.96 + }
3.97 +
3.98 + for (Resource r : resources) {
3.99 + if (r.httpPath.equals(request.getRequestURI())) {
3.100 + response.setContentType(r.httpType);
3.101 + r.httpContent.reset();
3.102 + String[] params = null;
3.103 + if (r.parameters.length != 0) {
3.104 + params = new String[r.parameters.length];
3.105 + for (int i = 0; i < r.parameters.length; i++) {
3.106 + params[i] = request.getParameter(r.parameters[i]);
3.107 + if (params[i] == null) {
3.108 + if ("http.method".equals(r.parameters[i])) {
3.109 + params[i] = request.getMethod().toString();
3.110 + } else if ("http.requestBody".equals(r.parameters[i])) {
3.111 + Reader rdr = request.getReader();
3.112 + StringBuilder sb = new StringBuilder();
3.113 + for (;;) {
3.114 + int ch = rdr.read();
3.115 + if (ch == -1) {
3.116 + break;
3.117 + }
3.118 + sb.append((char) ch);
3.119 + }
3.120 + params[i] = sb.toString();
3.121 + }
3.122 + }
3.123 + if (params[i] == null) {
3.124 + params[i] = "null";
3.125 + }
3.126 + }
3.127 + }
3.128 +
3.129 + copyStream(r.httpContent, response.getOutputStream(), null, params);
3.130 + }
3.131 + }
3.132 + }
3.133 +
3.134 + private URI registerResource(Resource r) {
3.135 + if (!resources.contains(r)) {
3.136 + resources.add(r);
3.137 + conf.addHttpHandler(this, r.httpPath);
3.138 + }
3.139 + return pageURL(server, r.httpPath);
3.140 + }
3.141 +
3.142 + private static URI pageURL(HttpServer server, final String page) {
3.143 + NetworkListener listener = server.getListeners().iterator().next();
3.144 + int port = listener.getPort();
3.145 + try {
3.146 + return new URI("http://localhost:" + port + page);
3.147 + } catch (URISyntaxException ex) {
3.148 + throw new IllegalStateException(ex);
3.149 + }
3.150 + }
3.151 +
3.152 + static final class Resource {
3.153 +
3.154 + final InputStream httpContent;
3.155 + final String httpType;
3.156 + final String httpPath;
3.157 + final String[] parameters;
3.158 +
3.159 + Resource(InputStream httpContent, String httpType, String httpPath,
3.160 + String[] parameters) {
3.161 + httpContent.mark(Integer.MAX_VALUE);
3.162 + this.httpContent = httpContent;
3.163 + this.httpType = httpType;
3.164 + this.httpPath = httpPath;
3.165 + this.parameters = parameters;
3.166 + }
3.167 + }
3.168 +
3.169 + static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
3.170 + for (;;) {
3.171 + int ch = is.read();
3.172 + if (ch == -1) {
3.173 + break;
3.174 + }
3.175 + if (ch == '$' && params.length > 0) {
3.176 + int cnt = is.read() - '0';
3.177 + if (baseURL != null && cnt == 'U' - '0') {
3.178 + os.write(baseURL.getBytes("UTF-8"));
3.179 + } else {
3.180 + if (cnt >= 0 && cnt < params.length) {
3.181 + os.write(params[cnt].getBytes("UTF-8"));
3.182 + } else {
3.183 + os.write('$');
3.184 + os.write(cnt + '0');
3.185 + }
3.186 + }
3.187 + } else {
3.188 + os.write(ch);
3.189 + }
3.190 + }
3.191 + }
3.192 +
3.193 +}
4.1 --- a/ko-fx/src/test/java/org/apidesign/html/kofx/KnockoutFXTest.java Mon Jun 24 16:51:33 2013 +0200
4.2 +++ b/ko-fx/src/test/java/org/apidesign/html/kofx/KnockoutFXTest.java Mon Jun 24 16:51:38 2013 +0200
4.3 @@ -23,10 +23,8 @@
4.4 import java.io.BufferedReader;
4.5 import java.io.IOException;
4.6 import java.io.InputStreamReader;
4.7 -import java.io.PrintWriter;
4.8 import java.lang.annotation.Annotation;
4.9 import java.lang.reflect.Method;
4.10 -import java.net.HttpURLConnection;
4.11 import java.net.URI;
4.12 import java.net.URISyntaxException;
4.13 import java.net.URL;
4.14 @@ -48,8 +46,6 @@
4.15 import org.openide.util.lookup.ServiceProvider;
4.16 import org.testng.annotations.Factory;
4.17 import static org.testng.Assert.*;
4.18 -import org.testng.ITest;
4.19 -import org.testng.annotations.Test;
4.20
4.21 /**
4.22 *
4.23 @@ -59,7 +55,7 @@
4.24 public final class KnockoutFXTest extends KnockoutTCK {
4.25 public KnockoutFXTest() {
4.26 }
4.27 -
4.28 +
4.29 @Factory public static Object[] compatibilityTests() throws Exception {
4.30 Class[] arr = testClasses();
4.31 ClassLoader l = KnockoutFXTest.class.getClassLoader();
4.32 @@ -84,8 +80,10 @@
4.33 }
4.34 R r = new R();
4.35
4.36 + URI uri = DynamicHTTP.initServer();
4.37 +
4.38 final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(KnockoutFXTest.class).
4.39 - loadPage("test.html").
4.40 + loadPage(uri.toString()).
4.41 onClassReady(r.browserClass).
4.42 onLoad(r);
4.43 Executors.newSingleThreadExecutor().submit(new Runnable() {