ko4j/src/main/java/org/netbeans/html/ko4j/LoadJSON.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 02 Aug 2014 12:59:31 +0200
changeset 790 30f20d9c0986
parent 754 ce30cad0ed95
child 838 bdc3d696dd4a
permissions -rw-r--r--
Fixing Javadoc to succeed on JDK8
     1 /**
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     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]"
    26  *
    27  * Contributor(s):
    28  *
    29  * The Original Software is NetBeans. The Initial Developer of the Original
    30  * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    31  *
    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.
    42  */
    43 package org.netbeans.html.ko4j;
    44 
    45 import java.io.ByteArrayOutputStream;
    46 import java.io.IOException;
    47 import java.io.InputStream;
    48 import java.io.InputStreamReader;
    49 import net.java.html.js.JavaScriptBody;
    50 import org.apidesign.html.json.spi.JSONCall;
    51 import org.apidesign.html.json.spi.Transfer;
    52 import org.apidesign.html.json.spi.WSTransfer;
    53 
    54 /**
    55  *
    56  * @author Jaroslav Tulach
    57  */
    58 final class LoadJSON implements Transfer, WSTransfer<LoadWS> {
    59     private LoadJSON() {}
    60     
    61     @Override
    62     public void extract(Object obj, String[] props, Object[] values) {
    63         extractJSON(obj, props, values);
    64     }
    65 
    66     @Override
    67     public void loadJSON(final JSONCall call) {
    68         if (call.isJSONP()) {
    69             String me = createJSONP(call);
    70             loadJSONP(call.composeURL(me), me);
    71         } else {
    72             String data = null;
    73             if (call.isDoOutput()) {
    74                 try {
    75                     ByteArrayOutputStream bos = new ByteArrayOutputStream();
    76                     call.writeData(bos);
    77                     data = new String(bos.toByteArray(), "UTF-8");
    78                 } catch (IOException ex) {
    79                     call.notifyError(ex);
    80                 }
    81             }
    82             loadJSON(call.composeURL(null), call, call.getMethod(), data);
    83         }
    84     }
    85 
    86     @Override
    87     public Object toJSON(InputStream is) throws IOException {
    88         StringBuilder sb = new StringBuilder();
    89         InputStreamReader r = new InputStreamReader(is);
    90         for (;;) {
    91             int ch = r.read();
    92             if (ch == -1) {
    93                 break;
    94             }
    95             sb.append((char)ch);
    96         }
    97         return parse(sb.toString());
    98     }
    99 
   100     @Override
   101     public LoadWS open(String url, JSONCall callback) {
   102         return new LoadWS(callback, url);
   103     }
   104 
   105     @Override
   106     public void send(LoadWS socket, JSONCall data) {
   107         socket.send(data);
   108     }
   109 
   110     @Override
   111     public void close(LoadWS socket) {
   112         socket.close();
   113     }
   114     
   115     //
   116     // implementations
   117     //
   118     
   119     @JavaScriptBody(args = {"object", "property"},
   120         body
   121         = "if (property === null) return object;\n"
   122         + "if (object === null) return null;\n"
   123         + "var p = object[property]; return p ? p : null;"
   124     )
   125     private static Object getProperty(Object object, String property) {
   126         return null;
   127     }
   128 
   129     static String createJSONP(JSONCall whenDone) {
   130         int h = whenDone.hashCode();
   131         String name;
   132         for (;;) {
   133             name = "jsonp" + Integer.toHexString(h);
   134             if (defineIfUnused(name, whenDone)) {
   135                 return name;
   136             }
   137             h++;
   138         }
   139     }
   140 
   141     @JavaScriptBody(args = {"name", "done"}, javacall = true, body
   142         = "if (window[name]) return false;\n "
   143         + "window[name] = function(data) {\n "
   144         + "  delete window[name];\n"
   145         + "  var el = window.document.getElementById(name);\n"
   146         + "  el.parentNode.removeChild(el);\n"
   147         + "  done.@org.apidesign.html.json.spi.JSONCall::notifySuccess(Ljava/lang/Object;)(data);\n"
   148         + "};\n"
   149         + "return true;\n"
   150     )
   151     private static boolean defineIfUnused(String name, JSONCall done) {
   152         return true;
   153     }
   154 
   155     @JavaScriptBody(args = {"s"}, body = "return eval('(' + s + ')');")
   156     static Object parse(String s) {
   157         return s;
   158     }
   159 
   160     @JavaScriptBody(args = {"url", "done", "method", "data"}, javacall = true, body = ""
   161         + "var request = new XMLHttpRequest();\n"
   162         + "if (!method) method = 'GET';\n"
   163         + "request.open(method, url, true);\n"
   164         + "request.setRequestHeader('Content-Type', 'application/json; charset=utf-8');\n"
   165         + "request.onreadystatechange = function() {\n"
   166         + "  if (request.readyState !== 4) return;\n"
   167         + "  var r = request.response || request.responseText;\n"
   168         + "  try {\n"
   169         + "    if (request.status < 100 || request.status >= 400) throw request.status + ': ' + request.statusText;"
   170         + "    try { r = eval('(' + r + ')'); } catch (ignore) { }"
   171         + "    done.@org.apidesign.html.json.spi.JSONCall::notifySuccess(Ljava/lang/Object;)(r);\n"
   172         + "  } catch (error) {;\n"
   173         + "    @org.netbeans.html.ko4j.LoadJSON::notifyError(Ljava/lang/Object;Ljava/lang/Object;)(done, error);\n"
   174         + "  }\n"
   175         + "};\n"
   176         + "request.onerror = function (e) {\n"
   177         + "  console.log('error loading :' + url + ' props: ' + Object.getOwnPropertyNames(e));\n"
   178         + "  @org.netbeans.html.ko4j.LoadJSON::notifyError(Ljava/lang/Object;Ljava/lang/Object;)(done, e);\n"
   179         + "}\n"
   180         + "if (data) request.send(data);"
   181         + "else request.send();"
   182     )
   183     static void loadJSON(
   184         String url, JSONCall done, String method, String data
   185     ) {
   186     }
   187     
   188     static void notifyError(Object done, Object msg) {
   189         ((JSONCall)done).notifyError(new Exception(msg.toString()));
   190     }
   191 
   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"
   199     )
   200     static void loadJSONP(String url, String jsonp) {
   201 
   202     }
   203 
   204     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]);
   207         }
   208     }
   209     
   210 }