View Javadoc

1   /*
2    *    Copyright 2010-2011 The Meiyo Team
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.nnsoft.commons.meiyo.classvisitor;
17  
18  import java.lang.annotation.Annotation;
19  import java.lang.reflect.AnnotatedElement;
20  import java.lang.reflect.Constructor;
21  import java.lang.reflect.Field;
22  import java.lang.reflect.Method;
23  import java.security.AccessController;
24  import java.security.PrivilegedAction;
25  
26  /**
27   * FILL ME.
28   */
29  final class ClassVisitorImpl implements ClassVisitor {
30  
31      private static final String JAVA_PACKAGE = "java";
32  
33      private final AnnotationHandlerBinderImpl binder;
34  
35      public ClassVisitorImpl(final AnnotationHandlerBinderImpl binder) {
36          this.binder = binder;
37      }
38  
39      public void visit(final Class<?> type) {
40          if (type == null || type.getPackage().getName().startsWith(JAVA_PACKAGE)) {
41              return;
42          }
43  
44          // TYPE
45          this.visitElements(type);
46  
47          if (!type.isInterface()) {
48              // CONSTRUCTOR
49              this.visitElements(new PrivilegedAction<Constructor<?>[]>() {
50                  public Constructor<?>[] run() {
51                      return type.getDeclaredConstructors();
52                  }
53              });
54  
55              // FIELD
56              this.visitElements(new PrivilegedAction<Field[]>() {
57                  public Field[] run() {
58                      return type.getDeclaredFields();
59                  }
60              });
61          }
62  
63          // METHOD
64          this.visitElements(new PrivilegedAction<Method[]>() {
65              public Method[] run() {
66                  return type.getDeclaredMethods();
67              }
68          });
69  
70          this.visit(type.getSuperclass());
71      }
72  
73      private <AE extends AnnotatedElement> void visitElements(PrivilegedAction<AE[]> action) {
74          AE[] annotatedElements = null;
75          if (System.getSecurityManager() != null) {
76              annotatedElements = AccessController.doPrivileged(action);
77          } else {
78              annotatedElements = action.run();
79          }
80          this.visitElements(annotatedElements);
81      }
82  
83      private void visitElements(AnnotatedElement...annotatedElements) {
84          for (AnnotatedElement element : annotatedElements) {
85              for (Annotation annotation : element.getAnnotations()) {
86                  AnnotationHandler<AnnotatedElement, Annotation> handler =
87                      this.binder.getHandler(element.getClass(), annotation.annotationType());
88  
89                  if (handler != null) {
90                      handler.handle(element, annotation);
91                  }
92              }
93          }
94      }
95  
96  }