1.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Watcher.java Fri Aug 01 13:02:35 2014 +0200
1.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Watcher.java Fri Aug 01 14:08:55 2014 +0200
1.3 @@ -70,6 +70,9 @@
1.4 }
1.5
1.6 static Watcher register(Watcher mine, Watcher locked) {
1.7 + if (locked == DUMMY) {
1.8 + return mine;
1.9 + }
1.10 Watcher current = mine;
1.11 for (;;) {
1.12 if (current == null) {
1.13 @@ -97,13 +100,13 @@
1.14
1.15 Ref observe(Ref prev, String prop) {
1.16 if (this == DUMMY) {
1.17 - throw new IllegalStateException();
1.18 + return prev;
1.19 }
1.20 return new Ref(this, prop).chain(prev);
1.21 }
1.22
1.23 final boolean forbiddenValue(Proto aThis) {
1.24 - return proto == aThis;
1.25 + return this == DUMMY || proto == aThis;
1.26 }
1.27
1.28 static final class Ref extends WeakReference<Watcher> {
2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Aug 01 13:02:35 2014 +0200
2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Aug 01 14:08:55 2014 +0200
2.3 @@ -606,7 +606,8 @@
2.4 if (e.getKind() != ElementKind.METHOD) {
2.5 continue;
2.6 }
2.7 - if (e.getAnnotation(ComputedProperty.class) == null) {
2.8 + final ComputedProperty cp = e.getAnnotation(ComputedProperty.class);
2.9 + if (cp == null) {
2.10 continue;
2.11 }
2.12 if (!e.getModifiers().contains(Modifier.STATIC)) {
2.13 @@ -676,7 +677,11 @@
2.14 depends.add(new String[] { sn, gs[0] });
2.15 }
2.16 w.write(" try {\n");
2.17 - w.write(" proto.acquireLock(\"" + sn + "\");\n");
2.18 + if (cp.deep()) {
2.19 + w.write(" proto.acquireLock(\"" + sn + "\");\n");
2.20 + } else {
2.21 + w.write(" proto.acquireLock();\n");
2.22 + }
2.23 w.write(" return " + fqn(ee.getEnclosingElement().asType(), ee) + '.' + e.getSimpleName() + "(");
2.24 String sep = "";
2.25 for (int i = 1; i <= arg; i++) {
3.1 --- a/json/src/test/java/net/java/html/json/DeepChangeTest.java Fri Aug 01 13:02:35 2014 +0200
3.2 +++ b/json/src/test/java/net/java/html/json/DeepChangeTest.java Fri Aug 01 14:08:55 2014 +0200
3.3 @@ -80,6 +80,10 @@
3.4 static String sndName(MyY one) {
3.5 return one.getValue().toUpperCase();
3.6 }
3.7 + @ComputedProperty(deep = false)
3.8 + static String noName(MyY one) {
3.9 + return one.getValue().toUpperCase();
3.10 + }
3.11 @ComputedProperty(deep = true)
3.12 static String thrdName(MyY one) {
3.13 return "X" + one.getCount();
3.14 @@ -163,4 +167,38 @@
3.15 assertEquals(o2.changes, 1, "One change so far");
3.16 assertEquals(o2.get(), "X10");
3.17 }
3.18 +
3.19 + @Test public void onlyDeepPropsAreNotified() throws Exception {
3.20 + MyX p = Models.bind(
3.21 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
3.22 + ), c).applyBindings();
3.23 +
3.24 + Map m = (Map)Models.toRaw(p);
3.25 + Object v = m.get("oneName");
3.26 + assertNotNull(v, "Value should be in the map");
3.27 + Object v2 = m.get("noName");
3.28 + assertNotNull(v2, "Value2 should be in the map");
3.29 + One o = (One)v;
3.30 + One o2 = (One)v2;
3.31 + assertEquals(o.changes, 0, "No changes so far");
3.32 + assertEquals(o2.changes, 0, "No changes so far");
3.33 + assertTrue(o.pb.isReadOnly(), "Derived property");
3.34 + assertEquals(o.get(), "Ahoj");
3.35 + try {
3.36 + assertEquals(o2.get(), "AHOJ");
3.37 + } catch (IllegalStateException ex) {
3.38 + // is it OK to forbid access to subproperties of
3.39 + // when the deep is not true?
3.40 + // that would be incompatible change...
3.41 + return;
3.42 + }
3.43 +
3.44 + p.getOne().setValue("Nazdar");
3.45 +
3.46 + assertEquals(o.get(), "Nazdar");
3.47 + assertEquals(o.changes, 1, "One change so far");
3.48 + assertEquals(o2.changes, 0, "This change is not noticed");
3.49 + assertEquals(o2.get(), "NAZDAR", "but property value changes when computed");
3.50 + }
3.51 +
3.52 }