de.zalando.sprocwrapper.validation.SimpleConstraintDescriptor Maven / Gradle / Ivy
Show all versions of zalando-sprocwrapper Show documentation
package de.zalando.sprocwrapper.validation;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.validation.ConstraintValidator;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.ValidationException;
import javax.validation.metadata.ConstraintDescriptor;
public class SimpleConstraintDescriptor implements ConstraintDescriptor {
private static final String PAYLOAD = "payload";
private T annotation;
private Set> groups;
private Set> payload;
private List>> constraintValidatorClasses;
private Map attributes;
private Set> composingConstraints;
private boolean reportAsSingleViolation;
public SimpleConstraintDescriptor(final T annotation, final Set> groups,
final List>> constraintValidatorClasses,
final Set> composingConstraints) {
this.annotation = annotation;
this.groups = groups;
this.payload = buildPayloadSet(annotation);
this.constraintValidatorClasses = constraintValidatorClasses;
this.attributes = buildAnnotationParameterMap(annotation);
this.composingConstraints = composingConstraints;
this.reportAsSingleViolation = ((Class) this.annotation.annotationType()).isAnnotationPresent(
ReportAsSingleViolation.class);
}
@Override
public T getAnnotation() {
return annotation;
}
@Override
public Set> getGroups() {
return groups;
}
@Override
public Set> getPayload() {
return payload;
}
@Override
public List>> getConstraintValidatorClasses() {
return constraintValidatorClasses;
}
@Override
public Map getAttributes() {
return attributes;
}
@Override
public Set> getComposingConstraints() {
return composingConstraints;
}
@Override
public boolean isReportAsSingleViolation() {
return reportAsSingleViolation;
}
private Map buildAnnotationParameterMap(final Annotation annotation) {
final Method[] declaredMethods = annotation.annotationType().getDeclaredMethods();
Map parameters = new HashMap(declaredMethods.length);
for (Method m : declaredMethods) {
try {
parameters.put(m.getName(), m.invoke(annotation));
} catch (IllegalAccessException e) {
throw new ValidationException("Unable to read annotation attributes: " + annotation.getClass(), e);
} catch (InvocationTargetException e) {
throw new ValidationException("Unable to read annotation attributes: " + annotation.getClass(), e);
}
}
return Collections.unmodifiableMap(parameters);
}
private Set> buildPayloadSet(final T annotation) {
Set> payloadSet = new HashSet>();
Class[] payloadFromAnnotation;
try {
payloadFromAnnotation = getAnnotationParameter(annotation, PAYLOAD, Class[].class);
} catch (ValidationException e) {
payloadFromAnnotation = null;
}
if (payloadFromAnnotation != null) {
payloadSet.addAll(Arrays.asList(payloadFromAnnotation));
}
return Collections.unmodifiableSet(payloadSet);
}
private P getAnnotationParameter(final Annotation annotation, final String parameterName, final Class
type) {
try {
Method m = annotation.getClass().getMethod(parameterName);
m.setAccessible(true);
Object o = m.invoke(annotation);
if (o.getClass().getName().equals(type.getName())) {
return (P) o;
} else {
String msg = "Wrong parameter type. Expected: " + type.getName() + " Actual: " + o
.getClass().getName();
throw new ValidationException(msg);
}
} catch (NoSuchMethodException e) {
String msg = "The specified annotation defines no parameter '" + parameterName + "'.";
throw new ValidationException(msg, e);
} catch (IllegalAccessException e) {
String msg = "Unable to get '" + parameterName + "' from " + annotation.getClass().getName();
throw new ValidationException(msg, e);
} catch (InvocationTargetException e) {
String msg = "Unable to get '" + parameterName + "' from " + annotation.getClass().getName();
throw new ValidationException(msg, e);
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("SimpleConstraintDescriptor [annotation=");
builder.append(annotation);
builder.append(", groups=");
builder.append(groups);
builder.append(", payload=");
builder.append(payload);
builder.append(", constraintValidatorClasses=");
builder.append(constraintValidatorClasses);
builder.append(", attributes=");
builder.append(attributes);
builder.append(", composingConstraints=");
builder.append(composingConstraints);
builder.append(", reportAsSingleViolation=");
builder.append(reportAsSingleViolation);
builder.append("]");
return builder.toString();
}
}