ko4j/src/main/java/org/netbeans/html/ko4j/LoadJSON.java
author Jaroslav Tulach <jaroslav.tulach@netbeans.org>
Fri, 07 Feb 2014 07:44:34 +0100
changeset 551 7ca2253fa86d
parent 446 6dce58c06f58
child 679 9ca8cf2f2ce2
permissions -rw-r--r--
Updating copyright headers to mention current year
     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 <jtulach@netbeans.org>
    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 (this.readyState!==4) return;\n"
   167         + "  try {\n"
   168         + "    var r = this.response;\n"
   169         + "    try { r = eval('(' + this.response + ')'); } catch (ignore) { }"
   170         + "    done.@org.apidesign.html.json.spi.JSONCall::notifySuccess(Ljava/lang/Object;)(r);\n"
   171         + "  } catch (error) {;\n"
   172         + "    @org.netbeans.html.ko4j.LoadJSON::notifyError(Ljava/lang/Object;Ljava/lang/Object;)(done, this.response);\n"
   173         + "  }\n"
   174         + "};\n"
   175         + "request.onerror = function (e) {console.log('eeeor:' + Object.getOwnPropertyNames(e));\n"
   176         + "  @org.netbeans.html.ko4j.LoadJSON::notifyError(Ljava/lang/Object;Ljava/lang/Object;)(done, e);\n"
   177         + "}\n"
   178         + "if (data) request.send(data);"
   179         + "else request.send();"
   180     )
   181     static void loadJSON(
   182         String url, JSONCall done, String method, String data
   183     ) {
   184     }
   185     
   186     static void notifyError(Object done, Object msg) {
   187         ((JSONCall)done).notifyError(new Exception(msg.toString()));
   188     }
   189 
   190     @JavaScriptBody(args = {"url", "jsonp"}, body
   191         = "var scrpt = window.document.createElement('script');\n "
   192         + "scrpt.setAttribute('src', url);\n "
   193         + "scrpt.setAttribute('id', jsonp);\n "
   194         + "scrpt.setAttribute('type', 'text/javascript');\n "
   195         + "var body = document.getElementsByTagName('body')[0];\n "
   196         + "body.appendChild(scrpt);\n"
   197     )
   198     static void loadJSONP(String url, String jsonp) {
   199 
   200     }
   201 
   202     static void extractJSON(Object jsonObject, String[] props, Object[] values) {
   203         for (int i = 0; i < props.length; i++) {
   204             values[i] = getProperty(jsonObject, props[i]);
   205         }
   206     }
   207     
   208 }