1.1 --- a/json/src/main/java/net/java/html/json/Context.java Mon Apr 22 16:14:52 2013 +0200
1.2 +++ b/json/src/main/java/net/java/html/json/Context.java Mon Apr 22 21:12:16 2013 +0200
1.3 @@ -80,5 +80,10 @@
1.4 @Override
1.5 public void applyBindings(Object data) {
1.6 }
1.7 +
1.8 + @Override
1.9 + public Object wrapArray(Object[] arr) {
1.10 + return arr;
1.11 + }
1.12 }
1.13 }
2.1 --- a/json/src/main/java/org/apidesign/html/json/impl/Bindings.java Mon Apr 22 16:14:52 2013 +0200
2.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/Bindings.java Mon Apr 22 21:12:16 2013 +0200
2.3 @@ -24,6 +24,7 @@
2.4 import java.util.List;
2.5 import org.apidesign.html.json.spi.PropertyBinding;
2.6 import net.java.html.json.Context;
2.7 +import org.apidesign.html.json.impl.PropertyBindingAccessor.PBData;
2.8 import org.apidesign.html.json.spi.FunctionBinding;
2.9 import org.apidesign.html.json.spi.Technology;
2.10
2.11 @@ -35,31 +36,36 @@
2.12 private final Data data;
2.13 private final Technology<Data> bp;
2.14
2.15 - public Bindings(Data data, Technology<Data> bp) {
2.16 + private Bindings(Data data, Technology<Data> bp) {
2.17 this.data = data;
2.18 this.bp = bp;
2.19 }
2.20
2.21 - public static Bindings<?> apply(Context c, Object model, String[] propsAndGetters, String[] functions) {
2.22 + public <M> PropertyBinding registerProperty(String propName, M model, SetAndGet<M> access, boolean readOnly) {
2.23 + PropertyBinding pb = PropertyBindingAccessor.create(new PBData<>(propName, model, access, readOnly));
2.24 + bp.bind(pb, model, data);
2.25 + return pb;
2.26 + }
2.27 +
2.28 + public static Bindings<?> apply(Context c, Object model, String[] functions) {
2.29 Technology<?> bp = ContextAccessor.findTechnology(c);
2.30 - return apply(bp, model, propsAndGetters, functions);
2.31 + return apply(bp, model, null, functions);
2.32 }
2.33
2.34 private static <Data> Bindings<Data> apply(
2.35 Technology<Data> bp, Object model,
2.36 - String[] propsAndGetters, String[] methodsAndSignatures
2.37 + PropertyBinding[] propBindings, String[] methodsAndSignatures
2.38 ) {
2.39 Data d = bp.wrapModel(model);
2.40
2.41 - List<String> arr = Arrays.asList(propsAndGetters);
2.42 - for (int i = 0; i < propsAndGetters.length; i += 4) {
2.43 - PropertyBinding pb = PropertyBindingAccessor.create(
2.44 - arr.subList(i, i + 4)
2.45 - );
2.46 - bp.bind(pb, model, d);
2.47 + if (propBindings != null) {
2.48 + for (int i = 0; i < propBindings.length; i++) {
2.49 + PropertyBinding pb = propBindings[i];
2.50 + bp.bind(pb, model, d);
2.51 + }
2.52 }
2.53 -
2.54 - arr = Arrays.asList(methodsAndSignatures);
2.55 +
2.56 + List<String> arr = Arrays.asList(methodsAndSignatures);
2.57 for (int i = 0; i < methodsAndSignatures.length; i += 2) {
2.58 FunctionBinding fb = PropertyBindingAccessor.createFunction(arr.subList(i, i + 2));
2.59 bp.expose(fb, model, d);
2.60 @@ -80,4 +86,8 @@
2.61 public void applyBindings() {
2.62 bp.applyBindings(data);
2.63 }
2.64 +
2.65 + Object wrapArray(Object[] arr) {
2.66 + return bp.wrapArray(arr);
2.67 + }
2.68 }
3.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSONList.java Mon Apr 22 16:14:52 2013 +0200
3.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSONList.java Mon Apr 22 21:12:16 2013 +0200
3.3 @@ -162,20 +162,12 @@
3.4 return ko;
3.5 }
3.6
3.7 - @Override
3.8 - public boolean equals(Object o) {
3.9 - if (o instanceof WrapperObject) {
3.10 - ((WrapperObject)o).setRealObject(koData());
3.11 - }
3.12 - return super.equals(o);
3.13 - }
3.14 -
3.15 - private Object[] koData() {
3.16 + public Object koData() {
3.17 Object[] arr = toArray();
3.18 for (int i = 0; i < arr.length; i++) {
3.19 arr[i] = WrapperObject.find(arr[i]);
3.20 }
3.21 - return arr;
3.22 + return model.wrapArray(arr);
3.23 }
3.24
3.25 }
4.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Mon Apr 22 16:14:52 2013 +0200
4.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Mon Apr 22 21:12:16 2013 +0200
4.3 @@ -197,15 +197,44 @@
4.4 w.append(" };\n");
4.5 w.append(" private org.apidesign.html.json.impl.Bindings intKnckt() {\n");
4.6 w.append(" if (ko != null) return ko;\n");
4.7 - w.append(" return ko = org.apidesign.html.json.impl.Bindings.apply(context, this, ");
4.8 - writeStringArray(propsGetSet, w);
4.9 - w.append(", ");
4.10 + w.append(" ko = org.apidesign.html.json.impl.Bindings.apply(context, this, ");
4.11 writeStringArray(functions, w);
4.12 w.append(" );\n");
4.13 + for (int i = 0; i < propsGetSet.size(); i += 5) {
4.14 + w.append(" ko.registerProperty(\"").append(propsGetSet.get(i)).append("\", this, new P(");
4.15 + w.append((i / 5) + "), " + (propsGetSet.get(i + 2) == null) + ");\n");
4.16 + }
4.17 + w.append(" return ko;\n");
4.18 w.append(" };\n");
4.19 + w.append(" private static final class P implements org.apidesign.html.json.impl.SetAndGet<" + className + "> {\n");
4.20 + w.append(" private final int type;\n");
4.21 + w.append(" P(int t) { type = t; };\n");
4.22 + w.append(" public void setValue(" + className + " data, Object value) {\n");
4.23 + w.append(" switch (type) {\n");
4.24 + for (int i = 0; i < propsGetSet.size(); i += 5) {
4.25 + final String set = propsGetSet.get(i + 2);
4.26 + final String tn = propsGetSet.get(i + 4);
4.27 + if (set != null) {
4.28 + w.append(" case " + (i / 5) + ": data." + strip(set) + "((" + tn + ")value); return;\n");
4.29 + }
4.30 + }
4.31 + w.append(" }\n");
4.32 + w.append(" }\n");
4.33 + w.append(" public Object getValue(" + className + " data) {\n");
4.34 + w.append(" switch (type) {\n");
4.35 + for (int i = 0; i < propsGetSet.size(); i += 5) {
4.36 + final String get = propsGetSet.get(i + 1);
4.37 + if (get != null) {
4.38 + w.append(" case " + (i / 5) + ": return data." + strip(get) + "();\n");
4.39 + }
4.40 + }
4.41 + w.append(" }\n");
4.42 + w.append(" throw new UnsupportedOperationException();\n");
4.43 + w.append(" }\n");
4.44 + w.append(" }\n");
4.45 w.append(" ").append(className).append("(Object json) {\n");
4.46 int values = 0;
4.47 - for (int i = 0; i < propsGetSet.size(); i += 4) {
4.48 + for (int i = 0; i < propsGetSet.size(); i += 5) {
4.49 Prprt p = findPrprt(props, propsGetSet.get(i));
4.50 if (p == null) {
4.51 continue;
4.52 @@ -214,7 +243,7 @@
4.53 }
4.54 w.append(" Object[] ret = new Object[" + values + "];\n");
4.55 w.append(" org.apidesign.html.json.impl.JSON.extract(json, new String[] {\n");
4.56 - for (int i = 0; i < propsGetSet.size(); i += 4) {
4.57 + for (int i = 0; i < propsGetSet.size(); i += 5) {
4.58 Prprt p = findPrprt(props, propsGetSet.get(i));
4.59 if (p == null) {
4.60 continue;
4.61 @@ -222,7 +251,7 @@
4.62 w.append(" \"").append(propsGetSet.get(i)).append("\",\n");
4.63 }
4.64 w.append(" }, ret);\n");
4.65 - for (int i = 0, cnt = 0, prop = 0; i < propsGetSet.size(); i += 4) {
4.66 + for (int i = 0, cnt = 0, prop = 0; i < propsGetSet.size(); i += 5) {
4.67 final String pn = propsGetSet.get(i);
4.68 Prprt p = findPrprt(props, pn);
4.69 if (p == null) {
4.70 @@ -307,7 +336,8 @@
4.71 final String tn;
4.72 tn = typeName(where, p);
4.73 String[] gs = toGetSet(p.name(), tn, p.array());
4.74 -
4.75 + String castTo;
4.76 +
4.77 if (p.array()) {
4.78 w.write("private org.apidesign.html.json.impl.JSONList<" + tn + "> prop_" + p.name() + " = new org.apidesign.html.json.impl.JSONList<" + tn + ">(\""
4.79 + p.name() + "\"");
4.80 @@ -331,13 +361,15 @@
4.81 w.write("}})");
4.82 }
4.83 w.write(";\n");
4.84 -
4.85 +
4.86 + castTo = "java.util.List";
4.87 w.write("public java.util.List<" + tn + "> " + gs[0] + "() {\n");
4.88 w.write(" if (locked) throw new IllegalStateException();\n");
4.89 w.write(" prop_" + p.name() + ".assign(this.intKnckt());\n");
4.90 w.write(" return prop_" + p.name() + ";\n");
4.91 w.write("}\n");
4.92 } else {
4.93 + castTo = tn;
4.94 w.write("private " + tn + " prop_" + p.name() + ";\n");
4.95 w.write("public " + tn + " " + gs[0] + "() {\n");
4.96 w.write(" if (locked) throw new IllegalStateException();\n");
4.97 @@ -369,6 +401,7 @@
4.98 props.add(gs[2]);
4.99 props.add(gs[3]);
4.100 props.add(gs[0]);
4.101 + props.add(castTo);
4.102 }
4.103 return ok;
4.104 }
4.105 @@ -440,6 +473,7 @@
4.106 props.add(gs[2]);
4.107 props.add(null);
4.108 props.add(gs[0]);
4.109 + props.add(tn);
4.110 }
4.111
4.112 return ok;
4.113 @@ -1094,6 +1128,15 @@
4.114 return ret;
4.115 }
4.116
4.117 + private static String strip(String s) {
4.118 + int indx = s.indexOf("__");
4.119 + if (indx >= 0) {
4.120 + return s.substring(0, indx);
4.121 + } else {
4.122 + return s;
4.123 + }
4.124 + }
4.125 +
4.126 private static class Prprt {
4.127 private final Element e;
4.128 private final AnnotationMirror tm;
5.1 --- a/json/src/main/java/org/apidesign/html/json/impl/PropertyBindingAccessor.java Mon Apr 22 16:14:52 2013 +0200
5.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/PropertyBindingAccessor.java Mon Apr 22 21:12:16 2013 +0200
5.3 @@ -47,16 +47,39 @@
5.4 }
5.5 }
5.6
5.7 - protected abstract PropertyBinding newBinding(List<String> params);
5.8 + protected abstract <M> PropertyBinding newBinding(PBData<M> d);
5.9 protected abstract FunctionBinding newFunction(List<String> params);
5.10
5.11 - static PropertyBinding create(
5.12 - List<String> params
5.13 - ) {
5.14 - return DEFAULT.newBinding(params);
5.15 + static <M> PropertyBinding create(PBData<M> d) {
5.16 + return DEFAULT.newBinding(d);
5.17 }
5.18 static FunctionBinding createFunction(List<String> subList) {
5.19 return DEFAULT.newFunction(subList);
5.20 }
5.21
5.22 + public static final class PBData<M> {
5.23 + public final String name;
5.24 + public final M model;
5.25 + public final SetAndGet<M> access;
5.26 + public final boolean readOnly;
5.27 +
5.28 + public PBData(String name, M model, SetAndGet<M> access, boolean readOnly) {
5.29 + this.name = name;
5.30 + this.model = model;
5.31 + this.access = access;
5.32 + this.readOnly = readOnly;
5.33 + }
5.34 +
5.35 + public void setValue(Object v) {
5.36 + access.setValue(model, v);
5.37 + }
5.38 +
5.39 + public Object getValue() {
5.40 + return access.getValue(model);
5.41 + }
5.42 +
5.43 + public boolean isReadOnly() {
5.44 + return readOnly;
5.45 + }
5.46 + }
5.47 }
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/SetAndGet.java Mon Apr 22 21:12:16 2013 +0200
6.3 @@ -0,0 +1,33 @@
6.4 +/**
6.5 + * HTML via Java(tm) Language Bindings
6.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.7 + *
6.8 + * This program is free software: you can redistribute it and/or modify
6.9 + * it under the terms of the GNU General Public License as published by
6.10 + * the Free Software Foundation, version 2 of the License.
6.11 + *
6.12 + * This program is distributed in the hope that it will be useful,
6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 + * GNU General Public License for more details. apidesign.org
6.16 + * designates this particular file as subject to the
6.17 + * "Classpath" exception as provided by apidesign.org
6.18 + * in the License file that accompanied this code.
6.19 + *
6.20 + * You should have received a copy of the GNU General Public License
6.21 + * along with this program. Look for COPYING file in the top folder.
6.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
6.23 + */
6.24 +
6.25 +package org.apidesign.html.json.impl;
6.26 +
6.27 +import org.apidesign.html.json.spi.PropertyBinding;
6.28 +
6.29 +/** A way to implement a {@link PropertyBinding}.
6.30 + *
6.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
6.32 + */
6.33 +public interface SetAndGet<Data> {
6.34 + public void setValue(Data data, Object value);
6.35 + public Object getValue(Data data);
6.36 +}
7.1 --- a/json/src/main/java/org/apidesign/html/json/impl/WrapperObject.java Mon Apr 22 16:14:52 2013 +0200
7.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/WrapperObject.java Mon Apr 22 21:12:16 2013 +0200
7.3 @@ -37,6 +37,13 @@
7.4
7.5
7.6 public static Object find(Object model) {
7.7 + if (model == null) {
7.8 + return null;
7.9 + }
7.10 + if (model instanceof JSONList) {
7.11 + return ((JSONList<?>)model).koData();
7.12 + }
7.13 +
7.14 WrapperObject ro = new WrapperObject();
7.15 model.equals(ro);
7.16 return ro.ko;
8.1 --- a/json/src/main/java/org/apidesign/html/json/spi/PropertyBinding.java Mon Apr 22 16:14:52 2013 +0200
8.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/PropertyBinding.java Mon Apr 22 21:12:16 2013 +0200
8.3 @@ -22,6 +22,8 @@
8.4
8.5 import java.util.List;
8.6 import org.apidesign.html.json.impl.PropertyBindingAccessor;
8.7 +import org.apidesign.html.json.impl.PropertyBindingAccessor.PBData;
8.8 +import org.apidesign.html.json.impl.WrapperObject;
8.9
8.10 /** Describes a property when one is asked to
8.11 * bind it
8.12 @@ -29,17 +31,17 @@
8.13 * @author Jaroslav Tulach <jtulach@netbeans.org>
8.14 */
8.15 public final class PropertyBinding {
8.16 - private final List<String> params;
8.17 + private final PBData<?> data;
8.18
8.19 - private PropertyBinding(List<String> p) {
8.20 - this.params = p;
8.21 + private PropertyBinding(PBData<?> p) {
8.22 + this.data = p;
8.23 }
8.24
8.25 static {
8.26 new PropertyBindingAccessor() {
8.27 @Override
8.28 - protected PropertyBinding newBinding(List<String> params) {
8.29 - return new PropertyBinding(params);
8.30 + protected <M> PropertyBinding newBinding(PBData<M> d) {
8.31 + return new PropertyBinding(d);
8.32 }
8.33
8.34 @Override
8.35 @@ -50,27 +52,20 @@
8.36 }
8.37
8.38 public String getPropertyName() {
8.39 - return params.get(0);
8.40 + return data.name;
8.41 + }
8.42 +
8.43 + public void setValue(Object v) {
8.44 + data.setValue(v);
8.45 }
8.46
8.47 - public String getGetterName() {
8.48 - final String g = params.get(1);
8.49 - int end = g.indexOf("__");
8.50 - if (end == -1) {
8.51 - end = g.length();
8.52 - }
8.53 - return g.substring(0, end);
8.54 + public Object getValue() {
8.55 + Object v = data.getValue();
8.56 + Object r = WrapperObject.find(v);
8.57 + return r == null ? v : r;
8.58 }
8.59 -
8.60 - public String getSetterName() {
8.61 - final String g = params.get(2);
8.62 - if (g == null) {
8.63 - return null;
8.64 - }
8.65 - int end = g.indexOf("__");
8.66 - if (end == -1) {
8.67 - end = g.length();
8.68 - }
8.69 - return g.substring(0, end);
8.70 +
8.71 + public boolean isReadOnly() {
8.72 + return data.isReadOnly();
8.73 }
8.74 }
9.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Technology.java Mon Apr 22 16:14:52 2013 +0200
9.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Technology.java Mon Apr 22 21:12:16 2013 +0200
9.3 @@ -61,4 +61,12 @@
9.4 * @param data the data to apply
9.5 */
9.6 public void applyBindings(Data data);
9.7 +
9.8 + /** Some technologies may require wrapping a Java array into a special
9.9 + * object. In such case they may return it from this method.
9.10 + *
9.11 + * @param arr original array
9.12 + * @return wrapped array
9.13 + */
9.14 + public Object wrapArray(Object[] arr);
9.15 }
10.1 --- a/json/src/test/java/net/java/html/json/MapModelTest.java Mon Apr 22 16:14:52 2013 +0200
10.2 +++ b/json/src/test/java/net/java/html/json/MapModelTest.java Mon Apr 22 21:12:16 2013 +0200
10.3 @@ -56,6 +56,7 @@
10.4 assertEquals(v.getClass(), One.class, "It is instance of One");
10.5 One o = (One)v;
10.6 assertEquals(o.changes, 1, "One change so far");
10.7 + assertFalse(o.pb.isReadOnly(), "Mutable property");
10.8
10.9 assertEquals(o.get(), "Jarda", "Value should be in the map");
10.10
10.11 @@ -65,6 +66,17 @@
10.12 assertEquals(o.changes, 2, "Snd change");
10.13 }
10.14
10.15 + @Test public void derivedProperty() throws Exception {
10.16 + Person p = new Person(c);
10.17 +
10.18 + Map m = (Map)WrapperObject.find(p);
10.19 + Object v = m.get("fullName");
10.20 + assertNotNull(v, "Value should be in the map");
10.21 + assertEquals(v.getClass(), One.class, "It is instance of One");
10.22 + One o = (One)v;
10.23 + assertTrue(o.pb.isReadOnly(), "Mutable property");
10.24 + }
10.25 +
10.26 @Test public void changeSex() {
10.27 Person p = new Person(c);
10.28 p.setFirstName("Trans");
10.29 @@ -79,30 +91,18 @@
10.30
10.31 private static final class One {
10.32 int changes;
10.33 - private final Method getter;
10.34 - private final Object model;
10.35 - private final Method setter;
10.36 + final PropertyBinding pb;
10.37
10.38 - One(Object m, String get, String set) throws NoSuchMethodException {
10.39 - this.model = m;
10.40 - if (get != null) {
10.41 - this.getter = m.getClass().getMethod(get);
10.42 - } else {
10.43 - this.getter = null;
10.44 - }
10.45 - if (set != null) {
10.46 - this.setter = m.getClass().getMethod(set, this.getter.getReturnType());
10.47 - } else {
10.48 - this.setter = null;
10.49 - }
10.50 + One(Object m, PropertyBinding pb) throws NoSuchMethodException {
10.51 + this.pb = pb;
10.52 }
10.53
10.54 Object get() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
10.55 - return getter.invoke(model);
10.56 + return pb.getValue();
10.57 }
10.58
10.59 void set(Object v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
10.60 - setter.invoke(model, v);
10.61 + pb.setValue(v);
10.62 }
10.63 }
10.64
10.65 @@ -124,7 +124,7 @@
10.66 @Override
10.67 public void bind(PropertyBinding b, Object model, Map<String, One> data) {
10.68 try {
10.69 - One o = new One(model, b.getGetterName(), b.getSetterName());
10.70 + One o = new One(model, b);
10.71 data.put(b.getPropertyName(), o);
10.72 } catch (NoSuchMethodException ex) {
10.73 throw new IllegalStateException(ex);
10.74 @@ -134,7 +134,7 @@
10.75 @Override
10.76 public void expose(FunctionBinding fb, Object model, Map<String, One> data) {
10.77 try {
10.78 - data.put(fb.getFunctionName(), new One(model, null, null));
10.79 + data.put(fb.getFunctionName(), new One(model, null));
10.80 } catch (NoSuchMethodException ex) {
10.81 throw new IllegalStateException(ex);
10.82 }
10.83 @@ -143,5 +143,10 @@
10.84 @Override
10.85 public void applyBindings(Map<String, One> data) {
10.86 }
10.87 +
10.88 + @Override
10.89 + public Object wrapArray(Object[] arr) {
10.90 + return arr;
10.91 + }
10.92 }
10.93 }
11.1 --- a/json/src/test/java/net/java/html/json/ModelTest.java Mon Apr 22 16:14:52 2013 +0200
11.2 +++ b/json/src/test/java/net/java/html/json/ModelTest.java Mon Apr 22 21:12:16 2013 +0200
11.3 @@ -256,5 +256,10 @@
11.4 @Override
11.5 public void applyBindings(Object data) {
11.6 }
11.7 +
11.8 + @Override
11.9 + public Object wrapArray(Object[] arr) {
11.10 + return arr;
11.11 + }
11.12 }
11.13 }
12.1 --- a/json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java Mon Apr 22 16:14:52 2013 +0200
12.2 +++ b/json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java Mon Apr 22 21:12:16 2013 +0200
12.3 @@ -20,6 +20,8 @@
12.4 */
12.5 package org.apidesign.html.json.impl;
12.6
12.7 +import java.util.HashMap;
12.8 +import java.util.Map;
12.9 import net.java.html.json.Context;
12.10 import net.java.html.json.People;
12.11 import net.java.html.json.Person;
12.12 @@ -29,6 +31,7 @@
12.13 import org.apidesign.html.json.spi.PropertyBinding;
12.14 import org.apidesign.html.json.spi.Technology;
12.15 import static org.testng.Assert.*;
12.16 +import org.testng.annotations.BeforeMethod;
12.17 import org.testng.annotations.Test;
12.18
12.19 /**
12.20 @@ -36,9 +39,15 @@
12.21 * @author Jaroslav Tulach <jtulach@netbeans.org>
12.22 */
12.23 public class JSONListTest implements Technology<Object> {
12.24 + private boolean replaceArray;
12.25 + private final Map<String,PropertyBinding> bindings = new HashMap<>();
12.26
12.27 public JSONListTest() {
12.28 }
12.29 +
12.30 + @BeforeMethod public void clear() {
12.31 + replaceArray = false;
12.32 + }
12.33
12.34 @Test public void testConvertorOnAnObject() {
12.35 Context c = ContextBuilder.create().withTechnology(this).build();
12.36 @@ -62,13 +71,45 @@
12.37
12.38 People people = new People(c);
12.39 people.getInfo().add(p);
12.40 -
12.41 - Object real = WrapperObject.find(people.getInfo());
12.42 +
12.43 + PropertyBinding pb = bindings.get("info");
12.44 + assertNotNull(pb, "Binding for info found");
12.45 +
12.46 + Object real = pb.getValue();
12.47 assertTrue(real instanceof Object[], "It is an array: " + real);
12.48 Object[] arr = (Object[])real;
12.49 assertEquals(arr.length, 1, "Size is one");
12.50 assertEquals(this, arr[0], "I am the right model");
12.51 }
12.52 +
12.53 + @Test public void testConvertorOnAnArrayWithWrapper() {
12.54 + this.replaceArray = true;
12.55 + Context c = ContextBuilder.create().withTechnology(this).build();
12.56 +
12.57 + Person p = new Person(c);
12.58 + p.setFirstName("1");
12.59 + p.setLastName("2");
12.60 + p.setSex(Sex.MALE);
12.61 +
12.62 + People people = new People(c);
12.63 + people.getInfo().add(p);
12.64 +
12.65 + Object real = WrapperObject.find(people.getInfo());
12.66 + assertEquals(real, this, "I am the model of the array");
12.67 + }
12.68 +
12.69 + @Test public void bindingsOnArray() {
12.70 + this.replaceArray = true;
12.71 + Context c = ContextBuilder.create().withTechnology(this).build();
12.72 +
12.73 + People p = new People(c);
12.74 + p.getAge().add(30);
12.75 +
12.76 + PropertyBinding pb = bindings.get("age");
12.77 + assertNotNull(pb, "There is a binding for age list");
12.78 +
12.79 + assertEquals(pb.getValue(), this, "I am the model of the array");
12.80 + }
12.81
12.82 @Override
12.83 public Object wrapModel(Object model) {
12.84 @@ -77,6 +118,7 @@
12.85
12.86 @Override
12.87 public void bind(PropertyBinding b, Object model, Object data) {
12.88 + bindings.put(b.getPropertyName(), b);
12.89 }
12.90
12.91 @Override
12.92 @@ -90,5 +132,10 @@
12.93 @Override
12.94 public void applyBindings(Object data) {
12.95 }
12.96 +
12.97 + @Override
12.98 + public Object wrapArray(Object[] arr) {
12.99 + return replaceArray ? this : arr;
12.100 + }
12.101
12.102 }