]> source.dussan.org Git - vaadin-framework.git/commitdiff
Backported null value support for NestedMethodProperty to 7.1 (#12884)
authorJarno Rantala <jarno.rantala@vaadin.com>
Wed, 11 Dec 2013 13:31:30 +0000 (15:31 +0200)
committerHenri Sara <hesara@vaadin.com>
Mon, 16 Dec 2013 13:07:52 +0000 (13:07 +0000)
Support for null values in NestedMethodProperty was already implemented in master branch (#11435)
This changeset includes changesets made for that.

Change-Id: I10696467f792e234326075bbcdd5aad487905a7e
Merge: no

server/src/com/vaadin/data/util/AbstractBeanContainer.java
server/src/com/vaadin/data/util/BeanItem.java
server/src/com/vaadin/data/util/NestedMethodProperty.java
server/tests/src/com/vaadin/data/util/BeanContainerTest.java
server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
server/tests/src/com/vaadin/data/util/NestedMethodPropertyTest.java
server/tests/src/com/vaadin/data/util/PropertyDescriptorTest.java

index 35403d641950f5402e91cde55fcf4c768044490a..b19cdd980c43040d58e9ff93612115611905b98c 100644 (file)
@@ -836,8 +836,9 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
      * Adds a nested container property for the container, e.g.
      * "manager.address.street".
      * 
-     * All intermediate getters must exist and must return non-null values when
-     * the property value is accessed.
+     * All intermediate getters must exist and should return non-null values
+     * when the property value is accessed. If an intermediate getter returns
+     * null, a null value will be returned.
      * 
      * @see NestedMethodProperty
      * 
@@ -854,8 +855,9 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
      * property to the container. The named property itself is removed from the
      * model as its subproperties are added.
      * 
-     * All intermediate getters must exist and must return non-null values when
-     * the property value is accessed.
+     * All intermediate getters must exist and should return non-null values
+     * when the property value is accessed. If an intermediate getter returns
+     * null, a null value will be returned.
      * 
      * @see NestedMethodProperty
      * @see #addNestedContainerProperty(String)
index fc51be8f36413c871b0e437c01917573c800a4e3..49f5f958988fae4e7d93e97e86aa02229f7b2cbd 100644 (file)
@@ -255,12 +255,13 @@ public class BeanItem<BT> extends PropertysetItem {
     }
 
     /**
-     * Adds a nested property to the item.
+     * Adds a nested property to the item. The property must not exist in the
+     * item already and must of form "field1.field2" where field2 is a field in
+     * the object referenced to by field1. If an intermediate property returns
+     * null, the property will return a null value
      * 
      * @param nestedPropertyId
-     *            property id to add. This property must not exist in the item
-     *            already and must of of form "field1.field2" where field2 is a
-     *            field in the object referenced to by field1
+     *            property id to add.
      */
     public void addNestedProperty(String nestedPropertyId) {
         addItemProperty(nestedPropertyId, new NestedMethodProperty<Object>(
index b62ecfbfc35579cfb0ba83fb7b6ae00fb086b21d..8fe3b9d4c53a4d75570de609c2c5c9a2b93cb7d5 100644 (file)
@@ -31,8 +31,9 @@ import com.vaadin.data.util.MethodProperty.MethodException;
  * The property is specified in the dotted notation, e.g. "address.street", and
  * can contain multiple levels of nesting.
  * 
- * When accessing the property value, all intermediate getters must return
- * non-null values.
+ * When accessing the property value, all intermediate getters must exist and
+ * should return non-null values when the property value is accessed. If an
+ * intermediate getter returns null, a null value will be returned.
  * 
  * @see MethodProperty
  * 
@@ -76,6 +77,8 @@ public class NestedMethodProperty<T> extends AbstractProperty<T> {
      * Constructs a nested method property for a given object instance. The
      * property name is a dot separated string pointing to a nested property,
      * e.g. "manager.address.street".
+     * <p>
+     * Calling getValue will return null if any intermediate getter returns null
      * 
      * @param instance
      *            top-level bean to which the property applies
@@ -199,6 +202,9 @@ public class NestedMethodProperty<T> extends AbstractProperty<T> {
             Object object = instance;
             for (Method m : getMethods) {
                 object = m.invoke(object);
+                if (object == null) {
+                    return null;
+                }
             }
             return (T) object;
         } catch (final Throwable e) {
index 9037e303a875937c81bae7d236ac742004c243c5..684ab5d6bc8d7c9ce3614895f765bcab3ffd37a4 100644 (file)
@@ -457,4 +457,17 @@ public class BeanContainerTest extends AbstractBeanContainerTest {
                         .getValue());
     }
 
+    public void testNestedContainerPropertyWithNullBean() {
+        BeanContainer<String, NestedMethodPropertyTest.Person> container = new BeanContainer<String, NestedMethodPropertyTest.Person>(
+                NestedMethodPropertyTest.Person.class);
+        container.setBeanIdProperty("name");
+
+        container.addBean(new NestedMethodPropertyTest.Person("John", null));
+        assertTrue(container
+                .addNestedContainerProperty("address.postalCodeObject"));
+        assertTrue(container.addNestedContainerProperty("address.street"));
+        assertNull(container.getContainerProperty("John", "address.street")
+                .getValue());
+    }
+
 }
index 6b88eb336d5385afae8af6d4bdb2cacd9f5b1bdd..767a9e2e4d598ea70fcc6b26c3eddb125a8fa2ad 100644 (file)
@@ -714,4 +714,16 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
                         .getValue());
     }
 
+    public void testNestedContainerPropertyWithNullBean() {
+        BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+                NestedMethodPropertyTest.Person.class);
+        NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+                "John", null);
+        assertNotNull(container.addBean(john));
+        assertTrue(container
+                .addNestedContainerProperty("address.postalCodeObject"));
+        assertTrue(container.addNestedContainerProperty("address.street"));
+        assertNull(container.getContainerProperty(john, "address.street")
+                .getValue());
+    }
 }
index 640ede87432fb30015087090b26cc3a3d1e40042..1133626df9aea5d17d0cd12f1c4bff1e81fc2b60 100644 (file)
@@ -7,9 +7,10 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 
-import junit.framework.Assert;
 import junit.framework.TestCase;
 
+import org.junit.Assert;
+
 public class NestedMethodPropertyTest extends TestCase {
 
     public static class Address implements Serializable {
@@ -248,29 +249,16 @@ public class NestedMethodPropertyTest extends TestCase {
                 vaadin, "manager.address.street");
 
         joonas.setAddress(null);
-        try {
-            streetProperty.getValue();
-            fail();
-        } catch (Exception e) {
-            // should get exception
-        }
+        assertNull(streetProperty.getValue());
 
         vaadin.setManager(null);
-        try {
-            managerNameProperty.getValue();
-            fail();
-        } catch (Exception e) {
-            // should get exception
-        }
-        try {
-            streetProperty.getValue();
-            fail();
-        } catch (Exception e) {
-            // should get exception
-        }
+        assertNull(managerNameProperty.getValue());
+        assertNull(streetProperty.getValue());
 
         vaadin.setManager(joonas);
         Assert.assertEquals("Joonas", managerNameProperty.getValue());
+        Assert.assertNull(streetProperty.getValue());
+
     }
 
     public void testMultiLevelNestedPropertySetValue() {
@@ -314,6 +302,20 @@ public class NestedMethodPropertyTest extends TestCase {
         Assert.assertEquals("Ruukinkatu 2-4", property2.getValue());
     }
 
+    public void testSerializationWithIntermediateNull() throws IOException,
+            ClassNotFoundException {
+        vaadin.setManager(null);
+        NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
+                vaadin, "manager.address.street");
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new ObjectOutputStream(baos).writeObject(streetProperty);
+        @SuppressWarnings("unchecked")
+        NestedMethodProperty<String> property2 = (NestedMethodProperty<String>) new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray())).readObject();
+
+        Assert.assertNull(property2.getValue());
+    }
+
     public void testIsReadOnly() {
         NestedMethodProperty<String> streetProperty = new NestedMethodProperty<String>(
                 vaadin, "manager.address.street");
index 14e70d76d45b2d2cdc723755ee0a0736f46f4a00..12ded84fe229e8aebe0e4f333d8bffa4be799ca8 100644 (file)
@@ -39,7 +39,8 @@ public class PropertyDescriptorTest extends TestCase {
         Assert.assertEquals("John", property.getValue());
     }
 
-    public void testNestedPropertyDescriptorSerialization() throws Exception {
+    public void testSimpleNestedPropertyDescriptorSerialization()
+            throws Exception {
         NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>(
                 "name", Person.class);
 
@@ -52,4 +53,19 @@ public class PropertyDescriptorTest extends TestCase {
         Property<?> property = pd2.createProperty(new Person("John", null));
         Assert.assertEquals("John", property.getValue());
     }
+
+    public void testNestedPropertyDescriptorSerialization() throws Exception {
+        NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>(
+                "address.street", Person.class);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new ObjectOutputStream(baos).writeObject(pd);
+        @SuppressWarnings("unchecked")
+        VaadinPropertyDescriptor<Person> pd2 = (VaadinPropertyDescriptor<Person>) new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray())).readObject();
+
+        Property<?> property = pd2.createProperty(new Person("John", null));
+        Assert.assertNull(property.getValue());
+    }
+
 }