package org.junit.validator; import static java.util.Collections.singletonList; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.runners.model.Annotatable; import org.junit.runners.model.FrameworkField; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.TestClass; /** * An {@code AnnotationsValidator} validates all annotations of a test class, * including its annotated fields and methods. * * @since 4.12 */ public final class AnnotationsValidator implements TestClassValidator { private static final List> VALIDATORS = Arrays.>asList( new ClassValidator(), new MethodValidator(), new FieldValidator()); /** * Validate all annotations of the specified test class that are be * annotated with {@link ValidateWith}. * * @param testClass * the {@link TestClass} that is validated. * @return the errors found by the validator. */ public List validateTestClass(TestClass testClass) { List validationErrors= new ArrayList(); for (AnnotatableValidator validator : VALIDATORS) { List additionalErrors= validator .validateTestClass(testClass); validationErrors.addAll(additionalErrors); } return validationErrors; } private abstract static class AnnotatableValidator { private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory(); abstract Iterable getAnnotatablesForTestClass(TestClass testClass); abstract List validateAnnotatable( AnnotationValidator validator, T annotatable); public List validateTestClass(TestClass testClass) { List validationErrors= new ArrayList(); for (T annotatable : getAnnotatablesForTestClass(testClass)) { List additionalErrors= validateAnnotatable(annotatable); validationErrors.addAll(additionalErrors); } return validationErrors; } private List validateAnnotatable(T annotatable) { List validationErrors= new ArrayList(); for (Annotation annotation : annotatable.getAnnotations()) { Class annotationType = annotation .annotationType(); ValidateWith validateWith = annotationType .getAnnotation(ValidateWith.class); if (validateWith != null) { AnnotationValidator annotationValidator = ANNOTATION_VALIDATOR_FACTORY .createAnnotationValidator(validateWith); List errors= validateAnnotatable( annotationValidator, annotatable); validationErrors.addAll(errors); } } return validationErrors; } } private static class ClassValidator extends AnnotatableValidator { @Override Iterable getAnnotatablesForTestClass(TestClass testClass) { return singletonList(testClass); } @Override List validateAnnotatable( AnnotationValidator validator, TestClass testClass) { return validator.validateAnnotatedClass(testClass); } } private static class MethodValidator extends AnnotatableValidator { @Override Iterable getAnnotatablesForTestClass( TestClass testClass) { return testClass.getAnnotatedMethods(); } @Override List validateAnnotatable( AnnotationValidator validator, FrameworkMethod method) { return validator.validateAnnotatedMethod(method); } } private static class FieldValidator extends AnnotatableValidator { @Override Iterable getAnnotatablesForTestClass(TestClass testClass) { return testClass.getAnnotatedFields(); } @Override List validateAnnotatable( AnnotationValidator validator, FrameworkField field) { return validator.validateAnnotatedField(field); } } }