aboutsummaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorTatu Lund <tatu@vaadin.com>2020-04-21 11:38:19 +0300
committerGitHub <noreply@github.com>2020-04-21 11:38:19 +0300
commitd35bd4cde4ae0074d68c7e1f10f2be8757403cc7 (patch)
tree3b9765e462e939150715b9c037d4297a9ed911f2 /server/src
parent565eeb5b5a85e6ce6310e0098977f853869f01ba (diff)
downloadvaadin-framework-d35bd4cde4ae0074d68c7e1f10f2be8757403cc7.tar.gz
vaadin-framework-d35bd4cde4ae0074d68c7e1f10f2be8757403cc7.zip
Add methods to control validation (#11945)
- Enable / disable all validators on Binder level - Enable / disable validators on Binding level - add writeBeanAsDraft(bean,boolean) for writing draft bean with validators disabled Fixes https://github.com/vaadin/framework/issues/10709 Co-authored-by: Zhe Sun <31067185+ZheSun88@users.noreply.github.com>
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java122
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java79
2 files changed, 191 insertions, 10 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 07dbf20ce4..c64602edae 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -254,6 +254,25 @@ public class Binder<BEAN> implements Serializable {
* @since 8.10
*/
public boolean isAsRequiredEnabled();
+
+ /**
+ * Define whether validators are disabled or enabled for this
+ * specific binding.
+ *
+ * @param validatorsDisabled A boolean value
+ *
+ * @since
+ */
+ public void setValidatorsDisabled(boolean validatorsDisabled);
+
+ /**
+ * Returns if validators are currently disabled or not
+ *
+ * @return A boolean value
+ *
+ * @since
+ */
+ public boolean isValidatorsDisabled();
}
/**
@@ -800,6 +819,7 @@ public class Binder<BEAN> implements Serializable {
private final HasValue<FIELDVALUE> field;
private BindingValidationStatusHandler statusHandler;
private boolean isStatusHandlerChanged;
+ private Binding<BEAN, TARGET> binding;
private boolean bound;
@@ -855,6 +875,7 @@ public class Binder<BEAN> implements Serializable {
bound = true;
getBinder().incompleteBindings.remove(getField());
+ this.binding = binding;
return binding;
}
@@ -889,6 +910,7 @@ public class Binder<BEAN> implements Serializable {
Binding binding = ((BindingBuilder) finalBinding).bind(getter,
setter);
getBinder().boundProperties.put(propertyName, binding);
+ this.binding = binding;
return binding;
} finally {
getBinder().incompleteMemberFieldBindings.remove(getField());
@@ -909,8 +931,17 @@ public class Binder<BEAN> implements Serializable {
checkUnbound();
Objects.requireNonNull(validator, "validator cannot be null");
+ Validator<? super TARGET> wrappedValidator = ((value, context) -> {
+ if (getBinder().isValidatorsDisabled() ||
+ (binding != null && binding.isValidatorsDisabled())) {
+ return ValidationResult.ok();
+ } else {
+ return validator.apply(value, context);
+ }
+ });
+
converterValidatorChain = ((Converter<FIELDVALUE, TARGET>) converterValidatorChain)
- .chain(new ValidatorAsConverter<>(validator));
+ .chain(new ValidatorAsConverter<>(wrappedValidator));
return this;
}
@@ -1059,6 +1090,8 @@ public class Binder<BEAN> implements Serializable {
private boolean asRequiredSet;
+ private boolean validatorsDisabled = false;
+
public BindingImpl(BindingBuilderImpl<BEAN, FIELDVALUE, TARGET> builder,
ValueProvider<BEAN, TARGET> getter,
Setter<BEAN, TARGET> setter) {
@@ -1341,6 +1374,16 @@ public class Binder<BEAN> implements Serializable {
public boolean isAsRequiredEnabled() {
return field.isRequiredIndicatorVisible();
}
+
+ @Override
+ public void setValidatorsDisabled(boolean validatorsDisabled) {
+ this.validatorsDisabled = validatorsDisabled;
+ }
+
+ @Override
+ public boolean isValidatorsDisabled() {
+ return validatorsDisabled;
+ }
}
/**
@@ -1446,6 +1489,8 @@ public class Binder<BEAN> implements Serializable {
private Set<Binding<BEAN, ?>> changedBindings = new LinkedHashSet<>();
+ private boolean validatorsDisabled = false;
+
/**
* Creates a binder using a custom {@link PropertySet} implementation for
* finding and resolving property names for
@@ -1862,7 +1907,28 @@ public class Binder<BEAN> implements Serializable {
* @since 8.10
*/
public void writeBeanAsDraft(BEAN bean) {
- doWriteDraft(bean, new ArrayList<>(bindings));
+ doWriteDraft(bean, new ArrayList<>(bindings),false);
+ }
+
+ /**
+ * Writes successfully converted changes from the bound fields bypassing
+ * all the Validation, or all fields passing conversion if forced = true.
+ * If the conversion fails, the value written to the bean will be null.
+ *
+ * @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}
+ * @param forced
+ * disable all Validators during write
+ * @since
+ */
+ public void writeBeanAsDraft(BEAN bean, boolean forced) {
+ doWriteDraft(bean, new ArrayList<>(bindings),forced);
}
/**
@@ -1960,14 +2026,23 @@ public class Binder<BEAN> implements Serializable {
* the bean to write field values into
* @param bindings
* the set of bindings to write to the bean
+ * @param forced
+ * disable validators during write if true
*/
- @SuppressWarnings({ "unchecked" })
- private void doWriteDraft(BEAN bean,
- Collection<Binding<BEAN, ?>> bindings) {
+ private void doWriteDraft(BEAN bean,
+ Collection<Binding<BEAN, ?>> bindings, boolean forced) {
Objects.requireNonNull(bean, "bean cannot be null");
- bindings.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding)
- .writeFieldValue(bean));
+ if (!forced) {
+ bindings.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding)
+ .writeFieldValue(bean));
+ } else {
+ boolean isDisabled = isValidatorsDisabled();
+ setValidatorsDisabled(true);
+ bindings.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding)
+ .writeFieldValue(bean));
+ setValidatorsDisabled(isDisabled);
+ }
}
/**
@@ -2037,7 +2112,14 @@ public class Binder<BEAN> implements Serializable {
*/
public Binder<BEAN> withValidator(Validator<? super BEAN> validator) {
Objects.requireNonNull(validator, "validator cannot be null");
- validators.add(validator);
+ Validator<? super BEAN> wrappedValidator = ((value, context) -> {
+ if (isValidatorsDisabled()) {
+ return ValidationResult.ok();
+ } else {
+ return validator.apply(value, context);
+ }
+ });
+ validators.add(wrappedValidator);
return this;
}
@@ -3035,6 +3117,30 @@ public class Binder<BEAN> implements Serializable {
.ifPresent(Binding::unbind);
}
+ /**
+ * Control whether validators including bean level validators are
+ * disabled or enabled globally for this Binder.
+ *
+ * @param validatorsDisabled Boolean value
+ *
+ * @since
+ */
+ public void setValidatorsDisabled(boolean validatorsDisabled) {
+ this.validatorsDisabled = validatorsDisabled;
+ }
+
+ /**
+ * Returns if the validators including bean level validators
+ * are disabled or enabled for this Binder.
+ *
+ * @return Boolean value
+ *
+ * @since
+ */
+ public boolean isValidatorsDisabled() {
+ return validatorsDisabled;
+ }
+
private static final Logger getLogger() {
return Logger.getLogger(Binder.class.getName());
}
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index b3fe5a8194..b64dee9c6b 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -274,8 +274,11 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
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");
+ if (value.equals("Mike")) {
+ return ValidationResult.ok();
+ } else {
+ return ValidationResult.error("value must be Mike");
+ }
})
.bind(Person::getFirstName, Person::setFirstName);
binder.forField(ageField)
@@ -300,6 +303,78 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
// age is written to draft even if firstname validation
// fails
assertEquals(age, person.getAge());
+
+ binder.writeBeanAsDraft(person,true);
+ // name is now written despite validation as write was forced
+ assertEquals(fieldValue, person.getFirstName());
+ }
+
+ @Test
+ public void save_bound_bean_disable_validation_binding() throws ValidationException {
+ Binder<Person> binder = new Binder<>();
+ Binding<Person, String> nameBinding = 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");
+
+ nameBinding.setValidatorsDisabled(true);
+ binder.writeBean(person);
+
+ // name is now written as validation was disabled
+ assertEquals(fieldValue, person.getFirstName());
+ assertEquals(age, person.getAge());
+ }
+
+ @Test
+ public void save_bound_bean_disable_validation_binder() throws ValidationException {
+ 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.setValidatorsDisabled(true);
+ binder.writeBean(person);
+
+ // name is now written as validation was disabled
+ assertEquals(fieldValue, person.getFirstName());
+ assertEquals(age, person.getAge());
}
@Test