FileDocCategorySizeDatePackage
Annotation.javaAPI DocGlassfish v2 API26814Mon Mar 12 07:37:36 GMT 2007oracle.toplink.libraries.asm.attrs

Annotation

public 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}.
see
JSR 175 : A Metadata Facility for the Java Programming Language
author
Eugene Kuleshov

Fields Summary
public String
type
A fully qualified class name in internal form (see {@link Type Type}).
public List
elementValues
List 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 voidadd(java.lang.String name, java.lang.Object value)

    elementValues.add(new Object[]{name, value});
  
public intread(oracle.toplink.libraries.asm.ClassReader cr, int off, char[] buf)
Reads annotation data structures.

param
cr the class that contains the attribute to be read.
param
off index of the first byte of the data structure.
param
buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.
return
offset position in bytecode after reading annotation

    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 intreadAnnotations(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.

param
annotations the List to store parameters annotations.
param
cr the class that contains the attribute to be read.
param
off index of the first byte of the data structure.
param
buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.
return
offset position in bytecode after reading annotations

    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 voidreadParameterAnnotations(java.util.List parameters, oracle.toplink.libraries.asm.ClassReader cr, int off, char[] buf)
Utility method to read List of parameters annotations.

param
parameters the List to store parameters annotations. Each element of the parameters List will have List of Annotation instances.
param
cr the class that contains the attribute to be read.
param
off index of the first byte of the data structure.
param
buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.

    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.ObjectreadValue(oracle.toplink.libraries.asm.ClassReader cr, int[] off, char[] buf)
Reads element_value data structures.

param
cr the class that contains the attribute to be read.
param
off index of the first byte of the data structure.
param
buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.
return
offset position in bytecode after reading annotation

    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.StringstringAnnotations(java.util.List annotations)
Returns annotation values in the format described in JSR-175 for Java source code.

param
annotations a list of annotations.
return
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.StringstringParameterAnnotations(java.util.List parameters)
Returns parameter annotation values in the format described in JSR-175 for Java source code.

param
parameters a list of parameter annotations.
return
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.StringtoString()
Returns value in the format described in JSR-175 for Java source code.

return
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 voidwrite(oracle.toplink.libraries.asm.ByteVector bv, oracle.toplink.libraries.asm.ClassWriter cw)
Writes annotation data structures.

param
bv the byte array form to store data structures.
param
cw the class to which this attribute must be added. This parameter can be used to add to the constant pool of this class the items that corresponds to this attribute.

    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.ByteVectorwriteAnnotations(oracle.toplink.libraries.asm.ByteVector bv, java.util.List annotations, oracle.toplink.libraries.asm.ClassWriter cw)
Utility method to write List of annotations.

param
bv the byte array form to store data structures.
param
annotations the List of annotations to write. Elements should be instances of the Annotation class.
param
cw the class to which this attribute must be added. This parameter can be used to add to the constant pool of this class the items that corresponds to this attribute.
return
the byte array form with saved 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.ByteVectorwriteParametersAnnotations(oracle.toplink.libraries.asm.ByteVector bv, java.util.List parameters, oracle.toplink.libraries.asm.ClassWriter cw)
Utility method to write List of parameters annotations.

param
bv the byte array form to store data structures.
param
parameters the List of parametars to write. Elements should be instances of the List that contains instances of the Annotation class.
param
cw the class to which this attribute must be added. This parameter can be used to add to the constant pool of this class the items that corresponds to this attribute.
return
the byte array form with saved 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.ByteVectorwriteValue(oracle.toplink.libraries.asm.ByteVector bv, java.lang.Object value, oracle.toplink.libraries.asm.ClassWriter cw)
Writes element_value data structures.

param
bv the byte array form to store data structures.
param
value
param
cw the class to which this attribute must be added. This parameter can be used to add to the constant pool of this class the items that corresponds to this attribute.
return
bv.

    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;