ko4j/src/main/java/org/netbeans/html/ko4j/LoadJSON.java
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 26 Aug 2014 18:13:30 +0200
changeset 838 bdc3d696dd4a
parent 790 30f20d9c0986
child 864 dac3ef58c563
permissions -rw-r--r--
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.
jaroslav@37
     1
/**
jaroslav@358
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jaroslav@37
     3
 *
jaroslav@551
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jaroslav@37
     5
 *
jaroslav@358
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jaroslav@358
     7
 * Other names may be trademarks of their respective owners.
jaroslav@37
     8
 *
jaroslav@358
     9
 * The contents of this file are subject to the terms of either the GNU
jaroslav@358
    10
 * General Public License Version 2 only ("GPL") or the Common
jaroslav@358
    11
 * Development and Distribution License("CDDL") (collectively, the
jaroslav@358
    12
 * "License"). You may not use this file except in compliance with the
jaroslav@358
    13
 * License. You can obtain a copy of the License at
jaroslav@358
    14
 * http://www.netbeans.org/cddl-gplv2.html
jaroslav@358
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jaroslav@358
    16
 * specific language governing permissions and limitations under the
jaroslav@358
    17
 * License.  When distributing the software, include this License Header
jaroslav@358
    18
 * Notice in each file and include the License file at
jaroslav@358
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jaroslav@358
    20
 * particular file as subject to the "Classpath" exception as provided
jaroslav@358
    21
 * by Oracle in the GPL Version 2 section of the License file that
jaroslav@358
    22
 * accompanied this code. If applicable, add the following below the
jaroslav@358
    23
 * License Header, with the fields enclosed by brackets [] replaced by
jaroslav@358
    24
 * your own identifying information:
jaroslav@358
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
jaroslav@358
    26
 *
jaroslav@358
    27
 * Contributor(s):
jaroslav@358
    28
 *
jaroslav@358
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
jaroslav@551
    30
 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jaroslav@358
    31
 *
jaroslav@358
    32
 * If you wish your version of this file to be governed by only the CDDL
jaroslav@358
    33
 * or only the GPL Version 2, indicate your decision by adding
jaroslav@358
    34
 * "[Contributor] elects to include this software in this distribution
jaroslav@358
    35
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jaroslav@358
    36
 * single choice of license, a recipient has the option to distribute
jaroslav@358
    37
 * your version of this file under either the CDDL, the GPL Version 2 or
jaroslav@358
    38
 * to extend the choice of license to its licensees as provided above.
jaroslav@358
    39
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jaroslav@358
    40
 * Version 2 license, then the option applies only if the new code is
jaroslav@358
    41
 * made subject to such option by the copyright holder.
jaroslav@37
    42
 */
jaroslav@442
    43
package org.netbeans.html.ko4j;
jaroslav@37
    44
jaroslav@446
    45
import java.io.ByteArrayOutputStream;
jaroslav@37
    46
import java.io.IOException;
jaroslav@60
    47
import java.io.InputStream;
jaroslav@37
    48
import java.io.InputStreamReader;
jaroslav@131
    49
import net.java.html.js.JavaScriptBody;
jtulach@838
    50
import org.netbeans.html.json.spi.JSONCall;
jtulach@838
    51
import org.netbeans.html.json.spi.Transfer;
jtulach@838
    52
import org.netbeans.html.json.spi.WSTransfer;
jaroslav@37
    53
jaroslav@446
    54
/**
jaroslav@37
    55
 *
jtulach@790
    56
 * @author Jaroslav Tulach
jaroslav@37
    57
 */
jaroslav@446
    58
final class LoadJSON implements Transfer, WSTransfer<LoadWS> {
jaroslav@446
    59
    private LoadJSON() {}
jaroslav@446
    60
    
jaroslav@446
    61
    @Override
jaroslav@446
    62
    public void extract(Object obj, String[] props, Object[] values) {
jaroslav@446
    63
        extractJSON(obj, props, values);
jaroslav@37
    64
    }
jaroslav@37
    65
jaroslav@37
    66
    @Override
jaroslav@446
    67
    public void loadJSON(final JSONCall call) {
jaroslav@37
    68
        if (call.isJSONP()) {
jaroslav@446
    69
            String me = createJSONP(call);
jaroslav@446
    70
            loadJSONP(call.composeURL(me), me);
jaroslav@37
    71
        } else {
jaroslav@446
    72
            String data = null;
jaroslav@446
    73
            if (call.isDoOutput()) {
jaroslav@446
    74
                try {
jaroslav@446
    75
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
jaroslav@446
    76
                    call.writeData(bos);
jaroslav@446
    77
                    data = new String(bos.toByteArray(), "UTF-8");
jaroslav@446
    78
                } catch (IOException ex) {
jaroslav@446
    79
                    call.notifyError(ex);
jaroslav@75
    80
                }
jaroslav@74
    81
            }
jaroslav@446
    82
            loadJSON(call.composeURL(null), call, call.getMethod(), data);
jaroslav@37
    83
        }
jaroslav@37
    84
    }
jaroslav@37
    85
jaroslav@446
    86
    @Override
jaroslav@446
    87
    public Object toJSON(InputStream is) throws IOException {
jaroslav@446
    88
        StringBuilder sb = new StringBuilder();
jaroslav@446
    89
        InputStreamReader r = new InputStreamReader(is);
jaroslav@446
    90
        for (;;) {
jaroslav@446
    91
            int ch = r.read();
jaroslav@446
    92
            if (ch == -1) {
jaroslav@446
    93
                break;
jaroslav@37
    94
            }
jaroslav@446
    95
            sb.append((char)ch);
jaroslav@446
    96
        }
jaroslav@446
    97
        return parse(sb.toString());
jaroslav@446
    98
    }
jaroslav@446
    99
jaroslav@446
   100
    @Override
jaroslav@446
   101
    public LoadWS open(String url, JSONCall callback) {
jaroslav@446
   102
        return new LoadWS(callback, url);
jaroslav@446
   103
    }
jaroslav@446
   104
jaroslav@446
   105
    @Override
jaroslav@446
   106
    public void send(LoadWS socket, JSONCall data) {
jaroslav@446
   107
        socket.send(data);
jaroslav@446
   108
    }
jaroslav@446
   109
jaroslav@446
   110
    @Override
jaroslav@446
   111
    public void close(LoadWS socket) {
jaroslav@446
   112
        socket.close();
jaroslav@446
   113
    }
jaroslav@446
   114
    
jaroslav@446
   115
    //
jaroslav@446
   116
    // implementations
jaroslav@446
   117
    //
jaroslav@446
   118
    
jaroslav@446
   119
    @JavaScriptBody(args = {"object", "property"},
jaroslav@446
   120
        body
jaroslav@446
   121
        = "if (property === null) return object;\n"
jaroslav@446
   122
        + "if (object === null) return null;\n"
jaroslav@446
   123
        + "var p = object[property]; return p ? p : null;"
jaroslav@446
   124
    )
jaroslav@446
   125
    private static Object getProperty(Object object, String property) {
jaroslav@446
   126
        return null;
jaroslav@446
   127
    }
jaroslav@446
   128
jaroslav@446
   129
    static String createJSONP(JSONCall whenDone) {
jaroslav@446
   130
        int h = whenDone.hashCode();
jaroslav@446
   131
        String name;
jaroslav@446
   132
        for (;;) {
jaroslav@446
   133
            name = "jsonp" + Integer.toHexString(h);
jaroslav@446
   134
            if (defineIfUnused(name, whenDone)) {
jaroslav@446
   135
                return name;
jaroslav@37
   136
            }
jaroslav@446
   137
            h++;
jaroslav@446
   138
        }
jaroslav@446
   139
    }
jaroslav@446
   140
jaroslav@446
   141
    @JavaScriptBody(args = {"name", "done"}, javacall = true, body
jaroslav@446
   142
        = "if (window[name]) return false;\n "
jaroslav@446
   143
        + "window[name] = function(data) {\n "
jaroslav@446
   144
        + "  delete window[name];\n"
jaroslav@446
   145
        + "  var el = window.document.getElementById(name);\n"
jaroslav@446
   146
        + "  el.parentNode.removeChild(el);\n"
jtulach@838
   147
        + "  done.@org.netbeans.html.json.spi.JSONCall::notifySuccess(Ljava/lang/Object;)(data);\n"
jaroslav@446
   148
        + "};\n"
jaroslav@446
   149
        + "return true;\n"
jaroslav@446
   150
    )
jaroslav@446
   151
    private static boolean defineIfUnused(String name, JSONCall done) {
jaroslav@446
   152
        return true;
jaroslav@446
   153
    }
jaroslav@446
   154
jaroslav@446
   155
    @JavaScriptBody(args = {"s"}, body = "return eval('(' + s + ')');")
jaroslav@446
   156
    static Object parse(String s) {
jaroslav@446
   157
        return s;
jaroslav@446
   158
    }
jaroslav@446
   159
jaroslav@446
   160
    @JavaScriptBody(args = {"url", "done", "method", "data"}, javacall = true, body = ""
jaroslav@446
   161
        + "var request = new XMLHttpRequest();\n"
jaroslav@446
   162
        + "if (!method) method = 'GET';\n"
jaroslav@446
   163
        + "request.open(method, url, true);\n"
jaroslav@446
   164
        + "request.setRequestHeader('Content-Type', 'application/json; charset=utf-8');\n"
jaroslav@446
   165
        + "request.onreadystatechange = function() {\n"
jtulach@688
   166
        + "  if (request.readyState !== 4) return;\n"
jtulach@688
   167
        + "  var r = request.response || request.responseText;\n"
jaroslav@446
   168
        + "  try {\n"
jtulach@754
   169
        + "    if (request.status < 100 || request.status >= 400) throw request.status + ': ' + request.statusText;"
jtulach@679
   170
        + "    try { r = eval('(' + r + ')'); } catch (ignore) { }"
jtulach@838
   171
        + "    done.@org.netbeans.html.json.spi.JSONCall::notifySuccess(Ljava/lang/Object;)(r);\n"
jaroslav@446
   172
        + "  } catch (error) {;\n"
jtulach@748
   173
        + "    @org.netbeans.html.ko4j.LoadJSON::notifyError(Ljava/lang/Object;Ljava/lang/Object;)(done, error);\n"
jaroslav@446
   174
        + "  }\n"
jaroslav@446
   175
        + "};\n"
jtulach@688
   176
        + "request.onerror = function (e) {\n"
jtulach@691
   177
        + "  console.log('error loading :' + url + ' props: ' + Object.getOwnPropertyNames(e));\n"
jaroslav@446
   178
        + "  @org.netbeans.html.ko4j.LoadJSON::notifyError(Ljava/lang/Object;Ljava/lang/Object;)(done, e);\n"
jaroslav@446
   179
        + "}\n"
jaroslav@446
   180
        + "if (data) request.send(data);"
jaroslav@446
   181
        + "else request.send();"
jaroslav@446
   182
    )
jaroslav@446
   183
    static void loadJSON(
jaroslav@446
   184
        String url, JSONCall done, String method, String data
jaroslav@446
   185
    ) {
jaroslav@446
   186
    }
jaroslav@446
   187
    
jaroslav@446
   188
    static void notifyError(Object done, Object msg) {
jaroslav@446
   189
        ((JSONCall)done).notifyError(new Exception(msg.toString()));
jaroslav@446
   190
    }
jaroslav@446
   191
jaroslav@446
   192
    @JavaScriptBody(args = {"url", "jsonp"}, body
jaroslav@446
   193
        = "var scrpt = window.document.createElement('script');\n "
jaroslav@446
   194
        + "scrpt.setAttribute('src', url);\n "
jaroslav@446
   195
        + "scrpt.setAttribute('id', jsonp);\n "
jaroslav@446
   196
        + "scrpt.setAttribute('type', 'text/javascript');\n "
jaroslav@446
   197
        + "var body = document.getElementsByTagName('body')[0];\n "
jaroslav@446
   198
        + "body.appendChild(scrpt);\n"
jaroslav@446
   199
    )
jaroslav@446
   200
    static void loadJSONP(String url, String jsonp) {
jaroslav@446
   201
jaroslav@446
   202
    }
jaroslav@446
   203
jaroslav@446
   204
    static void extractJSON(Object jsonObject, String[] props, Object[] values) {
jaroslav@446
   205
        for (int i = 0; i < props.length; i++) {
jaroslav@446
   206
            values[i] = getProperty(jsonObject, props[i]);
jaroslav@37
   207
        }
jaroslav@37
   208
    }
jaroslav@37
   209
    
jaroslav@37
   210
}