1 8 package org.codehaus.aspectwerkz.annotation; 9 10 import com.thoughtworks.qdox.JavaDocBuilder; 11 import com.thoughtworks.qdox.model.DocletTag; 12 import com.thoughtworks.qdox.model.JavaClass; 13 import com.thoughtworks.qdox.model.JavaField; 14 import com.thoughtworks.qdox.model.JavaMethod; 15 16 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException; 17 import org.codehaus.aspectwerkz.exception.DefinitionException; 18 import org.codehaus.aspectwerkz.util.Strings; 19 import org.codehaus.aspectwerkz.annotation.expression.AnnotationVisitor; 20 import org.codehaus.aspectwerkz.annotation.expression.ast.ParseException; 21 22 import java.io.File ; 23 import java.io.FileNotFoundException ; 24 import java.io.IOException ; 25 import java.io.ObjectInputStream ; 26 import java.io.Serializable ; 27 import java.util.ArrayList ; 28 import java.util.Collection ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.lang.reflect.Proxy ; 34 import java.lang.reflect.InvocationHandler ; 35 import java.lang.reflect.Method ; 36 37 43 public class AnnotationManager { 44 45 private static final String JAVA_LANG_OBJECT_CLASS_NAME = "java.lang.Object"; 46 47 50 private final JavaDocBuilder m_parser = new JavaDocBuilder(); 51 52 55 private final Map m_registeredAnnotations = new HashMap (); 56 57 63 public AnnotationManager(ClassLoader loader) { 64 m_parser.getClassLibrary().addClassLoader(loader); 65 } 66 67 72 public void addSourceTrees(final String [] srcDirs) { 73 for (int i = 0; i < srcDirs.length; i++) { 74 m_parser.addSourceTree(new File (srcDirs[i])); 75 } 76 } 77 78 83 public void addSource(final String srcFile) { 84 try { 85 m_parser.addSource(new File (srcFile)); 86 } catch (Exception e) { 87 throw new WrappedRuntimeException(e); 88 } 89 } 90 91 98 public void registerAnnotationProxy(final Class proxyClass, final String docletName) { 99 m_registeredAnnotations.put(docletName, proxyClass); 100 } 101 102 107 public JavaClass[] getAllClasses() { 108 Collection classes = m_parser.getClassLibrary().all(); 109 Collection javaClasses = new ArrayList (); 110 String className; 111 for (Iterator it = classes.iterator(); it.hasNext();) { 112 className = (String ) it.next(); 113 if (JAVA_LANG_OBJECT_CLASS_NAME.equals(className)) { 114 continue; 115 } 116 JavaClass clazz = m_parser.getClassByName(className); 117 javaClasses.add(clazz); 118 } 119 return (JavaClass[]) javaClasses.toArray(new JavaClass[]{}); 120 } 121 122 129 public Annotation[] getAnnotations(final String name, final JavaClass clazz) { 130 DocletTag[] tags = clazz.getTags(); 131 List annotations = new ArrayList (); 132 for (int i = 0; i < tags.length; i++) { 133 DocletTag tag = tags[i]; 134 RawAnnotation rawAnnotation = getRawAnnotation(name, tag); 135 if (rawAnnotation != null) { 136 annotations.add(instantiateAnnotation(rawAnnotation)); 137 } 138 } 139 return (Annotation[]) annotations.toArray(new Annotation[]{}); 140 } 141 142 149 public Annotation[] getAnnotations(final String name, final JavaMethod method) { 150 DocletTag[] tags = method.getTags(); 151 List annotations = new ArrayList (); 152 for (int i = 0; i < tags.length; i++) { 153 DocletTag tag = tags[i]; 154 RawAnnotation rawAnnotation = getRawAnnotation(name, tag); 155 if (rawAnnotation != null) { 156 annotations.add(instantiateAnnotation(rawAnnotation)); 157 } 158 } 159 return (Annotation[]) annotations.toArray(new Annotation[]{}); 160 } 161 162 169 public Annotation[] getAnnotations(final String name, final JavaField field) { 170 DocletTag[] tags = field.getTags(); 171 List annotations = new ArrayList (); 172 for (int i = 0; i < tags.length; i++) { 173 DocletTag tag = tags[i]; 174 RawAnnotation rawAnnotation = getRawAnnotation(name, tag); 175 if (rawAnnotation != null) { 176 annotations.add(instantiateAnnotation(rawAnnotation)); 177 } 178 } 179 return (Annotation[]) annotations.toArray(new Annotation[]{}); 180 } 181 182 183 190 private Annotation instantiateAnnotation(final RawAnnotation rawAnnotation) { 191 final Class proxyClass = (Class ) m_registeredAnnotations.get(rawAnnotation.name); 192 193 if (!proxyClass.isInterface()) { 194 throw new RuntimeException ("Annotation class is not defined as an interface for " + rawAnnotation.name 195 + ". Use of AspectWerkz 1.x Annotation proxies is not anymore supported."); 196 } 197 198 try { 199 InvocationHandler handler = new Java14AnnotationInvocationHander( 200 proxyClass, rawAnnotation.name, rawAnnotation.value 201 ); 202 Object annotationProxy = Proxy.newProxyInstance( 203 proxyClass.getClassLoader(), new Class []{Annotation.class, proxyClass}, handler 204 ); 205 return (Annotation) annotationProxy; 206 } catch (Throwable e) { 207 throw new DefinitionException( 208 "Unable to parse annotation @" + rawAnnotation.name + '(' + 209 " " + rawAnnotation.value + ')', e 210 ); 211 } 212 } 213 214 224 public static Annotation instantiateNestedAnnotation(final Class annotationClass, final Map elements) { 225 if (!annotationClass.isInterface()) { 226 throw new RuntimeException ("Annotation class is not defined as an interface for " + annotationClass.getName() 227 + ". Use of AspectWerkz 1.x Annotation proxies is not anymore supported."); 228 } 229 230 try { 231 InvocationHandler handler = new Java14AnnotationInvocationHander( 232 annotationClass, elements 233 ); 234 Object annotationProxy = Proxy.newProxyInstance( 235 annotationClass.getClassLoader(), new Class []{Annotation.class, annotationClass}, handler 236 ); 237 return (Annotation) annotationProxy; 238 } catch (Throwable e) { 239 throw new DefinitionException( 240 "Unable to parse nested annotation @" + annotationClass.getName(), e 241 ); 242 } 243 } 244 245 255 private RawAnnotation getRawAnnotation(String annotationName, DocletTag tag) { 256 String asIs = tag.getName() + " " + tag.getValue(); 257 asIs = asIs.trim(); 258 Strings.removeFormattingCharacters(asIs); 259 260 if (!asIs.startsWith(annotationName)) { 262 return null; 263 } 264 265 String name = null; 266 String value = null; 267 268 if (asIs.indexOf(' ') > 0) { 270 name = asIs.substring(0, asIs.indexOf(' ')); 271 } 272 if (annotationName.equals(name)) { 273 value = asIs.substring(asIs.indexOf(' ') + 1, asIs.length()); 275 if (value.startsWith("(") && value.endsWith(")")) { 276 if (value.length() > 2) { 277 value = value.substring(1, value.length()-1); 278 } else { 279 value = ""; 280 } 281 } 282 } else { 283 if (asIs.indexOf('(') > 0) { 285 name = asIs.substring(0, asIs.indexOf('(')); 286 } 287 if (annotationName.equals(name)) { 288 value = asIs.substring(asIs.indexOf('(') + 1, asIs.length()); 289 if (value.endsWith(")")) { 290 if (value.length() > 1) { 291 value = value.substring(0, value.length() - 1); 292 } else { 293 value = ""; 294 } 295 } 296 } else if (annotationName.equals(asIs)) { 297 value = ""; 298 } 299 } 300 301 if (value != null) { 303 RawAnnotation annotation = new RawAnnotation(); 304 annotation.name = annotationName; 305 annotation.value = value; 306 return annotation; 307 } else { 308 return null; 309 } 310 } 311 312 316 private static class RawAnnotation implements Serializable { 317 String name; 318 String value; 319 } 320 } | Popular Tags |