]> source.dussan.org Git - vaadin-framework.git/commitdiff
Make bindInstanceFields not bind fields already bound using functions (#8998)
authorArtur <artur@vaadin.com>
Mon, 3 Apr 2017 06:57:48 +0000 (09:57 +0300)
committerAleksi Hietanen <aleksi@vaadin.com>
Mon, 3 Apr 2017 06:57:48 +0000 (09:57 +0300)
Fixes #8858

server/src/main/java/com/vaadin/data/Binder.java
server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java

index 64f1224754af2712bbf22dfa404f9c91ce528f40..56bb9a6656c349fea5410e5ee5b5d6e70cbfe598 100644 (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 {
index 4b3bff2db6c1646f3899ed9633286130f585d39d..d0cd75649d55cada3776309e2893cf02eb7ad26e 100644 (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();