org.minijax.validator.MinijaxValidator Maven / Gradle / Ivy
package org.minijax.validator;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.ContainerElementTypeDescriptor;
import javax.validation.metadata.PropertyDescriptor;
import org.minijax.util.CopyOnWriteMap;
import org.minijax.validator.metadata.MinijaxBeanDescriptor;
import org.minijax.validator.metadata.MinijaxConstraintDescriptor;
import org.minijax.validator.metadata.MinijaxPropertyDescriptor;
public class MinijaxValidator implements Validator, ExecutableValidator {
private final Map, MinijaxBeanDescriptor> beanDescriptors;
public MinijaxValidator() {
beanDescriptors = new CopyOnWriteMap<>();
}
@Override
public MinijaxBeanDescriptor getConstraintsForClass(final Class> clazz) {
return beanDescriptors.computeIfAbsent(clazz, MinijaxBeanDescriptor::new);
}
@Override
public Set> validate(final T object, final Class>... groups) {
final MinijaxConstraintValidatorContext context = new MinijaxConstraintValidatorContext<>(object);
final BeanDescriptor descriptor = getConstraintsForClass(object.getClass());
for (final PropertyDescriptor propertyDescriptor : descriptor.getConstrainedProperties()) {
final Object value = ((MinijaxPropertyDescriptor) propertyDescriptor).getValue(object);
validateProperty(context, propertyDescriptor, value);
}
return context.getResult();
}
@Override
public Set> validateProperty(final T object, final String propertyName, final Class>... groups) {
final MinijaxConstraintValidatorContext context = new MinijaxConstraintValidatorContext<>(object);
final BeanDescriptor descriptor = getConstraintsForClass(object.getClass());
final PropertyDescriptor propertyDescriptor = descriptor.getConstraintsForProperty(propertyName);
final Object value = ((MinijaxPropertyDescriptor) propertyDescriptor).getValue(object);
validateProperty(context, propertyDescriptor, value);
return context.getResult();
}
@Override
public Set> validateValue(final Class beanType, final String propertyName, final Object value, final Class>... groups) {
final MinijaxConstraintValidatorContext context = new MinijaxConstraintValidatorContext<>(null);
final PropertyDescriptor property = getConstraintsForClass(beanType).getConstraintsForProperty(propertyName);
validateProperty(context, property, value);
return context.getResult();
}
private void validateProperty(
final MinijaxConstraintValidatorContext context,
final PropertyDescriptor property,
final Object value) {
context.push(property);
validatePropertyConstraints(context, property, value);
validatePropertyElementConstraints(context, property, value);
context.pop();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void validatePropertyConstraints(
final MinijaxConstraintValidatorContext context,
final PropertyDescriptor property,
final Object value) {
for (final ConstraintDescriptor constraint : property.getConstraintDescriptors()) {
final ConstraintValidator validator = ((MinijaxConstraintDescriptor) constraint).getValidator();
if (!validator.isValid(value, context)) {
context.buildViolation(constraint, value);
}
}
}
@SuppressWarnings("rawtypes")
private void validatePropertyElementConstraints(
final MinijaxConstraintValidatorContext context,
final PropertyDescriptor property,
final Object value) {
for (final ContainerElementTypeDescriptor descriptor : property.getConstrainedContainerElementTypes()) {
for (final ConstraintDescriptor constraint : descriptor.getConstraintDescriptors()) {
final ConstraintValidator validator = ((MinijaxConstraintDescriptor) constraint).getValidator();
if (value instanceof List) {
validateList(context, constraint, validator, (List) value);
} else if (value instanceof Iterable) {
validateIterable(context, constraint, validator, (Iterable) value);
} else if (value instanceof Map && descriptor.getTypeArgumentIndex() == 0) {
validateMapKeys(context, constraint, validator, (Map, ?>) value);
} else if (value instanceof Map) {
validateMapValues(context, constraint, validator, (Map, ?>) value);
} else if (value instanceof Optional) {
validateOptional(context, constraint, validator, (Optional) value);
}
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void validateList(
final MinijaxConstraintValidatorContext context,
final ConstraintDescriptor constraint,
final ConstraintValidator validator,
final List list) {
for (int i = 0; i < list.size(); i++) {
if (!validator.isValid(list.get(i), context)) {
context.buildViolation(constraint, list.get(i), "[" + i + "].");
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void validateIterable(
final MinijaxConstraintValidatorContext context,
final ConstraintDescriptor constraint,
final ConstraintValidator validator,
final Iterable iterable) {
for (final Object element : iterable) {
if (!validator.isValid(element, context)) {
context.buildViolation(constraint, element, "[].");
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void validateMapKeys(
final MinijaxConstraintValidatorContext context,
final ConstraintDescriptor constraint,
final ConstraintValidator validator,
final Map, ?> map) {
for (final Object element : map.keySet()) {
if (!validator.isValid(element, context)) {
context.buildViolation(constraint, element, "[].
© 2015 - 2024 Weber Informatics LLC | Privacy Policy