1.1 --- a/context/src/main/java/org/netbeans/html/context/spi/Contexts.java Mon Feb 29 05:33:31 2016 +0100
1.2 +++ b/context/src/main/java/org/netbeans/html/context/spi/Contexts.java Mon Feb 29 05:39:42 2016 +0100
1.3 @@ -42,6 +42,7 @@
1.4 */
1.5 package org.netbeans.html.context.spi;
1.6
1.7 +import java.lang.annotation.Documented;
1.8 import java.lang.annotation.ElementType;
1.9 import java.lang.annotation.Retention;
1.10 import java.lang.annotation.RetentionPolicy;
1.11 @@ -159,6 +160,7 @@
1.12 */
1.13 @Retention(RetentionPolicy.RUNTIME)
1.14 @Target(ElementType.TYPE)
1.15 + @Documented
1.16 public @interface Id {
1.17 /** Identifier(s) for the implementation.
1.18 *
2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/RcvrJSON.java Mon Feb 29 05:33:31 2016 +0100
2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/RcvrJSON.java Mon Feb 29 05:39:42 2016 +0100
2.3 @@ -42,8 +42,7 @@
2.4 */
2.5 package org.netbeans.html.json.impl;
2.6
2.7 -import java.util.ArrayList;
2.8 -import net.java.html.BrwsrCtx;
2.9 +import java.util.concurrent.Callable;
2.10
2.11 /** Super type for those who wish to receive JSON messages.
2.12 *
2.13 @@ -94,11 +93,20 @@
2.14 };
2.15 }
2.16
2.17 - public static MsgEvnt createMessage(final Object value) {
2.18 + public static MsgEvnt createMessage(final Object value) {
2.19 return new MsgEvnt() {
2.20 + private Object val = value;
2.21 +
2.22 @Override
2.23 public Object[] getValues() {
2.24 - return value instanceof Object[] ? (Object[])value : new Object[] { value };
2.25 + if (val instanceof Callable) {
2.26 + try {
2.27 + val = ((Callable)val).call();
2.28 + } catch (Exception ex) {
2.29 + throw new IllegalStateException("Cannot compute " + val, ex);
2.30 + }
2.31 + }
2.32 + return val instanceof Object[] ? (Object[])val : new Object[] { val };
2.33 }
2.34
2.35 @Override
3.1 --- a/pom.xml Mon Feb 29 05:33:31 2016 +0100
3.2 +++ b/pom.xml Mon Feb 29 05:39:42 2016 +0100
3.3 @@ -36,6 +36,7 @@
3.4 <module>equinox-agentclass-hook</module>
3.5 <module>boot-script</module>
3.6 <module>boot-agent-test</module>
3.7 + <module>xhr4j</module>
3.8 </modules>
3.9 <licenses>
3.10 <license>
3.11 @@ -123,7 +124,7 @@
3.12 <subpackages>${publicPackages}</subpackages>
3.13 <skip>false</skip>
3.14 <excludePackageNames>
3.15 -org.netbeans.html.boot.impl:org.netbeans.html.boot.fx:org.netbeans.html.context.impl:org.netbeans.html.equinox.*:org.netbeans.html.geo.impl:org.netbeans.html.json.impl:org.netbeans.html.sound.impl:org.netbeans.html.ko.*:org.netbeans.html.ko4j:org.netbeans.html.mojo:org.netbeans.html.wstyrus:net.java.html.js.tests:net.java.html.json.tests
3.16 +org.netbeans.html.boot.impl:org.netbeans.html.boot.fx:org.netbeans.html.context.impl:org.netbeans.html.equinox.*:org.netbeans.html.geo.impl:org.netbeans.html.json.impl:org.netbeans.html.sound.impl:org.netbeans.html.ko.*:org.netbeans.html.ko4j:org.netbeans.html.mojo:org.netbeans.html.wstyrus:net.java.html.js.tests:net.java.html.json.tests:org.netbeans.html.xhr4j
3.17 </excludePackageNames>
3.18 <groups>
3.19 <group>
4.1 --- a/src/main/javadoc/overview.html Mon Feb 29 05:33:31 2016 +0100
4.2 +++ b/src/main/javadoc/overview.html Mon Feb 29 05:39:42 2016 +0100
4.3 @@ -575,6 +575,7 @@
4.4 online:
4.5 <ul>
4.6 <li>Current <a target="_blank" href="http://bits.netbeans.org/html+java/dev/">development</a> version
4.7 + <li>Version <a target="_blank" href="http://bits.netbeans.org/html+java/1.2.3">1.2.3</a>
4.8 <li>Version <a target="_blank" href="http://bits.netbeans.org/html+java/1.1">1.1</a>
4.9 <li>Version <a target="_blank" href="http://bits.netbeans.org/html+java/1.0">1.0</a>
4.10 <li>Version <a target="_blank" href="http://bits.netbeans.org/html+java/0.9">0.9</a>
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/xhr4j/pom.xml Mon Feb 29 05:39:42 2016 +0100
5.3 @@ -0,0 +1,122 @@
5.4 +<?xml version="1.0"?>
5.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">
5.6 + <modelVersion>4.0.0</modelVersion>
5.7 + <parent>
5.8 + <groupId>org.netbeans.html</groupId>
5.9 + <artifactId>pom</artifactId>
5.10 + <version>2.0-SNAPSHOT</version>
5.11 + </parent>
5.12 + <groupId>org.netbeans.html</groupId>
5.13 + <artifactId>xhr4j</artifactId>
5.14 + <version>2.0-SNAPSHOT</version>
5.15 + <packaging>bundle</packaging>
5.16 + <name>XHR via Java</name>
5.17 + <url>http://maven.apache.org</url>
5.18 + <build>
5.19 + <plugins>
5.20 + <plugin>
5.21 + <groupId>org.apache.felix</groupId>
5.22 + <artifactId>maven-bundle-plugin</artifactId>
5.23 + </plugin>
5.24 + <plugin>
5.25 + <groupId>org.netbeans.html</groupId>
5.26 + <artifactId>html4j-maven-plugin</artifactId>
5.27 + </plugin>
5.28 + <plugin>
5.29 + <groupId>org.apache.maven.plugins</groupId>
5.30 + <artifactId>maven-javadoc-plugin</artifactId>
5.31 + <configuration>
5.32 + <skip>false</skip>
5.33 + </configuration>
5.34 + </plugin>
5.35 + </plugins>
5.36 + </build>
5.37 + <properties>
5.38 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
5.39 + <bundleSymbolicName>org.netbeans.html.xhr4j</bundleSymbolicName>
5.40 + </properties>
5.41 + <dependencies>
5.42 + <!-- compile only deps -->
5.43 + <dependency>
5.44 + <groupId>org.netbeans.api</groupId>
5.45 + <artifactId>org-openide-util-lookup</artifactId>
5.46 + <type>jar</type>
5.47 + <scope>provided</scope>
5.48 + </dependency>
5.49 +
5.50 + <!-- compile + runtime -->
5.51 + <dependency>
5.52 + <groupId>${project.groupId}</groupId>
5.53 + <artifactId>net.java.html</artifactId>
5.54 + <version>${project.version}</version>
5.55 + <type>jar</type>
5.56 + </dependency>
5.57 + <dependency>
5.58 + <groupId>${project.groupId}</groupId>
5.59 + <artifactId>net.java.html.json</artifactId>
5.60 + <version>${project.version}</version>
5.61 + <type>jar</type>
5.62 + </dependency>
5.63 + <!-- test only deps -->
5.64 + <dependency>
5.65 + <groupId>${project.groupId}</groupId>
5.66 + <artifactId>net.java.html.boot</artifactId>
5.67 + <version>${project.version}</version>
5.68 + <scope>provided</scope>
5.69 + <type>jar</type>
5.70 + </dependency>
5.71 + <dependency>
5.72 + <groupId>${project.groupId}</groupId>
5.73 + <artifactId>net.java.html.json.tck</artifactId>
5.74 + <version>${project.version}</version>
5.75 + <scope>test</scope>
5.76 + <type>jar</type>
5.77 + </dependency>
5.78 + <dependency>
5.79 + <groupId>${project.groupId}</groupId>
5.80 + <artifactId>ko4j</artifactId>
5.81 + <version>${project.version}</version>
5.82 + <scope>test</scope>
5.83 + <type>jar</type>
5.84 + </dependency>
5.85 + <dependency>
5.86 + <groupId>org.glassfish.grizzly</groupId>
5.87 + <artifactId>grizzly-http-server-core</artifactId>
5.88 + <version>${grizzly.version}</version>
5.89 + <scope>test</scope>
5.90 + <type>jar</type>
5.91 + </dependency>
5.92 + <dependency>
5.93 + <groupId>org.glassfish.grizzly</groupId>
5.94 + <artifactId>grizzly-websockets-server</artifactId>
5.95 + <version>${grizzly.version}</version>
5.96 + <scope>test</scope>
5.97 + <type>jar</type>
5.98 + </dependency>
5.99 + <dependency>
5.100 + <groupId>${project.groupId}</groupId>
5.101 + <artifactId>net.java.html.boot.fx</artifactId>
5.102 + <version>${project.version}</version>
5.103 + <scope>test</scope>
5.104 + </dependency>
5.105 + <dependency>
5.106 + <groupId>org.glassfish.grizzly</groupId>
5.107 + <artifactId>grizzly-http-server</artifactId>
5.108 + <version>${grizzly.version}</version>
5.109 + <scope>test</scope>
5.110 + </dependency>
5.111 + <dependency>
5.112 + <groupId>org.glassfish.grizzly</groupId>
5.113 + <artifactId>grizzly-http-servlet</artifactId>
5.114 + <version>${grizzly.version}</version>
5.115 + <scope>test</scope>
5.116 + </dependency>
5.117 + <dependency>
5.118 + <groupId>javax.servlet</groupId>
5.119 + <artifactId>javax.servlet-api</artifactId>
5.120 + <scope>test</scope>
5.121 + </dependency>
5.122 + </dependencies>
5.123 + <description>Implementation module with support for XHR via Java.
5.124 +Use it to workaround CORS limitations.</description>
5.125 +</project>
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/xhr4j/src/main/java/org/netbeans/html/xhr4j/LoadJSON.java Mon Feb 29 05:39:42 2016 +0100
6.3 @@ -0,0 +1,274 @@
6.4 +/**
6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
6.6 + *
6.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6.8 + *
6.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6.10 + * Other names may be trademarks of their respective owners.
6.11 + *
6.12 + * The contents of this file are subject to the terms of either the GNU
6.13 + * General Public License Version 2 only ("GPL") or the Common
6.14 + * Development and Distribution License("CDDL") (collectively, the
6.15 + * "License"). You may not use this file except in compliance with the
6.16 + * License. You can obtain a copy of the License at
6.17 + * http://www.netbeans.org/cddl-gplv2.html
6.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
6.19 + * specific language governing permissions and limitations under the
6.20 + * License. When distributing the software, include this License Header
6.21 + * Notice in each file and include the License file at
6.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
6.23 + * particular file as subject to the "Classpath" exception as provided
6.24 + * by Oracle in the GPL Version 2 section of the License file that
6.25 + * accompanied this code. If applicable, add the following below the
6.26 + * License Header, with the fields enclosed by brackets [] replaced by
6.27 + * your own identifying information:
6.28 + * "Portions Copyrighted [year] [name of copyright owner]"
6.29 + *
6.30 + * Contributor(s):
6.31 + *
6.32 + * The Original Software is NetBeans. The Initial Developer of the Original
6.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
6.34 + *
6.35 + * If you wish your version of this file to be governed by only the CDDL
6.36 + * or only the GPL Version 2, indicate your decision by adding
6.37 + * "[Contributor] elects to include this software in this distribution
6.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
6.39 + * single choice of license, a recipient has the option to distribute
6.40 + * your version of this file under either the CDDL, the GPL Version 2 or
6.41 + * to extend the choice of license to its licensees as provided above.
6.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
6.43 + * Version 2 license, then the option applies only if the new code is
6.44 + * made subject to such option by the copyright holder.
6.45 + */
6.46 +package org.netbeans.html.xhr4j;
6.47 +
6.48 +import java.io.IOException;
6.49 +import java.io.InputStream;
6.50 +import java.io.InputStreamReader;
6.51 +import java.io.OutputStream;
6.52 +import java.io.PushbackInputStream;
6.53 +import java.io.Reader;
6.54 +import java.io.UnsupportedEncodingException;
6.55 +import java.net.HttpURLConnection;
6.56 +import java.net.URL;
6.57 +import java.net.URLConnection;
6.58 +import java.util.concurrent.Callable;
6.59 +import java.util.concurrent.Executor;
6.60 +import java.util.concurrent.Executors;
6.61 +import java.util.concurrent.ThreadFactory;
6.62 +import java.util.logging.Logger;
6.63 +import net.java.html.js.JavaScriptBody;
6.64 +import org.netbeans.html.json.spi.JSONCall;
6.65 +
6.66 +/** This is an implementation package - just
6.67 + * include its JAR on classpath and use official {@link Context} API
6.68 + * to access the functionality.
6.69 + *
6.70 + * @author Jaroslav Tulach
6.71 + */
6.72 +final class LoadJSON implements Runnable {
6.73 + private static final Logger LOG = Logger.getLogger(LoadJSON.class.getName());
6.74 + private static final Executor REQ = Executors.newCachedThreadPool(new ThreadFactory() {
6.75 + @Override
6.76 + public Thread newThread(Runnable runnable) {
6.77 + Thread thread = Executors.defaultThreadFactory().newThread(runnable);
6.78 + thread.setDaemon(true);
6.79 + thread.setName("xhr4j daemon");
6.80 + return thread;
6.81 + }
6.82 + });
6.83 +
6.84 + private final JSONCall call;
6.85 + private final URL base;
6.86 +
6.87 +
6.88 + private LoadJSON(JSONCall call) {
6.89 + this.call = call;
6.90 + this.base = null;
6.91 + }
6.92 +
6.93 + public static void loadJSON(JSONCall call) {
6.94 + assert !"WebSocket".equals(call.getMethod());
6.95 + REQ.execute(new LoadJSON((call)));
6.96 + }
6.97 +
6.98 + @Override
6.99 + public void run() {
6.100 + final String url;
6.101 + Throwable error = null;
6.102 + Object json = null;
6.103 +
6.104 + if (call.isJSONP()) {
6.105 + url = call.composeURL("dummy");
6.106 + } else {
6.107 + url = call.composeURL(null);
6.108 + }
6.109 + try {
6.110 + final URL u = new URL(base, url.replace(" ", "%20"));
6.111 + URLConnection conn = u.openConnection();
6.112 + if (call.isDoOutput()) {
6.113 + conn.setDoOutput(true);
6.114 + }
6.115 + String h = call.getHeaders();
6.116 + if (h != null) {
6.117 + int pos = 0;
6.118 + while (pos < h.length()) {
6.119 + int tagEnd = h.indexOf(':', pos);
6.120 + if (tagEnd == -1) {
6.121 + break;
6.122 + }
6.123 + int r = h.indexOf('\r', tagEnd);
6.124 + int n = h.indexOf('\n', tagEnd);
6.125 + if (r == -1) {
6.126 + r = h.length();
6.127 + }
6.128 + if (n == -1) {
6.129 + n = h.length();
6.130 + }
6.131 + String key = h.substring(pos, tagEnd).trim();
6.132 + String val = h.substring(tagEnd + 1, Math.min(r, n)).trim();
6.133 + conn.setRequestProperty(key, val);;
6.134 + pos = Math.max(r, n);
6.135 + }
6.136 + }
6.137 + if (call.getMethod() != null && conn instanceof HttpURLConnection) {
6.138 + ((HttpURLConnection) conn).setRequestMethod(call.getMethod());
6.139 + }
6.140 + if (call.isDoOutput()) {
6.141 + final OutputStream os = conn.getOutputStream();
6.142 + call.writeData(os);
6.143 + os.flush();
6.144 + }
6.145 + final PushbackInputStream is = new PushbackInputStream(
6.146 + conn.getInputStream(), 1
6.147 + );
6.148 + boolean[] arrayOrString = { false, false };
6.149 + detectJSONType(call.isJSONP(), is, arrayOrString);
6.150 + String response = readStream(is);
6.151 + if (call.isJSONP()) {
6.152 + response = '(' + response;
6.153 + }
6.154 + json = new Result(response, arrayOrString[0], arrayOrString[1]);
6.155 + } catch (IOException ex) {
6.156 + error = ex;
6.157 + } finally {
6.158 + if (error != null) {
6.159 + call.notifyError(error);
6.160 + } else {
6.161 + call.notifySuccess(json);
6.162 + }
6.163 + }
6.164 + }
6.165 +
6.166 + private static final class Result implements Callable<Object> {
6.167 + private final String response;
6.168 + private final boolean array;
6.169 + private final boolean plain;
6.170 +
6.171 + Result(String response, boolean array, boolean plain) {
6.172 + this.response = response;
6.173 + this.array = array;
6.174 + this.plain = plain;
6.175 + }
6.176 +
6.177 + @Override
6.178 + public Object call() throws Exception {
6.179 + if (plain) {
6.180 + return response;
6.181 + } else {
6.182 + if (array) {
6.183 + Object r = parse(response);
6.184 + Object[] arr = r instanceof Object[] ? (Object[])r : new Object[] { r };
6.185 + for (int i = 0; i < arr.length; i++) {
6.186 + arr[i] = new JSObjToStr(response, arr[i]);
6.187 + }
6.188 + return arr;
6.189 + } else {
6.190 + return new JSObjToStr(response, parse(response));
6.191 + }
6.192 + }
6.193 + }
6.194 + }
6.195 + private static final class JSObjToStr {
6.196 + final String str;
6.197 + final Object obj;
6.198 +
6.199 + public JSObjToStr(Object str, Object obj) {
6.200 + this.str = str == null ? "" : str.toString();
6.201 + this.obj = obj;
6.202 + }
6.203 +
6.204 + @Override
6.205 + public String toString() {
6.206 + return str;
6.207 + }
6.208 + }
6.209 +
6.210 + static String readStream(InputStream is) throws IOException, UnsupportedEncodingException {
6.211 + Reader r = new InputStreamReader(is, "UTF-8");
6.212 + StringBuilder sb = new StringBuilder();
6.213 + char[] arr = new char[4096];
6.214 + for (;;) {
6.215 + int len = r.read(arr);
6.216 + if (len == -1) {
6.217 + break;
6.218 + }
6.219 + sb.append(arr, 0, len);
6.220 + }
6.221 + return sb.toString();
6.222 + }
6.223 +
6.224 + private static void detectJSONType(boolean skipAnything, final PushbackInputStream is, boolean[] arrayOrString) throws IOException {
6.225 + for (;;) {
6.226 + int ch = is.read();
6.227 + if (ch == -1) {
6.228 + arrayOrString[1] = true;
6.229 + break;
6.230 + }
6.231 + if (Character.isWhitespace(ch)) {
6.232 + continue;
6.233 + }
6.234 +
6.235 + if (ch == '[') {
6.236 + is.unread(ch);
6.237 + arrayOrString[0] = true;
6.238 + break;
6.239 + }
6.240 + if (ch == '{') {
6.241 + is.unread(ch);
6.242 + break;
6.243 + }
6.244 + if (!skipAnything) {
6.245 + is.unread(ch);
6.246 + arrayOrString[1] = true;
6.247 + break;
6.248 + }
6.249 + }
6.250 + }
6.251 +
6.252 + @JavaScriptBody(args = {"object", "property"}, body =
6.253 + "var ret;\n" +
6.254 + "if (property === null) ret = object;\n" +
6.255 + "else if (object === null) ret = null;\n" +
6.256 + "else ret = object[property];\n" +
6.257 + "return ret ? (typeof ko === 'undefined' ? ret : ko.utils.unwrapObservable(ret)) : null;"
6.258 + )
6.259 + private static Object getProperty(Object object, String property) {
6.260 + return null;
6.261 + }
6.262 +
6.263 + @JavaScriptBody(args = {"s"}, body = "return eval('(' + s + ')');")
6.264 + static Object parse(String s) {
6.265 + throw new IllegalStateException("No parser context for " + s);
6.266 + }
6.267 +
6.268 + static void extractJSON(Object js, String[] props, Object[] values) {
6.269 + if (js instanceof JSObjToStr) {
6.270 + js = ((JSObjToStr)js).obj;
6.271 + }
6.272 + for (int i = 0; i < props.length; i++) {
6.273 + values[i] = getProperty(js, props[i]);
6.274 + }
6.275 + }
6.276 +
6.277 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/xhr4j/src/main/java/org/netbeans/html/xhr4j/XmlHttpResourceContext.java Mon Feb 29 05:39:42 2016 +0100
7.3 @@ -0,0 +1,88 @@
7.4 +/**
7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7.6 + *
7.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
7.8 + *
7.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7.10 + * Other names may be trademarks of their respective owners.
7.11 + *
7.12 + * The contents of this file are subject to the terms of either the GNU
7.13 + * General Public License Version 2 only ("GPL") or the Common
7.14 + * Development and Distribution License("CDDL") (collectively, the
7.15 + * "License"). You may not use this file except in compliance with the
7.16 + * License. You can obtain a copy of the License at
7.17 + * http://www.netbeans.org/cddl-gplv2.html
7.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
7.19 + * specific language governing permissions and limitations under the
7.20 + * License. When distributing the software, include this License Header
7.21 + * Notice in each file and include the License file at
7.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
7.23 + * particular file as subject to the "Classpath" exception as provided
7.24 + * by Oracle in the GPL Version 2 section of the License file that
7.25 + * accompanied this code. If applicable, add the following below the
7.26 + * License Header, with the fields enclosed by brackets [] replaced by
7.27 + * your own identifying information:
7.28 + * "Portions Copyrighted [year] [name of copyright owner]"
7.29 + *
7.30 + * Contributor(s):
7.31 + *
7.32 + * The Original Software is NetBeans. The Initial Developer of the Original
7.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
7.34 + *
7.35 + * If you wish your version of this file to be governed by only the CDDL
7.36 + * or only the GPL Version 2, indicate your decision by adding
7.37 + * "[Contributor] elects to include this software in this distribution
7.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
7.39 + * single choice of license, a recipient has the option to distribute
7.40 + * your version of this file under either the CDDL, the GPL Version 2 or
7.41 + * to extend the choice of license to its licensees as provided above.
7.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
7.43 + * Version 2 license, then the option applies only if the new code is
7.44 + * made subject to such option by the copyright holder.
7.45 + */
7.46 +package org.netbeans.html.xhr4j;
7.47 +
7.48 +import java.io.IOException;
7.49 +import java.io.InputStream;
7.50 +import net.java.html.json.OnReceive;
7.51 +import org.netbeans.html.context.spi.Contexts;
7.52 +import org.netbeans.html.json.spi.JSONCall;
7.53 +import org.netbeans.html.json.spi.Transfer;
7.54 +import org.openide.util.lookup.ServiceProvider;
7.55 +
7.56 +/** Implementation module with support for XHR via Java.
7.57 + * Handles {@link OnReceive} requests by using Java to connect to given
7.58 + * URL and then parsing it via JavaScript. Use this module if you have
7.59 + * problems with CORS - as the Java connection isn't restricted by CORS
7.60 + * rules.
7.61 + *
7.62 + * Registers {@link Transfer} technology at position <code>50</code>.
7.63 + * The {@link Contexts.Id} of the technology is <b>xhr4j</b>.
7.64 + *
7.65 + * @author Jaroslav Tulach
7.66 + * @since 1.3
7.67 + */
7.68 +@Contexts.Id("xhr4j")
7.69 +@ServiceProvider(service = Contexts.Provider.class)
7.70 +public final class XmlHttpResourceContext
7.71 +implements Contexts.Provider, Transfer {
7.72 + @Override
7.73 + public void fillContext(Contexts.Builder context, Class<?> requestor) {
7.74 + context.register(Transfer.class, this, 50);
7.75 + }
7.76 +
7.77 + @Override
7.78 + public void extract(Object obj, String[] props, Object[] values) {
7.79 + LoadJSON.extractJSON(obj, props, values);
7.80 + }
7.81 +
7.82 + @Override
7.83 + public Object toJSON(InputStream is) throws IOException {
7.84 + return LoadJSON.parse(LoadJSON.readStream(is));
7.85 + }
7.86 +
7.87 + @Override
7.88 + public void loadJSON(JSONCall call) {
7.89 + LoadJSON.loadJSON(call);
7.90 + }
7.91 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/xhr4j/src/test/java/org/netbeans/html/xhr4j/JsonDynamicHTTP.java Mon Feb 29 05:39:42 2016 +0100
8.3 @@ -0,0 +1,262 @@
8.4 +/**
8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8.6 + *
8.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
8.8 + *
8.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
8.10 + * Other names may be trademarks of their respective owners.
8.11 + *
8.12 + * The contents of this file are subject to the terms of either the GNU
8.13 + * General Public License Version 2 only ("GPL") or the Common
8.14 + * Development and Distribution License("CDDL") (collectively, the
8.15 + * "License"). You may not use this file except in compliance with the
8.16 + * License. You can obtain a copy of the License at
8.17 + * http://www.netbeans.org/cddl-gplv2.html
8.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
8.19 + * specific language governing permissions and limitations under the
8.20 + * License. When distributing the software, include this License Header
8.21 + * Notice in each file and include the License file at
8.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
8.23 + * particular file as subject to the "Classpath" exception as provided
8.24 + * by Oracle in the GPL Version 2 section of the License file that
8.25 + * accompanied this code. If applicable, add the following below the
8.26 + * License Header, with the fields enclosed by brackets [] replaced by
8.27 + * your own identifying information:
8.28 + * "Portions Copyrighted [year] [name of copyright owner]"
8.29 + *
8.30 + * Contributor(s):
8.31 + *
8.32 + * The Original Software is NetBeans. The Initial Developer of the Original
8.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
8.34 + *
8.35 + * If you wish your version of this file to be governed by only the CDDL
8.36 + * or only the GPL Version 2, indicate your decision by adding
8.37 + * "[Contributor] elects to include this software in this distribution
8.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
8.39 + * single choice of license, a recipient has the option to distribute
8.40 + * your version of this file under either the CDDL, the GPL Version 2 or
8.41 + * to extend the choice of license to its licensees as provided above.
8.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
8.43 + * Version 2 license, then the option applies only if the new code is
8.44 + * made subject to such option by the copyright holder.
8.45 + */
8.46 +package org.netbeans.html.xhr4j;
8.47 +
8.48 +import java.io.ByteArrayInputStream;
8.49 +import java.io.ByteArrayOutputStream;
8.50 +import java.io.IOException;
8.51 +import java.io.InputStream;
8.52 +import java.io.OutputStream;
8.53 +import java.io.Reader;
8.54 +import java.net.URI;
8.55 +import java.net.URISyntaxException;
8.56 +import java.util.ArrayList;
8.57 +import java.util.List;
8.58 +import java.util.logging.Level;
8.59 +import java.util.logging.Logger;
8.60 +import org.glassfish.grizzly.PortRange;
8.61 +import org.glassfish.grizzly.http.server.HttpHandler;
8.62 +import org.glassfish.grizzly.http.server.HttpServer;
8.63 +import org.glassfish.grizzly.http.server.NetworkListener;
8.64 +import org.glassfish.grizzly.http.server.Request;
8.65 +import org.glassfish.grizzly.http.server.Response;
8.66 +import org.glassfish.grizzly.http.server.ServerConfiguration;
8.67 +import org.glassfish.grizzly.websockets.WebSocket;
8.68 +import org.glassfish.grizzly.websockets.WebSocketAddOn;
8.69 +import org.glassfish.grizzly.websockets.WebSocketApplication;
8.70 +import org.glassfish.grizzly.websockets.WebSocketEngine;
8.71 +
8.72 +/**
8.73 + *
8.74 + * @author Jaroslav Tulach
8.75 + */
8.76 +final class JsonDynamicHTTP extends HttpHandler {
8.77 + private static int resourcesCount;
8.78 + private static List<Resource> resources;
8.79 + private static ServerConfiguration conf;
8.80 + private static HttpServer server;
8.81 +
8.82 + private JsonDynamicHTTP() {
8.83 + }
8.84 +
8.85 + static URI initServer() throws Exception {
8.86 + server = HttpServer.createSimpleServer(null, new PortRange(8080, 65535));
8.87 + final WebSocketAddOn addon = new WebSocketAddOn();
8.88 + for (NetworkListener listener : server.getListeners()) {
8.89 + listener.registerAddOn(addon);
8.90 + }
8.91 + resources = new ArrayList<Resource>();
8.92 +
8.93 + conf = server.getServerConfiguration();
8.94 + final JsonDynamicHTTP dh = new JsonDynamicHTTP();
8.95 +
8.96 + conf.addHttpHandler(dh, "/");
8.97 +
8.98 + server.start();
8.99 +
8.100 + return pageURL("http", server, "/test.html");
8.101 + }
8.102 +
8.103 + @Override
8.104 + public void service(Request request, Response response) throws Exception {
8.105 + if ("/test.html".equals(request.getRequestURI())) {
8.106 + response.setContentType("text/html");
8.107 + final InputStream is = JsonDynamicHTTP.class.getResourceAsStream("test.html");
8.108 + copyStream(is, response.getOutputStream(), null);
8.109 + return;
8.110 + }
8.111 + if ("/dynamic".equals(request.getRequestURI())) {
8.112 + String mimeType = request.getParameter("mimeType");
8.113 + List<String> params = new ArrayList<String>();
8.114 + boolean webSocket = false;
8.115 + for (int i = 0;; i++) {
8.116 + String p = request.getParameter("param" + i);
8.117 + if (p == null) {
8.118 + break;
8.119 + }
8.120 + if ("protocol:ws".equals(p)) {
8.121 + webSocket = true;
8.122 + continue;
8.123 + }
8.124 + params.add(p);
8.125 + }
8.126 + final String cnt = request.getParameter("content");
8.127 + String mangle = cnt.replace("%20", " ").replace("%0A", "\n");
8.128 + ByteArrayInputStream is = new ByteArrayInputStream(mangle.getBytes("UTF-8"));
8.129 + URI url;
8.130 + final Resource res = new Resource(is, mimeType, "/dynamic/res" + ++resourcesCount, params.toArray(new String[params.size()]));
8.131 + if (webSocket) {
8.132 + url = registerWebSocket(res);
8.133 + } else {
8.134 + url = registerResource(res);
8.135 + }
8.136 + response.getWriter().write(url.toString());
8.137 + response.getWriter().write("\n");
8.138 + return;
8.139 + }
8.140 +
8.141 + for (Resource r : resources) {
8.142 + if (r.httpPath.equals(request.getRequestURI())) {
8.143 + response.setContentType(r.httpType);
8.144 + r.httpContent.reset();
8.145 + String[] params = null;
8.146 + if (r.parameters.length != 0) {
8.147 + params = new String[r.parameters.length];
8.148 + for (int i = 0; i < r.parameters.length; i++) {
8.149 + params[i] = request.getParameter(r.parameters[i]);
8.150 + if (params[i] == null) {
8.151 + if ("http.method".equals(r.parameters[i])) {
8.152 + params[i] = request.getMethod().toString();
8.153 + } else if ("http.requestBody".equals(r.parameters[i])) {
8.154 + Reader rdr = request.getReader();
8.155 + StringBuilder sb = new StringBuilder();
8.156 + for (;;) {
8.157 + int ch = rdr.read();
8.158 + if (ch == -1) {
8.159 + break;
8.160 + }
8.161 + sb.append((char) ch);
8.162 + }
8.163 + params[i] = sb.toString();
8.164 + } else if (r.parameters[i].startsWith("http.header.")) {
8.165 + params[i] = request.getHeader(r.parameters[i].substring(12));
8.166 + }
8.167 + }
8.168 + if (params[i] == null) {
8.169 + params[i] = "null";
8.170 + }
8.171 + }
8.172 + }
8.173 +
8.174 + copyStream(r.httpContent, response.getOutputStream(), null, params);
8.175 + }
8.176 + }
8.177 + }
8.178 +
8.179 + private URI registerWebSocket(Resource r) {
8.180 + WebSocketEngine.getEngine().register("", r.httpPath, new WS(r));
8.181 + return pageURL("ws", server, r.httpPath);
8.182 + }
8.183 +
8.184 + private URI registerResource(Resource r) {
8.185 + if (!resources.contains(r)) {
8.186 + resources.add(r);
8.187 + conf.addHttpHandler(this, r.httpPath);
8.188 + }
8.189 + return pageURL("http", server, r.httpPath);
8.190 + }
8.191 +
8.192 + private static URI pageURL(String proto, HttpServer server, final String page) {
8.193 + NetworkListener listener = server.getListeners().iterator().next();
8.194 + int port = listener.getPort();
8.195 + try {
8.196 + return new URI(proto + "://localhost:" + port + page);
8.197 + } catch (URISyntaxException ex) {
8.198 + throw new IllegalStateException(ex);
8.199 + }
8.200 + }
8.201 +
8.202 + static final class Resource {
8.203 +
8.204 + final InputStream httpContent;
8.205 + final String httpType;
8.206 + final String httpPath;
8.207 + final String[] parameters;
8.208 +
8.209 + Resource(InputStream httpContent, String httpType, String httpPath,
8.210 + String[] parameters) {
8.211 + httpContent.mark(Integer.MAX_VALUE);
8.212 + this.httpContent = httpContent;
8.213 + this.httpType = httpType;
8.214 + this.httpPath = httpPath;
8.215 + this.parameters = parameters;
8.216 + }
8.217 + }
8.218 +
8.219 + static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
8.220 + for (;;) {
8.221 + int ch = is.read();
8.222 + if (ch == -1) {
8.223 + break;
8.224 + }
8.225 + if (ch == '$' && params.length > 0) {
8.226 + int cnt = is.read() - '0';
8.227 + if (baseURL != null && cnt == 'U' - '0') {
8.228 + os.write(baseURL.getBytes("UTF-8"));
8.229 + } else {
8.230 + if (cnt >= 0 && cnt < params.length) {
8.231 + os.write(params[cnt].getBytes("UTF-8"));
8.232 + } else {
8.233 + os.write('$');
8.234 + os.write(cnt + '0');
8.235 + }
8.236 + }
8.237 + } else {
8.238 + os.write(ch);
8.239 + }
8.240 + }
8.241 + }
8.242 +
8.243 + private static class WS extends WebSocketApplication {
8.244 + private final Resource r;
8.245 +
8.246 + private WS(Resource r) {
8.247 + this.r = r;
8.248 + }
8.249 +
8.250 + @Override
8.251 + public void onMessage(WebSocket socket, String text) {
8.252 + try {
8.253 + r.httpContent.reset();
8.254 + ByteArrayOutputStream out = new ByteArrayOutputStream();
8.255 + copyStream(r.httpContent, out, null, text);
8.256 + String s = new String(out.toByteArray(), "UTF-8");
8.257 + socket.send(s);
8.258 + } catch (IOException ex) {
8.259 + LOG.log(Level.WARNING, null, ex);
8.260 + }
8.261 + }
8.262 + private static final Logger LOG = Logger.getLogger(WS.class.getName());
8.263 +
8.264 + }
8.265 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/xhr4j/src/test/java/org/netbeans/html/xhr4j/JsonFX.java Mon Feb 29 05:39:42 2016 +0100
9.3 @@ -0,0 +1,125 @@
9.4 +/**
9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
9.6 + *
9.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
9.8 + *
9.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
9.10 + * Other names may be trademarks of their respective owners.
9.11 + *
9.12 + * The contents of this file are subject to the terms of either the GNU
9.13 + * General Public License Version 2 only ("GPL") or the Common
9.14 + * Development and Distribution License("CDDL") (collectively, the
9.15 + * "License"). You may not use this file except in compliance with the
9.16 + * License. You can obtain a copy of the License at
9.17 + * http://www.netbeans.org/cddl-gplv2.html
9.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
9.19 + * specific language governing permissions and limitations under the
9.20 + * License. When distributing the software, include this License Header
9.21 + * Notice in each file and include the License file at
9.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
9.23 + * particular file as subject to the "Classpath" exception as provided
9.24 + * by Oracle in the GPL Version 2 section of the License file that
9.25 + * accompanied this code. If applicable, add the following below the
9.26 + * License Header, with the fields enclosed by brackets [] replaced by
9.27 + * your own identifying information:
9.28 + * "Portions Copyrighted [year] [name of copyright owner]"
9.29 + *
9.30 + * Contributor(s):
9.31 + *
9.32 + * The Original Software is NetBeans. The Initial Developer of the Original
9.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
9.34 + *
9.35 + * If you wish your version of this file to be governed by only the CDDL
9.36 + * or only the GPL Version 2, indicate your decision by adding
9.37 + * "[Contributor] elects to include this software in this distribution
9.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
9.39 + * single choice of license, a recipient has the option to distribute
9.40 + * your version of this file under either the CDDL, the GPL Version 2 or
9.41 + * to extend the choice of license to its licensees as provided above.
9.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
9.43 + * Version 2 license, then the option applies only if the new code is
9.44 + * made subject to such option by the copyright holder.
9.45 + */
9.46 +package org.netbeans.html.xhr4j;
9.47 +
9.48 +import java.lang.reflect.InvocationTargetException;
9.49 +import java.lang.reflect.Method;
9.50 +import javafx.application.Platform;
9.51 +import org.netbeans.html.boot.impl.FnContext;
9.52 +import org.netbeans.html.boot.spi.Fn;
9.53 +import org.testng.ITest;
9.54 +import org.testng.annotations.Test;
9.55 +
9.56 +/**
9.57 + *
9.58 + * @author Jaroslav Tulach
9.59 + */
9.60 +public final class JsonFX implements ITest, Runnable {
9.61 + private final Fn.Presenter p;
9.62 + private final Method m;
9.63 + private Object result;
9.64 + private Object inst;
9.65 + private int count;
9.66 +
9.67 + JsonFX(Fn.Presenter p, Method m) {
9.68 + this.p = p;
9.69 + this.m = m;
9.70 + }
9.71 +
9.72 + @Override
9.73 + public String getTestName() {
9.74 + return m.getName();
9.75 + }
9.76 +
9.77 + @Test
9.78 + public synchronized void executeTest() throws Exception {
9.79 + if (result == null) {
9.80 + Platform.runLater(this);
9.81 + wait();
9.82 + }
9.83 + if (result instanceof Exception) {
9.84 + throw (Exception)result;
9.85 + }
9.86 + if (result instanceof Error) {
9.87 + throw (Error)result;
9.88 + }
9.89 + }
9.90 +
9.91 + @Override
9.92 + public synchronized void run() {
9.93 + boolean notify = true;
9.94 + try {
9.95 + FnContext.currentPresenter(p);
9.96 + if (inst == null) {
9.97 + inst = m.getDeclaringClass().newInstance();
9.98 + }
9.99 + result = m.invoke(inst);
9.100 + if (result == null) {
9.101 + result = this;
9.102 + }
9.103 + } catch (InvocationTargetException ex) {
9.104 + Throwable r = ex.getTargetException();
9.105 + if (r instanceof InterruptedException) {
9.106 + if (count++ < 100) {
9.107 + notify = false;
9.108 + try {
9.109 + Thread.sleep(100);
9.110 + } catch (Exception ex1) {
9.111 + // ignore and continue
9.112 + }
9.113 + Platform.runLater(this);
9.114 + return;
9.115 + }
9.116 + }
9.117 + result = r;
9.118 + } catch (Exception ex) {
9.119 + result = ex;
9.120 + } finally {
9.121 + if (notify) {
9.122 + notifyAll();
9.123 + }
9.124 + FnContext.currentPresenter(null);
9.125 + }
9.126 + }
9.127 +
9.128 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/xhr4j/src/test/java/org/netbeans/html/xhr4j/JsonKnockoutTest.java Mon Feb 29 05:39:42 2016 +0100
10.3 @@ -0,0 +1,217 @@
10.4 +/**
10.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
10.6 + *
10.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
10.8 + *
10.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
10.10 + * Other names may be trademarks of their respective owners.
10.11 + *
10.12 + * The contents of this file are subject to the terms of either the GNU
10.13 + * General Public License Version 2 only ("GPL") or the Common
10.14 + * Development and Distribution License("CDDL") (collectively, the
10.15 + * "License"). You may not use this file except in compliance with the
10.16 + * License. You can obtain a copy of the License at
10.17 + * http://www.netbeans.org/cddl-gplv2.html
10.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
10.19 + * specific language governing permissions and limitations under the
10.20 + * License. When distributing the software, include this License Header
10.21 + * Notice in each file and include the License file at
10.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
10.23 + * particular file as subject to the "Classpath" exception as provided
10.24 + * by Oracle in the GPL Version 2 section of the License file that
10.25 + * accompanied this code. If applicable, add the following below the
10.26 + * License Header, with the fields enclosed by brackets [] replaced by
10.27 + * your own identifying information:
10.28 + * "Portions Copyrighted [year] [name of copyright owner]"
10.29 + *
10.30 + * Contributor(s):
10.31 + *
10.32 + * The Original Software is NetBeans. The Initial Developer of the Original
10.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
10.34 + *
10.35 + * If you wish your version of this file to be governed by only the CDDL
10.36 + * or only the GPL Version 2, indicate your decision by adding
10.37 + * "[Contributor] elects to include this software in this distribution
10.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
10.39 + * single choice of license, a recipient has the option to distribute
10.40 + * your version of this file under either the CDDL, the GPL Version 2 or
10.41 + * to extend the choice of license to its licensees as provided above.
10.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
10.43 + * Version 2 license, then the option applies only if the new code is
10.44 + * made subject to such option by the copyright holder.
10.45 + */
10.46 +package org.netbeans.html.xhr4j;
10.47 +
10.48 +import java.io.BufferedReader;
10.49 +import java.io.IOException;
10.50 +import java.io.InputStreamReader;
10.51 +import java.lang.annotation.Annotation;
10.52 +import java.lang.reflect.Method;
10.53 +import java.net.URI;
10.54 +import java.net.URISyntaxException;
10.55 +import java.net.URL;
10.56 +import java.net.URLConnection;
10.57 +import java.util.ArrayList;
10.58 +import java.util.List;
10.59 +import java.util.Map;
10.60 +import java.util.concurrent.Executor;
10.61 +import java.util.concurrent.Executors;
10.62 +import net.java.html.BrwsrCtx;
10.63 +import net.java.html.boot.BrowserBuilder;
10.64 +import net.java.html.js.JavaScriptBody;
10.65 +import org.netbeans.html.boot.spi.Fn;
10.66 +import org.netbeans.html.context.spi.Contexts;
10.67 +import org.netbeans.html.json.spi.Technology;
10.68 +import org.netbeans.html.json.tck.KOTest;
10.69 +import org.netbeans.html.json.tck.KnockoutTCK;
10.70 +import org.netbeans.html.ko4j.KO4J;
10.71 +import org.openide.util.lookup.ServiceProvider;
10.72 +import org.testng.Assert;
10.73 +import static org.testng.Assert.*;
10.74 +import org.testng.annotations.Factory;
10.75 +
10.76 +/**
10.77 + *
10.78 + * @author Jaroslav Tulach
10.79 + */
10.80 +@ServiceProvider(service = KnockoutTCK.class)
10.81 +public final class JsonKnockoutTest extends KnockoutTCK {
10.82 + private static Class<?> browserClass;
10.83 + private static Fn.Presenter browserContext;
10.84 +
10.85 + public JsonKnockoutTest() {
10.86 + }
10.87 +
10.88 + @Factory public static Object[] compatibilityTests() throws Exception {
10.89 + Class[] arr = testClasses();
10.90 + for (int i = 0; i < arr.length; i++) {
10.91 + assertEquals(arr[i].getClassLoader(),
10.92 + JsonKnockoutTest.class.getClassLoader(),
10.93 + "All classes loaded by the same classloader"
10.94 + );
10.95 + }
10.96 +
10.97 + URI uri = JsonDynamicHTTP.initServer();
10.98 +
10.99 + final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(JsonKnockoutTest.class).
10.100 + loadPage(uri.toString()).
10.101 + invoke("initialized");
10.102 +
10.103 + Executors.newSingleThreadExecutor().submit(new Runnable() {
10.104 + @Override
10.105 + public void run() {
10.106 + bb.showAndWait();
10.107 + }
10.108 + });
10.109 +
10.110 + ClassLoader l = getClassLoader();
10.111 + List<Object> res = new ArrayList<Object>();
10.112 + for (int i = 0; i < arr.length; i++) {
10.113 + Class<?> c = Class.forName(arr[i].getName(), true, l);
10.114 + Class<? extends Annotation> koTest =
10.115 + c.getClassLoader().loadClass(KOTest.class.getName()).
10.116 + asSubclass(Annotation.class);
10.117 + for (Method m : c.getMethods()) {
10.118 + if (m.getAnnotation(koTest) != null) {
10.119 + res.add(new JsonFX(browserContext, m));
10.120 + }
10.121 + }
10.122 + }
10.123 + return res.toArray();
10.124 + }
10.125 +
10.126 + static synchronized ClassLoader getClassLoader() throws InterruptedException {
10.127 + while (browserClass == null) {
10.128 + JsonKnockoutTest.class.wait();
10.129 + }
10.130 + return browserClass.getClassLoader();
10.131 + }
10.132 +
10.133 + public static synchronized void initialized(Class<?> browserCls) throws Exception {
10.134 + browserClass = browserCls;
10.135 + browserContext = Fn.activePresenter();
10.136 + JsonKnockoutTest.class.notifyAll();
10.137 + }
10.138 +
10.139 + public static void initialized() throws Exception {
10.140 + Assert.assertSame(JsonKnockoutTest.class.getClassLoader(),
10.141 + ClassLoader.getSystemClassLoader(),
10.142 + "No special classloaders"
10.143 + );
10.144 + JsonKnockoutTest.initialized(JsonKnockoutTest.class);
10.145 + }
10.146 +
10.147 + @Override
10.148 + public boolean canFailWebSocketTest() {
10.149 + return true;
10.150 + }
10.151 +
10.152 + @Override
10.153 + public BrwsrCtx createContext() {
10.154 + KO4J ko = new KO4J(browserContext);
10.155 + XmlHttpResourceContext tc = new XmlHttpResourceContext();
10.156 + Contexts.Builder cb = Contexts.newBuilder().
10.157 + register(Technology.class, ko.knockout(), 10).
10.158 + register(Executor.class, (Executor)browserContext, 10).
10.159 + register(Fn.Presenter.class, (Fn.Presenter)browserContext, 10);
10.160 + tc.fillContext(cb, browserClass);
10.161 + return cb.build();
10.162 + }
10.163 +
10.164 + @Override
10.165 + public Object createJSON(Map<String, Object> values) {
10.166 + Object json = createJSON();
10.167 + for (Map.Entry<String, Object> entry : values.entrySet()) {
10.168 + setProperty(json, entry.getKey(), entry.getValue());
10.169 + }
10.170 + return json;
10.171 + }
10.172 +
10.173 + @JavaScriptBody(args = {}, body = "return new Object();")
10.174 + private static native Object createJSON();
10.175 +
10.176 + @JavaScriptBody(args = {"json", "key", "value"}, body = "json[key] = value;")
10.177 + private static native void setProperty(Object json, String key, Object value);
10.178 +
10.179 + @Override
10.180 + @JavaScriptBody(args = { "s", "args" }, body = ""
10.181 + + "var f = new Function(s); "
10.182 + + "return f.apply(null, args);"
10.183 + )
10.184 + public native Object executeScript(String script, Object[] arguments);
10.185 +
10.186 + @JavaScriptBody(args = { }, body =
10.187 + "var h;"
10.188 + + "if (!!window && !!window.location && !!window.location.href)\n"
10.189 + + " h = window.location.href;\n"
10.190 + + "else "
10.191 + + " h = null;"
10.192 + + "return h;\n"
10.193 + )
10.194 + private static native String findBaseURL();
10.195 +
10.196 + @Override
10.197 + public URI prepareURL(String content, String mimeType, String[] parameters) {
10.198 + try {
10.199 + final URL baseURL = new URL(findBaseURL());
10.200 + StringBuilder sb = new StringBuilder();
10.201 + sb.append("/dynamic?mimeType=").append(mimeType);
10.202 + for (int i = 0; i < parameters.length; i++) {
10.203 + sb.append("¶m" + i).append("=").append(parameters[i]);
10.204 + }
10.205 + String mangle = content.replace("\n", "%0a")
10.206 + .replace("\"", "\\\"").replace(" ", "%20");
10.207 + sb.append("&content=").append(mangle);
10.208 +
10.209 + URL query = new URL(baseURL, sb.toString());
10.210 + URLConnection c = query.openConnection();
10.211 + BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
10.212 + URI connectTo = new URI(br.readLine());
10.213 + return connectTo;
10.214 + } catch (IOException ex) {
10.215 + throw new IllegalStateException(ex);
10.216 + } catch (URISyntaxException ex) {
10.217 + throw new IllegalStateException(ex);
10.218 + }
10.219 + }
10.220 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/xhr4j/src/test/resources/org/netbeans/html/xhr4j/test.html Mon Feb 29 05:39:42 2016 +0100
11.3 @@ -0,0 +1,56 @@
11.4 +<!--
11.5 +
11.6 + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
11.7 +
11.8 + Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
11.9 +
11.10 + Oracle and Java are registered trademarks of Oracle and/or its affiliates.
11.11 + Other names may be trademarks of their respective owners.
11.12 +
11.13 + The contents of this file are subject to the terms of either the GNU
11.14 + General Public License Version 2 only ("GPL") or the Common
11.15 + Development and Distribution License("CDDL") (collectively, the
11.16 + "License"). You may not use this file except in compliance with the
11.17 + License. You can obtain a copy of the License at
11.18 + http://www.netbeans.org/cddl-gplv2.html
11.19 + or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
11.20 + specific language governing permissions and limitations under the
11.21 + License. When distributing the software, include this License Header
11.22 + Notice in each file and include the License file at
11.23 + nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
11.24 + particular file as subject to the "Classpath" exception as provided
11.25 + by Oracle in the GPL Version 2 section of the License file that
11.26 + accompanied this code. If applicable, add the following below the
11.27 + License Header, with the fields enclosed by brackets [] replaced by
11.28 + your own identifying information:
11.29 + "Portions Copyrighted [year] [name of copyright owner]"
11.30 +
11.31 + Contributor(s):
11.32 +
11.33 + The Original Software is NetBeans. The Initial Developer of the Original
11.34 + Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
11.35 +
11.36 + If you wish your version of this file to be governed by only the CDDL
11.37 + or only the GPL Version 2, indicate your decision by adding
11.38 + "[Contributor] elects to include this software in this distribution
11.39 + under the [CDDL or GPL Version 2] license." If you do not indicate a
11.40 + single choice of license, a recipient has the option to distribute
11.41 + your version of this file under either the CDDL, the GPL Version 2 or
11.42 + to extend the choice of license to its licensees as provided above.
11.43 + However, if you add GPL Version 2 code and therefore, elected the GPL
11.44 + Version 2 license, then the option applies only if the new code is
11.45 + made subject to such option by the copyright holder.
11.46 +
11.47 +-->
11.48 +<!DOCTYPE html>
11.49 +<html>
11.50 + <head>
11.51 + <title>XHR via Java Harness</title>
11.52 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
11.53 + <meta name="viewport" content="width=device-width">
11.54 + </head>
11.55 + <body>
11.56 + <h1>XHR via Java Harness</h1>
11.57 + </body>
11.58 + <script></script>
11.59 +</html>