KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > asm2 > AnnReader


1 /*
2  * Manage Java 5 annotations using ASM toolkit
3  * Copyright (c) 2004, Eugene Kuleshov
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package asm2;
21
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.lang.reflect.Proxy JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
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 JavaDoc classAnns = new ArrayList JavaDoc();
47   private Map JavaDoc fieldAnns = new HashMap JavaDoc();
48   private Map JavaDoc methodAnns = new HashMap JavaDoc();
49   private Map JavaDoc methodParamAnns = new HashMap JavaDoc();
50
51
52   public AnnReader(InputStream JavaDoc is)
53       throws IOException JavaDoc {
54     ClassReader r = new ClassReader(is);
55     r.accept(this,
56         Attributes.getDefaultAttributes(), true);
57   }
58
59   public List JavaDoc getClassAnnotations() {
60     return classAnns;
61   }
62   
63   public Map JavaDoc getFieldAnnotations() {
64     return fieldAnns;
65   }
66   
67   public Map JavaDoc getMethodAnnotations() {
68     return methodAnns;
69   }
70   
71   public Map JavaDoc 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 JavaDoc name, String JavaDoc desc, Object JavaDoc value,
82         Attribute attrs) {
83     fieldAnns.put(name+desc, loadAnns(attrs));
84   }
85   
86   public CodeVisitor visitMethod(int access,
87         String JavaDoc name, String JavaDoc desc,
88         String JavaDoc[] 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 JavaDoc name, String JavaDoc superName,
97       String JavaDoc[] interfaces, String JavaDoc sourceFile) {
98   }
99
100   public void visitInnerClass( String JavaDoc name,
101       String JavaDoc outer, String JavaDoc inner, int access) {
102   }
103   
104   public void visitEnd() {
105   }
106   
107   
108   // Annotation loading
109

110   private List JavaDoc loadAnns(Attribute a) {
111     List JavaDoc anns = new ArrayList JavaDoc();
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 JavaDoc loadParamAnns(Attribute a) {
130     List JavaDoc anns = new ArrayList JavaDoc();
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 JavaDoc anns, List JavaDoc params) {
149     for(Iterator JavaDoc it = params.iterator(); it.hasNext();) {
150       List JavaDoc paramAttrs = (List JavaDoc) it.next();
151       List JavaDoc paramAnns = new ArrayList JavaDoc();
152       addAnns(paramAnns, paramAttrs);
153       anns.add(paramAnns);
154     }
155   }
156
157   private void addAnns(List JavaDoc anns, List JavaDoc attr) {
158     for(int i = 0; i<attr.size(); i++) {
159       anns.add(loadAnn((Annotation) attr.get(i)));
160     }
161   }
162
163   private Object JavaDoc loadAnn(Annotation annotation) {
164     String JavaDoc type = annotation.type;
165     List JavaDoc vals = annotation.elementValues;
166     List JavaDoc nvals = new ArrayList JavaDoc(vals.size());
167     for(int i = 0; i < vals.size(); i++) {
168       Object JavaDoc[] element = (Object JavaDoc[]) vals.get(i);
169       String JavaDoc name = (String JavaDoc) element[0];
170       Object JavaDoc value = getValue(element[1]);
171       nvals.add(new Object JavaDoc[] { name, value});
172     }
173     
174     try {
175       Type t = Type.getType(type);
176       String JavaDoc cname = t.getClassName();
177       Class JavaDoc typeClass = Class.forName(cname);
178       ClassLoader JavaDoc cl = getClass().getClassLoader();
179       return Proxy.newProxyInstance(cl,
180           new Class JavaDoc[] { Ann.class, typeClass},
181           new AnnInvocationHandler(type, nvals));
182     
183     } catch(ClassNotFoundException JavaDoc ex) {
184       throw new RuntimeException JavaDoc(ex.toString());
185     
186     }
187   }
188
189   private Object JavaDoc getValue(Object JavaDoc value) {
190     if (value instanceof EnumConstValue) {
191       // TODO convert to java.lang.Enum adapter
192
return value;
193     }
194     if (value instanceof Type) {
195       String JavaDoc cname = ((Type)value).getClassName();
196       try {
197         // TODO may require additional filtering
198
return Class.forName(cname);
199       } catch(ClassNotFoundException JavaDoc e) {
200         throw new RuntimeException JavaDoc(e.toString());
201       }
202     }
203     if (value instanceof Annotation) {
204       return loadAnn(((Annotation) value));
205     }
206     if (value instanceof Object JavaDoc[]) {
207       Object JavaDoc[] values = (Object JavaDoc[]) value;
208       Object JavaDoc[] o = new Object JavaDoc[ 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