2 * Back 2 Browser Bytecode Translator
3 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. Look for COPYING file in the top folder.
16 * If not, see http://opensource.org/licenses/GPL-2.0.
18 package org.apidesign.bck2brwsr.ko2brwsr;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.InputStreamReader;
24 import org.apidesign.bck2brwsr.core.JavaScriptBody;
25 import org.apidesign.html.json.spi.JSONCall;
26 import org.apidesign.html.json.spi.Transfer;
27 import org.apidesign.html.json.spi.WSTransfer;
31 * @author Jaroslav Tulach <jtulach@netbeans.org>
33 final class BrwsrCtxImpl implements Transfer, WSTransfer<LoadWS> {
34 private BrwsrCtxImpl() {}
36 public static final BrwsrCtxImpl DEFAULT = new BrwsrCtxImpl();
39 public void extract(Object obj, String[] props, Object[] values) {
40 extractJSON(obj, props, values);
44 public void loadJSON(final JSONCall call) {
45 class R implements Runnable {
46 final boolean success;
48 public R(boolean success) {
49 this.success = success;
52 Object[] arr = { null };
56 call.notifySuccess(arr[0]);
59 if (arr[0] instanceof Throwable) {
60 t = (Throwable) arr[0];
63 t = new IOException();
65 t = new IOException(arr[0].toString());
72 R success = new R(true);
73 R failure = new R(false);
75 String me = createJSONP(success.arr, success);
76 loadJSONP(call.composeURL(me), me);
79 if (call.isDoOutput()) {
81 ByteArrayOutputStream bos = new ByteArrayOutputStream();
83 data = new String(bos.toByteArray(), "UTF-8");
84 } catch (IOException ex) {
88 loadJSON(call.composeURL(null), success.arr, success, failure, call.getMethod(), data);
93 public Object toJSON(InputStream is) throws IOException {
94 StringBuilder sb = new StringBuilder();
95 InputStreamReader r = new InputStreamReader(is);
103 return parse(sb.toString());
107 public LoadWS open(String url, JSONCall callback) {
108 return new LoadWS(callback, url);
112 public void send(LoadWS socket, JSONCall data) {
117 public void close(LoadWS socket) {
125 @JavaScriptBody(args = {"object", "property"},
127 = "if (property === null) return object;\n"
128 + "if (object === null) return null;\n"
129 + "var p = object[property]; return p ? p : null;"
131 private static Object getProperty(Object object, String property) {
135 public static String createJSONP(Object[] jsonResult, Runnable whenDone) {
136 int h = whenDone.hashCode();
139 name = "jsonp" + Integer.toHexString(h);
140 if (defineIfUnused(name, jsonResult, whenDone)) {
147 @JavaScriptBody(args = {"name", "arr", "run"}, body
148 = "if (window[name]) return false;\n "
149 + "window[name] = function(data) {\n "
150 + " delete window[name];\n"
151 + " var el = window.document.getElementById(name);\n"
152 + " el.parentNode.removeChild(el);\n"
153 + " arr[0] = data;\n"
158 private static boolean defineIfUnused(String name, Object[] arr, Runnable run) {
162 @JavaScriptBody(args = {"s"}, body = "return eval('(' + s + ')');")
163 static Object parse(String s) {
167 @JavaScriptBody(args = {"url", "arr", "callback", "onError", "method", "data"}, body = ""
168 + "var request = new XMLHttpRequest();\n"
169 + "if (!method) method = 'GET';\n"
170 + "request.open(method, url, true);\n"
171 + "request.setRequestHeader('Content-Type', 'application/json; charset=utf-8');\n"
172 + "request.onreadystatechange = function() {\n"
173 + " if (this.readyState!==4) return;\n"
175 + " arr[0] = eval('(' + this.response + ')');\n"
176 + " } catch (error) {;\n"
177 + " arr[0] = this.response;\n"
179 + " callback.run__V();\n"
181 + "request.onerror = function (e) {\n"
182 + " arr[0] = e; onError.run__V();\n"
184 + "if (data) request.send(data);"
185 + "else request.send();"
187 static void loadJSON(
188 String url, Object[] jsonResult, Runnable whenDone, Runnable whenErr, String method, String data
192 @JavaScriptBody(args = {"url", "jsonp"}, body
193 = "var scrpt = window.document.createElement('script');\n "
194 + "scrpt.setAttribute('src', url);\n "
195 + "scrpt.setAttribute('id', jsonp);\n "
196 + "scrpt.setAttribute('type', 'text/javascript');\n "
197 + "var body = document.getElementsByTagName('body')[0];\n "
198 + "body.appendChild(scrpt);\n"
200 static void loadJSONP(String url, String jsonp) {
204 public static void extractJSON(Object jsonObject, String[] props, Object[] values) {
205 for (int i = 0; i < props.length; i++) {
206 values[i] = getProperty(jsonObject, props[i]);