1package org.junit.internal.runners.rules; 2 3import java.lang.annotation.Annotation; 4import java.util.List; 5 6import org.junit.ClassRule; 7import org.junit.Rule; 8import org.junit.rules.TestRule; 9import org.junit.runners.model.FrameworkField; 10import org.junit.runners.model.TestClass; 11 12/** 13 * A RuleFieldValidator validates the rule fields of a 14 * {@link org.junit.runners.model.TestClass}. All reasons for rejecting the 15 * {@code TestClass} are written to a list of errors. 16 * 17 * There are two slightly different validators. The {@link #CLASS_RULE_VALIDATOR} 18 * validates fields with a {@link ClassRule} annotation and the 19 * {@link #RULE_VALIDATOR} validates fields with a {@link Rule} annotation. 20 */ 21public enum RuleFieldValidator { 22 /** 23 * Validates fields with a {@link ClassRule} annotation. 24 */ 25 CLASS_RULE_VALIDATOR(ClassRule.class, true), 26 /** 27 * Validates fields with a {@link Rule} annotation. 28 */ 29 RULE_VALIDATOR(Rule.class, false); 30 31 private final Class<? extends Annotation> fAnnotation; 32 33 private final boolean fOnlyStaticFields; 34 35 private RuleFieldValidator(Class<? extends Annotation> annotation, 36 boolean onlyStaticFields) { 37 this.fAnnotation= annotation; 38 this.fOnlyStaticFields= onlyStaticFields; 39 } 40 41 /** 42 * Validate the {@link org.junit.runners.model.TestClass} and adds reasons 43 * for rejecting the class to a list of errors. 44 * @param target the {@code TestClass} to validate. 45 * @param errors the list of errors. 46 */ 47 public void validate(TestClass target, List<Throwable> errors) { 48 List<FrameworkField> fields= target.getAnnotatedFields(fAnnotation); 49 for (FrameworkField each : fields) 50 validateField(each, errors); 51 } 52 53 private void validateField(FrameworkField field, List<Throwable> errors) { 54 optionallyValidateStatic(field, errors); 55 validatePublic(field, errors); 56 validateTestRuleOrMethodRule(field, errors); 57 } 58 59 private void optionallyValidateStatic(FrameworkField field, 60 List<Throwable> errors) { 61 if (fOnlyStaticFields && !field.isStatic()) 62 addError(errors, field, "must be static."); 63 } 64 65 private void validatePublic(FrameworkField field, List<Throwable> errors) { 66 if (!field.isPublic()) 67 addError(errors, field, "must be public."); 68 } 69 70 private void validateTestRuleOrMethodRule(FrameworkField field, 71 List<Throwable> errors) { 72 if (!isMethodRule(field) && !isTestRule(field)) 73 addError(errors, field, "must implement MethodRule or TestRule."); 74 } 75 76 private boolean isTestRule(FrameworkField target) { 77 return TestRule.class.isAssignableFrom(target.getType()); 78 } 79 80 @SuppressWarnings("deprecation") 81 private boolean isMethodRule(FrameworkField target) { 82 return org.junit.rules.MethodRule.class.isAssignableFrom(target 83 .getType()); 84 } 85 86 private void addError(List<Throwable> errors, FrameworkField field, 87 String suffix) { 88 String message= "The @" + fAnnotation.getSimpleName() + " '" 89 + field.getName() + "' " + suffix; 90 errors.add(new Exception(message)); 91 } 92} 93