1.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Proto.java Fri Aug 01 15:24:57 2014 +0200
1.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Proto.java Fri Aug 01 16:02:10 2014 +0200
1.3 @@ -422,6 +422,9 @@
1.4 // internal state
1.5 //
1.6
1.7 + final String toStr() {
1.8 + return "Proto[" + obj + "]@" + Integer.toHexString(System.identityHashCode(this));
1.9 + }
1.10
1.11 final Bindings initBindings() {
1.12 if (ko == null) {
2.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Watcher.java Fri Aug 01 15:24:57 2014 +0200
2.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Watcher.java Fri Aug 01 16:02:10 2014 +0200
2.3 @@ -132,17 +132,21 @@
2.4 if (locked.prop == null) {
2.5 return mine;
2.6 }
2.7 + if (mine == null) {
2.8 + return locked;
2.9 + }
2.10 + if (locked.prop.equals(mine.prop)) {
2.11 + locked.next = mine.next;
2.12 + return locked;
2.13 + }
2.14 Watcher current = mine;
2.15 for (;;) {
2.16 - if (current == null) {
2.17 - return locked;
2.18 - }
2.19 Watcher next = current.next;
2.20 if (next == null) {
2.21 current.next = locked;
2.22 return mine;
2.23 }
2.24 - if (next.prop.equals(locked.prop)) {
2.25 + if (locked.prop.equals(next.prop)) {
2.26 locked.next = next.next;
2.27 current.next = locked;
2.28 return mine;
2.29 @@ -164,6 +168,11 @@
2.30 return new Ref(this, prop).chain(prev);
2.31 }
2.32
2.33 + @Override
2.34 + public String toString() {
2.35 + return "Watcher: " + proto + ", " + prop + "\n -> " + next;
2.36 + }
2.37 +
2.38 static final class Ref extends WeakReference<Watcher> {
2.39 private final String prop;
2.40 private Ref next;
3.1 --- a/json/src/test/java/net/java/html/json/DeepChangeTest.java Fri Aug 01 15:24:57 2014 +0200
3.2 +++ b/json/src/test/java/net/java/html/json/DeepChangeTest.java Fri Aug 01 16:02:10 2014 +0200
3.3 @@ -162,6 +162,33 @@
3.4 assertEquals(o.get(), "NazdarHello");
3.5 assertEquals(o.changes, 1, "One change so far");
3.6 }
3.7 +
3.8 + @Test public void addingIntoArray() throws Exception {
3.9 + MyX p = Models.bind(
3.10 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
3.11 + ), c).applyBindings();
3.12 +
3.13 + Map m = (Map)Models.toRaw(p);
3.14 + Object v = m.get("allNames");
3.15 + assertNotNull(v, "Value should be in the map");
3.16 + assertEquals(v.getClass(), One.class, "It is instance of One");
3.17 + One o = (One)v;
3.18 + assertEquals(o.changes, 0, "No changes so far");
3.19 + assertTrue(o.pb.isReadOnly(), "Derived property");
3.20 + assertEquals(o.get(), "HiHello");
3.21 +
3.22 + MyY y = new MyY("Cus", 1);
3.23 + p.getAll().add(y);
3.24 +
3.25 + assertEquals(o.changes, 1, "One change so far");
3.26 + assertEquals(o.get(), "HiHelloCus");
3.27 +
3.28 + y.setValue("Nazdar");
3.29 +
3.30 + assertEquals(o.changes, 2, "2nd change so far");
3.31 + assertEquals(o.get(), "HiHelloNazdar");
3.32 +
3.33 + }
3.34
3.35 @Test public void firstChangeInArrayNotifiedProperly() throws Exception {
3.36 MyX p = Models.bind(