# HG changeset patch # User Jaroslav Tulach # Date 1406958855 -7200 # Node ID f8ac4d547ad35e21e8bb23f110f5e8dd455de562 # Parent a0e8f185c0d45e0f77974005e35300562066e184 Deep checking of @ComputedProperties is now default if one depends on another model class diff -r a0e8f185c0d4 -r f8ac4d547ad3 json/src/main/java/net/java/html/json/ComputedProperty.java --- a/json/src/main/java/net/java/html/json/ComputedProperty.java Sat Aug 02 07:28:37 2014 +0200 +++ b/json/src/main/java/net/java/html/json/ComputedProperty.java Sat Aug 02 07:54:15 2014 +0200 @@ -54,7 +54,11 @@ * The name of the derived property is the name of the method. The arguments * of the method must match names and types of some of the properties * from {@link Model#properties()} list. As soon as one of these properties - * changes, the method is called to recompute its new value. + * changes, the method is called to recompute its new value. + * This applies to inner changes in derived properties as well - e.g. + * if the dependant property is another type generated by {@link Model @Model} annotation - + * changes in its own properties trigger recomputation of this derived + * property as well (since version 0.9). *

* Method's return type defines the type of the derived property. It may be * any primitive type, {@link String}, {@link Enum enum type} or a diff -r a0e8f185c0d4 -r f8ac4d547ad3 json/src/main/java/net/java/html/json/Model.java --- a/json/src/main/java/net/java/html/json/Model.java Sat Aug 02 07:28:37 2014 +0200 +++ b/json/src/main/java/net/java/html/json/Model.java Sat Aug 02 07:54:15 2014 +0200 @@ -47,6 +47,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.net.URL; +import java.util.List; /** Defines a model class that represents a single * JSON-like object @@ -82,6 +83,14 @@ * return firstName + " " + lastName; * } * + * {@link ComputedProperty @ComputedProperty} + * static String mainAddress({@link List List<Address>} addresses) { + * for (Address a : addresses) { + * return a.getStreet() + " " + a.getTown(); + * } + * return "No address"; + * } + * * {@link Model @Model}(className="Address", properties={ * {@link Property @Property}(name = "street", type=String.class), * {@link Property @Property}(name = "town", type=String.class) diff -r a0e8f185c0d4 -r f8ac4d547ad3 json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sat Aug 02 07:28:37 2014 +0200 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sat Aug 02 07:54:15 2014 +0200 @@ -658,14 +658,24 @@ } w.write(" " + gs[0] + "() {\n"); int arg = 0; + boolean deep = false; for (VariableElement pe : ee.getParameters()) { final String dn = pe.getSimpleName().toString(); if (!verifyPropName(pe, dn, fixedProps)) { ok = false; } - - final String dt = fqn(pe.asType(), ee); + final TypeMirror pt = pe.asType(); + if (isModel(pt)) { + deep = true; + } + final String dt = fqn(pt, ee); + if (dt.startsWith("java.util.List") && pt instanceof DeclaredType) { + final List ptArgs = ((DeclaredType)pt).getTypeArguments(); + if (ptArgs.size() == 1 && isModel(ptArgs.get(0))) { + deep = true; + } + } String[] call = toGetSet(dn, dt, false); w.write(" " + dt + " arg" + (++arg) + " = "); w.write(call[0] + "();\n"); @@ -678,7 +688,10 @@ depends.add(new String[] { sn, gs[0] }); } w.write(" try {\n"); - if (tp != null && tp.deep()) { + if (tp != null) { + deep = tp.deep(); + } + if (deep) { w.write(" proto.acquireLock(\"" + sn + "\");\n"); } else { w.write(" proto.acquireLock();\n"); diff -r a0e8f185c0d4 -r f8ac4d547ad3 json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java --- a/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Sat Aug 02 07:28:37 2014 +0200 +++ b/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Sat Aug 02 07:54:15 2014 +0200 @@ -86,7 +86,7 @@ static String oneName(MyY one) { return one.getValue(); } - @ComputedProperty @Transitive(deep = true) + @ComputedProperty static String sndName(MyY one) { return one.getValue().toUpperCase(); } @@ -99,7 +99,7 @@ return "X" + one.getCount(); } - @ComputedProperty @Transitive(deep = true) + @ComputedProperty static String allNames(List all) { StringBuilder sb = new StringBuilder(); for (MyY y : all) { diff -r a0e8f185c0d4 -r f8ac4d547ad3 json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java --- a/json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java Sat Aug 02 07:28:37 2014 +0200 +++ b/json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java Sat Aug 02 07:54:15 2014 +0200 @@ -74,7 +74,7 @@ static class ItemCtrl { } - @ComputedProperty @Transitive(deep = true) + @ComputedProperty static int remaining( List todos, String todoText ) { diff -r a0e8f185c0d4 -r f8ac4d547ad3 src/main/javadoc/overview.html --- a/src/main/javadoc/overview.html Sat Aug 02 07:28:37 2014 +0200 +++ b/src/main/javadoc/overview.html Sat Aug 02 07:54:15 2014 +0200 @@ -79,6 +79,9 @@

System can run in {@link net.java.html.boot.BrowserBuilder#classloader(java.lang.ClassLoader) Felix OSGi container} (originally only Equinox). + {@link net.java.html.json.ComputedProperty Derived properties} + now deeply check changes in other {@link net.java.html.json.Model model + classes} they depend on and recompute their values accordingly.

What's New in 0.8.x Versions?