1 19 20 package asm2; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.lang.reflect.Proxy ; 25 import java.util.ArrayList ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 31 import org.objectweb.asm.Attribute; 32 import org.objectweb.asm.ClassReader; 33 import org.objectweb.asm.ClassVisitor; 34 import org.objectweb.asm.CodeVisitor; 35 import org.objectweb.asm.Type; 36 import org.objectweb.asm.attrs.Annotation; 37 import org.objectweb.asm.attrs.Annotation.EnumConstValue; 38 import org.objectweb.asm.attrs.Attributes; 39 import org.objectweb.asm.attrs.RuntimeInvisibleAnnotations; 40 import org.objectweb.asm.attrs.RuntimeInvisibleParameterAnnotations; 41 import org.objectweb.asm.attrs.RuntimeVisibleAnnotations; 42 import org.objectweb.asm.attrs.RuntimeVisibleParameterAnnotations; 43 44 45 public class AnnReader implements ClassVisitor { 46 private List classAnns = new ArrayList (); 47 private Map fieldAnns = new HashMap (); 48 private Map methodAnns = new HashMap (); 49 private Map methodParamAnns = new HashMap (); 50 51 52 public AnnReader(InputStream is) 53 throws IOException { 54 ClassReader r = new ClassReader(is); 55 r.accept(this, 56 Attributes.getDefaultAttributes(), true); 57 } 58 59 public List getClassAnnotations() { 60 return classAnns; 61 } 62 63 public Map getFieldAnnotations() { 64 return fieldAnns; 65 } 66 67 public Map getMethodAnnotations() { 68 return methodAnns; 69 } 70 71 public Map getMethodParamAnnotations() { 72 return methodParamAnns; 73 } 74 75 76 public void visitAttribute(Attribute attr) { 77 classAnns.addAll(loadAnns(attr)); 78 } 79 80 public void visitField(int access, 81 String name, String desc, Object value, 82 Attribute attrs) { 83 fieldAnns.put(name+desc, loadAnns(attrs)); 84 } 85 86 public CodeVisitor visitMethod(int access, 87 String name, String desc, 88 String [] exceptions, Attribute attrs) { 89 methodAnns.put(name+desc, loadAnns(attrs)); 90 methodParamAnns.put(name+desc, 91 loadParamAnns(attrs)); 92 return null; 93 } 94 95 public void visit( int version, int access, 96 String name, String superName, 97 String [] interfaces, String sourceFile) { 98 } 99 100 public void visitInnerClass( String name, 101 String outer, String inner, int access) { 102 } 103 104 public void visitEnd() { 105 } 106 107 108 110 private List loadAnns(Attribute a) { 111 List anns = new ArrayList (); 112 while(a!=null) { 113 if(a instanceof 114 RuntimeVisibleAnnotations) { 115 RuntimeVisibleAnnotations ra = 116 (RuntimeVisibleAnnotations) a; 117 addAnns(anns, ra.annotations); 118 } else if(a instanceof 119 RuntimeInvisibleAnnotations) { 120 RuntimeInvisibleAnnotations ra = 121 (RuntimeInvisibleAnnotations) a; 122 addAnns(anns, ra.annotations); 123 } 124 a = a.next; 125 } 126 return anns; 127 } 128 129 private List loadParamAnns(Attribute a) { 130 List anns = new ArrayList (); 131 while(a!=null) { 132 if(a instanceof 133 RuntimeVisibleParameterAnnotations) { 134 RuntimeVisibleParameterAnnotations ra = 135 (RuntimeVisibleParameterAnnotations) a; 136 addParamAnns( anns, ra.parameters); 137 } else if(a instanceof 138 RuntimeInvisibleParameterAnnotations) { 139 RuntimeInvisibleParameterAnnotations ra = 140 (RuntimeInvisibleParameterAnnotations) a; 141 addParamAnns( anns, ra.parameters); 142 } 143 a = a.next; 144 } 145 return anns; 146 } 147 148 private void addParamAnns( List anns, List params) { 149 for(Iterator it = params.iterator(); it.hasNext();) { 150 List paramAttrs = (List ) it.next(); 151 List paramAnns = new ArrayList (); 152 addAnns(paramAnns, paramAttrs); 153 anns.add(paramAnns); 154 } 155 } 156 157 private void addAnns(List anns, List attr) { 158 for(int i = 0; i<attr.size(); i++) { 159 anns.add(loadAnn((Annotation) attr.get(i))); 160 } 161 } 162 163 private Object loadAnn(Annotation annotation) { 164 String type = annotation.type; 165 List vals = annotation.elementValues; 166 List nvals = new ArrayList (vals.size()); 167 for(int i = 0; i < vals.size(); i++) { 168 Object [] element = (Object []) vals.get(i); 169 String name = (String ) element[0]; 170 Object value = getValue(element[1]); 171 nvals.add(new Object [] { name, value}); 172 } 173 174 try { 175 Type t = Type.getType(type); 176 String cname = t.getClassName(); 177 Class typeClass = Class.forName(cname); 178 ClassLoader cl = getClass().getClassLoader(); 179 return Proxy.newProxyInstance(cl, 180 new Class [] { Ann.class, typeClass}, 181 new AnnInvocationHandler(type, nvals)); 182 183 } catch(ClassNotFoundException ex) { 184 throw new RuntimeException (ex.toString()); 185 186 } 187 } 188 189 private Object getValue(Object value) { 190 if (value instanceof EnumConstValue) { 191 return value; 193 } 194 if (value instanceof Type) { 195 String cname = ((Type)value).getClassName(); 196 try { 197 return Class.forName(cname); 199 } catch(ClassNotFoundException e) { 200 throw new RuntimeException (e.toString()); 201 } 202 } 203 if (value instanceof Annotation) { 204 return loadAnn(((Annotation) value)); 205 } 206 if (value instanceof Object []) { 207 Object [] values = (Object []) value; 208 Object [] o = new Object [ values.length]; 209 for(int i = 0; i < values.length; i++) { 210 o[ i] = getValue(values[ i]); 211 } 212 return o; 213 } 214 215 return value; 216 } 217 218 } 219 220 | Popular Tags |