]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix nested bean property name (#10271)
authorschaerl <luki.schaer@hispeed.ch>
Wed, 22 Nov 2017 05:26:57 +0000 (06:26 +0100)
committercaalador <mikael.grankvist@gmail.com>
Wed, 22 Nov 2017 05:26:57 +0000 (07:26 +0200)
* Changed retrieval of names of nested properties (#10159)

The getName() function in NestedBeanPropertyDefinition will return only the top level name, which causes problems when adding a nested property that has the same name as a non-nested (e.g "value" & "sub.value")

This change should fix this behaviour by changing the return value of "getName()" of NestedBeanPropertyDefinition and introducing a function "getTopLevelName()" that only returns the last part of the full name for where it's needed

server/src/main/java/com/vaadin/data/BeanPropertySet.java
server/src/main/java/com/vaadin/data/BeanValidationBinder.java
server/src/main/java/com/vaadin/data/PropertyDefinition.java
server/src/test/java/com/vaadin/data/NestedPropertyNameTest.java [new file with mode: 0644]

index b302c837096e9d6719a17a93d322a7d042e85055..b877fdf93928865e7a2a80ee76882898ca581537 100644 (file)
@@ -170,37 +170,13 @@ public class BeanPropertySet<T> implements PropertySet<T> {
 
         private final PropertyDefinition<T, ?> parent;
 
-        private boolean useLongFormName = false;
-
         public NestedBeanPropertyDefinition(BeanPropertySet<T> propertySet,
                 PropertyDefinition<T, ?> parent,
                 PropertyDescriptor descriptor) {
             super(propertySet, parent.getType(), descriptor);
             this.parent = parent;
         }
-
-        /**
-         * Create nested property definition. Allows use of a long form name.
-         *
-         * @param propertySet
-         *            property set this property belongs to
-         * @param parent
-         *            parent property for this nested property
-         * @param descriptor
-         *            property descriptor
-         * @param useLongFormName
-         *            use format grandparent.parent.property for name if
-         *            {@code true}, needed when creating nested definitions
-         *            recursively like in findNestedDefinitions
-         * @since 8.2
-         */
-        public NestedBeanPropertyDefinition(BeanPropertySet<T> propertySet,
-                PropertyDefinition<T, ?> parent, PropertyDescriptor descriptor,
-                boolean useLongFormName) {
-            this(propertySet, parent, descriptor);
-            this.useLongFormName = useLongFormName;
-        }
-
+      
         @Override
         public ValueProvider<T, V> getGetter() {
             return bean -> {
@@ -229,6 +205,16 @@ public class BeanPropertySet<T> implements PropertySet<T> {
             return Optional.of(setter);
         }
 
+        @Override
+        public String getName() {
+            return parent.getName() + "." + super.getName();
+        }
+        
+        @Override
+        public String getTopLevelName() {
+            return super.getName();
+        }
+        
         private Object writeReplace() {
             /*
              * Instead of serializing this actual property definition, only
@@ -236,8 +222,9 @@ public class BeanPropertySet<T> implements PropertySet<T> {
              * property definition from the cache.
              */
             return new SerializedPropertyDefinition(getPropertySet().beanType,
-                    parent.getName() + "." + super.getName());
+                    getName());
         }
+        
 
         /**
          * Gets the parent property definition.
@@ -247,15 +234,6 @@ public class BeanPropertySet<T> implements PropertySet<T> {
         public PropertyDefinition<T, ?> getParent() {
             return parent;
         }
-
-        @Override
-        public String getName() {
-            if (useLongFormName) {
-                return parent.getName() + "." + super.getName();
-            }
-            return super.getName();
-        }
-
     }
 
     /**
@@ -394,7 +372,7 @@ public class BeanPropertySet<T> implements PropertySet<T> {
                     PropertyDescriptor subDescriptor = BeanUtil
                             .getPropertyDescriptor(beanType, name);
                     moreProps.put(name, new NestedBeanPropertyDefinition<>(this,
-                            parentProperty, subDescriptor, true));
+                            parentProperty, subDescriptor));
 
                 }
             } catch (IntrospectionException e) {
index c358d64ae65d133c6a8e2c18448090fc524e2b2e..630eef15b78249e759bbe69622c7331c6caa37dc 100644 (file)
@@ -96,7 +96,7 @@ public class BeanValidationBinder<BEAN> extends Binder<BEAN> {
             PropertyDefinition<BEAN, ?> definition) {
         Class<?> actualBeanType = findBeanType(beanType, definition);
         BeanValidator validator = new BeanValidator(actualBeanType,
-                definition.getName());
+                definition.getTopLevelName());
         if (requiredConfigurator != null) {
             configureRequired(binding, definition, validator);
         }
@@ -132,7 +132,7 @@ public class BeanValidationBinder<BEAN> extends Binder<BEAN> {
         BeanDescriptor descriptor = validator.getJavaxBeanValidator()
                 .getConstraintsForClass(propertyHolderType);
         PropertyDescriptor propertyDescriptor = descriptor
-                .getConstraintsForProperty(definition.getName());
+                .getConstraintsForProperty(definition.getTopLevelName());
         if (propertyDescriptor == null) {
             return;
         }
index 06252f8a7491da85016a319dc0023916dcc12c1c..68be55a48bfcca9cc7e57f13f6f7f8f46c6b7f0e 100644 (file)
@@ -64,12 +64,19 @@ public interface PropertyDefinition<T, V> extends Serializable {
     public Class<?> getPropertyHolderType();
 
     /**
-     * Gets the name of this property.
+     * Gets the full name of this property.
      *
      * @return the property name, not <code>null</code>
      */
     public String getName();
 
+    /**
+     * Gets the top level name of this property
+     * 
+     * @return the top level property name, not <code>null</code>
+     */
+    public default String getTopLevelName() {return getName();}
+    
     /**
      * Gets the human readable caption to show for this property.
      *
diff --git a/server/src/test/java/com/vaadin/data/NestedPropertyNameTest.java b/server/src/test/java/com/vaadin/data/NestedPropertyNameTest.java
new file mode 100644 (file)
index 0000000..070a3de
--- /dev/null
@@ -0,0 +1,48 @@
+package com.vaadin.data;
+
+import org.junit.Test;
+
+import com.vaadin.ui.Grid;
+
+public class NestedPropertyNameTest {
+    
+    @Test
+    public void nestedProperty_sameNameCanBeAdded() {
+        Grid<Person> grid = new Grid<>(Person.class);
+        grid.addColumn("street.name");
+    }
+
+    private class Person{
+        String name;
+        Street street;
+        
+        public String getName() {
+            return name;
+        }
+        
+        public void setName(String name) {
+            this.name = name;
+        }
+        
+        public Street getStreet() {
+            return street;
+        }
+        
+        public void setStreet(Street street) {
+            this.street = street;
+        }
+        
+    }
+    
+    private class Street{
+        String name;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+}