Annotationpublic class Annotation extends Object Annotation data contains an annotated type and its array of the element-value
pairs. Structure is in the following format:
annotation {
u2 type_index;
u2 num_element_value_pairs;
{
u2 element_name_index;
element_value value;
} element_value_pairs[num_element_value_pairs];
}
The items of the annotation structure are as follows:
- type_index
- The value of the type_index item must be a valid index into the constant_pool
table. The constant_pool entry at that index must be a CONSTANT_Utf8_info
structure representing a field descriptor representing the annotation
interface corresponding to the annotation represented by this annotation
structure.
- num_element_value_pairs
- The value of the num_element_value_pairs item gives the number of element-value
pairs in the annotation represented by this annotation structure. Note that a
maximum of 65535 element-value pairs may be contained in a single annotation.
- element_value_pairs
- Each value of the element_value_pairs table represents a single element-value
pair in the annotation represented by this annotation structure.
Each element_value_pairs entry contains the following two items:
- element_name_index
- The value of the element_name_index item must be a valid index into the
constant_pool table. The constant_pool entry at that index must be a
CONSTANT_Utf8_info structure representing the name of the annotation type
element corresponding to this element_value_pairs entry.
- value
- The value item represents the value in the element-value pair represented by
this element_value_pairs entry.
The element_value structure is a discriminated union representing the value of a
element-value pair. It is used to represent values in all class file attributes
that describe annotations ( RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations,
RuntimeVisibleParameterAnnotations, and RuntimeInvisibleParameterAnnotations).
The element_value structure has the following format:
element_value {
u1 tag;
union {
u2 const_value_index;
{
u2 type_name_index;
u2 const_name_index;
} enum_const_value;
u2 class_info_index;
annotation annotation_value;
{
u2 num_values;
element_value values[num_values];
} array_value;
} value;
}
The items of the element_value structure are as follows:
- tag
- The tag item indicates the type of this annotation element-value pair. The letters
'B', 'C', 'D', 'F', 'I', 'J', 'S', and 'Z' indicate a primitive type. These
letters are interpreted as BaseType characters (Table 4.2). The other legal
values for tag are listed with their interpretations in this table:
tag value Element Type
's' String
'e' enum constant
'c' class
'@' annotation type
'[' array
- value
- The value item represents the value of this annotation element. This item is
a union. The tag item, above, determines which item of the union is to be used:
- const_value_index
- The const_value_index item is used if the tag item is one of 'B', 'C', 'D',
'F', 'I', 'J', 'S', 'Z', or 's'. The value of the const_value_index item must
be a valid index into the constant_pool table. The constant_pool entry at
that index must be of the correct entry type for the field type designated by
the tag item, as specified in table 4.6, with one exception: if the tag is
's', the the value of the const_value_index item must be the index of a
CONSTANT_Utf8 structure, rather than a CONSTANT_String.
- enum_const_value
- The enum_const_value item is used if the tag item is 'e'. The
enum_const_value item consists of the following two items:
- type_name_index
- The value of the type_name_index item must be a valid index into the
constant_pool table. The constant_pool entry at that index must be a
CONSTANT_Utf8_info structure representing the binary name (JLS 13.1) of the
type of the enum constant represented by this element_value structure.
- const_name_index
- The value of the const_name_index item must be a valid index into the
constant_pool table. The constant_pool entry at that index must be a
CONSTANT_Utf8_info structure representing the simple name of the enum
constant represented by this element_value structure.
- class_info_index
- The class_info_index item is used if the tag item is 'c'. The
class_info_index item must be a valid index into the constant_pool table.
The constant_pool entry at that index must be a CONSTANT_Utf8_info
structure representing the return descriptor of the type that is
reified by the class represented by this element_value structure.
- annotation_value
- The annotation_value item is used if the tag item is '@'. The element_value
structure represents a "nested" {@link oracle.toplink.libraries.asm.attrs.Annotation annotation}.
- array_value
- The array_value item is used if the tag item is '['. The array_value item
consists of the following two items:
- num_values
- The value of the num_values item gives the number of elements in the
array-typed value represented by this element_value structure. Note that a
maximum of 65535 elements are permitted in an array-typed element value.
- values
- Each element of the values table gives the value of an element of the
array-typed value represented by this {@link AnnotationElementValue element_value structure}.
|
Fields Summary |
---|
public String | typeA fully qualified class name in internal form (see {@link Type Type}). | public List | elementValuesList of Object[]{name, value} pairs.
Where name is String and value is one of
Byte , Character , Double ,
Float , Integer , Long , Short ,
Boolean , String ,
Annotation.EnumConstValue , Type ,
Annotation or Object[] . |
Constructors Summary |
---|
public Annotation()
| public Annotation(String type)
this.type = type;
|
Methods Summary |
---|
public void | add(java.lang.String name, java.lang.Object value)
elementValues.add(new Object[]{name, value});
| public int | read(oracle.toplink.libraries.asm.ClassReader cr, int off, char[] buf)Reads annotation data structures.
type = cr.readUTF8(off, buf);
int numElementValuePairs = cr.readUnsignedShort(off + 2);
off += 4;
int[] aoff = new int[] { off};
for (int i = 0; i < numElementValuePairs; i++) {
String elementName = cr.readUTF8(aoff[ 0], buf);
aoff[ 0] += 2;
elementValues.add(new Object[]{elementName, readValue(cr, aoff, buf)});
}
return aoff[ 0];
| public static int | readAnnotations(java.util.List annotations, oracle.toplink.libraries.asm.ClassReader cr, int off, char[] buf)Utility method to read List of annotations. Each element of annotations
List will have Annotation instance.
int size = cr.readUnsignedShort(off);
off += 2;
for (int i = 0; i < size; i++) {
Annotation ann = new Annotation();
off = ann.read(cr, off, buf);
annotations.add(ann);
}
return off;
| public static void | readParameterAnnotations(java.util.List parameters, oracle.toplink.libraries.asm.ClassReader cr, int off, char[] buf)Utility method to read List of parameters annotations.
int numParameters = cr.b[off++] & 0xff;
for (int i = 0; i < numParameters; i++) {
List annotations = new ArrayList();
off = Annotation.readAnnotations(annotations, cr, off, buf);
parameters.add(annotations);
}
| protected static java.lang.Object | readValue(oracle.toplink.libraries.asm.ClassReader cr, int[] off, char[] buf)Reads element_value data structures.
Object value = null;
int tag = cr.readByte(off[ 0]++);
switch (tag) {
case 'I": // pointer to CONSTANT_Integer
case 'J": // pointer to CONSTANT_Long
case 'D": // pointer to CONSTANT_Double
case 'F": // pointer to CONSTANT_Float
value = cr.readConst(cr.readUnsignedShort(off[0]), buf);
off[0] += 2;
break;
case 'B": // pointer to CONSTANT_Byte
value = new Byte(( byte) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
off[0] += 2;
break;
case 'C": // pointer to CONSTANT_Char
value = new Character(( char) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
off[0] += 2;
break;
case 'S": // pointer to CONSTANT_Short
value = new Short(( short) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
off[0] += 2;
break;
case 'Z": // pointer to CONSTANT_Boolean
value = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))==0 ? Boolean.FALSE : Boolean.TRUE;
off[0] += 2;
break;
case 's": // pointer to CONSTANT_Utf8
value = cr.readUTF8(off[0], buf);
off[0] += 2;
break;
case 'e": // enum_const_value
// TODO verify the data structures
value = new EnumConstValue(cr.readUTF8(off[0], buf), cr.readUTF8(off[0] + 2, buf));
off[0] += 4;
break;
case 'c": // class_info
value = Type.getType(cr.readUTF8(off[0], buf));
off[0] += 2;
break;
case '@": // annotation_value
value = new Annotation();
off[0] = ((Annotation) value).read(cr, off[0], buf);
break;
case '[": // array_value
int size = cr.readUnsignedShort(off[0]);
off[0] += 2;
//PATCH for GF#1624 (From ASM Team) - handle empty annotation array value
if(size==0) return new Object[0];
int childTag = cr.readByte( off[ 0]);
switch( childTag) {
case 'I": // pointer to CONSTANT_Integer
{
int[] v = new int[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
off[ 0] += 2;
}
value = v;
}
break;
case 'J": // pointer to CONSTANT_Long
{
long[] v = new long[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = cr.readLong( cr.getItem( cr.readUnsignedShort(off[0])));
off[ 0] += 2;
}
value = v;
}
break;
case 'D": // pointer to CONSTANT_Double
{
double[] v = new double[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = Double.longBitsToDouble( cr.readLong( cr.getItem( cr.readUnsignedShort(off[0]))));
off[ 0] += 2;
}
value = v;
}
break;
case 'F": // pointer to CONSTANT_Float
{
float[] v = new float[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = Float.intBitsToFloat( cr.readInt( cr.getItem( cr.readUnsignedShort(off[0]))));
off[ 0] += 2;
}
value = v;
}
break;
case 'B": // pointer to CONSTANT_Byte
{
byte[] v = new byte[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = ( byte) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
off[ 0] += 2;
}
value = v;
}
break;
case 'C": // pointer to CONSTANT_Char
{
char[] v = new char[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = ( char) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
off[ 0] += 2;
}
value = v;
}
break;
case 'S": // pointer to CONSTANT_Short
{
short[] v = new short[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = ( short) cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])));
off[ 0] += 2;
}
value = v;
}
break;
case 'Z": // pointer to CONSTANT_Boolean
{
boolean[] v = new boolean[ size];
for( int i = 0; i < size; i++) {
off[ 0]++; // skip element tag
v[ i] = cr.readInt( cr.getItem( cr.readUnsignedShort(off[0])))!=0;
off[ 0] += 2;
}
value = v;
}
break;
default:
Object[] v = new Object[ size];
value = v;
for (int i = 0; i < size; i++) {
v[i] = readValue(cr, off, buf);
}
break;
}
}
return value;
| public static java.lang.String | stringAnnotations(java.util.List annotations)Returns annotation values in the format described in JSR-175 for Java
source code.
StringBuffer sb = new StringBuffer();
if (annotations.size() > 0) {
for (int i = 0; i < annotations.size(); i++) {
sb.append('\n").append(annotations.get(i));
}
} else {
sb.append( "<none>");
}
return sb.toString();
| public static java.lang.String | stringParameterAnnotations(java.util.List parameters)Returns parameter annotation values in the format described in JSR-175
for Java source code.
StringBuffer sb = new StringBuffer();
String sep = "";
for (int i = 0; i < parameters.size(); i++) {
sb.append(sep).append(stringAnnotations((List)parameters.get(i)));
sep = ", ";
}
return sb.toString();
| public java.lang.String | toString()Returns value in the format described in JSR-175 for Java source code.
StringBuffer sb = new StringBuffer("@").append(type);
// shorthand syntax for marker annotation
if (elementValues.size() > 0) {
sb.append(" ( ");
String sep = "";
for (int i = 0; i < elementValues.size(); i++) {
Object[] value = (Object[])elementValues.get(i);
// using shorthand syntax for single-element annotation
if ( !( elementValues.size()==1 || "value".equals( elementValues.get( 0)))) {
sb.append(sep).append(value[0]).append(" = ");
}
if(value[1] instanceof Object[]) {
Object[] v = ( Object[]) value[1];
sb.append("{");
String sep2 = "";
for( int j = 0; j < v.length; j++) {
sb.append(sep2).append(v[ j]);
sep2 = ", ";
}
sb.append("}");
} else {
sb.append(value[1]);
}
sep = ", ";
}
sb.append(" )");
}
return sb.toString();
| public void | write(oracle.toplink.libraries.asm.ByteVector bv, oracle.toplink.libraries.asm.ClassWriter cw)Writes annotation data structures.
bv.putShort(cw.newUTF8(type));
bv.putShort(elementValues.size());
for (int i = 0; i < elementValues.size(); i++) {
Object[] value = (Object[])elementValues.get(i);
bv.putShort(cw.newUTF8((String)value[0]));
writeValue(bv, value[1], cw);
}
| public static oracle.toplink.libraries.asm.ByteVector | writeAnnotations(oracle.toplink.libraries.asm.ByteVector bv, java.util.List annotations, oracle.toplink.libraries.asm.ClassWriter cw)Utility method to write List of annotations.
bv.putShort(annotations.size());
for (int i = 0; i < annotations.size(); i++) {
((Annotation)annotations.get(i)).write(bv, cw);
}
return bv;
| public static oracle.toplink.libraries.asm.ByteVector | writeParametersAnnotations(oracle.toplink.libraries.asm.ByteVector bv, java.util.List parameters, oracle.toplink.libraries.asm.ClassWriter cw)Utility method to write List of parameters annotations.
bv.putByte(parameters.size());
for (int i = 0; i < parameters.size(); i++) {
writeAnnotations(bv, (List)parameters.get(i), cw);
}
return bv;
| protected static oracle.toplink.libraries.asm.ByteVector | writeValue(oracle.toplink.libraries.asm.ByteVector bv, java.lang.Object value, oracle.toplink.libraries.asm.ClassWriter cw)Writes element_value data structures.
if (value instanceof String) {
bv.putByte('s");
bv.putShort(cw.newUTF8((String)value));
} else if (value instanceof EnumConstValue) {
bv.putByte('e");
bv.putShort(cw.newUTF8(((EnumConstValue)value).typeName));
bv.putShort(cw.newUTF8(((EnumConstValue)value).constName));
} else if (value instanceof Type) {
bv.putByte('c");
bv.putShort(cw.newUTF8(((Type)value).getDescriptor()));
} else if (value instanceof Annotation) {
bv.putByte('@");
((Annotation)value).write(bv, cw);
} else if (value instanceof Object[]) {
bv.putByte('[");
Object[] v = (Object[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
writeValue(bv, v[i], cw);
}
} else if( value instanceof byte[]) {
bv.putByte('[");
byte[] v = (byte[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('B");
bv.putShort(cw.newConstInt(v[i]));
}
} else if( value instanceof short[]) {
bv.putByte('[");
short[] v = (short[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('S");
bv.putShort(cw.newConstInt(v[i]));
}
} else if( value instanceof int[]) {
bv.putByte('[");
int[] v = (int[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('I");
bv.putShort(cw.newConstInt(v[i]));
}
} else if( value instanceof char[]) {
bv.putByte('[");
char[] v = (char[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('C");
bv.putShort(cw.newConstInt(v[i]));
}
} else if( value instanceof boolean[]) {
bv.putByte('[");
boolean[] v = (boolean[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('Z");
bv.putShort(cw.newConstInt(v[i] ? 1 : 0));
}
} else if( value instanceof long[]) {
bv.putByte('[");
long[] v = (long[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('J");
bv.putShort(cw.newConstLong(v[i]));
}
} else if( value instanceof float[]) {
bv.putByte('[");
float[] v = (float[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('F");
bv.putShort(cw.newConstFloat(v[i]));
}
} else if( value instanceof double[]) {
bv.putByte('[");
double[] v = (double[])value;
bv.putShort(v.length);
for (int i = 0; i < v.length; i++) {
bv.putByte('D");
bv.putShort(cw.newConstDouble(v[i]));
}
} else {
int tag = -1;
if (value instanceof Integer) {
tag = 'I";
} else if (value instanceof Byte) {
tag = 'B";
} else if (value instanceof Character) {
tag = 'C";
} else if (value instanceof Double) {
tag = 'D";
} else if (value instanceof Float) {
tag = 'F";
} else if (value instanceof Long) {
tag = 'J";
} else if (value instanceof Short) {
tag = 'S";
} else if (value instanceof Boolean) {
tag = 'Z";
}
bv.putByte(tag);
bv.putShort(cw.newConst(value));
}
return bv;
|
|