Browse Source

Fix nested bean property name (#10271)

* 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
tags/8.3.0.alpha1
schaerl 6 years ago
parent
commit
3569a33239

+ 14
- 36
server/src/main/java/com/vaadin/data/BeanPropertySet.java View 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) {

+ 2
- 2
server/src/main/java/com/vaadin/data/BeanValidationBinder.java View 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;
}

+ 8
- 1
server/src/main/java/com/vaadin/data/PropertyDefinition.java View 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.
*

+ 48
- 0
server/src/test/java/com/vaadin/data/NestedPropertyNameTest.java View File

@@ -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;
}
}
}

Loading…
Cancel
Save