KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > bytecode > JavaAnnotation


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.bytecode;
31
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.lang.reflect.Method JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.logging.Level JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38
39 /**
40  * Represents a java annotation.
41  */

42 public class JavaAnnotation extends JAnnotation {
43   static private final Logger JavaDoc log =
44     Logger.getLogger(JavaAnnotation.class.getName());
45
46   private static Method JavaDoc _enumValueOf;
47
48   private JavaClassLoader _loader;
49   private HashMap JavaDoc<String JavaDoc,Object JavaDoc> _valueMap = new HashMap JavaDoc<String JavaDoc,Object JavaDoc>(8);
50   private String JavaDoc _type;
51
52   /**
53    * Sets the class loader.
54    */

55   public void setClassLoader(JavaClassLoader loader)
56   {
57     _loader = loader;
58   }
59
60   /**
61    * Gets the class loader.
62    */

63   public JavaClassLoader getClassLoader()
64   {
65     return _loader;
66   }
67
68   /**
69    * Sets the type.
70    */

71   public void setType(String JavaDoc type)
72   {
73     _type = type;
74   }
75
76   /**
77    * Gets the type.
78    */

79   public String JavaDoc getType()
80   {
81     return _type;
82   }
83
84   /**
85    * Returns the value map.
86    */

87   public HashMap JavaDoc<String JavaDoc,Object JavaDoc> getValueMap()
88   {
89     return _valueMap;
90   }
91
92   /**
93    * Sets a value.
94    */

95   public Object JavaDoc putValue(String JavaDoc key, Object JavaDoc value)
96   {
97     return _valueMap.put(key, value);
98   }
99
100   /**
101    * Parses the annotation from an annotation block.
102    */

103   static JavaAnnotation []parseAnnotations(InputStream JavaDoc is,
104                        ConstantPool cp,
105                        JavaClassLoader loader)
106     throws IOException JavaDoc
107   {
108     int n = readShort(is);
109
110     JavaAnnotation []annArray = new JavaAnnotation[n];
111
112     for (int i = 0; i < n; i++) {
113       annArray[i] = parseAnnotation(is, cp, loader);
114     }
115
116     return annArray;
117   }
118
119   private static JavaAnnotation parseAnnotation(InputStream JavaDoc is,
120                         ConstantPool cp,
121                         JavaClassLoader loader)
122     throws IOException JavaDoc
123   {
124     JavaAnnotation ann = new JavaAnnotation();
125     ann.setClassLoader(loader);
126       
127     int type = readShort(is);
128
129     String JavaDoc typeName = cp.getUtf8(type).getValue();
130
131     if (typeName.endsWith(";"))
132       typeName = typeName.substring(1, typeName.length() - 1).replace('/', '.');
133     
134     ann.setType(typeName);
135
136     try {
137       Class JavaDoc aClass = Class.forName(typeName, false, Thread.currentThread().getContextClassLoader());
138
139       for (Method JavaDoc method : aClass.getDeclaredMethods()) {
140     Object JavaDoc value = method.getDefaultValue();
141
142     if (value instanceof Class JavaDoc) {
143       String JavaDoc className = ((Class JavaDoc) value).getName();
144       
145       ann.putValue(method.getName(), loader.forName(className));
146     }
147     else if (value != null)
148       ann.putValue(method.getName(), value);
149       }
150     } catch (Exception JavaDoc e) {
151       log.log(Level.FINER, e.toString(), e);
152     }
153
154     int nPairs = readShort(is);
155     for (int j = 0; j < nPairs; j++) {
156       int nameIndex = readShort(is);
157
158       String JavaDoc name = cp.getUtf8(nameIndex).getValue();
159       
160       Object JavaDoc value = parseElementValue(is, cp, loader);
161
162       ann.putValue(name, value);
163     }
164
165     return ann;
166   }
167
168   private static Object JavaDoc parseElementValue(InputStream JavaDoc is,
169                       ConstantPool cp,
170                       JavaClassLoader loader)
171     throws IOException JavaDoc
172   {
173     int tag = is.read();
174
175     switch (tag) {
176     case 'Z':
177       {
178     int i = readShort(is);
179
180     return cp.getInteger(i).getValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
181       }
182       
183     case 'B':
184       {
185     int i = readShort(is);
186
187     return new Byte JavaDoc((byte) cp.getInteger(i).getValue());
188       }
189       
190     case 'S':
191       {
192     int i = readShort(is);
193
194     return new Short JavaDoc((short) cp.getInteger(i).getValue());
195       }
196       
197     case 'I':
198       {
199     int i = readShort(is);
200
201     return new Integer JavaDoc(cp.getInteger(i).getValue());
202       }
203       
204     case 'J':
205       {
206     int i = readShort(is);
207
208     return new Long JavaDoc(cp.getLong(i).getValue());
209       }
210       
211     case 'F':
212       {
213     int i = readShort(is);
214
215     return new Float JavaDoc(cp.getFloat(i).getValue());
216       }
217       
218     case 'D':
219       {
220     int i = readShort(is);
221
222     return new Double JavaDoc(cp.getDouble(i).getValue());
223       }
224       
225     case 'C':
226       {
227     int i = readShort(is);
228
229     return new Character JavaDoc((char) cp.getInteger(i).getValue());
230       }
231       
232     case 's':
233       int i = readShort(is);
234       return cp.getUtf8(i).getValue();
235     case 'e':
236       {
237     int type = readShort(is);
238     int value = readShort(is);
239     String JavaDoc enumClassName = cp.getUtf8(type).getValue();
240     enumClassName = enumClassName.substring(1, enumClassName.length() - 1);
241     enumClassName = enumClassName.replace('/', '.');
242
243     try {
244       Class JavaDoc enumClass = Class.forName(enumClassName, false, Thread.currentThread().getContextClassLoader());
245       String JavaDoc enumName = cp.getUtf8(value).getValue();
246
247       return _enumValueOf.invoke(null, enumClass, enumName);
248       
249     } catch (Exception JavaDoc e) {
250       log.log(Level.FINE, e.toString(), e);
251
252       return null;
253     }
254       }
255     case 'c':
256       // class
257
{
258     String JavaDoc className = cp.getUtf8(readShort(is)).getValue();
259
260     return loader.descriptorToClass(className, 0);
261       }
262     case '@':
263       return parseAnnotation(is, cp, loader);
264     case '[':
265       {
266     int n = readShort(is);
267     
268     Object JavaDoc []array = new Object JavaDoc[n];
269     for (int j = 0; j < n; j++) {
270       array[j] = parseElementValue(is, cp, loader);
271     }
272
273     return array;
274       }
275     default:
276       throw new IllegalStateException JavaDoc();
277     }
278   }
279
280   static int readShort(InputStream JavaDoc is)
281     throws IOException JavaDoc
282   {
283     return (((is.read() & 0xff) << 8) +
284         (is.read() & 0xff));
285   }
286
287   static int readInt(InputStream JavaDoc is)
288     throws IOException JavaDoc
289   {
290     return (((is.read() & 0xff) << 24) +
291         ((is.read() & 0xff) << 16) +
292         ((is.read() & 0xff) << 8) +
293         ((is.read() & 0xff)));
294   }
295
296   public String JavaDoc toString()
297   {
298     return "JavaAnnotation[" + _type + "]";
299   }
300
301   static {
302     try {
303       Class JavaDoc cl = Class.forName("java.lang.Enum");
304       _enumValueOf = cl.getMethod("valueOf",
305                   new Class JavaDoc[] { Class JavaDoc.class, String JavaDoc.class });
306     } catch (Throwable JavaDoc e) {
307       e.printStackTrace();
308     }
309   }
310 }
311
Popular Tags