#258578: Pass arguments to failure handling methods generated for @OnReceive annotation
authorJaroslav Tulach <jtulach@netbeans.org>
Tue, 29 Mar 2016 18:42:00 +0200
changeset 1079bffa7d006d87
parent 1078 580295a6aeeb
child 1081 190af5cc34cc
#258578: Pass arguments to failure handling methods generated for @OnReceive annotation
json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
json/src/test/java/org/netbeans/html/json/impl/EmployeeImpl.java
json/src/test/java/org/netbeans/html/json/impl/OnReceiveTest.java
     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  }