#258578: Pass arguments to failure handling methods generated for @OnReceive annotation
1.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Mar 04 10:17:46 2016 +0100
1.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Tue Mar 29 18:42:00 2016 +0200
1.3 @@ -1381,9 +1381,20 @@
1.4 " ex.printStackTrace();\n"
1.5 );
1.6 } else {
1.7 - error = !findOnError(e, ((TypeElement)clazz), onR.onError(), className);
1.8 + int errorParamsLength = findOnError(e, ((TypeElement)clazz), onR.onError(), className);
1.9 + error = errorParamsLength < 0;
1.10 body.append(" ").append(clazz.getSimpleName()).append(".").append(onR.onError()).append("(");
1.11 - body.append("model, ex);\n");
1.12 + body.append("model, ex");
1.13 + for (int i = 2; i < errorParamsLength; i++) {
1.14 + String arg = args.get(i);
1.15 + body.append(", ");
1.16 + if (arg.startsWith("arr") || arg.startsWith("java.util.Array")) {
1.17 + body.append("null");
1.18 + } else {
1.19 + body.append(arg);
1.20 + }
1.21 + }
1.22 + body.append(");\n");
1.23 }
1.24 body.append(
1.25 " return;\n" +
1.26 @@ -1470,11 +1481,22 @@
1.27 " value.printStackTrace();\n"
1.28 );
1.29 } else {
1.30 - if (!findOnError(e, ((TypeElement)clazz), onR.onError(), className)) {
1.31 + int errorParamsLength = findOnError(e, ((TypeElement)clazz), onR.onError(), className);
1.32 + if (errorParamsLength < 0) {
1.33 return true;
1.34 }
1.35 body.append(" ").append(inPckName(clazz, true)).append(".").append(onR.onError()).append("(");
1.36 - body.append("model, value);\n");
1.37 + body.append("model, value");
1.38 + for (int i = 2; i < errorParamsLength; i++) {
1.39 + String arg = args.get(i);
1.40 + body.append(", ");
1.41 + if (arg.startsWith("arr") || arg.startsWith("java.util.Array")) {
1.42 + body.append("null");
1.43 + } else {
1.44 + body.append(arg);
1.45 + }
1.46 + }
1.47 + body.append(");\n");
1.48 }
1.49 body.append(
1.50 " return;\n" +
1.51 @@ -2113,7 +2135,7 @@
1.52 return Completions.of('"' + method + '"', rb.getString("MSG_Completion_" + method));
1.53 }
1.54
1.55 - private boolean findOnError(ExecutableElement errElem, TypeElement te, String name, String className) {
1.56 + private int findOnError(ExecutableElement errElem, TypeElement te, String name, String className) {
1.57 String err = null;
1.58 METHODS:
1.59 for (Element e : te.getEnclosedElements()) {
1.60 @@ -2132,7 +2154,7 @@
1.61 TypeMirror excType = processingEnv.getElementUtils().getTypeElement(Exception.class.getName()).asType();
1.62 final List<? extends VariableElement> params = ee.getParameters();
1.63 boolean error = false;
1.64 - if (params.size() != 2) {
1.65 + if (params.size() < 2 || params.size() > errElem.getParameters().size()) {
1.66 error = true;
1.67 } else {
1.68 String firstType = params.get(0).asType().toString();
1.69 @@ -2146,19 +2168,28 @@
1.70 if (!processingEnv.getTypeUtils().isAssignable(excType, params.get(1).asType())) {
1.71 error = true;
1.72 }
1.73 + for (int i = 2; i < params.size(); i++) {
1.74 + final VariableElement expectedParam = errElem.getParameters().get(i);
1.75 + if (!processingEnv.getTypeUtils().isSameType(params.get(i).asType(), errElem.getParameters().get(i).asType())) {
1.76 + error = true;
1.77 + err = "Parameter #" + (i + 1) + " should be of type " + expectedParam;
1.78 + }
1.79 + }
1.80 }
1.81 if (error) {
1.82 errElem = (ExecutableElement) e;
1.83 - err = "Error method first argument needs to be " + className + " and second Exception";
1.84 + if (err == null) {
1.85 + err = "Error method first argument needs to be " + className + " and second Exception";
1.86 + }
1.87 continue;
1.88 }
1.89 - return true;
1.90 + return params.size();
1.91 }
1.92 if (err == null) {
1.93 err = "Cannot find " + name + "(" + className + ", Exception) method in this class";
1.94 }
1.95 error(err, errElem);
1.96 - return false;
1.97 + return -1;
1.98 }
1.99
1.100 private ExecutableElement findWrite(ExecutableElement computedPropElem, TypeElement te, String name, String className) {
2.1 --- a/json/src/test/java/org/netbeans/html/json/impl/EmployeeImpl.java Fri Mar 04 10:17:46 2016 +0100
2.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/EmployeeImpl.java Tue Mar 29 18:42:00 2016 +0200
2.3 @@ -75,6 +75,24 @@
2.4 e.setCall(new Call(i, d, s, o, data.toArray(new Person[0])));
2.5 }
2.6
2.7 + @OnReceive(url = "some/other/url", onError = "errorPersonalitiesWithEx")
2.8 + static void changePersonalitiesWithEx(Employee e, List<Person> data, int i, double d, String s, Person o) {
2.9 + e.setCall(new Call(i, d, s, o, data.toArray(new Person[0])));
2.10 + }
2.11 +
2.12 + static void errorPersonalitiesWithEx(Employee e, Exception ex) {
2.13 + e.setCall(new Call(-1, -1, null, null));
2.14 + }
2.15 +
2.16 + @OnReceive(url = "some/other/url", onError = "errorPersonalitiesWithParam")
2.17 + static void changePersonalitiesWithParam(Employee e, List<Person> data, int i, double d, String s, Person o) {
2.18 + e.setCall(new Call(i, d, s, o, data.toArray(new Person[0])));
2.19 + }
2.20 +
2.21 + static void errorPersonalitiesWithParam(Employee e, Exception ex, int i, double d, String s, Person o) {
2.22 + e.setCall(new Call(i, d, s, o));
2.23 + }
2.24 +
2.25 @OnReceive(url = "{url}", method = "PUT", data = Person.class)
2.26 static void updatePersonalities(Employee e, List<Person> p, int i, double d, String s, Person o) {
2.27 e.setPerson(p.get(0));
3.1 --- a/json/src/test/java/org/netbeans/html/json/impl/OnReceiveTest.java Fri Mar 04 10:17:46 2016 +0100
3.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/OnReceiveTest.java Tue Mar 29 18:42:00 2016 +0200
3.3 @@ -83,9 +83,73 @@
3.4 assertEquals(c.getData().get(0).getLastName(), "Tulach");
3.5 }
3.6
3.7 + @Test public void performErrorJSONCallNoHandling() {
3.8 + MockTrans mt = new MockTrans();
3.9 + mt.err = new Exception("Error");
3.10 + BrwsrCtx ctx = Contexts.newBuilder().register(Transfer.class, mt, 1).build();
3.11 +
3.12 + Employee e = Models.bind(new Employee(), ctx);
3.13 + e.setCall(null);
3.14 + Person p = new Person();
3.15 +
3.16 + mt.result = new HashMap<String, String>();
3.17 + mt.result.put("firstName", "Jarda");
3.18 + mt.result.put("lastName", "Tulach");
3.19 + e.changePersonalities(1, 2.0, "3", p);
3.20 + final Call c = e.getCall();
3.21 + assertNull(c, "Error has been swallowed");
3.22 + }
3.23 +
3.24 + @Test public void performErrorJSONCall() {
3.25 + MockTrans mt = new MockTrans();
3.26 + mt.err = new Exception("Error");
3.27 + BrwsrCtx ctx = Contexts.newBuilder().register(Transfer.class, mt, 1).build();
3.28 +
3.29 + Employee e = Models.bind(new Employee(), ctx);
3.30 + e.setCall(null);
3.31 + Person p = new Person();
3.32 +
3.33 + mt.result = new HashMap<String, String>();
3.34 + mt.result.put("firstName", "Jarda");
3.35 + mt.result.put("lastName", "Tulach");
3.36 + e.changePersonalitiesWithEx(1, 2.0, "3", p);
3.37 + final Call c = e.getCall();
3.38 + assertNotNull(c, "A call has been made");
3.39 + assertTrue(c.getData().isEmpty(), "No data provided");
3.40 +
3.41 + assertEquals(c.getI(), -1);
3.42 + assertEquals(c.getD(), -1.0);
3.43 + assertEquals(c.getS(), null);
3.44 + assertEquals(c.getP(), null);
3.45 + }
3.46 +
3.47 + @Test public void performErrorWithValuesJSONCall() {
3.48 + MockTrans mt = new MockTrans();
3.49 + mt.err = new Exception("Error");
3.50 + BrwsrCtx ctx = Contexts.newBuilder().register(Transfer.class, mt, 1).build();
3.51 +
3.52 + Employee e = Models.bind(new Employee(), ctx);
3.53 + e.setCall(null);
3.54 + Person p = new Person();
3.55 +
3.56 + mt.result = new HashMap<String, String>();
3.57 + mt.result.put("firstName", "Jarda");
3.58 + mt.result.put("lastName", "Tulach");
3.59 + e.changePersonalitiesWithParam(1, 2.0, "3", p);
3.60 + final Call c = e.getCall();
3.61 + assertNotNull(c, "A call has been made");
3.62 + assertTrue(c.getData().isEmpty(), "No data provided");
3.63 +
3.64 + assertEquals(c.getI(), 1);
3.65 + assertEquals(c.getD(), 2.0);
3.66 + assertEquals(c.getS(), "3");
3.67 + assertEquals(c.getP(), p);
3.68 + }
3.69 +
3.70
3.71 public static class MockTrans implements Transfer {
3.72 Map<String,String> result;
3.73 + Exception err;
3.74
3.75 @Override
3.76 public void extract(Object obj, String[] props, Object[] values) {
3.77 @@ -106,7 +170,11 @@
3.78 Object r = result;
3.79 assertNotNull(r, "We need a reply!");
3.80 result = null;
3.81 - call.notifySuccess(r);
3.82 + if (err != null) {
3.83 + call.notifyError(err);
3.84 + } else {
3.85 + call.notifySuccess(r);
3.86 + }
3.87 }
3.88 }
3.89 }