Skip to content

Commit

Permalink
Add methods to control validation
Browse files Browse the repository at this point in the history
- 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: #5030
  • Loading branch information
TatuLund authored Apr 17, 2020
1 parent 9ccbc6c commit 4da5f80
Showing 1 changed file with 105 additions and 7 deletions.
112 changes: 105 additions & 7 deletions flow-data/src/main/java/com/vaadin/flow/data/binder/Binder.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,21 @@ default BindingValidationStatus<TARGET> validate() {
* {@code true} otherwise (default)
*/
public boolean isAsRequiredEnabled();

/**
* Define whether validators are disabled or enabled for this
* specific binding.
*
* @param validatorsDisabled A boolean value
*/
public void setValidatorsDisabled(boolean validatorsDisabled);

/**
* Returns if validators are currently disabled or not
*
* @return A boolean value
*/
public boolean isValidatorsDisabled();
}

/**
Expand Down Expand Up @@ -754,6 +769,7 @@ protected static class BindingBuilderImpl<BEAN, FIELDVALUE, TARGET>
private final HasValue<?, FIELDVALUE> field;
private BindingValidationStatusHandler statusHandler;
private boolean isStatusHandlerChanged;
private Binding<BEAN, TARGET> binding;

private boolean bound;

Expand Down Expand Up @@ -815,6 +831,7 @@ public Binding<BEAN, TARGET> bind(ValueProvider<BEAN, TARGET> getter,
if (getBinder().incompleteBindings != null) {
getBinder().incompleteBindings.remove(getField());
}
this.binding = binding;

return binding;
}
Expand Down Expand Up @@ -849,6 +866,7 @@ public Binding<BEAN, TARGET> bind(String propertyName) {
Binding binding = ((BindingBuilder) finalBinding).bind(getter,
setter);
getBinder().boundProperties.put(propertyName, binding);
this.binding = binding;
return binding;
} finally {
if (getBinder().incompleteMemberFieldBindings != null) {
Expand All @@ -872,8 +890,17 @@ public BindingBuilder<BEAN, TARGET> withValidator(
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;
}

Expand Down Expand Up @@ -1026,6 +1053,8 @@ protected static class BindingImpl<BEAN, FIELDVALUE, TARGET>

private final boolean asRequiredSet;

private boolean validatorsDisabled = false;

public BindingImpl(BindingBuilderImpl<BEAN, FIELDVALUE, TARGET> builder,
ValueProvider<BEAN, TARGET> getter,
Setter<BEAN, TARGET> setter) {
Expand Down Expand Up @@ -1306,6 +1335,16 @@ public void setAsRequiredEnabled(boolean asRequiredEnabled) {
public boolean isAsRequiredEnabled() {
return field.isRequiredIndicatorVisible();
}

@Override
public void setValidatorsDisabled(boolean validatorsDisabled) {
this.validatorsDisabled = validatorsDisabled;
}

@Override
public boolean isValidatorsDisabled() {
return validatorsDisabled;
}
}

/**
Expand Down Expand Up @@ -1412,6 +1451,8 @@ void setIdentity() {

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
Expand Down Expand Up @@ -1831,7 +1872,27 @@ public void writeBean(BEAN bean) throws ValidationException {
* {@code null}
*/
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
*/
public void writeBeanAsDraft(BEAN bean, boolean forced) {
doWriteDraft(bean, new ArrayList<>(bindings),true);
}

/**
Expand Down Expand Up @@ -1929,14 +1990,24 @@ private BinderValidationStatus<BEAN> doWriteIfValid(BEAN bean,
* 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);
}
}

/**
Expand Down Expand Up @@ -1998,7 +2069,14 @@ protected void restoreBeanState(BEAN bean,
*/
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;
}

Expand Down Expand Up @@ -2986,4 +3064,24 @@ public void removeBinding(String propertyName) {
Optional.ofNullable(boundProperties.get(propertyName))
.ifPresent(Binding::unbind);
}

/**
* Control whether validators including bean level validators are
* disabled or enabled globally for this Binder.
*
* @param validatorsDisabled Boolean value
*/
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
*/
public boolean isValidatorsDisabled() {
return validatorsDisabled;
}
}

0 comments on commit 4da5f80

Please sign in to comment.