1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.io.IOException;
22 import java.lang.annotation.Annotation;
23 import java.lang.reflect.Modifier;
24 import java.util.Set;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.classification.InterfaceStability;
30 import org.apache.hadoop.hbase.testclassification.SmallTests;
31 import org.apache.hadoop.hbase.ClassFinder.And;
32 import org.apache.hadoop.hbase.ClassFinder.FileNameFilter;
33 import org.apache.hadoop.hbase.ClassFinder.Not;
34 import org.apache.hadoop.hbase.ClassTestFinder.TestClassFilter;
35 import org.apache.hadoop.hbase.ClassTestFinder.TestFileNameFilter;
36 import org.junit.Assert;
37 import org.junit.Test;
38 import org.junit.experimental.categories.Category;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 @Category(SmallTests.class)
60 public class TestInterfaceAudienceAnnotations {
61
62 private static final Log LOG = LogFactory.getLog(TestInterfaceAudienceAnnotations.class);
63
64
65 class GeneratedClassFilter implements ClassFinder.ClassFilter {
66 @Override
67 public boolean isCandidateClass(Class<?> c) {
68 return c.getPackage().getName().contains("generated");
69 }
70 }
71
72
73
74
75 class InterfaceAudienceAnnotatedClassFilter implements ClassFinder.ClassFilter {
76 @Override
77 public boolean isCandidateClass(Class<?> c) {
78 if (getAnnotation(c) != null) {
79
80 return true;
81 }
82
83
84
85 return isAnnotatedPrivate(c.getEnclosingClass());
86 }
87
88 private boolean isAnnotatedPrivate(Class<?> c) {
89 if (c == null) {
90 return false;
91 }
92
93 Class<?> ann = getAnnotation(c);
94 if (ann != null &&
95 !InterfaceAudience.Public.class.equals(ann)) {
96 return true;
97 }
98
99 return isAnnotatedPrivate(c.getEnclosingClass());
100 }
101
102 protected Class<?> getAnnotation(Class<?> c) {
103
104 Annotation[] anns = c.getDeclaredAnnotations();
105
106 for (Annotation ann : anns) {
107
108
109 Class<?> type = ann.annotationType();
110 if (isInterfaceAudienceClass(type)) {
111 return type;
112 }
113 }
114 return null;
115 }
116 }
117
118
119
120
121 class InterfaceStabilityAnnotatedClassFilter implements ClassFinder.ClassFilter {
122 @Override
123 public boolean isCandidateClass(Class<?> c) {
124 if (getAnnotation(c) != null) {
125
126 return true;
127 }
128 return false;
129 }
130
131 protected Class<?> getAnnotation(Class<?> c) {
132
133 Annotation[] anns = c.getDeclaredAnnotations();
134
135 for (Annotation ann : anns) {
136
137
138 Class<?> type = ann.annotationType();
139 if (isInterfaceStabilityClass(type)) {
140 return type;
141 }
142 }
143 return null;
144 }
145 }
146
147
148
149
150 class InterfaceAudiencePublicAnnotatedClassFilter extends InterfaceAudienceAnnotatedClassFilter {
151 @Override
152 public boolean isCandidateClass(Class<?> c) {
153 return (InterfaceAudience.Public.class.equals(getAnnotation(c)));
154 }
155 }
156
157
158
159
160 class IsInterfaceStabilityClassFilter implements ClassFinder.ClassFilter {
161 @Override
162 public boolean isCandidateClass(Class<?> c) {
163 return
164 isInterfaceAudienceClass(c) ||
165 isInterfaceStabilityClass(c);
166 }
167 }
168
169 private boolean isInterfaceAudienceClass(Class<?> c) {
170 return
171 c.equals(InterfaceAudience.Public.class) ||
172 c.equals(InterfaceAudience.Private.class) ||
173 c.equals(InterfaceAudience.LimitedPrivate.class);
174 }
175
176 private boolean isInterfaceStabilityClass(Class<?> c) {
177 return
178 c.equals(InterfaceStability.Stable.class) ||
179 c.equals(InterfaceStability.Unstable.class) ||
180 c.equals(InterfaceStability.Evolving.class);
181 }
182
183
184 class PublicClassFilter implements ClassFinder.ClassFilter {
185 @Override
186 public boolean isCandidateClass(Class<?> c) {
187 int mod = c.getModifiers();
188 return Modifier.isPublic(mod);
189 }
190 }
191
192
193 class MainCodeResourcePathFilter implements ClassFinder.ResourcePathFilter {
194 @Override
195 public boolean isCandidatePath(String resourcePath, boolean isJar) {
196 return !resourcePath.contains("test-classes") &&
197 !resourcePath.contains("tests.jar");
198 }
199 }
200
201
202
203
204
205 @Test
206 public void testInterfaceAudienceAnnotation()
207 throws ClassNotFoundException, IOException, LinkageError {
208
209
210
211
212
213
214
215 ClassFinder classFinder = new ClassFinder(
216 new MainCodeResourcePathFilter(),
217 new Not((FileNameFilter)new TestFileNameFilter()),
218 new And(new PublicClassFilter(),
219 new Not(new TestClassFilter()),
220 new Not(new GeneratedClassFilter()),
221 new Not(new IsInterfaceStabilityClassFilter()),
222 new Not(new InterfaceAudienceAnnotatedClassFilter()))
223 );
224
225 Set<Class<?>> classes = classFinder.findClasses(false);
226
227 LOG.info("These are the classes that DO NOT have @InterfaceAudience annotation:");
228 for (Class<?> clazz : classes) {
229 LOG.info(clazz);
230 }
231
232 Assert.assertEquals("All classes should have @InterfaceAudience annotation",
233 0, classes.size());
234 }
235
236
237
238
239
240 @Test
241 public void testInterfaceStabilityAnnotation()
242 throws ClassNotFoundException, IOException, LinkageError {
243
244
245
246
247
248
249
250
251 ClassFinder classFinder = new ClassFinder(
252 new MainCodeResourcePathFilter(),
253 new Not((FileNameFilter)new TestFileNameFilter()),
254 new And(new PublicClassFilter(),
255 new Not(new TestClassFilter()),
256 new Not(new GeneratedClassFilter()),
257 new InterfaceAudiencePublicAnnotatedClassFilter(),
258 new Not(new IsInterfaceStabilityClassFilter()),
259 new Not(new InterfaceStabilityAnnotatedClassFilter()))
260 );
261
262 Set<Class<?>> classes = classFinder.findClasses(false);
263
264 LOG.info("These are the classes that DO NOT have @InterfaceStability annotation:");
265 for (Class<?> clazz : classes) {
266 LOG.info(clazz);
267 }
268
269 Assert.assertEquals("All classes that are marked with @InterfaceAudience.Public should "
270 + "have @InterfaceStability annotation as well",
271 0, classes.size());
272 }
273 }