KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > libraries > asm > attrs > Annotation


1 /**
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000,2002,2003 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package oracle.toplink.libraries.asm.attrs;
32
33 import java.util.ArrayList JavaDoc;
34 import java.util.List JavaDoc;
35
36 import oracle.toplink.libraries.asm.ByteVector;
37 import oracle.toplink.libraries.asm.ClassReader;
38 import oracle.toplink.libraries.asm.ClassWriter;
39 import oracle.toplink.libraries.asm.Type;
40
41 /**
42  * Annotation data contains an annotated type and its array of the element-value
43  * pairs. Structure is in the following format:
44  * <pre>
45  * annotation {
46  * u2 type_index;
47  * u2 num_element_value_pairs;
48  * {
49  * u2 element_name_index;
50  * element_value value;
51  * } element_value_pairs[num_element_value_pairs];
52  * }
53  * </pre>
54  * The items of the annotation structure are as follows:
55  * <dl>
56  * <dt>type_index</dt>
57  * <dd>The value of the type_index item must be a valid index into the constant_pool
58  * table. The constant_pool entry at that index must be a CONSTANT_Utf8_info
59  * structure representing a field descriptor representing the annotation
60  * interface corresponding to the annotation represented by this annotation
61  * structure.</dd>
62  * <dt>num_element_value_pairs</dt>
63  * <dd>The value of the num_element_value_pairs item gives the number of element-value
64  * pairs in the annotation represented by this annotation structure. Note that a
65  * maximum of 65535 element-value pairs may be contained in a single annotation.</dd>
66  * <dt>element_value_pairs</dt>
67  * <dd>Each value of the element_value_pairs table represents a single element-value
68  * pair in the annotation represented by this annotation structure.
69  * Each element_value_pairs entry contains the following two items:
70  * <dt>element_name_index</dt>
71  * <dd>The value of the element_name_index item must be a valid index into the
72  * constant_pool table. The constant_pool entry at that index must be a
73  * CONSTANT_Utf8_info structure representing the name of the annotation type
74  * element corresponding to this element_value_pairs entry.</dd>
75  * <dt>value</dt>
76  * <dd>The value item represents the value in the element-value pair represented by
77  * this element_value_pairs entry.</dd>
78  * </dl>
79  * </dd>
80  * </dl>
81  *
82  * The element_value structure is a discriminated union representing the value of a
83  * element-value pair. It is used to represent values in all class file attributes
84  * that describe annotations ( RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations,
85  * RuntimeVisibleParameterAnnotations, and RuntimeInvisibleParameterAnnotations).
86  * <p>
87  * The element_value structure has the following format:
88  * <pre>
89  * element_value {
90  * u1 tag;
91  * union {
92  * u2 const_value_index;
93  * {
94  * u2 type_name_index;
95  * u2 const_name_index;
96  * } enum_const_value;
97  * u2 class_info_index;
98  * annotation annotation_value;
99  * {
100  * u2 num_values;
101  * element_value values[num_values];
102  * } array_value;
103  * } value;
104  * }
105  * </pre>
106  * The items of the element_value structure are as follows:
107  * <dl>
108  * <dt>tag</dt>
109  * <dd>The tag item indicates the type of this annotation element-value pair. The letters
110  * 'B', 'C', 'D', 'F', 'I', 'J', 'S', and 'Z' indicate a primitive type. These
111  * letters are interpreted as BaseType characters (Table 4.2). The other legal
112  * values for tag are listed with their interpretations in this table:
113  * <pre>
114  * tag value Element Type
115  * 's' String
116  * 'e' enum constant
117  * 'c' class
118  * '@' annotation type
119  * '[' array
120  * </pre>
121  * </dd>
122  * <dt>value</dt>
123  * <dd>The value item represents the value of this annotation element. This item is
124  * a union. The tag item, above, determines which item of the union is to be used:
125  * <dl>
126  * <dt>const_value_index</dt>
127  * <dd>The const_value_index item is used if the tag item is one of 'B', 'C', 'D',
128  * 'F', 'I', 'J', 'S', 'Z', or 's'. The value of the const_value_index item must
129  * be a valid index into the constant_pool table. The constant_pool entry at
130  * that index must be of the correct entry type for the field type designated by
131  * the tag item, as specified in table 4.6, with one exception: if the tag is
132  * 's', the the value of the const_value_index item must be the index of a
133  * CONSTANT_Utf8 structure, rather than a CONSTANT_String.</dd>
134  * <dt>enum_const_value</dt>
135  * <dd>The enum_const_value item is used if the tag item is 'e'. The
136  * enum_const_value item consists of the following two items:
137  * <dl>
138  * <dt>type_name_index</dt>
139  * <dd>The value of the type_name_index item must be a valid index into the
140  * constant_pool table. The constant_pool entry at that index must be a
141  * CONSTANT_Utf8_info structure representing the binary name (JLS 13.1) of the
142  * type of the enum constant represented by this element_value structure.</dd>
143  * <dt>const_name_index</dt>
144  * <dd>The value of the const_name_index item must be a valid index into the
145  * constant_pool table. The constant_pool entry at that index must be a
146  * CONSTANT_Utf8_info structure representing the simple name of the enum
147  * constant represented by this element_value structure.</dd>
148  * </dl>
149  * </dd>
150  * <dt>class_info_index</dt>
151  * <dd>The class_info_index item is used if the tag item is 'c'. The
152  * class_info_index item must be a valid index into the constant_pool table.
153  * The constant_pool entry at that index must be a CONSTANT_Utf8_info
154  * structure representing the return descriptor of the type that is
155  * reified by the class represented by this element_value structure.</dd>
156  * <dt>annotation_value</dt>
157  * <dd>The annotation_value item is used if the tag item is '@'. The element_value
158  * structure represents a "nested" {@link oracle.toplink.libraries.asm.attrs.Annotation annotation}.</dd>
159  * <dt>array_value</dt>
160  * <dd>The array_value item is used if the tag item is '['. The array_value item
161  * consists of the following two items:
162  * <dl>
163  * <dt>num_values</dt>
164  * <dd>The value of the num_values item gives the number of elements in the
165  * array-typed value represented by this element_value structure. Note that a
166  * maximum of 65535 elements are permitted in an array-typed element value.</dd>
167  * <dt>values</dt>
168  * <dd>Each element of the values table gives the value of an element of the
169  * array-typed value represented by this {@link AnnotationElementValue element_value structure}.</dd>
170  * </dl>
171  * </dd>
172  * </dl>
173  * </dd>
174  * </dl>
175  *
176  * @see <a HREF="http://www.jcp.org/en/jsr/detail?id=175">JSR 175 : A Metadata
177  * Facility for the Java Programming Language</a>
178  *
179  * @author Eugene Kuleshov
180  */

181
182 public class Annotation {
183
184   /**
185    * A fully qualified class name in internal form (see {@link Type Type}).
186    */

187   public String JavaDoc type;
188   
189   /**
190    * <code>List</code> of <code>Object[]{name, value}</code> pairs.
191    * Where name is <code>String</code> and value is one of
192    * <code>Byte</code>, <code>Character</code>, <code>Double</code>,
193    * <code>Float</code>, <code>Integer</code>, <code>Long</code>, <code>Short</code>,
194    * <code>Boolean</code>, <code>String</code>,
195    * <code>Annotation.EnumConstValue</code>, <code>Type</code>,
196    * <code>Annotation</code> or <code>Object[]</code>.
197    */

198   public List JavaDoc elementValues = new ArrayList JavaDoc();
199
200   public Annotation() {
201   }
202   
203   public Annotation( String JavaDoc type) {
204     this.type = type;
205   }
206
207   public void add (String JavaDoc name, Object JavaDoc value) {
208     elementValues.add(new Object JavaDoc[]{name, value});
209   }
210
211   /**
212    * Reads annotation data structures.
213    *
214    * @param cr the class that contains the attribute to be read.
215    * @param off index of the first byte of the data structure.
216    * @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
217    * {@link ClassReader#readClass(int,char[]) readClass} or {@link
218    * ClassReader#readConst readConst}.
219    *
220    * @return offset position in bytecode after reading annotation
221    */

222
223   public int read (ClassReader cr, int off, char[] buf) {
224     type = cr.readUTF8(off, buf);
225     int numElementValuePairs = cr.readUnsignedShort(off + 2);
226     off += 4;
227     int[] aoff = new int[] { off};
228     for (int i = 0; i < numElementValuePairs; i++) {
229       String JavaDoc elementName = cr.readUTF8(aoff[ 0], buf);
230       aoff[ 0] += 2;
231       elementValues.add(new Object JavaDoc[]{elementName, readValue(cr, aoff, buf)});
232     }
233     return aoff[ 0];
234   }
235
236   /**
237    * Writes annotation data structures.
238    *
239    * @param bv the byte array form to store data structures.
240    * @param cw the class to which this attribute must be added. This parameter
241    * can be used to add to the constant pool of this class the items that
242    * corresponds to this attribute.
243    */

244
245   public void write (ByteVector bv, ClassWriter cw) {
246     bv.putShort(cw.newUTF8(type));
247     bv.putShort(elementValues.size());
248     for (int i = 0; i < elementValues.size(); i++) {
249       Object JavaDoc[] value = (Object JavaDoc[])elementValues.get(i);
250       bv.putShort(cw.newUTF8((String JavaDoc)value[0]));
251       writeValue(bv, value[1], cw);
252     }
253   }
254
255   /**
256    * Utility method to read List of annotations. Each element of annotations
257    * List will have Annotation instance.
258    *
259    * @param annotations the List to store parameters annotations.
260    * @param cr the class that contains the attribute to be read.
261    * @param off index of the first byte of the data structure.
262    * @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
263    * {@link ClassReader#readClass(int,char[]) readClass} or {@link
264    * ClassReader#readConst readConst}.
265    *
266    * @return offset position in bytecode after reading annotations
267    */

268
269   public static int readAnnotations (
270     List JavaDoc annotations, ClassReader cr, int off, char[] buf) {
271     int size = cr.readUnsignedShort(off);
272     off += 2;
273     for (int i = 0; i < size; i++) {
274       Annotation ann = new Annotation();
275       off = ann.read(cr, off, buf);
276       annotations.add(ann);
277     }
278     return off;
279   }
280
281   /**
282    * Utility method to read List of parameters annotations.
283    *
284    * @param parameters the List to store parameters annotations.
285    * Each element of the parameters List will have List of Annotation
286    * instances.
287    * @param cr the class that contains the attribute to be read.
288    * @param off index of the first byte of the data structure.
289    * @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
290    * {@link ClassReader#readClass(int,char[]) readClass} or {@link
291    * ClassReader#readConst readConst}.
292    */

293
294   public static void readParameterAnnotations (
295     List JavaDoc parameters, ClassReader cr, int off, char[] buf) {
296     int numParameters = cr.b[off++] & 0xff;
297     for (int i = 0; i < numParameters; i++) {
298       List JavaDoc annotations = new ArrayList JavaDoc();
299       off = Annotation.readAnnotations(annotations, cr, off, buf);
300       parameters.add(annotations);
301     }
302   }
303
304   /**
305    * Utility method to write List of annotations.
306    *
307    * @param bv the byte array form to store data structures.
308    * @param annotations the List of annotations to write.
309    * Elements should be instances of the Annotation class.
310    * @param cw the class to which this attribute must be added. This parameter
311    * can be used to add to the constant pool of this class the items that
312    * corresponds to this attribute.
313    *
314    * @return the byte array form with saved annotations.
315    */

316
317   public static ByteVector writeAnnotations (ByteVector bv,
318                                              List JavaDoc annotations, ClassWriter cw) {
319     bv.putShort(annotations.size());
320     for (int i = 0; i < annotations.size(); i++) {
321       ((Annotation)annotations.get(i)).write(bv, cw);
322     }
323     return bv;
324   }
325
326   /**
327    * Utility method to write List of parameters annotations.
328    *
329    * @param bv the byte array form to store data structures.
330    * @param parameters the List of parametars to write. Elements should be
331    * instances of the List that contains instances of the Annotation class.
332    * @param cw the class to which this attribute must be added. This parameter
333    * can be used to add to the constant pool of this class the items that
334    * corresponds to this attribute.
335    *
336    * @return the byte array form with saved annotations.
337    */

338
339   public static ByteVector writeParametersAnnotations (ByteVector bv,
340                                                        List JavaDoc parameters,
341                                                        ClassWriter cw) {
342     bv.putByte(parameters.size());
343     for (int i = 0; i < parameters.size(); i++) {
344       writeAnnotations(bv, (List JavaDoc)parameters.get(i), cw);
345     }
346     return bv;
347   }
348
349   /**
350    * Returns annotation values in the format described in JSR-175 for Java
351    * source code.
352    *
353    * @param annotations a list of annotations.
354    * @return annotation values in the format described in JSR-175 for Java
355    * source code.
356    */

357
358   public static String JavaDoc stringAnnotations (List JavaDoc annotations) {
359     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
360     if (annotations.size() > 0) {
361       for (int i = 0; i < annotations.size(); i++) {
362         sb.append('\n').append(annotations.get(i));
363       }
364     } else {
365       sb.append( "<none>");
366     }
367     return sb.toString();
368   }
369
370   /**
371    * Returns parameter annotation values in the format described in JSR-175
372    * for Java source code.
373    *
374    * @param parameters a list of parameter annotations.
375    * @return parameter annotation values in the format described in JSR-175
376    * for Java source code.
377    */

378
379   public static String JavaDoc stringParameterAnnotations (List JavaDoc parameters) {
380     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
381     String JavaDoc sep = "";
382     for (int i = 0; i < parameters.size(); i++) {
383       sb.append(sep).append(stringAnnotations((List JavaDoc)parameters.get(i)));
384       sep = ", ";
385     }
386     return sb.toString();
387   }
388
389   /**
390    * Reads element_value data structures.
391    *
392    * @param cr the class that contains the attribute to be read.
393    * @param off index of the first byte of the data structure.
394    * @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
395    * {@link ClassReader#readClass(int,char[]) readClass} or {@link
396    * ClassReader#readConst readConst}.
397    *
398    * @return offset position in bytecode after reading annotation
399    */

400
401   protected static Object JavaDoc readValue (ClassReader cr, int[] off, char[] buf) {
402     Object JavaDoc value = null;
403     int tag = cr.readByte(off[ 0]++);
404     switch (tag) {
405       case 'I': // pointer to CONSTANT_Integer
406
case 'J': // pointer to CONSTANT_Long
407
case 'D': // pointer to CONSTANT_Double
408
case 'F': // pointer to CONSTANT_Float
409
value = cr.readConst(cr.readUnsignedShort(off[0]), buf);
410         off[0] += 2;
411         break;
412
413       case 'B': // pointer to CONSTANT_Byte
414
value = new Byte JavaDoc(( byte) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
415         off[0] += 2;
416         break;
417         
418       case 'C': // pointer to CONSTANT_Char
419
value = new Character JavaDoc(( char) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
420         off[0] += 2;
421         break;
422         
423       case 'S': // pointer to CONSTANT_Short
424
value = new Short JavaDoc(( short) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
425         off[0] += 2;
426         break;
427         
428       case 'Z': // pointer to CONSTANT_Boolean
429
value = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))==0 ? Boolean.FALSE : Boolean.TRUE;
430         off[0] += 2;
431         break;
432         
433       case 's': // pointer to CONSTANT_Utf8
434
value = cr.readUTF8(off[0], buf);
435         off[0] += 2;
436         break;
437
438       case 'e': // enum_const_value
439
// TODO verify the data structures
440
value = new EnumConstValue(cr.readUTF8(off[0], buf), cr.readUTF8(off[0] + 2, buf));
441         off[0] += 4;
442         break;
443
444       case 'c': // class_info
445
value = Type.getType(cr.readUTF8(off[0], buf));
446         off[0] += 2;
447         break;
448
449       case '@': // annotation_value
450
value = new Annotation();
451         off[0] = ((Annotation) value).read(cr, off[0], buf);
452         break;
453
454       case '[': // array_value
455
int size = cr.readUnsignedShort(off[0]);
456         off[0] += 2;
457         int childTag = cr.readByte( off[ 0]);
458         switch( childTag) {
459           case 'I': // pointer to CONSTANT_Integer
460
{
461               int[] v = new int[ size];
462               for( int i = 0; i < size; i++) {
463                 off[ 0]++; // skip element tag
464
v[ i] = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
465                 off[ 0] += 2;
466               }
467               value = v;
468             }
469             break;
470             
471           case 'J': // pointer to CONSTANT_Long
472
{
473               long[] v = new long[ size];
474               for( int i = 0; i < size; i++) {
475                 off[ 0]++; // skip element tag
476
v[ i] = cr.readLong( cr.getItem( cr.readUnsignedShort(off[0])));
477                 off[ 0] += 2;
478               }
479               value = v;
480             }
481             break;
482             
483           case 'D': // pointer to CONSTANT_Double
484
{
485               double[] v = new double[ size];
486               for( int i = 0; i < size; i++) {
487                 off[ 0]++; // skip element tag
488
v[ i] = Double.longBitsToDouble( cr.readLong( cr.getItem( cr.readUnsignedShort(off[0]))));
489                 off[ 0] += 2;
490               }
491               value = v;
492             }
493             break;
494             
495           case 'F': // pointer to CONSTANT_Float
496
{
497               float[] v = new float[ size];
498               for( int i = 0; i < size; i++) {
499                 off[ 0]++; // skip element tag
500
v[ i] = Float.intBitsToFloat( cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
501                 off[ 0] += 2;
502               }
503               value = v;
504             }
505             break;
506     
507           case 'B': // pointer to CONSTANT_Byte
508
{
509               byte[] v = new byte[ size];
510               for( int i = 0; i < size; i++) {
511                 off[ 0]++; // skip element tag
512
v[ i] = ( byte) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
513                 off[ 0] += 2;
514               }
515               value = v;
516             }
517             break;
518               
519           case 'C': // pointer to CONSTANT_Char
520
{
521               char[] v = new char[ size];
522               for( int i = 0; i < size; i++) {
523                 off[ 0]++; // skip element tag
524
v[ i] = ( char) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
525                 off[ 0] += 2;
526               }
527               value = v;
528             }
529             break;
530               
531           case 'S': // pointer to CONSTANT_Short
532
{
533               short[] v = new short[ size];
534               for( int i = 0; i < size; i++) {
535                 off[ 0]++; // skip element tag
536
v[ i] = ( short) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
537                 off[ 0] += 2;
538               }
539               value = v;
540             }
541             break;
542               
543           case 'Z': // pointer to CONSTANT_Boolean
544
{
545               boolean[] v = new boolean[ size];
546               for( int i = 0; i < size; i++) {
547                 off[ 0]++; // skip element tag
548
v[ i] = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))!=0;
549                 off[ 0] += 2;
550               }
551               value = v;
552             }
553             break;
554               
555           default:
556             Object JavaDoc[] v = new Object JavaDoc[ size];
557             value = v;
558             for (int i = 0; i < size; i++) {
559               v[i] = readValue(cr, off, buf);
560             }
561             break;
562         }
563         
564     }
565     return value;
566   }
567
568   /**
569    * Writes element_value data structures.
570    *
571    * @param bv the byte array form to store data structures.
572    * @param value
573    * @param cw the class to which this attribute must be added. This parameter
574    * can be used to add to the constant pool of this class the items that
575    * corresponds to this attribute.
576    * @return bv.
577    */

578
579   protected static ByteVector writeValue (ByteVector bv, Object JavaDoc value, ClassWriter cw) {
580     if (value instanceof String JavaDoc) {
581       bv.putByte('s');
582       bv.putShort(cw.newUTF8((String JavaDoc)value));
583     
584     } else if (value instanceof EnumConstValue) {
585       bv.putByte('e');
586       bv.putShort(cw.newUTF8(((EnumConstValue)value).typeName));
587       bv.putShort(cw.newUTF8(((EnumConstValue)value).constName));
588     
589     } else if (value instanceof Type) {
590       bv.putByte('c');
591       bv.putShort(cw.newUTF8(((Type)value).getDescriptor()));
592     
593     } else if (value instanceof Annotation) {
594       bv.putByte('@');
595       ((Annotation)value).write(bv, cw);
596     
597     } else if (value instanceof Object JavaDoc[]) {
598       bv.putByte('[');
599       Object JavaDoc[] v = (Object JavaDoc[])value;
600       bv.putShort(v.length);
601       for (int i = 0; i < v.length; i++) {
602         writeValue(bv, v[i], cw);
603       }
604     
605     } else if( value instanceof byte[]) {
606       bv.putByte('[');
607       byte[] v = (byte[])value;
608       bv.putShort(v.length);
609       for (int i = 0; i < v.length; i++) {
610         bv.putByte('B');
611         bv.putShort(cw.newConstInt(v[i]));
612       }
613       
614     } else if( value instanceof short[]) {
615       bv.putByte('[');
616       short[] v = (short[])value;
617       bv.putShort(v.length);
618       for (int i = 0; i < v.length; i++) {
619         bv.putByte('S');
620         bv.putShort(cw.newConstInt(v[i]));
621       }
622       
623     } else if( value instanceof int[]) {
624       bv.putByte('[');
625       int[] v = (int[])value;
626       bv.putShort(v.length);
627       for (int i = 0; i < v.length; i++) {
628         bv.putByte('I');
629         bv.putShort(cw.newConstInt(v[i]));
630       }
631       
632     } else if( value instanceof char[]) {
633       bv.putByte('[');
634       char[] v = (char[])value;
635       bv.putShort(v.length);
636       for (int i = 0; i < v.length; i++) {
637         bv.putByte('C');
638         bv.putShort(cw.newConstInt(v[i]));
639       }
640       
641     } else if( value instanceof boolean[]) {
642       bv.putByte('[');
643       boolean[] v = (boolean[])value;
644       bv.putShort(v.length);
645       for (int i = 0; i < v.length; i++) {
646         bv.putByte('Z');
647         bv.putShort(cw.newConstInt(v[i] ? 1 : 0));
648       }
649       
650     } else if( value instanceof long[]) {
651       bv.putByte('[');
652       long[] v = (long[])value;
653       bv.putShort(v.length);
654       for (int i = 0; i < v.length; i++) {
655         bv.putByte('J');
656         bv.putShort(cw.newConstLong(v[i]));
657       }
658       
659     } else if( value instanceof float[]) {
660       bv.putByte('[');
661       float[] v = (float[])value;
662       bv.putShort(v.length);
663       for (int i = 0; i < v.length; i++) {
664         bv.putByte('F');
665         bv.putShort(cw.newConstFloat(v[i]));
666       }
667       
668     } else if( value instanceof double[]) {
669       bv.putByte('[');
670       double[] v = (double[])value;
671       bv.putShort(v.length);
672       for (int i = 0; i < v.length; i++) {
673         bv.putByte('D');
674         bv.putShort(cw.newConstDouble(v[i]));
675       }
676       
677     } else {
678       int tag = -1;
679       if (value instanceof Integer JavaDoc) {
680         tag = 'I';
681       } else if (value instanceof Byte JavaDoc) {
682         tag = 'B';
683       } else if (value instanceof Character JavaDoc) {
684         tag = 'C';
685       } else if (value instanceof Double JavaDoc) {
686         tag = 'D';
687       } else if (value instanceof Float JavaDoc) {
688         tag = 'F';
689       } else if (value instanceof Long JavaDoc) {
690         tag = 'J';
691       } else if (value instanceof Short JavaDoc) {
692         tag = 'S';
693       } else if (value instanceof Boolean JavaDoc) {
694         tag = 'Z';
695       }
696       bv.putByte(tag);
697       bv.putShort(cw.newConst(value));
698     
699     }
700
701     return bv;
702   }
703
704   
705   /**
706    * Returns value in the format described in JSR-175 for Java source code.
707    *
708    * @return value in the format described in JSR-175 for Java source code.
709    */

710
711   public String JavaDoc toString () {
712     StringBuffer JavaDoc sb = new StringBuffer JavaDoc("@").append(type);
713     // shorthand syntax for marker annotation
714
if (elementValues.size() > 0) {
715       sb.append(" ( ");
716       String JavaDoc sep = "";
717       for (int i = 0; i < elementValues.size(); i++) {
718         Object JavaDoc[] value = (Object JavaDoc[])elementValues.get(i);
719         // using shorthand syntax for single-element annotation
720
if ( !( elementValues.size()==1 || "value".equals( elementValues.get( 0)))) {
721           sb.append(sep).append(value[0]).append(" = ");
722         }
723         if(value[1] instanceof Object JavaDoc[]) {
724           Object JavaDoc[] v = ( Object JavaDoc[]) value[1];
725           sb.append("{");
726           String JavaDoc sep2 = "";
727           for( int j = 0; j < v.length; j++) {
728             sb.append(sep2).append(v[ j]);
729             sep2 = ", ";
730           }
731           sb.append("}");
732         } else {
733           sb.append(value[1]);
734         }
735         sep = ", ";
736       }
737       sb.append(" )");
738     }
739     return sb.toString();
740   }
741   
742   
743   /**
744    * Container class used to store enum_const_value structure.
745    */

746   public static class EnumConstValue {
747
748     public String JavaDoc typeName;
749
750     public String JavaDoc constName;
751
752     public EnumConstValue (String JavaDoc typeName, String JavaDoc constName) {
753       this.typeName = typeName;
754       this.constName = constName;
755     }
756
757     public String JavaDoc toString () {
758       return typeName + ":" + constName;
759     }
760   }
761   
762 }
763
764
Popular Tags