Making JSON calls work without references to non-public packages osgi
authorJaroslav Tulach <jaroslav.tulach@netbeans.org>
Fri, 03 Jan 2014 08:16:39 +0100
branchosgi
changeset 3862fc4100fcd32
parent 385 68012e8398a8
child 387 972a38bebd50
Making JSON calls work without references to non-public packages
json/src/main/java/org/apidesign/html/json/spi/Proto.java
json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
json/src/main/java/org/netbeans/html/json/impl/RcvrJSON.java
     1.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Proto.java	Thu Dec 26 22:42:01 2013 +0100
     1.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Proto.java	Fri Jan 03 08:16:39 2014 +0100
     1.3 @@ -48,6 +48,8 @@
     1.4  import org.netbeans.html.json.impl.Bindings;
     1.5  import org.netbeans.html.json.impl.JSON;
     1.6  import org.netbeans.html.json.impl.JSONList;
     1.7 +import org.netbeans.html.json.impl.RcvrJSON;
     1.8 +import org.netbeans.html.json.impl.RcvrJSON.MsgEvnt;
     1.9  
    1.10  /**
    1.11   *
    1.12 @@ -149,6 +151,24 @@
    1.13          type.onChange(obj, index);
    1.14      }
    1.15  
    1.16 +    public void loadJSON(final int index, 
    1.17 +        String urlBefore, String urlAfter, String method,
    1.18 +        final Object data
    1.19 +    ) {
    1.20 +        class Rcvr extends RcvrJSON {
    1.21 +            @Override
    1.22 +            protected void onMessage(MsgEvnt msg) {
    1.23 +                type.onMessage(obj, index, 1, msg.getValues());
    1.24 +            }
    1.25 +
    1.26 +            @Override
    1.27 +            protected void onError(MsgEvnt msg) {
    1.28 +                type.onMessage(obj, index, 2, msg.getException());
    1.29 +            }
    1.30 +        }
    1.31 +        JSON.loadJSON(context, new Rcvr(), urlBefore, urlAfter, method, data);
    1.32 +    }
    1.33 +    
    1.34      public String toString(Object data, String propName) {
    1.35          return JSON.toString(context, data, propName);
    1.36      }
    1.37 @@ -177,7 +197,7 @@
    1.38              }
    1.39          }
    1.40      }
    1.41 -    
    1.42 +
    1.43      /** Functionality used by the code generated by annotation
    1.44       * processor for the {@link net.java.html.json.Model} annotation.
    1.45       * 
    1.46 @@ -225,6 +245,21 @@
    1.47          public abstract Model read(BrwsrCtx c, Object json);
    1.48          public abstract void onChange(Model model, int index);
    1.49          public abstract Proto protoFor(Object object);
    1.50 +
    1.51 +        /**
    1.52 +         * 
    1.53 +         * @param model
    1.54 +         * @param index
    1.55 +         * @param type 0 - onOpen, 1 - onMessage, 2 - onError, 3 - onClose
    1.56 +         * @param data 
    1.57 +         */
    1.58 +        public abstract void onMessage(Model model, int index, int type, Object data);
    1.59 +
    1.60 +        public <T> void copyJSON(BrwsrCtx context, Object[] src, Class<T> destType, T[] dest) {
    1.61 +            for (int i = 0; i < src.length && i < dest.length; i++) {
    1.62 +                dest[i] = org.netbeans.html.json.impl.JSON.read(context, destType, src[i]);
    1.63 +            }
    1.64 +        }
    1.65          
    1.66          //
    1.67          // Various support methods the generated classes use
     2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java	Thu Dec 26 22:42:01 2013 +0100
     2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java	Fri Jan 03 08:16:39 2014 +0100
     2.3 @@ -183,6 +183,7 @@
     2.4          models.put(e, className);
     2.5          try {
     2.6              StringWriter body = new StringWriter();
     2.7 +            StringBuilder onReceiveType = new StringBuilder();
     2.8              List<String> propsGetSet = new ArrayList<String>();
     2.9              List<String> functions = new ArrayList<String>();
    2.10              Map<String, Collection<String>> propsDeps = new HashMap<String, Collection<String>>();
    2.11 @@ -201,7 +202,7 @@
    2.12              if (!generateFunctions(e, body, className, e.getEnclosedElements(), functions)) {
    2.13                  ok = false;
    2.14              }
    2.15 -            if (!generateReceive(e, body, className, e.getEnclosedElements(), functions)) {
    2.16 +            if (!generateReceive(e, body, className, e.getEnclosedElements(), onReceiveType)) {
    2.17                  ok = false;
    2.18              }
    2.19              if (!generateOperation(e, body, className, e.getEnclosedElements())) {
    2.20 @@ -372,6 +373,7 @@
    2.21                  w.append("    }\n");
    2.22                  w.append("      throw new UnsupportedOperationException();\n");
    2.23                  w.append("    }\n");
    2.24 +                w.append(onReceiveType);
    2.25                  w.append("    @Override public " + className + " read(net.java.html.BrwsrCtx c, Object json) { return new " + className + "(c, json); }\n");
    2.26                  w.append("    @Override public " + className + " cloneTo(Object o, net.java.html.BrwsrCtx c) { return ((" + className + ")o).clone(c); }\n");
    2.27                  w.append("  }\n");
    2.28 @@ -930,8 +932,11 @@
    2.29      
    2.30      private boolean generateReceive(
    2.31          Element clazz, StringWriter body, String className, 
    2.32 -        List<? extends Element> enclosedElements, List<String> functions
    2.33 +        List<? extends Element> enclosedElements, StringBuilder inType
    2.34      ) {
    2.35 +        inType.append("  @Override public void onMessage(").append(className).append(" model, int index, int type, Object data) {\n");
    2.36 +        inType.append("    switch (index) {\n");
    2.37 +        int index = 0;
    2.38          for (Element m : enclosedElements) {
    2.39              if (m.getKind() != ElementKind.METHOD) {
    2.40                  continue;
    2.41 @@ -979,7 +984,7 @@
    2.42                          simpleName = type.toString();
    2.43                      }
    2.44                      if (simpleName.toString().equals(className)) {
    2.45 -                        args.add(className + ".this");
    2.46 +                        args.add("model");
    2.47                      } else if (isModel(ve.asType())) {
    2.48                          modelType = ve.asType();
    2.49                      } else if (ve.asType().getKind() == TypeKind.ARRAY) {
    2.50 @@ -1042,47 +1047,49 @@
    2.51              body.append(") {\n");
    2.52              boolean webSocket = onR.method().equals("WebSocket");
    2.53              if (webSocket) {
    2.54 -                if (generateWSReceiveBody(body, onR, e, clazz, className, expectsList, modelClass, n, args, urlBefore, jsonpVarName, urlAfter, dataMirror)) {
    2.55 -                    return false;
    2.56 -                }
    2.57 +//                if (generateWSReceiveBody(body, onR, e, clazz, className, expectsList, modelClass, n, args, urlBefore, jsonpVarName, urlAfter, dataMirror)) {
    2.58 +//                    return false;
    2.59 +//                }
    2.60                  body.append("  }\n");
    2.61                  body.append("  private org.netbeans.html.json.impl.JSON.WS ws_" + e.getSimpleName() + ";\n");
    2.62              } else {
    2.63 -                if (generateJSONReceiveBody(body, onR, e, clazz, className, expectsList, modelClass, n, args, urlBefore, jsonpVarName, urlAfter, dataMirror)) {
    2.64 +                if (generateJSONReceiveBody(index++, body, inType, onR, e, clazz, className, expectsList, modelClass, n, args, urlBefore, jsonpVarName, urlAfter, dataMirror)) {
    2.65                      return false;
    2.66                  }
    2.67                  body.append("  }\n");
    2.68              }
    2.69          }
    2.70 +        inType.append("    }\n");
    2.71 +        inType.append("    throw new UnsupportedOperationException(\"index: \" + index + \" type: \" + type);\n");
    2.72 +        inType.append("  }\n");
    2.73          return true;
    2.74      }
    2.75  
    2.76 -    private boolean generateJSONReceiveBody(StringWriter body, OnReceive onR, ExecutableElement e, Element clazz, String className, boolean expectsList, String modelClass, String n, List<String> args, StringBuilder urlBefore, String jsonpVarName, StringBuilder urlAfter, String dataMirror) {
    2.77 +    private boolean generateJSONReceiveBody(int index, StringWriter method, StringBuilder body, OnReceive onR, ExecutableElement e, Element clazz, String className, boolean expectsList, String modelClass, String n, List<String> args, StringBuilder urlBefore, String jsonpVarName, StringBuilder urlAfter, String dataMirror) {
    2.78          body.append(
    2.79 -            "    class ProcessResult extends org.netbeans.html.json.impl.RcvrJSON {\n" +
    2.80 -            "      @Override\n" +
    2.81 -            "      public void onError(org.netbeans.html.json.impl.RcvrJSON.MsgEvnt ev) {\n" +
    2.82 -            "        Exception value = ev.getException();\n"
    2.83 +            "    case " + index + ": {\n" +
    2.84 +            "      if (type == 2) { /* on error */\n" +
    2.85 +            "        Exception ex = (Exception)data;\n"
    2.86              );
    2.87          if (onR.onError().isEmpty()) {
    2.88              body.append(
    2.89 -                "        value.printStackTrace();\n"
    2.90 +                "        ex.printStackTrace();\n"
    2.91                  );
    2.92          } else {
    2.93              if (!findOnError(e, ((TypeElement)clazz), onR.onError(), className)) {
    2.94                  return true;
    2.95              }
    2.96              body.append("        ").append(clazz.getSimpleName()).append(".").append(onR.onError()).append("(");
    2.97 -            body.append(className).append(".this, value);\n");
    2.98 +            body.append("model, ex);\n");
    2.99          }
   2.100          body.append(
   2.101 -            "      }\n" +
   2.102 -            "      @Override\n" +
   2.103 -            "      public void onMessage(org.netbeans.html.json.impl.RcvrJSON.MsgEvnt ev) {\n"
   2.104 +            "        return;\n" +
   2.105 +            "      } else if (type == 1) {\n" +
   2.106 +            "        Object[] ev = (Object[])data;\n"
   2.107              );
   2.108          if (expectsList) {
   2.109              body.append(
   2.110 -                "        " + modelClass + "[] arr = new " + modelClass + "[ev.dataSize()];\n"
   2.111 +                "        " + modelClass + "[] arr = new " + modelClass + "[ev.length];\n"
   2.112                  );
   2.113          } else {
   2.114              body.append(
   2.115 @@ -1090,8 +1097,8 @@
   2.116                  );
   2.117          }
   2.118          body.append(
   2.119 -            "        ev.dataRead(proto.getContext(), " + modelClass + ".class, arr);\n"
   2.120 -            );
   2.121 +            "        TYPE.copyJSON(model.proto.getContext(), ev, " + modelClass + ".class, arr);\n"
   2.122 +        );
   2.123          {
   2.124              body.append("        ").append(clazz.getSimpleName()).append(".").append(n).append("(");
   2.125              String sep = "";
   2.126 @@ -1103,28 +1110,28 @@
   2.127              body.append(");\n");
   2.128          }
   2.129          body.append(
   2.130 +            "        return;\n" +
   2.131              "      }\n" +
   2.132              "    }\n"
   2.133              );
   2.134 -        body.append("    ProcessResult pr = new ProcessResult();\n");
   2.135 -        body.append("    org.netbeans.html.json.impl.JSON.loadJSON(proto.getContext(), pr,\n        ");
   2.136 -        body.append(urlBefore).append(", ");
   2.137 +        method.append("    proto.loadJSON(" + index + ",\n        ");
   2.138 +        method.append(urlBefore).append(", ");
   2.139          if (jsonpVarName != null) {
   2.140 -            body.append(urlAfter);
   2.141 +            method.append(urlAfter);
   2.142          } else {
   2.143 -            body.append("null");
   2.144 +            method.append("null");
   2.145          }
   2.146          if (!"GET".equals(onR.method()) || dataMirror != null) {
   2.147 -            body.append(", \"").append(onR.method()).append('"');
   2.148 +            method.append(", \"").append(onR.method()).append('"');
   2.149              if (dataMirror != null) {
   2.150 -                body.append(", data");
   2.151 +                method.append(", data");
   2.152              } else {
   2.153 -                body.append(", null");
   2.154 +                method.append(", null");
   2.155              }
   2.156          } else {
   2.157 -            body.append(", null, null");
   2.158 +            method.append(", null, null");
   2.159          }
   2.160 -        body.append(");\n");
   2.161 +        method.append(");\n");
   2.162          return false;
   2.163      }
   2.164      
     3.1 --- a/json/src/main/java/org/netbeans/html/json/impl/RcvrJSON.java	Thu Dec 26 22:42:01 2013 +0100
     3.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/RcvrJSON.java	Fri Jan 03 08:16:39 2014 +0100
     3.3 @@ -42,6 +42,7 @@
     3.4   */
     3.5  package org.netbeans.html.json.impl;
     3.6  
     3.7 +import java.util.ArrayList;
     3.8  import net.java.html.BrwsrCtx;
     3.9  
    3.10  /** Super type for those who wish to receive JSON messages.
    3.11 @@ -73,13 +74,10 @@
    3.12              return new Exception(t);
    3.13          }
    3.14          
    3.15 -        public int dataSize() {
    3.16 -            return -1;
    3.17 +        public Object[] getValues() {
    3.18 +            return null;
    3.19          }
    3.20          
    3.21 -        public <Data> void dataRead(BrwsrCtx ctx, Class<? extends Data> type, Data[] fillTheArray) {
    3.22 -        }
    3.23 -
    3.24          public abstract void dispatch(RcvrJSON r);
    3.25          
    3.26          public static MsgEvnt createError(final Throwable t) {
    3.27 @@ -99,26 +97,8 @@
    3.28          public static MsgEvnt createMessage(final Object value) {
    3.29              return new MsgEvnt() {
    3.30                  @Override
    3.31 -                public int dataSize() {
    3.32 -                    if (value instanceof Object[]) {
    3.33 -                        return ((Object[])value).length;
    3.34 -                    } else {
    3.35 -                        return 1;
    3.36 -                    }
    3.37 -                }
    3.38 -                
    3.39 -                @Override
    3.40 -                public <Data> void dataRead(BrwsrCtx context, Class<? extends Data> type, Data[] arr) {
    3.41 -                    if (value instanceof Object[]) {
    3.42 -                        Object[] data = ((Object[]) value);
    3.43 -                        for (int i = 0; i < data.length && i < arr.length; i++) {
    3.44 -                            arr[i] = org.netbeans.html.json.impl.JSON.read(context, type, data[i]);
    3.45 -                        }
    3.46 -                    } else {
    3.47 -                        if (arr.length > 0) {
    3.48 -                            arr[0] = org.netbeans.html.json.impl.JSON.read(context, type, value);
    3.49 -                        }
    3.50 -                    }
    3.51 +                public Object[] getValues() {
    3.52 +                    return value instanceof Object[] ? (Object[])value : new Object[] { value };
    3.53                  }
    3.54                  
    3.55                  @Override
    3.56 @@ -145,5 +125,4 @@
    3.57                  }
    3.58              };
    3.59          }
    3.60 -    } // end MsgEvnt
    3.61 -}
    3.62 +    } }