summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2017-09-19 16:09:56 +0300
committerGitHub <noreply@github.com>2017-09-19 16:09:56 +0300
commit1f59cb51af097b8e314fde6d7c3a25821d13868d (patch)
treed0541765efd5039adce7119b8261232ef9977a8c /server
parent159d21f55f0ef24fc2a1a31661be3227988a41ee (diff)
downloadvaadin-framework-1f59cb51af097b8e314fde6d7c3a25821d13868d.tar.gz
vaadin-framework-1f59cb51af097b8e314fde6d7c3a25821d13868d.zip
Add API for running BindingValidationStatusHandlers (#9966)
This patch adds an API to Binding for accessing the validation status handlers from a custom BinderValidationStatusHandler.
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java19
-rw-r--r--server/src/main/java/com/vaadin/data/BinderValidationStatus.java35
-rw-r--r--server/src/main/java/com/vaadin/data/BinderValidationStatusHandler.java6
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java63
4 files changed, 111 insertions, 12 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 0582182d16..75d210eb61 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -127,6 +127,15 @@ public class Binder<BEAN> implements Serializable {
public BindingValidationStatus<TARGET> validate();
/**
+ * Gets the validation status handler for this Binding.
+ *
+ * @return the validation status handler for this binding
+ *
+ * @since 8.2
+ */
+ public BindingValidationStatusHandler getValidationStatusHandler();
+
+ /**
* Unbinds the binding from its respective {@code Binder}
* Removes any {@code ValueChangeListener} {@code Registration} from
* associated {@code HasValue}
@@ -134,7 +143,6 @@ public class Binder<BEAN> implements Serializable {
* @since 8.2
*/
public void unbind();
-
}
/**
@@ -990,8 +998,9 @@ public class Binder<BEAN> implements Serializable {
return binder;
}
- private void notifyStatusHandler(BindingValidationStatus<?> status) {
- statusHandler.statusChange(status);
+ @Override
+ public BindingValidationStatusHandler getValidationStatusHandler() {
+ return statusHandler;
}
}
@@ -1948,9 +1957,7 @@ public class Binder<BEAN> implements Serializable {
protected void handleBinderValidationStatus(
BinderValidationStatus<BEAN> binderStatus) {
// let field events go to binding status handlers
- binderStatus.getFieldValidationStatuses()
- .forEach(status -> ((BindingImpl<?, ?, ?>) status.getBinding())
- .notifyStatusHandler(status));
+ binderStatus.notifyBindingValidationStatusHandlers();
// show first possible error or OK status in the label if set
if (getStatusLabel().isPresent()) {
diff --git a/server/src/main/java/com/vaadin/data/BinderValidationStatus.java b/server/src/main/java/com/vaadin/data/BinderValidationStatus.java
index 90600f1800..151a4b549b 100644
--- a/server/src/main/java/com/vaadin/data/BinderValidationStatus.java
+++ b/server/src/main/java/com/vaadin/data/BinderValidationStatus.java
@@ -23,6 +23,7 @@ import java.util.Objects;
import java.util.stream.Collectors;
import com.vaadin.data.Binder.BindingBuilder;
+import com.vaadin.server.SerializablePredicate;
/**
* Binder validation status change. Represents the outcome of binder level
@@ -33,8 +34,8 @@ import com.vaadin.data.Binder.BindingBuilder;
* Note: if there are any field level validation errors, the bean level
* validation is not run.
* <p>
- * Use {@link Binder#setValidationStatusHandler(BinderValidationStatusHandler)} to handle
- * form level validation status changes.
+ * Use {@link Binder#setValidationStatusHandler(BinderValidationStatusHandler)}
+ * to handle form level validation status changes.
*
* @author Vaadin Ltd
*
@@ -188,4 +189,34 @@ public class BinderValidationStatus<BEAN> implements Serializable {
return binderStatuses.stream().filter(ValidationResult::isError)
.collect(Collectors.toList());
}
+
+ /**
+ * Notifies all validation status handlers in bindings.
+ *
+ * @see #notifyBindingValidationStatusHandlers(SerializablePredicate)
+ *
+ * @since 8.2
+ */
+ public void notifyBindingValidationStatusHandlers() {
+ notifyBindingValidationStatusHandlers(t -> true);
+ }
+
+ /**
+ * Notifies validation status handlers for bindings that pass given filter.
+ * The filter should return {@code true} for each
+ * {@link BindingValidationStatus} that should be delegated to the status
+ * handler in the binding.
+ *
+ * @see #notifyBindingValidationStatusHandlers()
+ *
+ * @param filter
+ * the filter to select bindings to run status handling for
+ *
+ * @since 8.2
+ */
+ public void notifyBindingValidationStatusHandlers(
+ SerializablePredicate<BindingValidationStatus<?>> filter) {
+ bindingStatuses.stream().filter(filter).forEach(s -> s.getBinding()
+ .getValidationStatusHandler().statusChange(s));
+ }
}
diff --git a/server/src/main/java/com/vaadin/data/BinderValidationStatusHandler.java b/server/src/main/java/com/vaadin/data/BinderValidationStatusHandler.java
index 9f144ac430..3bfa9c863a 100644
--- a/server/src/main/java/com/vaadin/data/BinderValidationStatusHandler.java
+++ b/server/src/main/java/com/vaadin/data/BinderValidationStatusHandler.java
@@ -21,8 +21,9 @@ import com.vaadin.ui.AbstractComponent;
/**
* Handler for {@link BinderValidationStatus} changes.
* <p>
- * {@link Binder#setValidationStatusHandler(BinderValidationStatusHandler) Register} an
- * instance of this class to be able to customize validation status handling.
+ * {@link Binder#setValidationStatusHandler(BinderValidationStatusHandler)
+ * Register} an instance of this class to be able to customize validation status
+ * handling.
* <p>
* The default handler will show
* {@link AbstractComponent#setComponentError(com.vaadin.server.ErrorMessage) an
@@ -53,5 +54,4 @@ public interface BinderValidationStatusHandler<BEAN>
* the changed status
*/
void statusChange(BinderValidationStatus<BEAN> statusChange);
-
}
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index 99317745d5..4d3fe2db9b 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -749,6 +749,68 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
String.valueOf(item.getAge()), ageField.getValue());
}
+ static class MyBindingHandler implements BindingValidationStatusHandler {
+
+ boolean expectingError = false;
+ int callCount = 0;
+
+ @Override
+ public void statusChange(BindingValidationStatus<?> statusChange) {
+ ++callCount;
+ if (expectingError) {
+ Assert.assertTrue("Expecting error", statusChange.isError());
+ } else {
+ Assert.assertFalse("Unexpected error", statusChange.isError());
+ }
+ }
+ }
+
+ @Test
+ public void execute_binding_status_handler_from_binder_status_handler() {
+ MyBindingHandler bindingHandler = new MyBindingHandler();
+ binder.forField(nameField)
+ .withValidator(t -> !t.isEmpty(), "No empty values.")
+ .withValidationStatusHandler(bindingHandler)
+ .bind(Person::getFirstName, Person::setFirstName);
+
+ String ageError = "CONVERSIONERROR";
+ binder.forField(ageField)
+ .withConverter(new StringToIntegerConverter(ageError))
+ .bind(Person::getAge, Person::setAge);
+
+ binder.setValidationStatusHandler(status -> {
+ status.notifyBindingValidationStatusHandlers();
+ });
+
+ String initialName = item.getFirstName();
+ int initialAge = item.getAge();
+
+ binder.setBean(item);
+
+ // Test specific error handling.
+ bindingHandler.expectingError = true;
+ nameField.setValue("");
+
+ // Test default error handling.
+ ageField.setValue("foo");
+ Assert.assertTrue("Component error does not contain error message",
+ ageField.getComponentError().getFormattedHtmlMessage()
+ .contains(ageError));
+
+ // Restore values and test no errors.
+ ageField.setValue(String.valueOf(initialAge));
+ Assert.assertNull("There should be no component error",
+ ageField.getComponentError());
+
+ bindingHandler.expectingError = false;
+ nameField.setValue(initialName);
+
+ // Assert that the handler was called.
+ Assert.assertEquals(
+ "Unexpected callCount to binding validation status handler", 4,
+ bindingHandler.callCount);
+ }
+
@Test
public void removed_binding_not_updates_value() {
Binding<Person, Integer> binding = binder.forField(ageField)
@@ -766,6 +828,5 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
Assert.assertEquals("Binding still affects bean even after unbind",
ageBeforeUnbind, String.valueOf(item.getAge()));
-
}
}