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