Moving the ability to control whether the value change is transitive or not out from the public API. Will make it default.
1.1 --- a/json/src/main/java/net/java/html/json/ComputedProperty.java Sat Aug 02 07:13:47 2014 +0200
1.2 +++ b/json/src/main/java/net/java/html/json/ComputedProperty.java Sat Aug 02 07:28:37 2014 +0200
1.3 @@ -71,5 +71,4 @@
1.4 @Retention(RetentionPolicy.SOURCE)
1.5 @Target(ElementType.METHOD)
1.6 public @interface ComputedProperty {
1.7 - boolean deep() default false;
1.8 }
2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sat Aug 02 07:13:47 2014 +0200
2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sat Aug 02 07:28:37 2014 +0200
2.3 @@ -607,6 +607,7 @@
2.4 continue;
2.5 }
2.6 final ComputedProperty cp = e.getAnnotation(ComputedProperty.class);
2.7 + final Transitive tp = e.getAnnotation(Transitive.class);
2.8 if (cp == null) {
2.9 continue;
2.10 }
2.11 @@ -677,7 +678,7 @@
2.12 depends.add(new String[] { sn, gs[0] });
2.13 }
2.14 w.write(" try {\n");
2.15 - if (cp.deep()) {
2.16 + if (tp != null && tp.deep()) {
2.17 w.write(" proto.acquireLock(\"" + sn + "\");\n");
2.18 } else {
2.19 w.write(" proto.acquireLock();\n");
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/Transitive.java Sat Aug 02 07:28:37 2014 +0200
3.3 @@ -0,0 +1,60 @@
3.4 +/**
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 + *
3.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
3.8 + *
3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
3.10 + * Other names may be trademarks of their respective owners.
3.11 + *
3.12 + * The contents of this file are subject to the terms of either the GNU
3.13 + * General Public License Version 2 only ("GPL") or the Common
3.14 + * Development and Distribution License("CDDL") (collectively, the
3.15 + * "License"). You may not use this file except in compliance with the
3.16 + * License. You can obtain a copy of the License at
3.17 + * http://www.netbeans.org/cddl-gplv2.html
3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.19 + * specific language governing permissions and limitations under the
3.20 + * License. When distributing the software, include this License Header
3.21 + * Notice in each file and include the License file at
3.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
3.23 + * particular file as subject to the "Classpath" exception as provided
3.24 + * by Oracle in the GPL Version 2 section of the License file that
3.25 + * accompanied this code. If applicable, add the following below the
3.26 + * License Header, with the fields enclosed by brackets [] replaced by
3.27 + * your own identifying information:
3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
3.29 + *
3.30 + * Contributor(s):
3.31 + *
3.32 + * The Original Software is NetBeans. The Initial Developer of the Original
3.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
3.34 + *
3.35 + * If you wish your version of this file to be governed by only the CDDL
3.36 + * or only the GPL Version 2, indicate your decision by adding
3.37 + * "[Contributor] elects to include this software in this distribution
3.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
3.39 + * single choice of license, a recipient has the option to distribute
3.40 + * your version of this file under either the CDDL, the GPL Version 2 or
3.41 + * to extend the choice of license to its licensees as provided above.
3.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
3.43 + * Version 2 license, then the option applies only if the new code is
3.44 + * made subject to such option by the copyright holder.
3.45 + */
3.46 +package org.netbeans.html.json.impl;
3.47 +
3.48 +import java.lang.annotation.ElementType;
3.49 +import java.lang.annotation.Retention;
3.50 +import java.lang.annotation.RetentionPolicy;
3.51 +import java.lang.annotation.Target;
3.52 +
3.53 +/** A way to control {@link ComputedProperty} behavior - whether it tracks
3.54 + * deeply or not. Not public yet, maybe it won't be needed in the API at all.
3.55 + * Used in tests only.
3.56 + *
3.57 + * @author Jaroslav Tulach
3.58 + */
3.59 +@Retention(RetentionPolicy.SOURCE)
3.60 +@Target(ElementType.METHOD)
3.61 +@interface Transitive {
3.62 + boolean deep() default false;
3.63 +}
4.1 --- a/json/src/test/java/net/java/html/json/DeepChangeTest.java Sat Aug 02 07:13:47 2014 +0200
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,382 +0,0 @@
4.4 -/**
4.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4.6 - *
4.7 - * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
4.8 - *
4.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
4.10 - * Other names may be trademarks of their respective owners.
4.11 - *
4.12 - * The contents of this file are subject to the terms of either the GNU
4.13 - * General Public License Version 2 only ("GPL") or the Common
4.14 - * Development and Distribution License("CDDL") (collectively, the
4.15 - * "License"). You may not use this file except in compliance with the
4.16 - * License. You can obtain a copy of the License at
4.17 - * http://www.netbeans.org/cddl-gplv2.html
4.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
4.19 - * specific language governing permissions and limitations under the
4.20 - * License. When distributing the software, include this License Header
4.21 - * Notice in each file and include the License file at
4.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
4.23 - * particular file as subject to the "Classpath" exception as provided
4.24 - * by Oracle in the GPL Version 2 section of the License file that
4.25 - * accompanied this code. If applicable, add the following below the
4.26 - * License Header, with the fields enclosed by brackets [] replaced by
4.27 - * your own identifying information:
4.28 - * "Portions Copyrighted [year] [name of copyright owner]"
4.29 - *
4.30 - * Contributor(s):
4.31 - *
4.32 - * The Original Software is NetBeans. The Initial Developer of the Original
4.33 - * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
4.34 - *
4.35 - * If you wish your version of this file to be governed by only the CDDL
4.36 - * or only the GPL Version 2, indicate your decision by adding
4.37 - * "[Contributor] elects to include this software in this distribution
4.38 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
4.39 - * single choice of license, a recipient has the option to distribute
4.40 - * your version of this file under either the CDDL, the GPL Version 2 or
4.41 - * to extend the choice of license to its licensees as provided above.
4.42 - * However, if you add GPL Version 2 code and therefore, elected the GPL
4.43 - * Version 2 license, then the option applies only if the new code is
4.44 - * made subject to such option by the copyright holder.
4.45 - */
4.46 -package net.java.html.json;
4.47 -
4.48 -import java.util.List;
4.49 -import java.util.Map;
4.50 -import net.java.html.BrwsrCtx;
4.51 -import net.java.html.json.MapModelTest.MapTechnology;
4.52 -import net.java.html.json.MapModelTest.One;
4.53 -import org.apidesign.html.context.spi.Contexts;
4.54 -import org.apidesign.html.json.spi.Technology;
4.55 -import org.apidesign.html.json.spi.Transfer;
4.56 -import static org.testng.Assert.*;
4.57 -import org.testng.annotations.BeforeMethod;
4.58 -import org.testng.annotations.Test;
4.59 -
4.60 -/**
4.61 - *
4.62 - * @author Jaroslav Tulach <jtulach@netbeans.org>
4.63 - */
4.64 -public class DeepChangeTest {
4.65 - private MapTechnology t;
4.66 - private BrwsrCtx c;
4.67 -
4.68 - @BeforeMethod public void initTechnology() {
4.69 - t = new MapTechnology();
4.70 - c = Contexts.newBuilder().register(Technology.class, t, 1).
4.71 - register(Transfer.class, t, 1).build();
4.72 - }
4.73 -
4.74 - @Model(className = "MyX", properties = {
4.75 - @Property(name = "one", type = MyY.class),
4.76 - @Property(name = "all", type = MyY.class, array = true)
4.77 - })
4.78 - static class X {
4.79 - @ComputedProperty(deep = true)
4.80 - static String oneName(MyY one) {
4.81 - return one.getValue();
4.82 - }
4.83 - @ComputedProperty(deep = true)
4.84 - static String sndName(MyY one) {
4.85 - return one.getValue().toUpperCase();
4.86 - }
4.87 - @ComputedProperty(deep = false)
4.88 - static String noName(MyY one) {
4.89 - return one.getValue().toUpperCase();
4.90 - }
4.91 - @ComputedProperty(deep = true)
4.92 - static String thrdName(MyY one) {
4.93 - return "X" + one.getCount();
4.94 - }
4.95 -
4.96 - @ComputedProperty(deep = true)
4.97 - static String allNames(List<MyY> all) {
4.98 - StringBuilder sb = new StringBuilder();
4.99 - for (MyY y : all) {
4.100 - sb.append(y.getValue());
4.101 - }
4.102 - return sb.toString();
4.103 - }
4.104 -
4.105 - @ComputedProperty(deep = true)
4.106 - static String firstFromNames(List<MyY> all) {
4.107 - for (MyY y : all) {
4.108 - if (y != null && y.getValue() != null) {
4.109 - return y.getValue();
4.110 - }
4.111 - }
4.112 - return null;
4.113 - }
4.114 - }
4.115 - @Model(className = "MyY", properties = {
4.116 - @Property(name = "value", type = String.class),
4.117 - @Property(name = "count", type = int.class)
4.118 - })
4.119 - static class Y {
4.120 - }
4.121 - @Model(className = "MyOverall", properties = {
4.122 - @Property(name = "x", type = MyX.class)
4.123 - })
4.124 - static class Overall {
4.125 - @ComputedProperty(deep = true)
4.126 - static String valueAccross(MyX x) {
4.127 - return x.getFirstFromNames();
4.128 - }
4.129 - }
4.130 -
4.131 - @Test public void isTransitiveChangeNotifiedProperly() throws Exception {
4.132 - MyX p = Models.bind(
4.133 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.134 - ), c).applyBindings();
4.135 -
4.136 - Map m = (Map)Models.toRaw(p);
4.137 - Object v = m.get("oneName");
4.138 - assertNotNull(v, "Value should be in the map");
4.139 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.140 - One o = (One)v;
4.141 - assertEquals(o.changes, 0, "No changes so far");
4.142 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.143 - assertEquals(o.get(), "Ahoj");
4.144 -
4.145 - p.getOne().setValue("Nazdar");
4.146 -
4.147 - assertEquals(o.get(), "Nazdar");
4.148 - assertEquals(o.changes, 1, "One change so far");
4.149 - }
4.150 -
4.151 - @Test public void isTransitiveChangeInArrayNotifiedProperly() throws Exception {
4.152 - MyX p = Models.bind(
4.153 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.154 - ), c).applyBindings();
4.155 -
4.156 - Map m = (Map)Models.toRaw(p);
4.157 - Object v = m.get("allNames");
4.158 - assertNotNull(v, "Value should be in the map");
4.159 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.160 - One o = (One)v;
4.161 - assertEquals(o.changes, 0, "No changes so far");
4.162 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.163 - assertEquals(o.get(), "HiHello");
4.164 -
4.165 - p.getAll().get(0).setValue("Nazdar");
4.166 -
4.167 - assertEquals(o.get(), "NazdarHello");
4.168 - assertEquals(o.changes, 1, "One change so far");
4.169 - }
4.170 -
4.171 - @Test public void addingIntoArray() throws Exception {
4.172 - MyX p = Models.bind(
4.173 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.174 - ), c).applyBindings();
4.175 -
4.176 - Map m = (Map)Models.toRaw(p);
4.177 - Object v = m.get("allNames");
4.178 - assertNotNull(v, "Value should be in the map");
4.179 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.180 - One o = (One)v;
4.181 - assertEquals(o.changes, 0, "No changes so far");
4.182 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.183 - assertEquals(o.get(), "HiHello");
4.184 -
4.185 - MyY y = new MyY("Cus", 1);
4.186 - p.getAll().add(y);
4.187 -
4.188 - assertEquals(o.changes, 1, "One change so far");
4.189 - assertEquals(o.get(), "HiHelloCus");
4.190 -
4.191 - y.setValue("Nazdar");
4.192 -
4.193 - assertEquals(o.changes, 2, "2nd change so far");
4.194 - assertEquals(o.get(), "HiHelloNazdar");
4.195 -
4.196 - y.setValue("Zdravim");
4.197 -
4.198 - assertEquals(o.changes, 3, "3rd change so far");
4.199 - assertEquals(o.get(), "HiHelloZdravim");
4.200 - }
4.201 -
4.202 - @Test public void firstChangeInArrayNotifiedProperly() throws Exception {
4.203 - MyX p = Models.bind(
4.204 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.205 - ), c).applyBindings();
4.206 -
4.207 - Map m = (Map)Models.toRaw(p);
4.208 - Object v = m.get("firstFromNames");
4.209 - assertNotNull(v, "Value should be in the map");
4.210 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.211 - One o = (One)v;
4.212 - assertEquals(o.changes, 0, "No changes so far");
4.213 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.214 - assertEquals(o.get(), "Hi");
4.215 -
4.216 - p.getAll().get(0).setValue("Nazdar");
4.217 -
4.218 - assertEquals(o.get(), "Nazdar");
4.219 - assertEquals(o.changes, 1, "One change so far");
4.220 - }
4.221 -
4.222 - @Test public void firstChangeInArrayToNull() throws Exception {
4.223 - MyX p = Models.bind(
4.224 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.225 - ), c).applyBindings();
4.226 -
4.227 - Map m = (Map)Models.toRaw(p);
4.228 - Object v = m.get("firstFromNames");
4.229 - assertNotNull(v, "Value should be in the map");
4.230 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.231 - One o = (One)v;
4.232 - assertEquals(o.changes, 0, "No changes so far");
4.233 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.234 - assertEquals(o.get(), "Hi");
4.235 -
4.236 - p.getAll().get(0).setValue(null);
4.237 -
4.238 - assertEquals(o.get(), "Hello");
4.239 - assertEquals(o.changes, 1, "One change so far");
4.240 -
4.241 - p.getAll().get(0).setValue("Nazdar");
4.242 -
4.243 - assertEquals(o.get(), "Nazdar");
4.244 - assertEquals(o.changes, 2, "2nd change so far");
4.245 - }
4.246 -
4.247 - @Test public void firstChangeInArrayNotifiedTransitively() throws Exception {
4.248 - MyOverall p = Models.bind(
4.249 - new MyOverall(new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999))
4.250 - ), c).applyBindings();
4.251 -
4.252 - Map m = (Map)Models.toRaw(p);
4.253 - Object v = m.get("valueAccross");
4.254 - assertNotNull(v, "Value should be in the map");
4.255 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.256 - One o = (One)v;
4.257 - assertEquals(o.changes, 0, "No changes so far");
4.258 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.259 - assertEquals(o.get(), "Hi");
4.260 -
4.261 - p.getX().getAll().get(0).setValue("Nazdar");
4.262 -
4.263 - assertEquals(o.get(), "Nazdar");
4.264 - assertEquals(o.changes, 1, "One change so far");
4.265 - }
4.266 -
4.267 - @Test public void secondChangeInArrayIgnored() throws Exception {
4.268 - MyX p = Models.bind(
4.269 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.270 - ), c).applyBindings();
4.271 -
4.272 - Map m = (Map)Models.toRaw(p);
4.273 - Object v = m.get("firstFromNames");
4.274 - assertNotNull(v, "Value should be in the map");
4.275 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.276 - One o = (One)v;
4.277 - assertEquals(o.changes, 0, "No changes so far");
4.278 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.279 - assertEquals(o.get(), "Hi");
4.280 -
4.281 - p.getAll().get(1).setValue("Nazdar");
4.282 -
4.283 - assertEquals(o.get(), "Hi");
4.284 - assertEquals(o.changes, 0, "No change so far");
4.285 - }
4.286 -
4.287 - @Test public void changeInArraySizeNeedsToBeRecomputed() throws Exception {
4.288 - MyX p = Models.bind(
4.289 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.290 - ), c).applyBindings();
4.291 -
4.292 - Map m = (Map)Models.toRaw(p);
4.293 - Object v = m.get("firstFromNames");
4.294 - assertNotNull(v, "Value should be in the map");
4.295 - assertEquals(v.getClass(), One.class, "It is instance of One");
4.296 - One o = (One)v;
4.297 - assertEquals(o.changes, 0, "No changes so far");
4.298 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.299 - assertEquals(o.get(), "Hi");
4.300 -
4.301 - p.getAll().remove(1);
4.302 -
4.303 - assertEquals(o.get(), "Hi");
4.304 - assertEquals(o.changes, 1, "This required a change");
4.305 - }
4.306 -
4.307 - @Test public void doublePropertyChangeNotified() throws Exception {
4.308 - MyX p = Models.bind(
4.309 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.310 - ), c).applyBindings();
4.311 -
4.312 - Map m = (Map)Models.toRaw(p);
4.313 - Object v = m.get("oneName");
4.314 - assertNotNull(v, "Value should be in the map");
4.315 - Object v2 = m.get("sndName");
4.316 - assertNotNull(v2, "Value2 should be in the map");
4.317 - One o = (One)v;
4.318 - One o2 = (One)v2;
4.319 - assertEquals(o.changes, 0, "No changes so far");
4.320 - assertEquals(o2.changes, 0, "No changes so far");
4.321 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.322 - assertEquals(o.get(), "Ahoj");
4.323 - assertEquals(o2.get(), "AHOJ");
4.324 -
4.325 - p.getOne().setValue("Nazdar");
4.326 -
4.327 - assertEquals(o.get(), "Nazdar");
4.328 - assertEquals(o.changes, 1, "One change so far");
4.329 - assertEquals(o2.changes, 1, "One change so far");
4.330 - assertEquals(o2.get(), "NAZDAR");
4.331 - }
4.332 -
4.333 - @Test public void onlyAffectedPropertyChangeNotified() throws Exception {
4.334 - MyX p = Models.bind(
4.335 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.336 - ), c).applyBindings();
4.337 -
4.338 - Map m = (Map)Models.toRaw(p);
4.339 - Object v = m.get("oneName");
4.340 - assertNotNull(v, "Value should be in the map");
4.341 - Object v2 = m.get("thrdName");
4.342 - assertNotNull(v2, "Value2 should be in the map");
4.343 - One o = (One)v;
4.344 - One o2 = (One)v2;
4.345 - assertEquals(o.changes, 0, "No changes so far");
4.346 - assertEquals(o2.changes, 0, "No changes so far");
4.347 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.348 - assertEquals(o.get(), "Ahoj");
4.349 - assertEquals(o2.get(), "X0");
4.350 -
4.351 - p.getOne().setCount(10);
4.352 -
4.353 - assertEquals(o.get(), "Ahoj");
4.354 - assertEquals(o.changes, 0, "Still no change");
4.355 - assertEquals(o2.changes, 1, "One change so far");
4.356 - assertEquals(o2.get(), "X10");
4.357 - }
4.358 -
4.359 - @Test public void onlyDeepPropsAreNotified() throws Exception {
4.360 - MyX p = Models.bind(
4.361 - new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
4.362 - ), c).applyBindings();
4.363 -
4.364 - Map m = (Map)Models.toRaw(p);
4.365 - Object v = m.get("oneName");
4.366 - assertNotNull(v, "Value should be in the map");
4.367 - Object v2 = m.get("noName");
4.368 - assertNotNull(v2, "Value2 should be in the map");
4.369 - One o = (One)v;
4.370 - One o2 = (One)v2;
4.371 - assertEquals(o.changes, 0, "No changes so far");
4.372 - assertEquals(o2.changes, 0, "No changes so far");
4.373 - assertTrue(o.pb.isReadOnly(), "Derived property");
4.374 - assertEquals(o.get(), "Ahoj");
4.375 - assertEquals(o2.get(), "AHOJ");
4.376 -
4.377 - p.getOne().setValue("Nazdar");
4.378 -
4.379 - assertEquals(o.get(), "Nazdar");
4.380 - assertEquals(o.changes, 1, "One change so far");
4.381 - assertEquals(o2.changes, 0, "This change is not noticed");
4.382 - assertEquals(o2.get(), "NAZDAR", "but property value changes when computed");
4.383 - }
4.384 -
4.385 -}
5.1 --- a/json/src/test/java/net/java/html/json/MapModelTest.java Sat Aug 02 07:13:47 2014 +0200
5.2 +++ b/json/src/test/java/net/java/html/json/MapModelTest.java Sat Aug 02 07:28:37 2014 +0200
5.3 @@ -54,7 +54,6 @@
5.4 import org.apidesign.html.json.spi.PropertyBinding;
5.5 import org.apidesign.html.json.spi.Technology;
5.6 import org.apidesign.html.json.spi.Transfer;
5.7 -import org.netbeans.html.json.impl.JSON;
5.8 import org.testng.annotations.BeforeMethod;
5.9 import org.testng.annotations.Test;
5.10 import static org.testng.Assert.*;
6.1 --- a/json/src/test/java/net/java/html/json/ToDoTest.java Sat Aug 02 07:13:47 2014 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,126 +0,0 @@
6.4 -/**
6.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
6.6 - *
6.7 - * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6.8 - *
6.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6.10 - * Other names may be trademarks of their respective owners.
6.11 - *
6.12 - * The contents of this file are subject to the terms of either the GNU
6.13 - * General Public License Version 2 only ("GPL") or the Common
6.14 - * Development and Distribution License("CDDL") (collectively, the
6.15 - * "License"). You may not use this file except in compliance with the
6.16 - * License. You can obtain a copy of the License at
6.17 - * http://www.netbeans.org/cddl-gplv2.html
6.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
6.19 - * specific language governing permissions and limitations under the
6.20 - * License. When distributing the software, include this License Header
6.21 - * Notice in each file and include the License file at
6.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
6.23 - * particular file as subject to the "Classpath" exception as provided
6.24 - * by Oracle in the GPL Version 2 section of the License file that
6.25 - * accompanied this code. If applicable, add the following below the
6.26 - * License Header, with the fields enclosed by brackets [] replaced by
6.27 - * your own identifying information:
6.28 - * "Portions Copyrighted [year] [name of copyright owner]"
6.29 - *
6.30 - * Contributor(s):
6.31 - *
6.32 - * The Original Software is NetBeans. The Initial Developer of the Original
6.33 - * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
6.34 - *
6.35 - * If you wish your version of this file to be governed by only the CDDL
6.36 - * or only the GPL Version 2, indicate your decision by adding
6.37 - * "[Contributor] elects to include this software in this distribution
6.38 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
6.39 - * single choice of license, a recipient has the option to distribute
6.40 - * your version of this file under either the CDDL, the GPL Version 2 or
6.41 - * to extend the choice of license to its licensees as provided above.
6.42 - * However, if you add GPL Version 2 code and therefore, elected the GPL
6.43 - * Version 2 license, then the option applies only if the new code is
6.44 - * made subject to such option by the copyright holder.
6.45 - */
6.46 -package net.java.html.json;
6.47 -
6.48 -import java.util.List;
6.49 -import java.util.Map;
6.50 -import net.java.html.BrwsrCtx;
6.51 -import net.java.html.json.MapModelTest.One;
6.52 -import org.apidesign.html.context.spi.Contexts;
6.53 -import org.apidesign.html.json.spi.Technology;
6.54 -import org.apidesign.html.json.spi.Transfer;
6.55 -import static org.testng.Assert.*;
6.56 -import org.testng.annotations.BeforeMethod;
6.57 -import org.testng.annotations.Test;
6.58 -
6.59 -/**
6.60 - *
6.61 - * @author Jaroslav Tulach
6.62 - */
6.63 -@Model(className = "TodoUI", properties = {
6.64 - @Property(name = "todos", type = Todo.class, array = true),
6.65 - @Property(name = "todoText", type = String.class)
6.66 -})
6.67 -public class ToDoTest {
6.68 - @Model(className = "Todo", properties = {
6.69 - @Property(name = "text", type = String.class),
6.70 - @Property(name = "done", type = boolean.class)
6.71 - })
6.72 - static class ItemCtrl {
6.73 - }
6.74 -
6.75 - @ComputedProperty(deep = true)
6.76 - static int remaining(
6.77 - List<Todo> todos, String todoText
6.78 - ) {
6.79 - int count = 0;
6.80 - for (Todo d : todos) {
6.81 - if (!d.isDone()) {
6.82 - count++;
6.83 - }
6.84 - }
6.85 - return count;
6.86 - }
6.87 -
6.88 - private MapModelTest.MapTechnology t;
6.89 - private BrwsrCtx c;
6.90 -
6.91 - @BeforeMethod
6.92 - public void initTechnology() {
6.93 - t = new MapModelTest.MapTechnology();
6.94 - c = Contexts.newBuilder().register(Technology.class, t, 1).
6.95 - register(Transfer.class, t, 1).build();
6.96 - }
6.97 -
6.98 -
6.99 - @Test public void checkAndUncheckFirstItem() throws Exception {
6.100 - TodoUI ui = Models.bind(
6.101 - new TodoUI(
6.102 - null,
6.103 - new Todo("First", false),
6.104 - new Todo("2nd", true),
6.105 - new Todo("Third", false)
6.106 - ), c).applyBindings();
6.107 -
6.108 - Map m = (Map) Models.toRaw(ui);
6.109 - Object v = m.get("remaining");
6.110 - assertNotNull(v, "Value should be in the map");
6.111 - assertEquals(v.getClass(), One.class, "It is instance of One");
6.112 - One o = (One) v;
6.113 - assertEquals(o.changes, 0, "No changes so far");
6.114 - assertTrue(o.pb.isReadOnly(), "Derived property");
6.115 - assertEquals(o.get(), 2);
6.116 -
6.117 - ui.getTodos().get(0).setDone(true);
6.118 -
6.119 - assertEquals(o.get(), 1);
6.120 - assertEquals(o.changes, 1, "One change so far");
6.121 -
6.122 - ui.getTodos().get(0).setDone(false);
6.123 -
6.124 - assertEquals(o.get(), 2);
6.125 - assertEquals(o.changes, 2, "2nd change so far");
6.126 -
6.127 - }
6.128 -
6.129 -}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Sat Aug 02 07:28:37 2014 +0200
7.3 @@ -0,0 +1,496 @@
7.4 +/**
7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7.6 + *
7.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
7.8 + *
7.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7.10 + * Other names may be trademarks of their respective owners.
7.11 + *
7.12 + * The contents of this file are subject to the terms of either the GNU
7.13 + * General Public License Version 2 only ("GPL") or the Common
7.14 + * Development and Distribution License("CDDL") (collectively, the
7.15 + * "License"). You may not use this file except in compliance with the
7.16 + * License. You can obtain a copy of the License at
7.17 + * http://www.netbeans.org/cddl-gplv2.html
7.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
7.19 + * specific language governing permissions and limitations under the
7.20 + * License. When distributing the software, include this License Header
7.21 + * Notice in each file and include the License file at
7.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
7.23 + * particular file as subject to the "Classpath" exception as provided
7.24 + * by Oracle in the GPL Version 2 section of the License file that
7.25 + * accompanied this code. If applicable, add the following below the
7.26 + * License Header, with the fields enclosed by brackets [] replaced by
7.27 + * your own identifying information:
7.28 + * "Portions Copyrighted [year] [name of copyright owner]"
7.29 + *
7.30 + * Contributor(s):
7.31 + *
7.32 + * The Original Software is NetBeans. The Initial Developer of the Original
7.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
7.34 + *
7.35 + * If you wish your version of this file to be governed by only the CDDL
7.36 + * or only the GPL Version 2, indicate your decision by adding
7.37 + * "[Contributor] elects to include this software in this distribution
7.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
7.39 + * single choice of license, a recipient has the option to distribute
7.40 + * your version of this file under either the CDDL, the GPL Version 2 or
7.41 + * to extend the choice of license to its licensees as provided above.
7.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
7.43 + * Version 2 license, then the option applies only if the new code is
7.44 + * made subject to such option by the copyright holder.
7.45 + */
7.46 +package org.netbeans.html.json.impl;
7.47 +
7.48 +import java.io.IOException;
7.49 +import java.io.InputStream;
7.50 +import java.lang.reflect.InvocationTargetException;
7.51 +import java.util.HashMap;
7.52 +import java.util.List;
7.53 +import java.util.Map;
7.54 +import net.java.html.BrwsrCtx;
7.55 +import net.java.html.json.ComputedProperty;
7.56 +import net.java.html.json.Model;
7.57 +import net.java.html.json.Models;
7.58 +import net.java.html.json.Property;
7.59 +import org.apidesign.html.context.spi.Contexts;
7.60 +import org.apidesign.html.json.spi.FunctionBinding;
7.61 +import org.apidesign.html.json.spi.JSONCall;
7.62 +import org.apidesign.html.json.spi.PropertyBinding;
7.63 +import org.apidesign.html.json.spi.Technology;
7.64 +import org.apidesign.html.json.spi.Transfer;
7.65 +import static org.testng.Assert.*;
7.66 +import org.testng.annotations.BeforeMethod;
7.67 +import org.testng.annotations.Test;
7.68 +
7.69 +/**
7.70 + *
7.71 + * @author Jaroslav Tulach <jtulach@netbeans.org>
7.72 + */
7.73 +public class DeepChangeTest {
7.74 + private MapTechnology t;
7.75 + private BrwsrCtx c;
7.76 +
7.77 + @BeforeMethod public void initTechnology() {
7.78 + t = new MapTechnology();
7.79 + c = Contexts.newBuilder().register(Technology.class, t, 1).
7.80 + register(Transfer.class, t, 1).build();
7.81 + }
7.82 +
7.83 + @Model(className = "MyX", properties = {
7.84 + @Property(name = "one", type = MyY.class),
7.85 + @Property(name = "all", type = MyY.class, array = true)
7.86 + })
7.87 + static class X {
7.88 + @ComputedProperty @Transitive(deep = true)
7.89 + static String oneName(MyY one) {
7.90 + return one.getValue();
7.91 + }
7.92 + @ComputedProperty @Transitive(deep = true)
7.93 + static String sndName(MyY one) {
7.94 + return one.getValue().toUpperCase();
7.95 + }
7.96 + @ComputedProperty @Transitive(deep = false)
7.97 + static String noName(MyY one) {
7.98 + return one.getValue().toUpperCase();
7.99 + }
7.100 + @ComputedProperty @Transitive(deep = true)
7.101 + static String thrdName(MyY one) {
7.102 + return "X" + one.getCount();
7.103 + }
7.104 +
7.105 + @ComputedProperty @Transitive(deep = true)
7.106 + static String allNames(List<MyY> all) {
7.107 + StringBuilder sb = new StringBuilder();
7.108 + for (MyY y : all) {
7.109 + sb.append(y.getValue());
7.110 + }
7.111 + return sb.toString();
7.112 + }
7.113 +
7.114 + @ComputedProperty @Transitive(deep = true)
7.115 + static String firstFromNames(List<MyY> all) {
7.116 + for (MyY y : all) {
7.117 + if (y != null && y.getValue() != null) {
7.118 + return y.getValue();
7.119 + }
7.120 + }
7.121 + return null;
7.122 + }
7.123 + }
7.124 + @Model(className = "MyY", properties = {
7.125 + @Property(name = "value", type = String.class),
7.126 + @Property(name = "count", type = int.class)
7.127 + })
7.128 + static class Y {
7.129 + }
7.130 + @Model(className = "MyOverall", properties = {
7.131 + @Property(name = "x", type = MyX.class)
7.132 + })
7.133 + static class Overall {
7.134 + @ComputedProperty @Transitive(deep = true)
7.135 + static String valueAccross(MyX x) {
7.136 + return x.getFirstFromNames();
7.137 + }
7.138 + }
7.139 +
7.140 + @Test public void isTransitiveChangeNotifiedProperly() throws Exception {
7.141 + MyX p = Models.bind(
7.142 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.143 + ), c).applyBindings();
7.144 +
7.145 + Map m = (Map)Models.toRaw(p);
7.146 + Object v = m.get("oneName");
7.147 + assertNotNull(v, "Value should be in the map");
7.148 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.149 + One o = (One)v;
7.150 + assertEquals(o.changes, 0, "No changes so far");
7.151 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.152 + assertEquals(o.get(), "Ahoj");
7.153 +
7.154 + p.getOne().setValue("Nazdar");
7.155 +
7.156 + assertEquals(o.get(), "Nazdar");
7.157 + assertEquals(o.changes, 1, "One change so far");
7.158 + }
7.159 +
7.160 + @Test public void isTransitiveChangeInArrayNotifiedProperly() throws Exception {
7.161 + MyX p = Models.bind(
7.162 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.163 + ), c).applyBindings();
7.164 +
7.165 + Map m = (Map)Models.toRaw(p);
7.166 + Object v = m.get("allNames");
7.167 + assertNotNull(v, "Value should be in the map");
7.168 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.169 + One o = (One)v;
7.170 + assertEquals(o.changes, 0, "No changes so far");
7.171 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.172 + assertEquals(o.get(), "HiHello");
7.173 +
7.174 + p.getAll().get(0).setValue("Nazdar");
7.175 +
7.176 + assertEquals(o.get(), "NazdarHello");
7.177 + assertEquals(o.changes, 1, "One change so far");
7.178 + }
7.179 +
7.180 + @Test public void addingIntoArray() throws Exception {
7.181 + MyX p = Models.bind(
7.182 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.183 + ), c).applyBindings();
7.184 +
7.185 + Map m = (Map)Models.toRaw(p);
7.186 + Object v = m.get("allNames");
7.187 + assertNotNull(v, "Value should be in the map");
7.188 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.189 + One o = (One)v;
7.190 + assertEquals(o.changes, 0, "No changes so far");
7.191 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.192 + assertEquals(o.get(), "HiHello");
7.193 +
7.194 + MyY y = new MyY("Cus", 1);
7.195 + p.getAll().add(y);
7.196 +
7.197 + assertEquals(o.changes, 1, "One change so far");
7.198 + assertEquals(o.get(), "HiHelloCus");
7.199 +
7.200 + y.setValue("Nazdar");
7.201 +
7.202 + assertEquals(o.changes, 2, "2nd change so far");
7.203 + assertEquals(o.get(), "HiHelloNazdar");
7.204 +
7.205 + y.setValue("Zdravim");
7.206 +
7.207 + assertEquals(o.changes, 3, "3rd change so far");
7.208 + assertEquals(o.get(), "HiHelloZdravim");
7.209 + }
7.210 +
7.211 + @Test public void firstChangeInArrayNotifiedProperly() throws Exception {
7.212 + MyX p = Models.bind(
7.213 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.214 + ), c).applyBindings();
7.215 +
7.216 + Map m = (Map)Models.toRaw(p);
7.217 + Object v = m.get("firstFromNames");
7.218 + assertNotNull(v, "Value should be in the map");
7.219 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.220 + One o = (One)v;
7.221 + assertEquals(o.changes, 0, "No changes so far");
7.222 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.223 + assertEquals(o.get(), "Hi");
7.224 +
7.225 + p.getAll().get(0).setValue("Nazdar");
7.226 +
7.227 + assertEquals(o.get(), "Nazdar");
7.228 + assertEquals(o.changes, 1, "One change so far");
7.229 + }
7.230 +
7.231 + @Test public void firstChangeInArrayToNull() throws Exception {
7.232 + MyX p = Models.bind(
7.233 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.234 + ), c).applyBindings();
7.235 +
7.236 + Map m = (Map)Models.toRaw(p);
7.237 + Object v = m.get("firstFromNames");
7.238 + assertNotNull(v, "Value should be in the map");
7.239 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.240 + One o = (One)v;
7.241 + assertEquals(o.changes, 0, "No changes so far");
7.242 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.243 + assertEquals(o.get(), "Hi");
7.244 +
7.245 + p.getAll().get(0).setValue(null);
7.246 +
7.247 + assertEquals(o.get(), "Hello");
7.248 + assertEquals(o.changes, 1, "One change so far");
7.249 +
7.250 + p.getAll().get(0).setValue("Nazdar");
7.251 +
7.252 + assertEquals(o.get(), "Nazdar");
7.253 + assertEquals(o.changes, 2, "2nd change so far");
7.254 + }
7.255 +
7.256 + @Test public void firstChangeInArrayNotifiedTransitively() throws Exception {
7.257 + MyOverall p = Models.bind(
7.258 + new MyOverall(new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999))
7.259 + ), c).applyBindings();
7.260 +
7.261 + Map m = (Map)Models.toRaw(p);
7.262 + Object v = m.get("valueAccross");
7.263 + assertNotNull(v, "Value should be in the map");
7.264 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.265 + One o = (One)v;
7.266 + assertEquals(o.changes, 0, "No changes so far");
7.267 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.268 + assertEquals(o.get(), "Hi");
7.269 +
7.270 + p.getX().getAll().get(0).setValue("Nazdar");
7.271 +
7.272 + assertEquals(o.get(), "Nazdar");
7.273 + assertEquals(o.changes, 1, "One change so far");
7.274 + }
7.275 +
7.276 + @Test public void secondChangeInArrayIgnored() throws Exception {
7.277 + MyX p = Models.bind(
7.278 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.279 + ), c).applyBindings();
7.280 +
7.281 + Map m = (Map)Models.toRaw(p);
7.282 + Object v = m.get("firstFromNames");
7.283 + assertNotNull(v, "Value should be in the map");
7.284 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.285 + One o = (One)v;
7.286 + assertEquals(o.changes, 0, "No changes so far");
7.287 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.288 + assertEquals(o.get(), "Hi");
7.289 +
7.290 + p.getAll().get(1).setValue("Nazdar");
7.291 +
7.292 + assertEquals(o.get(), "Hi");
7.293 + assertEquals(o.changes, 0, "No change so far");
7.294 + }
7.295 +
7.296 + @Test public void changeInArraySizeNeedsToBeRecomputed() throws Exception {
7.297 + MyX p = Models.bind(
7.298 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.299 + ), c).applyBindings();
7.300 +
7.301 + Map m = (Map)Models.toRaw(p);
7.302 + Object v = m.get("firstFromNames");
7.303 + assertNotNull(v, "Value should be in the map");
7.304 + assertEquals(v.getClass(), One.class, "It is instance of One");
7.305 + One o = (One)v;
7.306 + assertEquals(o.changes, 0, "No changes so far");
7.307 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.308 + assertEquals(o.get(), "Hi");
7.309 +
7.310 + p.getAll().remove(1);
7.311 +
7.312 + assertEquals(o.get(), "Hi");
7.313 + assertEquals(o.changes, 1, "This required a change");
7.314 + }
7.315 +
7.316 + @Test public void doublePropertyChangeNotified() throws Exception {
7.317 + MyX p = Models.bind(
7.318 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.319 + ), c).applyBindings();
7.320 +
7.321 + Map m = (Map)Models.toRaw(p);
7.322 + Object v = m.get("oneName");
7.323 + assertNotNull(v, "Value should be in the map");
7.324 + Object v2 = m.get("sndName");
7.325 + assertNotNull(v2, "Value2 should be in the map");
7.326 + One o = (One)v;
7.327 + One o2 = (One)v2;
7.328 + assertEquals(o.changes, 0, "No changes so far");
7.329 + assertEquals(o2.changes, 0, "No changes so far");
7.330 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.331 + assertEquals(o.get(), "Ahoj");
7.332 + assertEquals(o2.get(), "AHOJ");
7.333 +
7.334 + p.getOne().setValue("Nazdar");
7.335 +
7.336 + assertEquals(o.get(), "Nazdar");
7.337 + assertEquals(o.changes, 1, "One change so far");
7.338 + assertEquals(o2.changes, 1, "One change so far");
7.339 + assertEquals(o2.get(), "NAZDAR");
7.340 + }
7.341 +
7.342 + @Test public void onlyAffectedPropertyChangeNotified() throws Exception {
7.343 + MyX p = Models.bind(
7.344 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.345 + ), c).applyBindings();
7.346 +
7.347 + Map m = (Map)Models.toRaw(p);
7.348 + Object v = m.get("oneName");
7.349 + assertNotNull(v, "Value should be in the map");
7.350 + Object v2 = m.get("thrdName");
7.351 + assertNotNull(v2, "Value2 should be in the map");
7.352 + One o = (One)v;
7.353 + One o2 = (One)v2;
7.354 + assertEquals(o.changes, 0, "No changes so far");
7.355 + assertEquals(o2.changes, 0, "No changes so far");
7.356 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.357 + assertEquals(o.get(), "Ahoj");
7.358 + assertEquals(o2.get(), "X0");
7.359 +
7.360 + p.getOne().setCount(10);
7.361 +
7.362 + assertEquals(o.get(), "Ahoj");
7.363 + assertEquals(o.changes, 0, "Still no change");
7.364 + assertEquals(o2.changes, 1, "One change so far");
7.365 + assertEquals(o2.get(), "X10");
7.366 + }
7.367 +
7.368 + @Test public void onlyDeepPropsAreNotified() throws Exception {
7.369 + MyX p = Models.bind(
7.370 + new MyX(new MyY("Ahoj", 0), new MyY("Hi", 333), new MyY("Hello", 999)
7.371 + ), c).applyBindings();
7.372 +
7.373 + Map m = (Map)Models.toRaw(p);
7.374 + Object v = m.get("oneName");
7.375 + assertNotNull(v, "Value should be in the map");
7.376 + Object v2 = m.get("noName");
7.377 + assertNotNull(v2, "Value2 should be in the map");
7.378 + One o = (One)v;
7.379 + One o2 = (One)v2;
7.380 + assertEquals(o.changes, 0, "No changes so far");
7.381 + assertEquals(o2.changes, 0, "No changes so far");
7.382 + assertTrue(o.pb.isReadOnly(), "Derived property");
7.383 + assertEquals(o.get(), "Ahoj");
7.384 + assertEquals(o2.get(), "AHOJ");
7.385 +
7.386 + p.getOne().setValue("Nazdar");
7.387 +
7.388 + assertEquals(o.get(), "Nazdar");
7.389 + assertEquals(o.changes, 1, "One change so far");
7.390 + assertEquals(o2.changes, 0, "This change is not noticed");
7.391 + assertEquals(o2.get(), "NAZDAR", "but property value changes when computed");
7.392 + }
7.393 +
7.394 + static final class One {
7.395 +
7.396 + int changes;
7.397 + final PropertyBinding pb;
7.398 + final FunctionBinding fb;
7.399 +
7.400 + One(Object m, PropertyBinding pb) throws NoSuchMethodException {
7.401 + this.pb = pb;
7.402 + this.fb = null;
7.403 + }
7.404 +
7.405 + One(Object m, FunctionBinding fb) throws NoSuchMethodException {
7.406 + this.pb = null;
7.407 + this.fb = fb;
7.408 + }
7.409 +
7.410 + Object get() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
7.411 + return pb.getValue();
7.412 + }
7.413 +
7.414 + void set(Object v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
7.415 + pb.setValue(v);
7.416 + }
7.417 + }
7.418 +
7.419 + static final class MapTechnology
7.420 + implements Technology<Map<String, One>>, Transfer {
7.421 +
7.422 + @Override
7.423 + public Map<String, One> wrapModel(Object model) {
7.424 + return new HashMap<String, One>();
7.425 + }
7.426 +
7.427 + @Override
7.428 + public void valueHasMutated(Map<String, One> data, String propertyName) {
7.429 + One p = data.get(propertyName);
7.430 + if (p != null) {
7.431 + p.changes++;
7.432 + }
7.433 + }
7.434 +
7.435 + @Override
7.436 + public void bind(PropertyBinding b, Object model, Map<String, One> data) {
7.437 + try {
7.438 + One o = new One(model, b);
7.439 + data.put(b.getPropertyName(), o);
7.440 + } catch (NoSuchMethodException ex) {
7.441 + throw new IllegalStateException(ex);
7.442 + }
7.443 + }
7.444 +
7.445 + @Override
7.446 + public void expose(FunctionBinding fb, Object model, Map<String, One> data) {
7.447 + try {
7.448 + data.put(fb.getFunctionName(), new One(model, fb));
7.449 + } catch (NoSuchMethodException ex) {
7.450 + throw new IllegalStateException(ex);
7.451 + }
7.452 + }
7.453 +
7.454 + @Override
7.455 + public void applyBindings(Map<String, One> data) {
7.456 + }
7.457 +
7.458 + @Override
7.459 + public Object wrapArray(Object[] arr) {
7.460 + return arr;
7.461 + }
7.462 +
7.463 + @Override
7.464 + public void extract(Object obj, String[] props, Object[] values) {
7.465 + Map<?, ?> map = obj instanceof Map ? (Map<?, ?>) obj : null;
7.466 + for (int i = 0; i < Math.min(props.length, values.length); i++) {
7.467 + if (map == null) {
7.468 + values[i] = null;
7.469 + } else {
7.470 + values[i] = map.get(props[i]);
7.471 + if (values[i] instanceof One) {
7.472 + values[i] = ((One) values[i]).pb.getValue();
7.473 + }
7.474 + }
7.475 + }
7.476 + }
7.477 +
7.478 + @Override
7.479 + public void loadJSON(JSONCall call) {
7.480 + call.notifyError(new UnsupportedOperationException());
7.481 + }
7.482 +
7.483 + @Override
7.484 + public <M> M toModel(Class<M> modelClass, Object data) {
7.485 + return modelClass.cast(data);
7.486 + }
7.487 +
7.488 + @Override
7.489 + public Object toJSON(InputStream is) throws IOException {
7.490 + throw new IOException();
7.491 + }
7.492 +
7.493 + @Override
7.494 + public void runSafe(Runnable r) {
7.495 + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
7.496 + }
7.497 + }
7.498 +
7.499 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/ToDoTest.java Sat Aug 02 07:28:37 2014 +0200
8.3 @@ -0,0 +1,131 @@
8.4 +/**
8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8.6 + *
8.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
8.8 + *
8.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
8.10 + * Other names may be trademarks of their respective owners.
8.11 + *
8.12 + * The contents of this file are subject to the terms of either the GNU
8.13 + * General Public License Version 2 only ("GPL") or the Common
8.14 + * Development and Distribution License("CDDL") (collectively, the
8.15 + * "License"). You may not use this file except in compliance with the
8.16 + * License. You can obtain a copy of the License at
8.17 + * http://www.netbeans.org/cddl-gplv2.html
8.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
8.19 + * specific language governing permissions and limitations under the
8.20 + * License. When distributing the software, include this License Header
8.21 + * Notice in each file and include the License file at
8.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
8.23 + * particular file as subject to the "Classpath" exception as provided
8.24 + * by Oracle in the GPL Version 2 section of the License file that
8.25 + * accompanied this code. If applicable, add the following below the
8.26 + * License Header, with the fields enclosed by brackets [] replaced by
8.27 + * your own identifying information:
8.28 + * "Portions Copyrighted [year] [name of copyright owner]"
8.29 + *
8.30 + * Contributor(s):
8.31 + *
8.32 + * The Original Software is NetBeans. The Initial Developer of the Original
8.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
8.34 + *
8.35 + * If you wish your version of this file to be governed by only the CDDL
8.36 + * or only the GPL Version 2, indicate your decision by adding
8.37 + * "[Contributor] elects to include this software in this distribution
8.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
8.39 + * single choice of license, a recipient has the option to distribute
8.40 + * your version of this file under either the CDDL, the GPL Version 2 or
8.41 + * to extend the choice of license to its licensees as provided above.
8.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
8.43 + * Version 2 license, then the option applies only if the new code is
8.44 + * made subject to such option by the copyright holder.
8.45 + */
8.46 +package org.netbeans.html.json.impl;
8.47 +
8.48 +import java.util.List;
8.49 +import java.util.Map;
8.50 +import net.java.html.BrwsrCtx;
8.51 +import net.java.html.json.ComputedProperty;
8.52 +import net.java.html.json.Model;
8.53 +import net.java.html.json.Models;
8.54 +import net.java.html.json.Property;
8.55 +import org.apidesign.html.context.spi.Contexts;
8.56 +import org.apidesign.html.json.spi.Technology;
8.57 +import org.apidesign.html.json.spi.Transfer;
8.58 +import org.netbeans.html.json.impl.DeepChangeTest.MapTechnology;
8.59 +import org.netbeans.html.json.impl.DeepChangeTest.One;
8.60 +import static org.testng.Assert.*;
8.61 +import org.testng.annotations.BeforeMethod;
8.62 +import org.testng.annotations.Test;
8.63 +
8.64 +/**
8.65 + *
8.66 + * @author Jaroslav Tulach
8.67 + */
8.68 +@Model(className = "TodoUI", properties = {
8.69 + @Property(name = "todos", type = Todo.class, array = true),
8.70 + @Property(name = "todoText", type = String.class)
8.71 +})
8.72 +public class ToDoTest {
8.73 + @Model(className = "Todo", properties = {
8.74 + @Property(name = "text", type = String.class),
8.75 + @Property(name = "done", type = boolean.class)
8.76 + })
8.77 + static class ItemCtrl {
8.78 + }
8.79 +
8.80 + @ComputedProperty @Transitive(deep = true)
8.81 + static int remaining(
8.82 + List<Todo> todos, String todoText
8.83 + ) {
8.84 + int count = 0;
8.85 + for (Todo d : todos) {
8.86 + if (!d.isDone()) {
8.87 + count++;
8.88 + }
8.89 + }
8.90 + return count;
8.91 + }
8.92 +
8.93 + private MapTechnology t;
8.94 + private BrwsrCtx c;
8.95 +
8.96 + @BeforeMethod
8.97 + public void initTechnology() {
8.98 + t = new MapTechnology();
8.99 + c = Contexts.newBuilder().register(Technology.class, t, 1).
8.100 + register(Transfer.class, t, 1).build();
8.101 + }
8.102 +
8.103 +
8.104 + @Test public void checkAndUncheckFirstItem() throws Exception {
8.105 + TodoUI ui = Models.bind(
8.106 + new TodoUI(
8.107 + null,
8.108 + new Todo("First", false),
8.109 + new Todo("2nd", true),
8.110 + new Todo("Third", false)
8.111 + ), c).applyBindings();
8.112 +
8.113 + Map m = (Map) Models.toRaw(ui);
8.114 + Object v = m.get("remaining");
8.115 + assertNotNull(v, "Value should be in the map");
8.116 + assertEquals(v.getClass(), One.class, "It is instance of One");
8.117 + One o = (One) v;
8.118 + assertEquals(o.changes, 0, "No changes so far");
8.119 + assertTrue(o.pb.isReadOnly(), "Derived property");
8.120 + assertEquals(o.get(), 2);
8.121 +
8.122 + ui.getTodos().get(0).setDone(true);
8.123 +
8.124 + assertEquals(o.get(), 1);
8.125 + assertEquals(o.changes, 1, "One change so far");
8.126 +
8.127 + ui.getTodos().get(0).setDone(false);
8.128 +
8.129 + assertEquals(o.get(), 2);
8.130 + assertEquals(o.changes, 2, "2nd change so far");
8.131 +
8.132 + }
8.133 +
8.134 +}