argos/dmp-backend/core/src/main/java/eu/eudat/commons/validation/AbstractValidator.java

120 lines
5.0 KiB
Java

package eu.eudat.commons.validation;
import eu.eudat.commons.validation.specification.*;
import eu.eudat.convention.ConventionService;
import eu.eudat.errorcode.ErrorThesaurusProperties;
import gr.cite.tools.exception.MyValidationException;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ValidationUtils;
import java.text.MessageFormat;
import java.util.*;
public abstract class AbstractValidator<T> implements Validator {
private BeanPropertyBindingResult bindingResult;
protected abstract Class<T> modelClass();
protected abstract List<Specification> specifications(T item);
@Override
public boolean supports(Class clazz) {
return clazz == null ? false : this.modelClass().equals(clazz);
}
@Override
public void validate(Object obj, Errors e) {
if (obj == null) return;
T item = this.modelClass().cast(obj);
List<Specification> specifications = this.specifications(item);
if (specifications == null) return;;
List<PropertySpecification> propertySpecifications = specifications.stream().filter(x-> x instanceof PropertySpecification).map(x-> (PropertySpecification)x).toList();
for (PropertySpecification propertySpecification : propertySpecifications){
if ((propertySpecification.getPrecondition() == null || propertySpecification.getPrecondition().get()) &&
(propertySpecification.getSpecification() == null || !propertySpecification.getSpecification().get())
){
e.rejectValue(propertySpecification.getErrorKey(), propertySpecification.getErrorCode(), propertySpecification.getErrorMessage());
}
}
List<NavigationReferenceSpecification> navigationReferenceSpecifications = specifications.stream().filter(x-> x instanceof NavigationReferenceSpecification).map(x-> (NavigationReferenceSpecification)x).toList();
for (NavigationReferenceSpecification navigationReferenceSpecification : navigationReferenceSpecifications){
if (navigationReferenceSpecification.getReference() != null && (navigationReferenceSpecification.getPrecondition() == null || navigationReferenceSpecification.getPrecondition().get())){
try {
e.pushNestedPath(navigationReferenceSpecification.getKey());
ValidationUtils.invokeValidator(navigationReferenceSpecification.getValidator().get(), navigationReferenceSpecification.getReference(), e);
} finally {
e.popNestedPath();
}
}
}
List<NavigationDetailsSpecification> navigationDetailsSpecifications = specifications.stream().filter(x-> x instanceof NavigationDetailsSpecification).map(x-> (NavigationDetailsSpecification)x).toList();
for (NavigationDetailsSpecification navigationDetailsSpecification : navigationDetailsSpecifications){
if (navigationDetailsSpecification.getDetails() != null && (navigationDetailsSpecification.getPrecondition() == null || navigationDetailsSpecification.getPrecondition().get())){
for (int i = 0; i < navigationDetailsSpecification.getDetails().size(); i++) {
try {
e.pushNestedPath(MessageFormat.format("{0}[{1}]", navigationDetailsSpecification.getKey(), i));
ValidationUtils.invokeValidator(navigationDetailsSpecification.getValidator().get(), navigationDetailsSpecification.getDetails().get(i), e);
} finally {
e.popNestedPath();
}
}
}
}
}
@Override
public void validate(Object target){
this.bindingResult = new BeanPropertyBindingResult(target, target.getClass().getName());
if (target instanceof Collection<?>) {
((Collection<?>) target).forEach(x -> this.validate(x, this.bindingResult));
} else {
this.validate(target, this.bindingResult);
}
}
@Override
public ValidationResult result() {
ValidationResult validationResult = new ValidationResult();
if (this.bindingResult != null && bindingResult.hasErrors()){
for (FieldError fieldError : bindingResult.getFieldErrors()){
validationResult.add(new ValidationFailure(fieldError.getField(), fieldError.getDefaultMessage()));
}
}
return validationResult;
}
protected List<Map.Entry<String, List<String>>> flattenValidationResult() {
ValidationResult result = result();
List<Map.Entry<String, List<String>>> errorsMap = new ArrayList<>();
for (ValidationFailure fieldError : result.getErrors()){
Map.Entry<String, List<String>> entry = errorsMap.stream().filter(x-> Objects.equals(x.getKey(), fieldError.getErrorKey())).findFirst().orElse(null);
if (entry == null) {
entry = new AbstractMap.SimpleEntry<>(fieldError.getErrorKey(), new ArrayList<>());
errorsMap.add(entry);
}
entry.getValue().add(fieldError.getErrorMessage());
}
return errorsMap;
}
protected PropertySpecificationBuilder spec() {
return new PropertySpecificationBuilder();
}
protected NavigationReferenceSpecificationBuilder refSpec() {
return new NavigationReferenceSpecificationBuilder();
}
protected NavigationDetailsSpecificationBuilder navSpec()
{
return new NavigationDetailsSpecificationBuilder();
}
}