A bit striker mode for non-deep properties DeepWatch
authorJaroslav Tulach <jtulach@netbeans.org>
Fri, 01 Aug 2014 14:08:55 +0200
branchDeepWatch
changeset 7767e25ba02d9ce
parent 775 2fb16596688f
child 777 c865a31c848d
A bit striker mode for non-deep properties
json/src/main/java/org/apidesign/html/json/spi/Watcher.java
json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
json/src/test/java/net/java/html/json/DeepChangeTest.java
     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  }