Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.kiwiproject.validation.FieldRangeValidator Maven / Gradle / Ivy
package org.kiwiproject.validation;
import static com.google.common.base.Verify.verify;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.kiwiproject.validation.InternalKiwiValidators.TEMPLATE_REQUIRED;
import static org.kiwiproject.validation.InternalKiwiValidators.toComparableOrNull;
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* Validator class for {@link FieldRange}.
*/
@Slf4j
public class FieldRangeValidator implements ConstraintValidator {
private static final String TEMPLATE_BETWEEN = "{org.kiwiproject.validation.FieldRange.between.message}";
private static final String TEMPLATE_MIN_ONLY = "{org.kiwiproject.validation.FieldRange.minOnly.message}";
private static final String TEMPLATE_MAX_ONLY = "{org.kiwiproject.validation.FieldRange.maxOnly.message}";
private static final String TEMPLATE_AFTER_EXCLUSIVE = "{org.kiwiproject.validation.FieldRange.afterExclusive.message}";
private static final String TEMPLATE_AFTER_INCLUSIVE = "{org.kiwiproject.validation.FieldRange.afterInclusive.message}";
private FieldRange fieldRange;
@Override
public void initialize(FieldRange constraintAnnotation) {
this.fieldRange = constraintAnnotation;
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
Validity validity;
try {
var start = getFieldValueAsComparable(value, fieldRange.startField());
var end = getFieldValueAsComparable(value, fieldRange.endField());
validity = checkValidity(start, end, context);
} catch (Exception e) {
addUnknownErrorConstraintViolation(context, fieldRange);
logWarning(value, fieldRange, e);
validity = Validity.INVALID;
}
return validity == Validity.VALID;
}
@SuppressWarnings("unchecked")
private static Comparable getFieldValueAsComparable(Object value, String fieldName) {
return (Comparable) KiwiValidations.getPropertyValue(value, fieldName);
}
private Validity checkValidity(Comparable start, Comparable end, ConstraintValidatorContext context) {
var validity = checkMinMax(start, end, context);
if (validity == Validity.CONTINUE) {
// check null first as checkRange checks won't work if null
validity = checkNull(start, end, context);
if (validity == Validity.CONTINUE) {
validity = checkRange(start, end, context);
}
}
return validity;
}
private Validity checkMinMax(Comparable start, Comparable end, ConstraintValidatorContext context) {
var validity = Validity.CONTINUE;
var min = toComparableOrNull(fieldRange.min(), start);
if (nonNull(min) && start.compareTo(min) < 0) {
var template = isBlank(fieldRange.max()) ? TEMPLATE_MIN_ONLY : TEMPLATE_BETWEEN;
KiwiValidations.addError(context, template, fieldRange.startField());
validity = Validity.INVALID;
}
var max = toComparableOrNull(fieldRange.max(), end);
if (nonNull(max) && end.compareTo(max) > 0) {
var template = isBlank(fieldRange.min()) ? TEMPLATE_MAX_ONLY : TEMPLATE_BETWEEN;
KiwiValidations.addError(context, template, fieldRange.endField());
validity = Validity.INVALID;
}
return validity;
}
private Validity checkNull(Comparable start, Comparable end, ConstraintValidatorContext context) {
var startValidity = checkFieldNullity(start, fieldRange.startField(), fieldRange.allowNullStart(), context);
var endValidity = checkFieldNullity(end, fieldRange.endField(), fieldRange.allowNullEnd(), context);
if (startValidity == Validity.INVALID || endValidity == Validity.INVALID) {
return Validity.INVALID;
}
if (isNull(start) || isNull(end)) {
return Validity.VALID;
}
return Validity.CONTINUE;
}
private static Validity checkFieldNullity(Comparable comparable,
String field,
boolean allowNull,
ConstraintValidatorContext context) {
if (nonNull(comparable) || allowNull) {
return Validity.CONTINUE;
}
KiwiValidations.addError(context, TEMPLATE_REQUIRED, field);
return Validity.INVALID;
}
private Validity checkRange(Comparable start, Comparable end, ConstraintValidatorContext context) {
verify(nonNull(start), "start should not be null at this point; checkNull should not have returned CONTINUE!");
verify(nonNull(end), "end should not be null at this point; checkNull should not have returned CONTINUE!");
var validity = Validity.VALID;
if (fieldRange.allowStartToEqualEnd()) {
if (start.compareTo(end) > 0) {
KiwiValidations.addError(context, TEMPLATE_AFTER_INCLUSIVE, fieldRange.startField());
validity = Validity.INVALID;
}
} else if (start.compareTo(end) >= 0) {
KiwiValidations.addError(context, TEMPLATE_AFTER_EXCLUSIVE, fieldRange.startField());
validity = Validity.INVALID;
}
return validity;
}
private static void addUnknownErrorConstraintViolation(ConstraintValidatorContext context, FieldRange fieldRange) {
KiwiValidations.addError(context, "unknown validation error", fieldRange.startField());
}
private static void logWarning(Object value, FieldRange fieldRange, Exception e) {
var valueAsString = isNull(value) ? "null" : value.getClass().getName();
LOG.warn("Error validating FieldRange with startField: {}, endField: {}, for value: {}; considering invalid",
fieldRange.startField(), fieldRange.endField(), valueAsString, e);
}
}