1 package spoon.processing; 2 3 import java.lang.annotation.Annotation ; 4 import java.lang.reflect.Method ; 5 import java.util.ArrayList ; 6 import java.util.Map ; 7 import java.util.Set ; 8 import java.util.TreeMap ; 9 import java.util.TreeSet ; 10 11 import spoon.reflect.declaration.CtAnnotation; 12 import spoon.reflect.declaration.CtElement; 13 14 18 public abstract class AbstractAnnotationProcessor<A extends Annotation , E extends CtElement> 19 extends AbstractProcessor<E> implements AnnotationProcessor<A, E> { 20 21 Map <String , Class <? extends A>> consumedAnnotationTypes = new TreeMap <String , Class <? extends A>>(); 22 23 Map <String , Class <? extends A>> processedAnnotationTypes = new TreeMap <String , Class <? extends A>>(); 24 25 28 @SuppressWarnings ("unchecked") 29 public AbstractAnnotationProcessor() { 30 if (inferConsumedAnnotationType()) { 31 for (Method m : getClass().getMethods()) { 32 if (m.getName().equals("process") 33 && m.getParameterTypes().length == 2) { 34 Class c = m.getParameterTypes()[0]; 35 if (Annotation .class != c) { 36 addConsumedAnnotationType((Class <? extends A>) m 37 .getParameterTypes()[0]); 38 } 39 } 40 } 41 if (processedAnnotationTypes.isEmpty()) { 42 addProcessedAnnotationType((Class <? extends A>) Annotation .class); 43 } 44 } 45 } 46 47 52 final protected void addConsumedAnnotationType( 53 Class <? extends A> annotationType) { 54 addProcessedAnnotationType(annotationType); 55 consumedAnnotationTypes.put(annotationType.getName(), annotationType); 56 } 57 58 61 final protected void addProcessedAnnotationType( 62 Class <? extends A> annotationType) { 63 processedAnnotationTypes.put(annotationType.getName(), annotationType); 64 } 65 66 69 final protected void removeProcessedAnnotationType(Class <? extends A> annotationType) { 70 processedAnnotationTypes.remove(annotationType.getName()); 71 } 72 73 76 final protected void clearProcessedAnnotationTypes() { 77 processedAnnotationTypes.clear(); 78 } 79 80 83 final protected void clearConsumedAnnotationTypes() { 84 consumedAnnotationTypes.clear(); 85 } 86 87 90 final protected void removeConsumedAnnotationType(Class <? extends A> annotationType) { 91 consumedAnnotationTypes.remove(annotationType.getName()); 92 } 93 94 final public Set <Class <? extends A>> getConsumedAnnotationTypes() { 95 return new TreeSet <Class <? extends A>>(consumedAnnotationTypes.values()); 96 } 97 98 final public Set <Class <? extends A>> getProcessedAnnotationTypes() { 99 return new TreeSet <Class <? extends A>>(processedAnnotationTypes 100 .values()); 101 } 102 103 public boolean inferConsumedAnnotationType() { 104 return true; 105 } 106 107 111 final public boolean isToBeProcessed(E element) { 112 if (element != null && element.getAnnotations() != null) { 113 for (CtAnnotation<? extends Annotation > a : element 114 .getAnnotations()) { 115 if (shoudBeProcessed(a)) 116 return true; 117 } 118 } 119 return false; 120 } 121 122 @SuppressWarnings ("unchecked") 123 final public void process(E element) { 124 for (CtAnnotation<? extends Annotation > annotation : new ArrayList <CtAnnotation>( 125 element.getAnnotations())) { 126 if (shoudBeProcessed(annotation)) { 127 try { 128 process((A) annotation.getActualAnnotation(), element); 129 } catch (Exception e) { 130 e.printStackTrace(); 131 } 132 if (shoudBeConsumed(annotation)) 133 element.getAnnotations().remove(annotation); 134 } 135 } 136 } 137 138 private boolean shoudBeConsumed( 139 CtAnnotation<? extends Annotation > annotation) { 140 if (consumedAnnotationTypes.containsKey(annotation.getAnnotationType() 141 .getQualifiedName())) { 142 return true; 143 } 144 return false; 145 } 146 147 private boolean shoudBeProcessed( 148 CtAnnotation<? extends Annotation > annotation) { 149 if (processedAnnotationTypes.containsKey(annotation.getAnnotationType() 150 .getQualifiedName())) { 151 return true; 152 } 153 return false; 154 } 155 156 } 157 | Popular Tags |