aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTatu Lund <tatu@vaadin.com>2019-11-29 14:33:59 +0200
committerGitHub <noreply@github.com>2019-11-29 14:33:59 +0200
commitdda9b052604967b8d8cfec5c20d06e72f6f78d33 (patch)
tree55a257469a401f6f4f0564a6ac5367455529050a
parenta8bce6437bb3fb05fa52910cc80cde325b1e72a9 (diff)
downloadvaadin-framework-dda9b052604967b8d8cfec5c20d06e72f6f78d33.tar.gz
vaadin-framework-dda9b052604967b8d8cfec5c20d06e72f6f78d33.zip
Add method writeBeanAsDraft(bean) in Binder (#11833)
* Add method writeBeanAsDraft(bean) in Binder With current Binder implementation it is not easy to support Forms, which you want to save as draft, i.e. incomplete. For example there can be big text areas, that require time to fill, or lot of fields. Therefore it is needed to that form can be saved, e.g. to other bean in incomplete state when it is not yet passing validation and this other bean can be persisted to draft storage for further editing in the future. This method helps to achieve that easily. * Add test case for Binder.writeBeanAsDraft(bean) Bind a field with validator, set value that does not pass validator and save, assert that value was saved. * Updating test * Fixing logic flaw in test * Further improvement of the test case * Clarification of the JavaDoc * Fixing typo * JavaDoc language check * Fixing whitespace issue * Fixing whitespaces * Fixing whitespaces * Updating JavaDoc
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java34
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java33
2 files changed, 67 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 699185dea3..747983bfa5 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -1787,6 +1787,23 @@ public class Binder<BEAN> implements Serializable {
}
/**
+ * Writes successfully converted and validated changes from the bound fields
+ * to the bean even if there are other fields with non-validated changes.
+ *
+ * @see #writeBean(Object)
+ * @see #writeBeanIfValid(Object)
+ * @see #readBean(Object)
+ * @see #setBean(Object)
+ *
+ * @param bean
+ * the object to which to write the field values, not
+ * {@code null}
+ */
+ public void writeBeanAsDraft(BEAN bean) {
+ doWriteDraft(bean, new ArrayList<>(bindings));
+ }
+
+ /**
* Writes changes from the bound fields to the given bean if all validators
* (binding and bean level) pass.
* <p>
@@ -1874,6 +1891,23 @@ public class Binder<BEAN> implements Serializable {
}
/**
+ * Writes the successfully converted and validated field values into the
+ * given bean.
+ *
+ * @param bean
+ * the bean to write field values into
+ * @param bindings
+ * the set of bindings to write to the bean
+ */
+ @SuppressWarnings({ "unchecked" })
+ private void doWriteDraft(BEAN bean, Collection<Binding<BEAN, ?>> bindings) {
+ Objects.requireNonNull(bean, "bean cannot be null");
+
+ bindings.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding)
+ .writeFieldValue(bean));
+ }
+
+ /**
* Restores the state of the bean from the given values. This method is used
* together with {@link #getBeanState(Object, Collection)} to provide a way
* to revert changes in case the bean validation fails after save.
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index 3e27cc5f9b..401cc07017 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -270,6 +270,39 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
}
@Test
+ public void save_bound_beanAsDraft() {
+ Binder<Person> binder = new Binder<>();
+ binder.forField(nameField)
+ .withValidator((value,context) -> {
+ if (value.equals("Mike")) return ValidationResult.ok();
+ else return ValidationResult.error("value must be Mike");
+ })
+ .bind(Person::getFirstName, Person::setFirstName);
+ binder.forField(ageField)
+ .withConverter(new StringToIntegerConverter(""))
+ .bind(Person::getAge, Person::setAge);
+
+ Person person = new Person();
+
+ String fieldValue = "John";
+ nameField.setValue(fieldValue);
+
+ int age = 10;
+ ageField.setValue("10");
+
+ person.setFirstName("Mark");
+
+ binder.writeBeanAsDraft(person);
+
+ // name is not written to draft as validation / conversion
+ // does not pass
+ assertNotEquals(fieldValue, person.getFirstName());
+ // age is written to draft even if firstname validation
+ // fails
+ assertEquals(age, person.getAge());
+ }
+
+ @Test
public void load_bound_fieldValueIsUpdated() {
binder.bind(nameField, Person::getFirstName, Person::setFirstName);