diff options
author | Artur <artur@vaadin.com> | 2017-04-03 09:57:48 +0300 |
---|---|---|
committer | Teemu Suo-Anttila <tsuoanttila@users.noreply.github.com> | 2017-05-08 14:46:35 +0300 |
commit | 0a0ff366849ffc2d1e5732ec1547b1a06a6efffa (patch) | |
tree | 139f31c7bf6de2a32373cb243fbb583861bd5859 | |
parent | 96da2b25be5b119195202b2283d3ac03043a94fb (diff) | |
download | vaadin-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.java | 24 | ||||
-rw-r--r-- | server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java | 23 |
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(); |