Cloning should record its usage of all model's properties, so it can be used in @ComputedProperty methods.
1.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Thu Jul 02 08:27:47 2015 +0200
1.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Jul 03 18:27:00 2015 +0200
1.3 @@ -231,7 +231,7 @@
1.4 w.append(" this.proto = TYPE.createProto(this, context);\n");
1.5 for (Prprt p : props) {
1.6 if (p.array()) {
1.7 - final String tn = typeName(e, p);
1.8 + final String tn = typeName(p);
1.9 String[] gs = toGetSet(p.name(), tn, p.array());
1.10 w.write(" this.prop_" + p.name() + " = proto.createList(\""
1.11 + p.name() + "\"");
1.12 @@ -280,7 +280,7 @@
1.13 }
1.14 continue;
1.15 }
1.16 - String tn = typeName(e, p);
1.17 + String tn = typeName(p);
1.18 w.write(sep);
1.19 w.write(tn);
1.20 String[] third = toGetSet(p.name(), tn, false);
1.21 @@ -562,7 +562,7 @@
1.22 boolean ok = true;
1.23 for (Prprt p : properties) {
1.24 final String tn;
1.25 - tn = typeName(where, p);
1.26 + tn = typeName(p);
1.27 String[] gs = toGetSet(p.name(), tn, p.array());
1.28 String castTo;
1.29
1.30 @@ -778,7 +778,7 @@
1.31 };
1.32 }
1.33
1.34 - private String typeName(Element where, Prprt p) {
1.35 + private String typeName(Prprt p) {
1.36 String ret;
1.37 boolean[] isModel = { false };
1.38 boolean[] isEnum = { false };
1.39 @@ -1580,18 +1580,20 @@
1.40 w.write(" private " + className + " clone(net.java.html.BrwsrCtx ctx) {\n");
1.41 w.write(" " + className + " ret = new " + className + "(ctx);\n");
1.42 for (Prprt p : props) {
1.43 + String tn = typeName(p);
1.44 + String[] gs = toGetSet(p.name(), tn, p.array());
1.45 if (!p.array()) {
1.46 boolean isModel[] = { false };
1.47 boolean isEnum[] = { false };
1.48 boolean isPrimitive[] = { false };
1.49 checkType(p, isModel, isEnum, isPrimitive);
1.50 if (!isModel[0]) {
1.51 - w.write(" ret.prop_" + p.name() + " = prop_" + p.name() + ";\n");
1.52 + w.write(" ret.prop_" + p.name() + " = " + gs[0] + "();\n");
1.53 continue;
1.54 }
1.55 - w.write(" ret.prop_" + p.name() + " = prop_" + p.name() + " == null ? null : prop_" + p.name() + ".clone();\n");
1.56 + w.write(" ret.prop_" + p.name() + " = " + gs[0] + "() == null ? null : prop_" + p.name() + ".clone();\n");
1.57 } else {
1.58 - w.write(" proto.cloneList(ret.prop_" + p.name() + ", ctx, prop_" + p.name() + ");\n");
1.59 + w.write(" proto.cloneList(ret." + gs[0] + "(), ctx, prop_" + p.name() + ");\n");
1.60 }
1.61 }
1.62
2.1 --- a/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Thu Jul 02 08:27:47 2015 +0200
2.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Fri Jul 03 18:27:00 2015 +0200
2.3 @@ -82,6 +82,10 @@
2.4 @Property(name = "all", type = MyY.class, array = true)
2.5 })
2.6 static class X {
2.7 + @ComputedProperty @Transitive(deep = true)
2.8 + static MyY oneCopy(MyY one) {
2.9 + return Models.bind(one, BrwsrCtx.findDefault(X.class));
2.10 + }
2.11 @ComputedProperty @Transitive(deep = true)
2.12 static String oneName(MyY one) {
2.13 return one.getValue();
2.14 @@ -389,6 +393,45 @@
2.15 assertEquals(o2.get(), "NAZDAR", "but property value changes when computed");
2.16 }
2.17
2.18 + @Test
2.19 + public void mixingContextsIsOK() throws Exception {
2.20 + BrwsrCtx ctx = Contexts.newBuilder().build();
2.21 + final MyY one = Models.bind(new MyY("Ahoj", 0), ctx);
2.22 + MyX p = Models.bind(
2.23 + new MyX(one, new MyY("Hi", 333), new MyY("Hello", 999)), c
2.24 + ).applyBindings();
2.25 +
2.26 + Map m = (Map) Models.toRaw(p);
2.27 + Object v = m.get("oneName");
2.28 + assertNotNull(v, "Value should be in the map");
2.29 + One o = (One) v;
2.30 + assertEquals(o.get(), "Ahoj");
2.31 +
2.32 + p.getOne().setValue("Nazdar");
2.33 +
2.34 + assertEquals(o.get(), "Nazdar");
2.35 + assertEquals(o.changes, 1, "One change so far");
2.36 + }
2.37 +
2.38 + @Test
2.39 + public void mixingWithCloneIsOK() throws Exception {
2.40 + BrwsrCtx ctx = Contexts.newBuilder().build();
2.41 + final MyY one = Models.bind(new MyY("Ahoj", 0), ctx);
2.42 + MyX p = Models.bind(new MyX(one, new MyY("Hi", 333), new MyY("Hello", 999)
2.43 + ), c).applyBindings();
2.44 +
2.45 + Map m = (Map) Models.toRaw(p);
2.46 + Object v = m.get("oneCopy");
2.47 + assertNotNull(v, "Value should be in the map");
2.48 + One o = (One) v;
2.49 + assertEquals(((MyY)o.get()).getValue(), "Ahoj");
2.50 +
2.51 + p.getOne().setValue("Nazdar");
2.52 +
2.53 + assertEquals(((MyY)o.get()).getValue(), "Nazdar");
2.54 + assertEquals(o.changes, 1, "One change so far");
2.55 + }
2.56 +
2.57 static final class One {
2.58
2.59 int changes;