Deep checking of @ComputedProperties is now default if one depends on another model class DeepWatch
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 02 Aug 2014 07:54:15 +0200
branchDeepWatch
changeset 788f8ac4d547ad3
parent 787 a0e8f185c0d4
child 789 64ddd3d0e8d9
Deep checking of @ComputedProperties is now default if one depends on another model class
json/src/main/java/net/java/html/json/ComputedProperty.java
json/src/main/java/net/java/html/json/Model.java
json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java
json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java
src/main/javadoc/overview.html
     1.1 --- a/json/src/main/java/net/java/html/json/ComputedProperty.java	Sat Aug 02 07:28:37 2014 +0200
     1.2 +++ b/json/src/main/java/net/java/html/json/ComputedProperty.java	Sat Aug 02 07:54:15 2014 +0200
     1.3 @@ -54,7 +54,11 @@
     1.4   * The name of the derived property is the name of the method. The arguments
     1.5   * of the method must match names and types of some of the properties 
     1.6   * from {@link Model#properties()} list. As soon as one of these properties
     1.7 - * changes, the method is called to recompute its new value.
     1.8 + * changes, the method is called to recompute its new value. 
     1.9 + * This applies to inner changes in derived properties as well - e.g.
    1.10 + * if the dependant property is another type generated by {@link Model @Model} annotation -
    1.11 + * changes in its own properties trigger recomputation of this derived 
    1.12 + * property as well (since version 0.9).
    1.13   * <p>
    1.14   * Method's return type defines the type of the derived property. It may be
    1.15   * any primitive type, {@link String}, {@link Enum enum type} or a 
     2.1 --- a/json/src/main/java/net/java/html/json/Model.java	Sat Aug 02 07:28:37 2014 +0200
     2.2 +++ b/json/src/main/java/net/java/html/json/Model.java	Sat Aug 02 07:54:15 2014 +0200
     2.3 @@ -47,6 +47,7 @@
     2.4  import java.lang.annotation.RetentionPolicy;
     2.5  import java.lang.annotation.Target;
     2.6  import java.net.URL;
     2.7 +import java.util.List;
     2.8  
     2.9  /** Defines a model class that represents a single 
    2.10   * <a href="http://en.wikipedia.org/wiki/JSON">JSON</a>-like object
    2.11 @@ -82,6 +83,14 @@
    2.12   *     return firstName + " " + lastName;
    2.13   *   }
    2.14   * 
    2.15 + *   {@link ComputedProperty @ComputedProperty}
    2.16 + *   static String mainAddress({@link List List&lt;Address&gt;} addresses) {
    2.17 + *     for (Address a : addresses) {
    2.18 + *       return a.getStreet() + " " + a.getTown();
    2.19 + *     }
    2.20 + *     return "No address";
    2.21 + *   }
    2.22 + * 
    2.23   *   {@link Model @Model}(className="Address", properties={
    2.24   *     {@link Property @Property}(name = "street", type=String.class),
    2.25   *     {@link Property @Property}(name = "town", type=String.class)
     3.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java	Sat Aug 02 07:28:37 2014 +0200
     3.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java	Sat Aug 02 07:54:15 2014 +0200
     3.3 @@ -658,14 +658,24 @@
     3.4              }
     3.5              w.write(" " + gs[0] + "() {\n");
     3.6              int arg = 0;
     3.7 +            boolean deep = false;
     3.8              for (VariableElement pe : ee.getParameters()) {
     3.9                  final String dn = pe.getSimpleName().toString();
    3.10                  
    3.11                  if (!verifyPropName(pe, dn, fixedProps)) {
    3.12                      ok = false;
    3.13                  }
    3.14 -                
    3.15 -                final String dt = fqn(pe.asType(), ee);
    3.16 +                final TypeMirror pt = pe.asType();
    3.17 +                if (isModel(pt)) {
    3.18 +                    deep = true;
    3.19 +                }
    3.20 +                final String dt = fqn(pt, ee);
    3.21 +                if (dt.startsWith("java.util.List") && pt instanceof DeclaredType) {
    3.22 +                    final List<? extends TypeMirror> ptArgs = ((DeclaredType)pt).getTypeArguments();
    3.23 +                    if (ptArgs.size() == 1 && isModel(ptArgs.get(0))) {
    3.24 +                        deep = true;
    3.25 +                    }
    3.26 +                }
    3.27                  String[] call = toGetSet(dn, dt, false);
    3.28                  w.write("    " + dt + " arg" + (++arg) + " = ");
    3.29                  w.write(call[0] + "();\n");
    3.30 @@ -678,7 +688,10 @@
    3.31                  depends.add(new String[] { sn, gs[0] });
    3.32              }
    3.33              w.write("    try {\n");
    3.34 -            if (tp != null && tp.deep()) {
    3.35 +            if (tp != null) {
    3.36 +                deep = tp.deep();
    3.37 +            }
    3.38 +            if (deep) {
    3.39                  w.write("      proto.acquireLock(\"" + sn + "\");\n");
    3.40              } else {
    3.41                  w.write("      proto.acquireLock();\n");
     4.1 --- a/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java	Sat Aug 02 07:28:37 2014 +0200
     4.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java	Sat Aug 02 07:54:15 2014 +0200
     4.3 @@ -86,7 +86,7 @@
     4.4          static String oneName(MyY one) {
     4.5              return one.getValue();
     4.6          }
     4.7 -        @ComputedProperty @Transitive(deep = true) 
     4.8 +        @ComputedProperty
     4.9          static String sndName(MyY one) {
    4.10              return one.getValue().toUpperCase();
    4.11          }
    4.12 @@ -99,7 +99,7 @@
    4.13              return "X" + one.getCount();
    4.14          }
    4.15          
    4.16 -        @ComputedProperty @Transitive(deep = true)
    4.17 +        @ComputedProperty
    4.18          static String allNames(List<MyY> all) {
    4.19              StringBuilder sb = new StringBuilder();
    4.20              for (MyY y : all) {
     5.1 --- a/json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java	Sat Aug 02 07:28:37 2014 +0200
     5.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java	Sat Aug 02 07:54:15 2014 +0200
     5.3 @@ -74,7 +74,7 @@
     5.4      static class ItemCtrl {
     5.5      }
     5.6  
     5.7 -    @ComputedProperty @Transitive(deep = true)
     5.8 +    @ComputedProperty
     5.9      static int remaining(
    5.10          List<Todo> todos, String todoText
    5.11      ) {
     6.1 --- a/src/main/javadoc/overview.html	Sat Aug 02 07:28:37 2014 +0200
     6.2 +++ b/src/main/javadoc/overview.html	Sat Aug 02 07:54:15 2014 +0200
     6.3 @@ -79,6 +79,9 @@
     6.4          
     6.5          <p>
     6.6              System can run in {@link net.java.html.boot.BrowserBuilder#classloader(java.lang.ClassLoader) Felix OSGi container} (originally only Equinox).
     6.7 +            {@link net.java.html.json.ComputedProperty Derived properties}
     6.8 +            now deeply check changes in other {@link net.java.html.json.Model model
     6.9 +            classes} they depend on and recompute their values accordingly.
    6.10          </p>
    6.11          
    6.12          <h3>What's New in 0.8.x Versions?</h3>