1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.common.junit48;
20
21 import java.lang.annotation.Inherited;
22 import java.util.ArrayList;
23 import java.util.HashSet;
24 import java.util.Set;
25
26 import org.apache.maven.surefire.group.match.AndGroupMatcher;
27 import org.apache.maven.surefire.group.match.GroupMatcher;
28 import org.apache.maven.surefire.group.match.InverseGroupMatcher;
29 import org.junit.experimental.categories.Category;
30 import org.junit.runner.Description;
31 import org.junit.runner.manipulation.Filter;
32
33 import static java.util.Collections.addAll;
34 import static org.junit.runner.Description.createSuiteDescription;
35
36 final class GroupMatcherCategoryFilter extends Filter {
37
38
39
40 private static final boolean IS_CATEGORY_INHERITED = Category.class.isAnnotationPresent(Inherited.class);
41
42 private final AndGroupMatcher matcher;
43
44 GroupMatcherCategoryFilter(GroupMatcher included, GroupMatcher excluded) {
45 GroupMatcher invertedExclude = excluded == null ? null : new InverseGroupMatcher(excluded);
46 if (included != null || invertedExclude != null) {
47 matcher = new AndGroupMatcher();
48 if (included != null) {
49 matcher.addMatcher(included);
50 }
51
52 if (invertedExclude != null) {
53 matcher.addMatcher(invertedExclude);
54 }
55 } else {
56 matcher = null;
57 }
58 }
59
60 @Override
61 public boolean shouldRun(Description description) {
62 if (invalidTestClass(description)) {
63 return shouldRun(description, null, null);
64 }
65
66 if (describesTestClass(description))
67 {
68 Class<?> testClass = description.getTestClass();
69 return shouldRun(description, null, testClass);
70 } else
71
72 {
73 Class<?> testClass = description.getTestClass();
74 return shouldRun(description, createSuiteDescription(testClass), testClass);
75 }
76 }
77
78 private boolean describesTestClass(Description description) {
79 String methodName = description.getMethodName();
80
81 return methodName == null || methodName.equals("null");
82 }
83
84 private boolean invalidTestClass(Description description) {
85 return description.getTestClass() == null;
86 }
87
88 private static void findSuperclassCategories(Set<Class<?>> cats, Class<?> clazz) {
89 if (IS_CATEGORY_INHERITED && hasSuperclass(clazz)) {
90 Category cat = clazz.getSuperclass().getAnnotation(Category.class);
91 if (cat != null) {
92
93 addAll(cats, cat.value());
94 }
95
96 findSuperclassCategories(cats, clazz.getSuperclass());
97 }
98 }
99
100 private static boolean hasSuperclass(Class<?> clazz) {
101 return clazz != null && clazz.getSuperclass() != null;
102 }
103
104 private boolean shouldRun(Description description, Description parent, Class<?> parentClass) {
105 if (matcher == null) {
106 return true;
107 } else {
108 Set<Class<?>> cats = new HashSet<>();
109 Category cat = description.getAnnotation(Category.class);
110 if (cat != null) {
111
112 addAll(cats, cat.value());
113 }
114
115 if (parent != null) {
116 cat = parent.getAnnotation(Category.class);
117 if (cat != null) {
118
119 addAll(cats, cat.value());
120 }
121 }
122 if (parentClass != null) {
123 findSuperclassCategories(cats, parentClass);
124 }
125
126 Class<?> testClass = description.getTestClass();
127 if (testClass != null) {
128 cat = testClass.getAnnotation(Category.class);
129 if (cat != null) {
130
131 addAll(cats, cat.value());
132 }
133 }
134
135 cats.remove(null);
136 boolean result = matcher.enabled(cats.toArray(new Class<?>[cats.size()]));
137
138 if (!result) {
139 ArrayList<Description> children = description.getChildren();
140 if (children != null) {
141 for (Description child : children) {
142 if (shouldRun(child, description, null)) {
143 result = true;
144 break;
145 }
146 }
147 }
148 }
149
150 return result;
151 }
152 }
153
154 @Override
155 public String describe() {
156 return matcher == null ? "ANY" : matcher.toString();
157 }
158 }