1.1 --- a/boot-script/pom.xml Wed Jun 04 06:36:44 2014 +0200
1.2 +++ b/boot-script/pom.xml Wed Jun 04 07:05:13 2014 +0200
1.3 @@ -20,10 +20,19 @@
1.4 <groupId>org.apache.felix</groupId>
1.5 <artifactId>maven-bundle-plugin</artifactId>
1.6 </plugin>
1.7 + <plugin>
1.8 + <groupId>org.netbeans.html</groupId>
1.9 + <artifactId>html4j-maven-plugin</artifactId>
1.10 + </plugin>
1.11 </plugins>
1.12 </build>
1.13 <dependencies>
1.14 <dependency>
1.15 + <groupId>org.netbeans.api</groupId>
1.16 + <artifactId>org-openide-util-lookup</artifactId>
1.17 + <scope>provided</scope>
1.18 + </dependency>
1.19 + <dependency>
1.20 <groupId>org.netbeans.html</groupId>
1.21 <artifactId>net.java.html.boot</artifactId>
1.22 <version>${project.version}</version>
1.23 @@ -46,5 +55,37 @@
1.24 <version>${project.version}</version>
1.25 <scope>test</scope>
1.26 </dependency>
1.27 + <dependency>
1.28 + <groupId>org.glassfish.grizzly</groupId>
1.29 + <artifactId>grizzly-http-server</artifactId>
1.30 + <version>${grizzly.version}</version>
1.31 + <scope>test</scope>
1.32 + </dependency>
1.33 + <dependency>
1.34 + <groupId>org.glassfish.grizzly</groupId>
1.35 + <artifactId>grizzly-websockets-server</artifactId>
1.36 + <version>${grizzly.version}</version>
1.37 + <scope>test</scope>
1.38 + <type>jar</type>
1.39 + </dependency>
1.40 + <dependency>
1.41 + <groupId>org.glassfish.grizzly</groupId>
1.42 + <artifactId>grizzly-http-servlet</artifactId>
1.43 + <version>${grizzly.version}</version>
1.44 + <scope>test</scope>
1.45 + </dependency>
1.46 + <dependency>
1.47 + <groupId>javax.servlet</groupId>
1.48 + <artifactId>javax.servlet-api</artifactId>
1.49 + <scope>test</scope>
1.50 + <version>3.1.0</version>
1.51 + </dependency>
1.52 + <dependency>
1.53 + <groupId>org.netbeans.html</groupId>
1.54 + <artifactId>ko4j</artifactId>
1.55 + <version>${project.version}</version>
1.56 + <scope>test</scope>
1.57 + <type>jar</type>
1.58 + </dependency>
1.59 </dependencies>
1.60 </project>
1.61 \ No newline at end of file
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/boot-script/src/test/java/net/java/html/boot/script/ko4j/DynamicHTTP.java Wed Jun 04 07:05:13 2014 +0200
2.3 @@ -0,0 +1,259 @@
2.4 +/**
2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2.6 + *
2.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
2.8 + *
2.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
2.10 + * Other names may be trademarks of their respective owners.
2.11 + *
2.12 + * The contents of this file are subject to the terms of either the GNU
2.13 + * General Public License Version 2 only ("GPL") or the Common
2.14 + * Development and Distribution License("CDDL") (collectively, the
2.15 + * "License"). You may not use this file except in compliance with the
2.16 + * License. You can obtain a copy of the License at
2.17 + * http://www.netbeans.org/cddl-gplv2.html
2.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
2.19 + * specific language governing permissions and limitations under the
2.20 + * License. When distributing the software, include this License Header
2.21 + * Notice in each file and include the License file at
2.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
2.23 + * particular file as subject to the "Classpath" exception as provided
2.24 + * by Oracle in the GPL Version 2 section of the License file that
2.25 + * accompanied this code. If applicable, add the following below the
2.26 + * License Header, with the fields enclosed by brackets [] replaced by
2.27 + * your own identifying information:
2.28 + * "Portions Copyrighted [year] [name of copyright owner]"
2.29 + *
2.30 + * Contributor(s):
2.31 + *
2.32 + * The Original Software is NetBeans. The Initial Developer of the Original
2.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
2.34 + *
2.35 + * If you wish your version of this file to be governed by only the CDDL
2.36 + * or only the GPL Version 2, indicate your decision by adding
2.37 + * "[Contributor] elects to include this software in this distribution
2.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
2.39 + * single choice of license, a recipient has the option to distribute
2.40 + * your version of this file under either the CDDL, the GPL Version 2 or
2.41 + * to extend the choice of license to its licensees as provided above.
2.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
2.43 + * Version 2 license, then the option applies only if the new code is
2.44 + * made subject to such option by the copyright holder.
2.45 + */
2.46 +package net.java.html.boot.script.ko4j;
2.47 +
2.48 +import java.io.ByteArrayInputStream;
2.49 +import java.io.ByteArrayOutputStream;
2.50 +import java.io.IOException;
2.51 +import java.io.InputStream;
2.52 +import java.io.OutputStream;
2.53 +import java.io.Reader;
2.54 +import java.net.URI;
2.55 +import java.net.URISyntaxException;
2.56 +import java.util.ArrayList;
2.57 +import java.util.List;
2.58 +import java.util.logging.Level;
2.59 +import java.util.logging.Logger;
2.60 +import org.glassfish.grizzly.PortRange;
2.61 +import org.glassfish.grizzly.http.server.HttpHandler;
2.62 +import org.glassfish.grizzly.http.server.HttpServer;
2.63 +import org.glassfish.grizzly.http.server.NetworkListener;
2.64 +import org.glassfish.grizzly.http.server.Request;
2.65 +import org.glassfish.grizzly.http.server.Response;
2.66 +import org.glassfish.grizzly.http.server.ServerConfiguration;
2.67 +import org.glassfish.grizzly.websockets.WebSocket;
2.68 +import org.glassfish.grizzly.websockets.WebSocketAddOn;
2.69 +import org.glassfish.grizzly.websockets.WebSocketApplication;
2.70 +import org.glassfish.grizzly.websockets.WebSocketEngine;
2.71 +
2.72 +/**
2.73 + *
2.74 + * @author Jaroslav Tulach <jtulach@netbeans.org>
2.75 + */
2.76 +final class DynamicHTTP extends HttpHandler {
2.77 + private static final Logger LOG = Logger.getLogger(DynamicHTTP.class.getName());
2.78 + private static int resourcesCount;
2.79 + private static List<Resource> resources;
2.80 + private static ServerConfiguration conf;
2.81 + private static HttpServer server;
2.82 +
2.83 + private DynamicHTTP() {
2.84 + }
2.85 +
2.86 + static URI initServer() throws Exception {
2.87 + server = HttpServer.createSimpleServer(null, new PortRange(8080, 65535));
2.88 + final WebSocketAddOn addon = new WebSocketAddOn();
2.89 + for (NetworkListener listener : server.getListeners()) {
2.90 + listener.registerAddOn(addon);
2.91 + }
2.92 + resources = new ArrayList<Resource>();
2.93 +
2.94 + conf = server.getServerConfiguration();
2.95 + final DynamicHTTP dh = new DynamicHTTP();
2.96 +
2.97 + conf.addHttpHandler(dh, "/");
2.98 +
2.99 + server.start();
2.100 +
2.101 + return pageURL("http", server, "/test.html");
2.102 + }
2.103 +
2.104 + @Override
2.105 + public void service(Request request, Response response) throws Exception {
2.106 + if ("/test.html".equals(request.getRequestURI())) {
2.107 + response.setContentType("text/html");
2.108 + final InputStream is = DynamicHTTP.class.getResourceAsStream("test.html");
2.109 + copyStream(is, response.getOutputStream(), null);
2.110 + return;
2.111 + }
2.112 + if ("/dynamic".equals(request.getRequestURI())) {
2.113 + String mimeType = request.getParameter("mimeType");
2.114 + List<String> params = new ArrayList<String>();
2.115 + boolean webSocket = false;
2.116 + for (int i = 0;; i++) {
2.117 + String p = request.getParameter("param" + i);
2.118 + if (p == null) {
2.119 + break;
2.120 + }
2.121 + if ("protocol:ws".equals(p)) {
2.122 + webSocket = true;
2.123 + continue;
2.124 + }
2.125 + params.add(p);
2.126 + }
2.127 + final String cnt = request.getParameter("content");
2.128 + String mangle = cnt.replace("%20", " ").replace("%0A", "\n");
2.129 + ByteArrayInputStream is = new ByteArrayInputStream(mangle.getBytes("UTF-8"));
2.130 + URI url;
2.131 + final Resource res = new Resource(is, mimeType, "/dynamic/res" + ++resourcesCount, params.toArray(new String[params.size()]));
2.132 + if (webSocket) {
2.133 + url = registerWebSocket(res);
2.134 + } else {
2.135 + url = registerResource(res);
2.136 + }
2.137 + response.getWriter().write(url.toString());
2.138 + response.getWriter().write("\n");
2.139 + return;
2.140 + }
2.141 +
2.142 + for (Resource r : resources) {
2.143 + if (r.httpPath.equals(request.getRequestURI())) {
2.144 + response.setContentType(r.httpType);
2.145 + r.httpContent.reset();
2.146 + String[] params = null;
2.147 + if (r.parameters.length != 0) {
2.148 + params = new String[r.parameters.length];
2.149 + for (int i = 0; i < r.parameters.length; i++) {
2.150 + params[i] = request.getParameter(r.parameters[i]);
2.151 + if (params[i] == null) {
2.152 + if ("http.method".equals(r.parameters[i])) {
2.153 + params[i] = request.getMethod().toString();
2.154 + } else if ("http.requestBody".equals(r.parameters[i])) {
2.155 + Reader rdr = request.getReader();
2.156 + StringBuilder sb = new StringBuilder();
2.157 + for (;;) {
2.158 + int ch = rdr.read();
2.159 + if (ch == -1) {
2.160 + break;
2.161 + }
2.162 + sb.append((char) ch);
2.163 + }
2.164 + params[i] = sb.toString();
2.165 + }
2.166 + }
2.167 + if (params[i] == null) {
2.168 + params[i] = "null";
2.169 + }
2.170 + }
2.171 + }
2.172 +
2.173 + copyStream(r.httpContent, response.getOutputStream(), null, params);
2.174 + }
2.175 + }
2.176 + }
2.177 +
2.178 + private URI registerWebSocket(Resource r) {
2.179 + WebSocketEngine.getEngine().register("", r.httpPath, new WS(r));
2.180 + return pageURL("ws", server, r.httpPath);
2.181 + }
2.182 +
2.183 + private URI registerResource(Resource r) {
2.184 + if (!resources.contains(r)) {
2.185 + resources.add(r);
2.186 + conf.addHttpHandler(this, r.httpPath);
2.187 + }
2.188 + return pageURL("http", server, r.httpPath);
2.189 + }
2.190 +
2.191 + private static URI pageURL(String proto, HttpServer server, final String page) {
2.192 + NetworkListener listener = server.getListeners().iterator().next();
2.193 + int port = listener.getPort();
2.194 + try {
2.195 + return new URI(proto + "://localhost:" + port + page);
2.196 + } catch (URISyntaxException ex) {
2.197 + throw new IllegalStateException(ex);
2.198 + }
2.199 + }
2.200 +
2.201 + static final class Resource {
2.202 +
2.203 + final InputStream httpContent;
2.204 + final String httpType;
2.205 + final String httpPath;
2.206 + final String[] parameters;
2.207 +
2.208 + Resource(InputStream httpContent, String httpType, String httpPath,
2.209 + String[] parameters) {
2.210 + httpContent.mark(Integer.MAX_VALUE);
2.211 + this.httpContent = httpContent;
2.212 + this.httpType = httpType;
2.213 + this.httpPath = httpPath;
2.214 + this.parameters = parameters;
2.215 + }
2.216 + }
2.217 +
2.218 + static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
2.219 + for (;;) {
2.220 + int ch = is.read();
2.221 + if (ch == -1) {
2.222 + break;
2.223 + }
2.224 + if (ch == '$' && params.length > 0) {
2.225 + int cnt = is.read() - '0';
2.226 + if (baseURL != null && cnt == 'U' - '0') {
2.227 + os.write(baseURL.getBytes("UTF-8"));
2.228 + } else {
2.229 + if (cnt >= 0 && cnt < params.length) {
2.230 + os.write(params[cnt].getBytes("UTF-8"));
2.231 + } else {
2.232 + os.write('$');
2.233 + os.write(cnt + '0');
2.234 + }
2.235 + }
2.236 + } else {
2.237 + os.write(ch);
2.238 + }
2.239 + }
2.240 + }
2.241 +
2.242 + private static class WS extends WebSocketApplication {
2.243 + private final Resource r;
2.244 +
2.245 + private WS(Resource r) {
2.246 + this.r = r;
2.247 + }
2.248 +
2.249 + @Override
2.250 + public void onMessage(WebSocket socket, String text) {
2.251 + try {
2.252 + r.httpContent.reset();
2.253 + ByteArrayOutputStream out = new ByteArrayOutputStream();
2.254 + copyStream(r.httpContent, out, null, text);
2.255 + String s = new String(out.toByteArray(), "UTF-8");
2.256 + socket.send(s);
2.257 + } catch (IOException ex) {
2.258 + LOG.log(Level.WARNING, "Error processing message " + text, ex);
2.259 + }
2.260 + }
2.261 + }
2.262 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/boot-script/src/test/java/net/java/html/boot/script/ko4j/KOCase.java Wed Jun 04 07:05:13 2014 +0200
3.3 @@ -0,0 +1,127 @@
3.4 +/**
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 + *
3.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
3.8 + *
3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
3.10 + * Other names may be trademarks of their respective owners.
3.11 + *
3.12 + * The contents of this file are subject to the terms of either the GNU
3.13 + * General Public License Version 2 only ("GPL") or the Common
3.14 + * Development and Distribution License("CDDL") (collectively, the
3.15 + * "License"). You may not use this file except in compliance with the
3.16 + * License. You can obtain a copy of the License at
3.17 + * http://www.netbeans.org/cddl-gplv2.html
3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.19 + * specific language governing permissions and limitations under the
3.20 + * License. When distributing the software, include this License Header
3.21 + * Notice in each file and include the License file at
3.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
3.23 + * particular file as subject to the "Classpath" exception as provided
3.24 + * by Oracle in the GPL Version 2 section of the License file that
3.25 + * accompanied this code. If applicable, add the following below the
3.26 + * License Header, with the fields enclosed by brackets [] replaced by
3.27 + * your own identifying information:
3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
3.29 + *
3.30 + * Contributor(s):
3.31 + *
3.32 + * The Original Software is NetBeans. The Initial Developer of the Original
3.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
3.34 + *
3.35 + * If you wish your version of this file to be governed by only the CDDL
3.36 + * or only the GPL Version 2, indicate your decision by adding
3.37 + * "[Contributor] elects to include this software in this distribution
3.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
3.39 + * single choice of license, a recipient has the option to distribute
3.40 + * your version of this file under either the CDDL, the GPL Version 2 or
3.41 + * to extend the choice of license to its licensees as provided above.
3.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
3.43 + * Version 2 license, then the option applies only if the new code is
3.44 + * made subject to such option by the copyright holder.
3.45 + */
3.46 +package net.java.html.boot.script.ko4j;
3.47 +
3.48 +import java.io.Closeable;
3.49 +import java.io.IOException;
3.50 +import java.lang.reflect.InvocationTargetException;
3.51 +import java.lang.reflect.Method;
3.52 +import java.util.concurrent.Executor;
3.53 +import java.util.concurrent.Executors;
3.54 +import org.apidesign.html.boot.spi.Fn;
3.55 +import org.testng.ITest;
3.56 +import org.testng.annotations.Test;
3.57 +
3.58 +/**
3.59 + *
3.60 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.61 + */
3.62 +public final class KOCase implements ITest, Runnable {
3.63 + private static final Executor JS = Executors.newSingleThreadExecutor();
3.64 + private final Fn.Presenter p;
3.65 + private final Method m;
3.66 + private Object result;
3.67 + private Object inst;
3.68 + private int count;
3.69 +
3.70 + KOCase(Fn.Presenter p, Method m) {
3.71 + this.p = p;
3.72 + this.m = m;
3.73 + }
3.74 +
3.75 + @Override
3.76 + public String getTestName() {
3.77 + return m.getName();
3.78 + }
3.79 +
3.80 + @Test
3.81 + public synchronized void executeTest() throws Exception {
3.82 + if (result == null) {
3.83 + JS.execute(this);
3.84 + wait();
3.85 + }
3.86 + if (result instanceof Exception) {
3.87 + throw (Exception)result;
3.88 + }
3.89 + if (result instanceof Error) {
3.90 + throw (Error)result;
3.91 + }
3.92 + }
3.93 +
3.94 + @Override
3.95 + public synchronized void run() {
3.96 + boolean notify = true;
3.97 + Closeable a = Fn.activate(p);
3.98 + try {
3.99 + if (inst == null) {
3.100 + inst = m.getDeclaringClass().newInstance();
3.101 + }
3.102 + result = m.invoke(inst);
3.103 + if (result == null) {
3.104 + result = this;
3.105 + }
3.106 + } catch (InvocationTargetException ex) {
3.107 + Throwable r = ex.getTargetException();
3.108 + if (r instanceof InterruptedException) {
3.109 + if (count++ < 10000) {
3.110 + notify = false;
3.111 + JS.execute(this);
3.112 + return;
3.113 + }
3.114 + }
3.115 + result = r;
3.116 + } catch (Exception ex) {
3.117 + result = ex;
3.118 + } finally {
3.119 + if (notify) {
3.120 + notifyAll();
3.121 + }
3.122 + try {
3.123 + a.close();
3.124 + } catch (IOException ex) {
3.125 + throw new IllegalStateException(ex);
3.126 + }
3.127 + }
3.128 + }
3.129 +
3.130 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/boot-script/src/test/java/net/java/html/boot/script/ko4j/KnockoutEnvJSTest.java Wed Jun 04 07:05:13 2014 +0200
4.3 @@ -0,0 +1,232 @@
4.4 +/**
4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4.6 + *
4.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
4.8 + *
4.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
4.10 + * Other names may be trademarks of their respective owners.
4.11 + *
4.12 + * The contents of this file are subject to the terms of either the GNU
4.13 + * General Public License Version 2 only ("GPL") or the Common
4.14 + * Development and Distribution License("CDDL") (collectively, the
4.15 + * "License"). You may not use this file except in compliance with the
4.16 + * License. You can obtain a copy of the License at
4.17 + * http://www.netbeans.org/cddl-gplv2.html
4.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
4.19 + * specific language governing permissions and limitations under the
4.20 + * License. When distributing the software, include this License Header
4.21 + * Notice in each file and include the License file at
4.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
4.23 + * particular file as subject to the "Classpath" exception as provided
4.24 + * by Oracle in the GPL Version 2 section of the License file that
4.25 + * accompanied this code. If applicable, add the following below the
4.26 + * License Header, with the fields enclosed by brackets [] replaced by
4.27 + * your own identifying information:
4.28 + * "Portions Copyrighted [year] [name of copyright owner]"
4.29 + *
4.30 + * Contributor(s):
4.31 + *
4.32 + * The Original Software is NetBeans. The Initial Developer of the Original
4.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
4.34 + *
4.35 + * If you wish your version of this file to be governed by only the CDDL
4.36 + * or only the GPL Version 2, indicate your decision by adding
4.37 + * "[Contributor] elects to include this software in this distribution
4.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
4.39 + * single choice of license, a recipient has the option to distribute
4.40 + * your version of this file under either the CDDL, the GPL Version 2 or
4.41 + * to extend the choice of license to its licensees as provided above.
4.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
4.43 + * Version 2 license, then the option applies only if the new code is
4.44 + * made subject to such option by the copyright holder.
4.45 + */
4.46 +package net.java.html.boot.script.ko4j;
4.47 +
4.48 +import java.io.BufferedReader;
4.49 +import java.io.IOException;
4.50 +import java.io.InputStreamReader;
4.51 +import java.lang.annotation.Annotation;
4.52 +import java.lang.reflect.Method;
4.53 +import java.net.URI;
4.54 +import java.net.URISyntaxException;
4.55 +import java.net.URL;
4.56 +import java.net.URLConnection;
4.57 +import java.util.ArrayList;
4.58 +import java.util.List;
4.59 +import java.util.Map;
4.60 +import java.util.concurrent.Executor;
4.61 +import java.util.concurrent.Executors;
4.62 +import net.java.html.BrwsrCtx;
4.63 +import net.java.html.boot.BrowserBuilder;
4.64 +import net.java.html.boot.script.ScriptPresenter;
4.65 +import net.java.html.js.JavaScriptBody;
4.66 +import net.java.html.js.JavaScriptResource;
4.67 +import org.apidesign.html.boot.spi.Fn;
4.68 +import org.apidesign.html.context.spi.Contexts;
4.69 +import org.apidesign.html.json.spi.Technology;
4.70 +import org.apidesign.html.json.spi.Transfer;
4.71 +import org.apidesign.html.json.spi.WSTransfer;
4.72 +import org.apidesign.html.json.tck.KOTest;
4.73 +import org.apidesign.html.json.tck.KnockoutTCK;
4.74 +import org.netbeans.html.boot.impl.FnContext;
4.75 +import org.netbeans.html.ko4j.KO4J;
4.76 +import org.openide.util.lookup.ServiceProvider;
4.77 +import org.testng.Assert;
4.78 +import static org.testng.Assert.*;
4.79 +import org.testng.annotations.Factory;
4.80 +
4.81 +/**
4.82 + *
4.83 + * @author Jaroslav Tulach <jtulach@netbeans.org>
4.84 + */
4.85 +@JavaScriptResource("/META-INF/resources/webjars/envjs/1.2/env.rhino.js")
4.86 +@ServiceProvider(service = KnockoutTCK.class)
4.87 +public final class KnockoutEnvJSTest extends KnockoutTCK {
4.88 + private static Class<?> browserClass;
4.89 + private static Fn.Presenter browserContext;
4.90 +
4.91 + public KnockoutEnvJSTest() {
4.92 + }
4.93 +
4.94 + @Factory public static Object[] compatibilityTests() throws Exception {
4.95 + Class[] arr = testClasses();
4.96 + for (int i = 0; i < arr.length; i++) {
4.97 + assertEquals(
4.98 + arr[i].getClassLoader(),
4.99 + KnockoutEnvJSTest.class.getClassLoader(),
4.100 + "All classes loaded by the same classloader"
4.101 + );
4.102 + }
4.103 +
4.104 + URI uri = DynamicHTTP.initServer();
4.105 +
4.106 + final BrowserBuilder bb = BrowserBuilder.newBrowser(new ScriptPresenter()).
4.107 + loadClass(KnockoutEnvJSTest.class).
4.108 + loadPage(uri.toString()).
4.109 + invoke("initialized");
4.110 +
4.111 + Executors.newSingleThreadExecutor().submit(new Runnable() {
4.112 + @Override
4.113 + public void run() {
4.114 + bb.showAndWait();
4.115 + }
4.116 + });
4.117 +
4.118 + ClassLoader l = getClassLoader();
4.119 + List<Object> res = new ArrayList<Object>();
4.120 + for (int i = 0; i < arr.length; i++) {
4.121 + Class<?> c = Class.forName(arr[i].getName(), true, l);
4.122 + seekKOTests(c, res);
4.123 + }
4.124 + Class<?> c = Class.forName(LessCallbacksCheck.class.getName(), true, l);
4.125 + seekKOTests(c, res);
4.126 + return res.toArray();
4.127 + }
4.128 +
4.129 + private static void seekKOTests(Class<?> c, List<Object> res) throws SecurityException, ClassNotFoundException {
4.130 + Class<? extends Annotation> koTest =
4.131 + c.getClassLoader().loadClass(KOTest.class.getName()).
4.132 + asSubclass(Annotation.class);
4.133 + for (Method m : c.getMethods()) {
4.134 + if (m.getAnnotation(koTest) != null) {
4.135 + res.add(new KOCase(browserContext, m));
4.136 + }
4.137 + }
4.138 + }
4.139 +
4.140 + static synchronized ClassLoader getClassLoader() throws InterruptedException {
4.141 + while (browserClass == null) {
4.142 + KnockoutEnvJSTest.class.wait();
4.143 + }
4.144 + return browserClass.getClassLoader();
4.145 + }
4.146 +
4.147 + public static synchronized void initialized(Class<?> browserCls) throws Exception {
4.148 + browserClass = browserCls;
4.149 + browserContext = Fn.activePresenter();
4.150 + KnockoutEnvJSTest.class.notifyAll();
4.151 + }
4.152 +
4.153 + public static void initialized() throws Exception {
4.154 + Assert.assertSame(
4.155 + KnockoutEnvJSTest.class.getClassLoader(),
4.156 + ClassLoader.getSystemClassLoader(),
4.157 + "No special classloaders"
4.158 + );
4.159 + KnockoutEnvJSTest.initialized(KnockoutEnvJSTest.class);
4.160 + browserContext = Fn.activePresenter();
4.161 + }
4.162 +
4.163 + @Override
4.164 + public BrwsrCtx createContext() {
4.165 + KO4J fx = new KO4J(browserContext);
4.166 + Contexts.Builder cb = Contexts.newBuilder().
4.167 + register(Technology.class, fx.knockout(), 10).
4.168 + register(Transfer.class, fx.transfer(), 10);
4.169 + cb.register(Executor.class, (Executor)browserContext, 10);
4.170 + cb.register(Fn.Presenter.class, browserContext, 10);
4.171 + BrwsrCtx ctx = cb.build();
4.172 + return ctx;
4.173 + }
4.174 +
4.175 + @Override
4.176 + public Object createJSON(Map<String, Object> values) {
4.177 + Object json = createJSON();
4.178 + for (Map.Entry<String, Object> entry : values.entrySet()) {
4.179 + setProperty(json, entry.getKey(), entry.getValue());
4.180 + }
4.181 + return json;
4.182 + }
4.183 +
4.184 + @JavaScriptBody(args = {}, body = "return new Object();")
4.185 + private static native Object createJSON();
4.186 + @JavaScriptBody(args = { "json", "key", "value" }, body = "json[key] = value;")
4.187 + private static native void setProperty(Object json, String key, Object value);
4.188 +
4.189 + @Override
4.190 + @JavaScriptBody(args = { "s", "args" }, body = ""
4.191 + + "var f = new Function(s); "
4.192 + + "return f.apply(null, args);"
4.193 + )
4.194 + public native Object executeScript(String script, Object[] arguments);
4.195 +
4.196 + @JavaScriptBody(args = { }, body =
4.197 + "var h;"
4.198 + + "if (!!window && !!window.location && !!window.location.href)\n"
4.199 + + " h = window.location.href;\n"
4.200 + + "else "
4.201 + + " h = null;"
4.202 + + "return h;\n"
4.203 + )
4.204 + private static native String findBaseURL();
4.205 +
4.206 + @Override
4.207 + public URI prepareURL(String content, String mimeType, String[] parameters) {
4.208 + try {
4.209 + final URL baseURL = new URL(findBaseURL());
4.210 + StringBuilder sb = new StringBuilder();
4.211 + sb.append("/dynamic?mimeType=").append(mimeType);
4.212 + for (int i = 0; i < parameters.length; i++) {
4.213 + sb.append("¶m" + i).append("=").append(parameters[i]);
4.214 + }
4.215 + String mangle = content.replace("\n", "%0a")
4.216 + .replace("\"", "\\\"").replace(" ", "%20");
4.217 + sb.append("&content=").append(mangle);
4.218 +
4.219 + URL query = new URL(baseURL, sb.toString());
4.220 + URLConnection c = query.openConnection();
4.221 + BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
4.222 + URI connectTo = new URI(br.readLine());
4.223 + return connectTo;
4.224 + } catch (IOException ex) {
4.225 + throw new IllegalStateException(ex);
4.226 + } catch (URISyntaxException ex) {
4.227 + throw new IllegalStateException(ex);
4.228 + }
4.229 + }
4.230 +
4.231 + @Override
4.232 + public boolean canFailWebSocketTest() {
4.233 + return true;
4.234 + }
4.235 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/boot-script/src/test/java/net/java/html/boot/script/ko4j/LessCallbacksCheck.java Wed Jun 04 07:05:13 2014 +0200
5.3 @@ -0,0 +1,97 @@
5.4 +/**
5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5.6 + *
5.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
5.8 + *
5.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
5.10 + * Other names may be trademarks of their respective owners.
5.11 + *
5.12 + * The contents of this file are subject to the terms of either the GNU
5.13 + * General Public License Version 2 only ("GPL") or the Common
5.14 + * Development and Distribution License("CDDL") (collectively, the
5.15 + * "License"). You may not use this file except in compliance with the
5.16 + * License. You can obtain a copy of the License at
5.17 + * http://www.netbeans.org/cddl-gplv2.html
5.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
5.19 + * specific language governing permissions and limitations under the
5.20 + * License. When distributing the software, include this License Header
5.21 + * Notice in each file and include the License file at
5.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
5.23 + * particular file as subject to the "Classpath" exception as provided
5.24 + * by Oracle in the GPL Version 2 section of the License file that
5.25 + * accompanied this code. If applicable, add the following below the
5.26 + * License Header, with the fields enclosed by brackets [] replaced by
5.27 + * your own identifying information:
5.28 + * "Portions Copyrighted [year] [name of copyright owner]"
5.29 + *
5.30 + * Contributor(s):
5.31 + *
5.32 + * The Original Software is NetBeans. The Initial Developer of the Original
5.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
5.34 + *
5.35 + * If you wish your version of this file to be governed by only the CDDL
5.36 + * or only the GPL Version 2, indicate your decision by adding
5.37 + * "[Contributor] elects to include this software in this distribution
5.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
5.39 + * single choice of license, a recipient has the option to distribute
5.40 + * your version of this file under either the CDDL, the GPL Version 2 or
5.41 + * to extend the choice of license to its licensees as provided above.
5.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
5.43 + * Version 2 license, then the option applies only if the new code is
5.44 + * made subject to such option by the copyright holder.
5.45 + */
5.46 +package net.java.html.boot.script.ko4j;
5.47 +
5.48 +import java.io.PrintWriter;
5.49 +import java.io.StringWriter;
5.50 +import net.java.html.json.ComputedProperty;
5.51 +import net.java.html.json.Model;
5.52 +import net.java.html.json.Property;
5.53 +import org.apidesign.html.json.tck.KOTest;
5.54 +
5.55 +/**
5.56 + *
5.57 + * @author Jaroslav Tulach <jtulach@netbeans.org>
5.58 + */
5.59 +@Model(className = "LessCalls", properties = {
5.60 + @Property(name = "value", type = int.class)
5.61 +})
5.62 +public class LessCallbacksCheck {
5.63 + private static StringWriter sw;
5.64 +
5.65 + @ComputedProperty static int plusOne(int value) {
5.66 + if (sw == null) {
5.67 + sw = new StringWriter();
5.68 + }
5.69 + new Exception("Who calls me?").printStackTrace(
5.70 + new PrintWriter(sw)
5.71 + );
5.72 + return value + 1;
5.73 + }
5.74 +
5.75 + @KOTest public void dontCallForInitialValueBackToJavaVM() {
5.76 + sw = null;
5.77 + LessCalls m = new LessCalls(10).applyBindings();
5.78 + assert m.getPlusOne() == 11 : "Expecting 11: " + m.getPlusOne();
5.79 +
5.80 + assert sw != null : "StringWriter should be initialized: " + sw;
5.81 +
5.82 + if (sw.toString().contains("$JsCallbacks$")) {
5.83 + assert false : "Don't call for initial value via JsCallbacks:\n" + sw;
5.84 + }
5.85 + }
5.86 +
5.87 + @KOTest public void dontCallForChangeValueBackToJavaVM() {
5.88 + LessCalls m = new LessCalls(10).applyBindings();
5.89 + assert m.getPlusOne() == 11 : "Expecting 11: " + m.getPlusOne();
5.90 +
5.91 + sw = null;
5.92 + m.setValue(5);
5.93 + assert m.getPlusOne() == 6: "Expecting 6: " + m.getPlusOne();
5.94 + assert sw != null : "StringWriter should be initialized: " + sw;
5.95 +
5.96 + if (sw.toString().contains("$JsCallbacks$")) {
5.97 + assert false : "Don't call for initial value via JsCallbacks:\n" + sw;
5.98 + }
5.99 + }
5.100 +}
6.1 --- a/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java Wed Jun 04 06:36:44 2014 +0200
6.2 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java Wed Jun 04 07:05:13 2014 +0200
6.3 @@ -151,7 +151,7 @@
6.4 }
6.5 final String res;
6.6 if (r.value().startsWith("/")) {
6.7 - res = r.value();
6.8 + res = r.value().substring(1);
6.9 } else {
6.10 res = findPkg(e).replace('.', '/') + "/" + r.value();
6.11 }
6.12 @@ -164,7 +164,12 @@
6.13 FileObject os2 = processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", res);
6.14 os2.openInputStream().close();
6.15 } catch (IOException ex2) {
6.16 - msg.printMessage(Diagnostic.Kind.ERROR, "Cannot find " + res + " in " + res + " package", e);
6.17 + try {
6.18 + FileObject os3 = processingEnv.getFiler().getResource(StandardLocation.CLASS_PATH, "", res);
6.19 + os3.openInputStream().close();
6.20 + } catch (IOException ex3) {
6.21 + msg.printMessage(Diagnostic.Kind.ERROR, "Cannot find resource " + res, e);
6.22 + }
6.23 }
6.24 }
6.25