Browse Source

Make bindInstanceFields not bind fields already bound using functions (#8998)

Fixes #8858
tags/8.1.0.alpha4
Artur 7 years ago
parent
commit
eef6e0bb50

+ 21
- 3
server/src/main/java/com/vaadin/data/Binder.java View File

@@ -2128,6 +2128,8 @@ public class Binder<BEAN> implements Serializable {
.stream()
.filter(memberField -> HasValue.class
.isAssignableFrom(memberField.getType()))
.filter(memberField -> !isFieldBound(memberField,
objectWithMemberFields))
.map(memberField -> handleProperty(memberField,
objectWithMemberFields,
(property, type) -> bindProperty(objectWithMemberFields,
@@ -2139,17 +2141,33 @@ public class Binder<BEAN> implements Serializable {
}
}

private boolean isFieldBound(Field memberField,
Object objectWithMemberFields) {
try {
HasValue field = (HasValue) getMemberFieldValue(memberField,
objectWithMemberFields);
return bindings.stream()
.anyMatch(binding -> binding.getField() == field);
} catch (Exception e) {
return false;
}
}

private int accumulate(int count, boolean value) {
return value ? count + 1 : count;
}

@SuppressWarnings("unchecked")
private BindingBuilder<BEAN, ?> getIncompleteMemberFieldBinding(
Field memberField, Object objectWithMemberFields) {
return incompleteMemberFieldBindings
.get(getMemberFieldValue(memberField, objectWithMemberFields));
}

private Object getMemberFieldValue(Field memberField,
Object objectWithMemberFields) {
memberField.setAccessible(true);
try {
return incompleteMemberFieldBindings
.get(memberField.get(objectWithMemberFields));
return memberField.get(objectWithMemberFields);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
} finally {

+ 23
- 0
server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java View File

@@ -73,6 +73,11 @@ public class BinderInstanceFieldTest {
private IntegerTextField firstName;
}

public static class BindOneFieldRequiresConverter extends FormLayout {
private TextField firstName;
private TextField age;
}

public static class BindGeneric<T> extends FormLayout {
private CustomField<T> firstName;
}
@@ -391,6 +396,24 @@ public class BinderInstanceFieldTest {
Assert.assertFalse(binder.validate().isOk());
}

@Test
public void bindInstanceFields_preconfiguredFieldNotBoundToPropertyPreserved() {
BindOneFieldRequiresConverter form = new BindOneFieldRequiresConverter();
form.age = new TextField();
form.firstName = new TextField();
Binder<Person> binder = new Binder<>(Person.class);
binder.forField(form.age)
.withConverter(str -> Integer.parseInt(str) / 2,
integer -> Integer.toString(integer * 2))
.bind(Person::getAge, Person::setAge);
binder.bindInstanceFields(form);
Person person = new Person();
person.setFirstName("first");
person.setAge(45);
binder.setBean(person);
Assert.assertEquals("90", form.age.getValue());
}

@Test(expected = IllegalStateException.class)
public void bindInstanceFields_explicitelyBoundFieldAndNotBoundField_throwNoBoundFields() {
BindOnlyOneField form = new BindOnlyOneField();

Loading…
Cancel
Save