KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > bytecode > annotation > Annotation


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 2004 Bill Burke. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.bytecode.annotation;
17
18 import javassist.bytecode.ConstPool;
19 import javassist.bytecode.Descriptor;
20 import javassist.CtClass;
21 import javassist.CtMethod;
22
23 import java.io.IOException JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.Iterator JavaDoc;
27
28 /**
29  * The <code>annotation</code> structure.
30  *
31  * <p>An instance of this class is returned by
32  * <code>getAnnotations()</code> in <code>AnnotationsAttribute</code>
33  * or in <code>ParameterAnnotationsAttribute</code>.
34  *
35  * @see javassist.bytecode.AnnotationsAttribute#getAnnotations()
36  * @see javassist.bytecode.ParameterAnnotationsAttribute#getAnnotations()
37  *
38  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
39  * @author Shigeru Chiba
40  */

41 public class Annotation {
42     static class Pair {
43         int name;
44         MemberValue value;
45     }
46
47     ConstPool pool;
48     int typeIndex;
49     HashMap JavaDoc members; // this sould be LinkedHashMap
50
// but it is not supported by JDK 1.3.
51

52     /**
53      * Constructs an annotation including no members. A member can be
54      * later added to the created annotation by <code>addMemberValue()</code>.
55      *
56      * @param type the index into the constant pool table.
57      * the entry at that index must be the
58      * <code>CONSTANT_Utf8_Info</code> structure
59      * repreenting the name of the annotation interface type.
60      * @param cp the constant pool table.
61      *
62      * @see #addMemberValue(String, MemberValue)
63      */

64     public Annotation(int type, ConstPool cp) {
65         pool = cp;
66         typeIndex = type;
67         members = null;
68     }
69
70     /**
71      * Constructs an annotation including no members. A member can be
72      * later added to the created annotation by <code>addMemberValue()</code>.
73      *
74      * @param typeName the name of the annotation interface type.
75      * @param cp the constant pool table.
76      *
77      * @see #addMemberValue(String, MemberValue)
78      */

79     public Annotation(String JavaDoc typeName, ConstPool cp) {
80         this(cp.addUtf8Info(Descriptor.of(typeName)), cp);
81     }
82
83     /**
84      * Constructs an annotation that can be accessed through the interface
85      * represented by <code>clazz</code>. The values of the members are
86      * not specified.
87      *
88      * @param cp the constant pool table.
89      * @param clazz the interface.
90      */

91     public Annotation(ConstPool cp, CtClass clazz)
92         throws javassist.NotFoundException
93     {
94         // todo Enums are not supported right now.
95
this(cp.addUtf8Info(Descriptor.of(clazz.getName())), cp);
96
97         if (!clazz.isInterface())
98             throw new RuntimeException JavaDoc(
99                 "Only interfaces are allowed for Annotation creation.");
100
101         CtMethod methods[] = clazz.getDeclaredMethods();
102         if (methods.length > 0)
103             members = new HashMap JavaDoc();
104
105         for (int i = 0; i < methods.length; i++) {
106             CtClass returnType = methods[i].getReturnType();
107             addMemberValue(methods[i].getName(),
108                            createMemberValue(cp, returnType));
109         }
110     }
111
112     private MemberValue createMemberValue(ConstPool cp, CtClass returnType)
113         throws javassist.NotFoundException
114     {
115         if (returnType == CtClass.booleanType)
116             return new BooleanMemberValue(cp);
117         else if (returnType == CtClass.byteType)
118             return new ByteMemberValue(cp);
119         else if (returnType == CtClass.charType)
120             return new CharMemberValue(cp);
121         else if (returnType == CtClass.shortType)
122             return new ShortMemberValue(cp);
123         else if (returnType == CtClass.intType)
124             return new IntegerMemberValue(cp);
125         else if (returnType == CtClass.longType)
126             return new LongMemberValue(cp);
127         else if (returnType == CtClass.floatType)
128             return new FloatMemberValue(cp);
129         else if (returnType == CtClass.doubleType)
130             return new DoubleMemberValue(cp);
131         else if (returnType.getName().equals("java.lang.Class"))
132             return new ClassMemberValue(cp);
133         else if (returnType.getName().equals("java.lang.String"))
134             return new StringMemberValue(cp);
135         else if (returnType.isArray()) {
136             CtClass arrayType = returnType.getComponentType();
137             MemberValue type = createMemberValue(cp, arrayType);
138             return new ArrayMemberValue(type, cp);
139         }
140         else if (returnType.isInterface()) {
141             Annotation info = new Annotation(cp, returnType);
142             return new AnnotationMemberValue(info, cp);
143         }
144         else {
145             // treat as enum. I know this is not typed,
146
// but JBoss has an Annotation Compiler for JDK 1.4
147
// and I want it to work with that. - Bill Burke
148
EnumMemberValue emv = new EnumMemberValue(cp);
149             emv.setType(returnType.getName());
150             return emv;
151         }
152     }
153
154     /**
155      * Adds a new member.
156      *
157      * @param nameIndex the index into the constant pool table.
158      * The entry at that index must be
159      * a <code>CONSTANT_Utf8_info</code> structure.
160      * structure representing the member name.
161      * @param value the member value.
162      */

163     public void addMemberValue(int nameIndex, MemberValue value) {
164         Pair p = new Pair();
165         p.name = nameIndex;
166         p.value = value;
167         addMemberValue(p);
168     }
169
170     /**
171      * Adds a new member.
172      *
173      * @param name the member name.
174      * @param value the member value.
175      */

176     public void addMemberValue(String JavaDoc name, MemberValue value) {
177         Pair p = new Pair();
178         p.name = pool.addUtf8Info(name);
179         p.value = value;
180         if (members == null)
181             members = new HashMap JavaDoc();
182
183         members.put(name, p);
184     }
185
186     private void addMemberValue(Pair pair) {
187         String JavaDoc name = pool.getUtf8Info(pair.name);
188         if (members == null)
189             members = new HashMap JavaDoc();
190
191         members.put(name, pair);
192     }
193
194     /**
195      * Returns a string representation of this object.
196      */

197     public String JavaDoc toString() {
198         StringBuffer JavaDoc buf = new StringBuffer JavaDoc("@");
199         buf.append(getTypeName());
200         if (members != null) {
201             buf.append("(");
202             Iterator JavaDoc mit = members.keySet().iterator();
203             while (mit.hasNext()) {
204                 String JavaDoc name = (String JavaDoc)mit.next();
205                 buf.append(name).append("=").append(getMemberValue(name));
206                 if (mit.hasNext())
207                     buf.append(", ");
208             }
209             buf.append(")");
210         }
211
212         return buf.toString();
213     }
214
215     /**
216      * Obtains the name of the annotation type.
217      */

218     public String JavaDoc getTypeName() {
219         return Descriptor.toClassName(pool.getUtf8Info(typeIndex));
220     }
221
222     /**
223      * Obtains all the member names.
224      *
225      * @return null if no members are defined.
226      */

227     public Set JavaDoc getMemberNames() {
228         if (members == null)
229             return null;
230         else
231             return members.keySet();
232     }
233
234     /**
235      * Obtains the member value with the given name.
236      *
237      * @return null if the member cannot be found.
238      */

239     public MemberValue getMemberValue(String JavaDoc name) {
240         if (members == null)
241             return null;
242         else {
243             Pair p = (Pair)members.get(name);
244             if (p == null)
245                 return null;
246             else
247                 return p.value;
248         }
249     }
250
251     /**
252      * Writes this annotation.
253      *
254      * @param writer the output.
255      */

256     public void write(AnnotationsWriter writer) throws IOException JavaDoc {
257         if (members == null) {
258             writer.annotation(typeIndex, 0);
259             return;
260         }
261
262         writer.annotation(typeIndex, members.size());
263         Iterator JavaDoc it = members.values().iterator();
264         while (it.hasNext()) {
265             Pair pair = (Pair)it.next();
266             writer.memberValuePair(pair.name);
267             pair.value.write(writer);
268         }
269     }
270 }
271
Popular Tags