Introducing special JSON receiver rather than using tricks with Runnable and Object[]
1.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSON.java Sat Aug 24 18:00:08 2013 +0200
1.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSON.java Sun Aug 25 09:36:33 2013 +0200
1.3 @@ -37,9 +37,6 @@
1.4 * @author Jaroslav Tulach <jtulach@netbeans.org>
1.5 */
1.6 public final class JSON {
1.7 - /** represents null exception value */
1.8 - public static final Exception NULL = new NullPointerException();
1.9 -
1.10 private JSON() {
1.11 }
1.12
1.13 @@ -52,7 +49,7 @@
1.14 Transfer t = Contexts.find(c, Transfer.class);
1.15 return t == null ? EmptyTech.EMPTY : t;
1.16 }
1.17 -
1.18 +
1.19 public static void runInBrowser(BrwsrCtx c, Runnable runnable) {
1.20 findTechnology(c).runSafe(runnable);
1.21 }
1.22 @@ -136,16 +133,6 @@
1.23 return (Character)val;
1.24 }
1.25
1.26 - public static Exception excValue(Object val) {
1.27 - if (val == NULL) {
1.28 - return null;
1.29 - }
1.30 - if (val instanceof Exception) {
1.31 - return (Exception)val;
1.32 - }
1.33 - return new Exception(val.toString());
1.34 - }
1.35 -
1.36 public static Boolean boolValue(Object val) {
1.37 if (val instanceof String) {
1.38 return Boolean.parseBoolean((String)val);
1.39 @@ -154,18 +141,11 @@
1.40 }
1.41
1.42 public static void loadJSON(
1.43 - BrwsrCtx c, Runnable whenDone, Object[] result,
1.44 - String urlBefore, String urlAfter
1.45 - ) {
1.46 - loadJSON(c, whenDone, result, urlBefore, urlAfter, null, null);
1.47 - }
1.48 -
1.49 - public static void loadJSON(
1.50 - BrwsrCtx c, Runnable whenDone, Object[] result,
1.51 + BrwsrCtx c, RcvrJSON callback,
1.52 String urlBefore, String urlAfter, String method,
1.53 Object data
1.54 ) {
1.55 - JSONCall call = PropertyBindingAccessor.createCall(whenDone, result, urlBefore, urlAfter, method, data);
1.56 + JSONCall call = PropertyBindingAccessor.createCall(callback, urlBefore, urlAfter, method, data);
1.57 Transfer t = findTransfer(c);
1.58 t.loadJSON(call);
1.59 }
2.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Sat Aug 24 18:00:08 2013 +0200
2.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Sun Aug 25 09:36:33 2013 +0200
2.3 @@ -982,40 +982,39 @@
2.4 }
2.5 }
2.6 body.append(") {\n");
2.7 - body.append(" final Object[] result = { null };\n");
2.8 body.append(
2.9 - " class ProcessResult implements Runnable {\n" +
2.10 + " class ProcessResult extends org.apidesign.html.json.impl.RcvrJSON {\n" +
2.11 " @Override\n" +
2.12 - " public void run() {\n" +
2.13 - " Object value = result[0];\n" +
2.14 - " if (value instanceof Throwable) {\n");
2.15 + " public void onError(org.apidesign.html.json.impl.RcvrJSON.MsgEvnt ev) {\n" +
2.16 + " Exception value = ev.getException();\n"
2.17 + );
2.18 if (onR.onError().isEmpty()) {
2.19 body.append(
2.20 - " ((Throwable)value).printStackTrace(); return;\n"
2.21 + " value.printStackTrace();\n"
2.22 );
2.23 } else {
2.24 if (!findOnError(e, ((TypeElement)clazz), onR.onError(), className)) {
2.25 return false;
2.26 }
2.27 - body.append(" ").append(clazz.getSimpleName()).append(".").append(onR.onError()).append("(");
2.28 - body.append(className).append(".this, org.apidesign.html.json.impl.JSON.excValue(value)); return;\n");
2.29 + body.append(" ").append(clazz.getSimpleName()).append(".").append(onR.onError()).append("(");
2.30 + body.append(className).append(".this, value);\n");
2.31 }
2.32 body.append(
2.33 - " }\n"
2.34 + " }\n" +
2.35 + " @Override\n" +
2.36 + " public void onMessage(org.apidesign.html.json.impl.RcvrJSON.MsgEvnt ev) {\n"
2.37 );
2.38 + if (expectsList) {
2.39 + body.append(
2.40 + " " + modelClass + "[] arr = new " + modelClass + "[ev.dataSize()];\n"
2.41 + );
2.42 + } else {
2.43 + body.append(
2.44 + " " + modelClass + "[] arr = { null };\n"
2.45 + );
2.46 + }
2.47 body.append(
2.48 - " " + modelClass + "[] arr;\n");
2.49 - body.append(
2.50 - " if (value instanceof Object[]) {\n" +
2.51 - " Object[] data = ((Object[])value);\n" +
2.52 - " arr = new " + modelClass + "[data.length];\n" +
2.53 - " for (int i = 0; i < data.length; i++) {\n" +
2.54 - " arr[i] = org.apidesign.html.json.impl.JSON.read(context, " + modelClass + ".class, data[i]);\n" +
2.55 - " }\n" +
2.56 - " } else {\n" +
2.57 - " arr = new " + modelClass + "[1];\n" +
2.58 - " arr[0] = org.apidesign.html.json.impl.JSON.read(context, " + modelClass + ".class, value);\n" +
2.59 - " }\n"
2.60 + " ev.dataRead(context, " + modelClass + ".class, arr);\n"
2.61 );
2.62 {
2.63 body.append(" ").append(clazz.getSimpleName()).append(".").append(n).append("(");
2.64 @@ -1032,7 +1031,7 @@
2.65 " }\n"
2.66 );
2.67 body.append(" ProcessResult pr = new ProcessResult();\n");
2.68 - body.append(" org.apidesign.html.json.impl.JSON.loadJSON(context, pr, result,\n ");
2.69 + body.append(" org.apidesign.html.json.impl.JSON.loadJSON(context, pr,\n ");
2.70 body.append(urlBefore).append(", ");
2.71 if (jsonpVarName != null) {
2.72 body.append(urlAfter);
2.73 @@ -1046,6 +1045,8 @@
2.74 } else {
2.75 body.append(", null");
2.76 }
2.77 + } else {
2.78 + body.append(", null, null");
2.79 }
2.80 body.append(");\n");
2.81 // body.append(" ").append(clazz.getSimpleName()).append(".").append(n).append("(");
3.1 --- a/json/src/main/java/org/apidesign/html/json/impl/PropertyBindingAccessor.java Sat Aug 24 18:00:08 2013 +0200
3.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/PropertyBindingAccessor.java Sun Aug 25 09:36:33 2013 +0200
3.3 @@ -43,7 +43,7 @@
3.4 protected abstract <M> PropertyBinding newBinding(PBData<M> d);
3.5 protected abstract <M> FunctionBinding newFunction(FBData<M> d);
3.6 protected abstract JSONCall newCall(
3.7 - Runnable whenDone, Object[] result, String urlBefore, String urlAfter, String method, Object data);
3.8 + RcvrJSON callback, String urlBefore, String urlAfter, String method, Object data);
3.9
3.10
3.11 static <M> PropertyBinding create(PBData<M> d) {
3.12 @@ -53,8 +53,8 @@
3.13 return DEFAULT.newFunction(d);
3.14 }
3.15 static JSONCall createCall(
3.16 - Runnable whenDone, Object[] result, String urlBefore, String urlAfter, String method, Object data) {
3.17 - return DEFAULT.newCall(whenDone, result, urlBefore, urlAfter, method, data);
3.18 + RcvrJSON callback, String urlBefore, String urlAfter, String method, Object data) {
3.19 + return DEFAULT.newCall(callback, urlBefore, urlAfter, method, data);
3.20 }
3.21
3.22 public static final class PBData<M> {
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/RcvrJSON.java Sun Aug 25 09:36:33 2013 +0200
4.3 @@ -0,0 +1,127 @@
4.4 +/**
4.5 + * HTML via Java(tm) Language Bindings
4.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.7 + *
4.8 + * This program is free software: you can redistribute it and/or modify
4.9 + * it under the terms of the GNU General Public License as published by
4.10 + * the Free Software Foundation, version 2 of the License.
4.11 + *
4.12 + * This program is distributed in the hope that it will be useful,
4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 + * GNU General Public License for more details. apidesign.org
4.16 + * designates this particular file as subject to the
4.17 + * "Classpath" exception as provided by apidesign.org
4.18 + * in the License file that accompanied this code.
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License
4.21 + * along with this program. Look for COPYING file in the top folder.
4.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
4.23 + */
4.24 +package org.apidesign.html.json.impl;
4.25 +
4.26 +import net.java.html.BrwsrCtx;
4.27 +
4.28 +/** Super type for those who wish to receive JSON messages.
4.29 + *
4.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
4.31 + */
4.32 +public abstract class RcvrJSON {
4.33 + protected void onOpen(MsgEvnt msg) {}
4.34 + protected abstract void onMessage(MsgEvnt msg);
4.35 + protected void onClose(MsgEvnt msg) {}
4.36 + protected abstract void onError(MsgEvnt msg);
4.37 +
4.38 + public abstract static class MsgEvnt {
4.39 + MsgEvnt() {
4.40 + }
4.41 +
4.42 + public Throwable getError() {
4.43 + return null;
4.44 + }
4.45 +
4.46 + public final Exception getException() {
4.47 + Throwable t = getError();
4.48 + if (t instanceof Exception) {
4.49 + return (Exception)t;
4.50 + }
4.51 + if (t == null) {
4.52 + return null;
4.53 + }
4.54 + return new Exception(t);
4.55 + }
4.56 +
4.57 + public int dataSize() {
4.58 + return -1;
4.59 + }
4.60 +
4.61 + public <Data> void dataRead(BrwsrCtx ctx, Class<? extends Data> type, Data[] fillTheArray) {
4.62 + }
4.63 +
4.64 + public abstract void dispatch(RcvrJSON r);
4.65 +
4.66 + public static MsgEvnt createError(final Throwable t) {
4.67 + return new MsgEvnt() {
4.68 + @Override
4.69 + public Throwable getError() {
4.70 + return t;
4.71 + }
4.72 +
4.73 + @Override
4.74 + public void dispatch(RcvrJSON r) {
4.75 + r.onError(this);
4.76 + }
4.77 + };
4.78 + }
4.79 +
4.80 + public static MsgEvnt createMessage(final Object value) {
4.81 + return new MsgEvnt() {
4.82 + @Override
4.83 + public int dataSize() {
4.84 + if (value instanceof Object[]) {
4.85 + return ((Object[])value).length;
4.86 + } else {
4.87 + return 1;
4.88 + }
4.89 + }
4.90 +
4.91 + @Override
4.92 + public <Data> void dataRead(BrwsrCtx context, Class<? extends Data> type, Data[] arr) {
4.93 + if (value instanceof Object[]) {
4.94 + Object[] data = ((Object[]) value);
4.95 + for (int i = 0; i < data.length && i < arr.length; i++) {
4.96 + arr[i] = org.apidesign.html.json.impl.JSON.read(context, type, data[i]);
4.97 + }
4.98 + } else {
4.99 + if (arr.length > 0) {
4.100 + arr[0] = org.apidesign.html.json.impl.JSON.read(context, type, value);
4.101 + }
4.102 + }
4.103 + }
4.104 +
4.105 + @Override
4.106 + public void dispatch(RcvrJSON r) {
4.107 + r.onMessage(this);
4.108 + }
4.109 + };
4.110 + }
4.111 +
4.112 + public static MsgEvnt createOpen() {
4.113 + return new MsgEvnt() {
4.114 + @Override
4.115 + public void dispatch(RcvrJSON r) {
4.116 + r.onOpen(this);
4.117 + }
4.118 + };
4.119 + }
4.120 +
4.121 + public static MsgEvnt createClose() {
4.122 + return new MsgEvnt() {
4.123 + @Override
4.124 + public void dispatch(RcvrJSON r) {
4.125 + r.onClose(this);
4.126 + }
4.127 + };
4.128 + }
4.129 + } // end MsgEvnt
4.130 +}
5.1 --- a/json/src/main/java/org/apidesign/html/json/spi/JSONCall.java Sat Aug 24 18:00:08 2013 +0200
5.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/JSONCall.java Sun Aug 25 09:36:33 2013 +0200
5.3 @@ -24,6 +24,7 @@
5.4 import java.io.IOException;
5.5 import java.io.OutputStream;
5.6 import org.apidesign.html.json.impl.JSON;
5.7 +import org.apidesign.html.json.impl.RcvrJSON;
5.8
5.9 /** Description of a JSON call request that is supposed to be processed
5.10 * by {@link Transfer#loadJSON(org.apidesign.html.json.spi.JSONCall)} implementors.
5.11 @@ -31,16 +32,14 @@
5.12 * @author Jaroslav Tulach <jtulach@netbeans.org>
5.13 */
5.14 public final class JSONCall {
5.15 - private final Runnable whenDone;
5.16 - private final Object[] result;
5.17 + private final RcvrJSON whenDone;
5.18 private final String urlBefore;
5.19 private final String urlAfter;
5.20 private final String method;
5.21 private final Object data;
5.22
5.23 - JSONCall(Runnable whenDone, Object[] result, String urlBefore, String urlAfter, String method, Object data) {
5.24 + JSONCall(RcvrJSON whenDone, String urlBefore, String urlAfter, String method, Object data) {
5.25 this.whenDone = whenDone;
5.26 - this.result = result;
5.27 this.urlBefore = urlBefore;
5.28 this.urlAfter = urlAfter;
5.29 this.method = method;
5.30 @@ -84,12 +83,14 @@
5.31 }
5.32
5.33 public void notifySuccess(Object result) {
5.34 - this.result[0] = result;
5.35 - this.whenDone.run();
5.36 + RcvrJSON.MsgEvnt.createMessage(result).dispatch(whenDone);
5.37 }
5.38
5.39 public void notifyError(Throwable error) {
5.40 - this.result[0] = error == null ? JSON.NULL : error;
5.41 - this.whenDone.run();
5.42 + RcvrJSON.MsgEvnt.createError(error).dispatch(whenDone);
5.43 + }
5.44 +
5.45 + public String getMessage() {
5.46 + return this.data.toString();
5.47 }
5.48 }
6.1 --- a/json/src/main/java/org/apidesign/html/json/spi/PropertyBinding.java Sat Aug 24 18:00:08 2013 +0200
6.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/PropertyBinding.java Sun Aug 25 09:36:33 2013 +0200
6.3 @@ -22,6 +22,7 @@
6.4
6.5 import org.apidesign.html.json.impl.PropertyBindingAccessor;
6.6 import org.apidesign.html.json.impl.PropertyBindingAccessor.PBData;
6.7 +import org.apidesign.html.json.impl.RcvrJSON;
6.8 import org.apidesign.html.json.impl.WrapperObject;
6.9
6.10 /** Describes a property when one is asked to
6.11 @@ -49,8 +50,8 @@
6.12 }
6.13
6.14 @Override
6.15 - protected JSONCall newCall(Runnable whenDone, Object[] result, String urlBefore, String urlAfter, String method, Object data) {
6.16 - return new JSONCall(whenDone, result, urlBefore, urlAfter, method, data);
6.17 + protected JSONCall newCall(RcvrJSON callback, String urlBefore, String urlAfter, String method, Object data) {
6.18 + return new JSONCall(callback, urlBefore, urlAfter, method, data);
6.19 }
6.20 };
6.21 }