1 package org.junit.validator; 2 3 import static java.util.Collections.singletonList; 4 5 import java.lang.annotation.Annotation; 6 import java.util.ArrayList; 7 import java.util.Arrays; 8 import java.util.List; 9 10 import org.junit.runners.model.Annotatable; 11 import org.junit.runners.model.FrameworkField; 12 import org.junit.runners.model.FrameworkMethod; 13 import org.junit.runners.model.TestClass; 14 15 /** 16 * An {@code AnnotationsValidator} validates all annotations of a test class, 17 * including its annotated fields and methods. 18 * 19 * @since 4.12 20 */ 21 public final class AnnotationsValidator implements TestClassValidator { 22 private static final List<AnnotatableValidator<?>> VALIDATORS = Arrays.<AnnotatableValidator<?>>asList( 23 new ClassValidator(), new MethodValidator(), new FieldValidator()); 24 25 /** 26 * Validate all annotations of the specified test class that are be 27 * annotated with {@link ValidateWith}. 28 * 29 * @param testClass 30 * the {@link TestClass} that is validated. 31 * @return the errors found by the validator. 32 */ validateTestClass(TestClass testClass)33 public List<Exception> validateTestClass(TestClass testClass) { 34 List<Exception> validationErrors= new ArrayList<Exception>(); 35 for (AnnotatableValidator<?> validator : VALIDATORS) { 36 List<Exception> additionalErrors= validator 37 .validateTestClass(testClass); 38 validationErrors.addAll(additionalErrors); 39 } 40 return validationErrors; 41 } 42 43 private static abstract class AnnotatableValidator<T extends Annotatable> { 44 private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory(); 45 getAnnotatablesForTestClass(TestClass testClass)46 abstract Iterable<T> getAnnotatablesForTestClass(TestClass testClass); 47 validateAnnotatable( AnnotationValidator validator, T annotatable)48 abstract List<Exception> validateAnnotatable( 49 AnnotationValidator validator, T annotatable); 50 validateTestClass(TestClass testClass)51 public List<Exception> validateTestClass(TestClass testClass) { 52 List<Exception> validationErrors= new ArrayList<Exception>(); 53 for (T annotatable : getAnnotatablesForTestClass(testClass)) { 54 List<Exception> additionalErrors= validateAnnotatable(annotatable); 55 validationErrors.addAll(additionalErrors); 56 } 57 return validationErrors; 58 } 59 validateAnnotatable(T annotatable)60 private List<Exception> validateAnnotatable(T annotatable) { 61 List<Exception> validationErrors= new ArrayList<Exception>(); 62 for (Annotation annotation : annotatable.getAnnotations()) { 63 Class<? extends Annotation> annotationType = annotation 64 .annotationType(); 65 ValidateWith validateWith = annotationType 66 .getAnnotation(ValidateWith.class); 67 if (validateWith != null) { 68 AnnotationValidator annotationValidator = ANNOTATION_VALIDATOR_FACTORY 69 .createAnnotationValidator(validateWith); 70 List<Exception> errors= validateAnnotatable( 71 annotationValidator, annotatable); 72 validationErrors.addAll(errors); 73 } 74 } 75 return validationErrors; 76 } 77 } 78 79 private static class ClassValidator extends AnnotatableValidator<TestClass> { 80 @Override getAnnotatablesForTestClass(TestClass testClass)81 Iterable<TestClass> getAnnotatablesForTestClass(TestClass testClass) { 82 return singletonList(testClass); 83 } 84 85 @Override validateAnnotatable( AnnotationValidator validator, TestClass testClass)86 List<Exception> validateAnnotatable( 87 AnnotationValidator validator, TestClass testClass) { 88 return validator.validateAnnotatedClass(testClass); 89 } 90 } 91 92 private static class MethodValidator extends 93 AnnotatableValidator<FrameworkMethod> { 94 @Override getAnnotatablesForTestClass( TestClass testClass)95 Iterable<FrameworkMethod> getAnnotatablesForTestClass( 96 TestClass testClass) { 97 return testClass.getAnnotatedMethods(); 98 } 99 100 @Override validateAnnotatable( AnnotationValidator validator, FrameworkMethod method)101 List<Exception> validateAnnotatable( 102 AnnotationValidator validator, FrameworkMethod method) { 103 return validator.validateAnnotatedMethod(method); 104 } 105 } 106 107 private static class FieldValidator extends 108 AnnotatableValidator<FrameworkField> { 109 @Override getAnnotatablesForTestClass(TestClass testClass)110 Iterable<FrameworkField> getAnnotatablesForTestClass(TestClass testClass) { 111 return testClass.getAnnotatedFields(); 112 } 113 114 @Override validateAnnotatable( AnnotationValidator validator, FrameworkField field)115 List<Exception> validateAnnotatable( 116 AnnotationValidator validator, FrameworkField field) { 117 return validator.validateAnnotatedField(field); 118 } 119 }; 120 } 121