1 package org.apache.onami.test.reflection;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static com.google.common.base.Preconditions.checkArgument;
23
24 import java.lang.annotation.Annotation;
25 import java.lang.reflect.AnnotatedElement;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29 import com.google.common.collect.ArrayListMultimap;
30 import com.google.common.collect.Multimap;
31
32
33
34
35
36
37
38
39
40 public final class ClassVisitor
41 {
42
43 private static final String JAVA_PACKAGE = "java";
44
45 private static final Logger LOGGER = Logger.getLogger( ClassVisitor.class.getName() );
46
47 private final Multimap<Class<? extends Annotation>, AnnotationHandler<? extends Annotation, ? extends AnnotatedElement>> handlers =
48 ArrayListMultimap.create();
49
50
51
52
53
54
55
56
57
58 public <A extends Annotation> ClassVisitor registerHandler( Class<A> annotationType,
59 AnnotationHandler<A, ? extends AnnotatedElement> handler )
60 {
61 handlers.put( annotationType, handler );
62 return this;
63 }
64
65
66
67
68
69
70
71
72 public <T> void visit( final Class<? super T> type )
73 throws HandleException
74 {
75 checkArgument( type != null, "Type to be visited cannot be null" );
76
77 if ( LOGGER.isLoggable( Level.FINER ) )
78 {
79 LOGGER.finer( " Visit class: " + type );
80 }
81
82 if ( type.getPackage() != null && type.getPackage().getName().startsWith( JAVA_PACKAGE ) )
83 {
84 return;
85 }
86
87 handle( type );
88 handle( type.getDeclaredFields() );
89 handle( type.getDeclaredMethods() );
90
91 visit( type.getSuperclass() );
92 }
93
94 @SuppressWarnings( "unchecked" )
95 private void handle( AnnotatedElement... elements )
96 throws HandleException
97 {
98 for ( AnnotatedElement element : elements )
99 {
100 for ( Annotation annotation : element.getAnnotations() )
101 {
102 for ( AnnotationHandler<? extends Annotation, ? extends AnnotatedElement> handler : handlers.get( annotation.annotationType() ) )
103 {
104 ( (AnnotationHandler<Annotation, AnnotatedElement>) handler ).handle( annotation, element );
105 }
106 }
107 }
108 }
109
110 }