summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur <artur@vaadin.com>2017-04-03 09:57:48 +0300
committerTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2017-05-08 14:46:35 +0300
commit0a0ff366849ffc2d1e5732ec1547b1a06a6efffa (patch)
tree139f31c7bf6de2a32373cb243fbb583861bd5859
parent96da2b25be5b119195202b2283d3ac03043a94fb (diff)
downloadvaadin-framework-0a0ff366849ffc2d1e5732ec1547b1a06a6efffa.tar.gz
vaadin-framework-0a0ff366849ffc2d1e5732ec1547b1a06a6efffa.zip
Make bindInstanceFields not bind fields already bound using functions (#8998)
Fixes #8858
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java24
-rw-r--r--server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java23
2 files changed, 44 insertions, 3 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 64f1224754..56bb9a6656 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -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 {
diff --git a/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java b/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java
index 4b3bff2db6..d0cd75649d 100644
--- a/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java
@@ -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();