During the API review process (bug 246133) the reviewers decided that in order to include html4j to NetBeans Platform, we need to stop using org.apidesign namespace and switch to NetBeans one. Repackaging all SPI packages into org.netbeans.html.smthng.spi.
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
9 * The contents of this file are subject to the terms of either the GNU
10 * General Public License Version 2 only ("GPL") or the Common
11 * Development and Distribution License("CDDL") (collectively, the
12 * "License"). You may not use this file except in compliance with the
13 * License. You can obtain a copy of the License at
14 * http://www.netbeans.org/cddl-gplv2.html
15 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 * specific language governing permissions and limitations under the
17 * License. When distributing the software, include this License Header
18 * Notice in each file and include the License file at
19 * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 * particular file as subject to the "Classpath" exception as provided
21 * by Oracle in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the
23 * License Header, with the fields enclosed by brackets [] replaced by
24 * your own identifying information:
25 * "Portions Copyrighted [year] [name of copyright owner]"
29 * The Original Software is NetBeans. The Initial Developer of the Original
30 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
32 * If you wish your version of this file to be governed by only the CDDL
33 * or only the GPL Version 2, indicate your decision by adding
34 * "[Contributor] elects to include this software in this distribution
35 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36 * single choice of license, a recipient has the option to distribute
37 * your version of this file under either the CDDL, the GPL Version 2 or
38 * to extend the choice of license to its licensees as provided above.
39 * However, if you add GPL Version 2 code and therefore, elected the GPL
40 * Version 2 license, then the option applies only if the new code is
41 * made subject to such option by the copyright holder.
43 package org.netbeans.html.wstyrus;
45 import java.io.IOException;
46 import java.io.InputStream;
48 import java.net.URISyntaxException;
49 import java.util.Iterator;
50 import javax.websocket.ClientEndpoint;
51 import javax.websocket.ContainerProvider;
52 import javax.websocket.OnClose;
53 import javax.websocket.OnError;
54 import javax.websocket.OnMessage;
55 import javax.websocket.OnOpen;
56 import javax.websocket.Session;
57 import javax.websocket.WebSocketContainer;
58 import net.java.html.json.OnReceive;
59 import org.netbeans.html.context.spi.Contexts;
60 import org.netbeans.html.json.spi.JSONCall;
61 import org.netbeans.html.json.spi.Transfer;
62 import org.netbeans.html.json.spi.WSTransfer;
63 import org.netbeans.html.wstyrus.TyrusContext.Comm;
64 import org.json.JSONArray;
65 import org.json.JSONException;
66 import org.json.JSONObject;
67 import org.json.JSONTokener;
68 import org.openide.util.lookup.ServiceProvider;
70 /** This is an implementation module that provides support for
71 * WebSocket protocol for {@link OnReceive} communication end point for
74 * Don't deal with this module directly, rather use the
75 * {@link OnReceive @OnReceive(url="ws://...", ...)} API to establish your
76 * WebSocket connection.
78 * There is no need to include this module in your application if you are
79 * running on JDK8. JDK8 WebView provides its own implementation of the
80 * WebSocket API based on WebSocket object inside a browser. This is included
81 * in the <code>org.netbeans.html:ko4j:1.0</code> module.
83 * @author Jaroslav Tulach
85 @ServiceProvider(service = Contexts.Provider.class)
86 public final class TyrusContext
87 implements Contexts.Provider, WSTransfer<Comm>, Transfer {
89 public void fillContext(Contexts.Builder context, Class<?> requestor) {
90 // default WebSocket transfer implementation is registered
91 // in ko-fx module with 100, provide this one as a fallback only
92 context.register(WSTransfer.class, this, 1000);
93 context.register(Transfer.class, this, 1000);
97 public Comm open(String url, JSONCall callback) {
99 return new Comm(new URI(url), callback);
100 } catch (URISyntaxException ex) {
101 throw new IllegalStateException(ex);
106 public void send(Comm socket, JSONCall data) {
107 socket.session.getAsyncRemote().sendText(data.getMessage());
111 public void close(Comm socket) {
113 final Session s = socket.session;
117 } catch (IOException ex) {
118 socket.callback.notifyError(ex);
123 public void extract(Object obj, String[] props, Object[] values) {
124 LoadJSON.extractJSON(obj, props, values);
128 public Object toJSON(InputStream is) throws IOException {
129 return LoadJSON.parse(is);
133 public void loadJSON(JSONCall call) {
134 LoadJSON.loadJSON(call);
137 /** Implementation class in an implementation. Represents a {@link ClientEndpoint} of the
138 * WebSocket channel. You are unlikely to get on hold of it.
141 public static final class Comm {
142 private final JSONCall callback;
143 private Session session;
145 Comm(final URI url, JSONCall callback) {
146 this.callback = callback;
148 final WebSocketContainer c = ContainerProvider.getWebSocketContainer();
149 c.connectToServer(Comm.this, url);
150 } catch (Exception ex) {
156 public synchronized void open(Session s) {
158 callback.notifySuccess(null);
162 public void close() {
164 callback.notifyError(null);
168 public void message(final String orig, Session s) {
170 String data = orig.trim();
172 JSONTokener tok = new JSONTokener(data);
173 Object obj = data.startsWith("[") ? new JSONArray(tok) : new JSONObject(tok);
174 json = convertToArray(obj);
175 } catch (JSONException ex) {
178 callback.notifySuccess(json);
182 public void wasAnError(Throwable t) {
183 callback.notifyError(t);
186 static Object convertToArray(Object o) throws JSONException {
187 if (o instanceof JSONArray) {
188 JSONArray ja = (JSONArray) o;
189 Object[] arr = new Object[ja.length()];
190 for (int i = 0; i < arr.length; i++) {
191 arr[i] = convertToArray(ja.get(i));
194 } else if (o instanceof JSONObject) {
195 JSONObject obj = (JSONObject) o;
196 Iterator it = obj.keys();
197 while (it.hasNext()) {
198 String key = (String) it.next();
199 obj.put(key, convertToArray(obj.get(key)));