From: Artur Date: Mon, 3 Apr 2017 06:57:48 +0000 (+0300) Subject: Make bindInstanceFields not bind fields already bound using functions (#8998) X-Git-Tag: 8.1.0.alpha4~10 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=eef6e0bb507546619abb01ca1b58c0a442940565;p=vaadin-framework.git Make bindInstanceFields not bind fields already bound using functions (#8998) Fixes #8858 --- 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 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 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 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 extends FormLayout { private CustomField 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 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();