git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@111 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
* A class representing | * A class representing | ||||
* <code>RuntimeVisibleAnnotations_attribute</code> and | * <code>RuntimeVisibleAnnotations_attribute</code> and | ||||
* <code>RuntimeInvisibleAnnotations_attribute</code>. | * <code>RuntimeInvisibleAnnotations_attribute</code>. | ||||
* | |||||
* <p>To obtain an AnnotationAttribute object, invoke | |||||
* <code>getAttribute(AnnotationsAttribute.invisibleTag)</code> | |||||
* in <code>ClassFile</code>, <code>MethodInfo</code>, | |||||
* or <code>FieldInfo</code>. The obtained attribute is a | |||||
* runtime invisible annotations attribute. | |||||
* If the parameter is | |||||
* <code>AnnotationAttribute.visibleTag</code>, then the obtained | |||||
* attribute is a runtime visible one. | |||||
* | |||||
* <p>If you want to record a new AnnotationAttribute object, execute the | |||||
* following snippet: | |||||
* | |||||
* <ul><pre> | |||||
* ClassFile cf = ... ; | |||||
* ConstPool cp = cf.getConstPool(); | |||||
* AnnotationsAttribute attr | |||||
* = new AnnotationsAttribute(cp, AnnotationsAttribute.invisibleTag); | |||||
* Annotation a = new Annotation("Author", cp); | |||||
* a.addMemberValue("name", new StringMemberValue("Chiba", cp)); | |||||
* attr.setAnnotation(a); | |||||
* cf.addAttribute(attr); | |||||
* </pre></ul> | |||||
*/ | */ | ||||
public class AnnotationsAttribute extends AttributeInfo { | public class AnnotationsAttribute extends AttributeInfo { | ||||
/** | /** | ||||
/** | /** | ||||
* The name of the <code>RuntimeInvisibleAnnotations</code> attribute. | * The name of the <code>RuntimeInvisibleAnnotations</code> attribute. | ||||
*/ | */ | ||||
public static final String invisibleTag = "RuntimeInvisibleAnnotations"; | |||||
public static final String invisibleTag = "RuntimeInvisibleAnnotations"; | |||||
/** | /** | ||||
* Constructs a <code>Runtime(In)VisisbleAnnotations_attribute</code>. | * Constructs a <code>Runtime(In)VisisbleAnnotations_attribute</code>. | ||||
/** | /** | ||||
* Constructs an empty | * Constructs an empty | ||||
* <code>Runtime(In)VisisbleAnnotations_attribute</code>. | * <code>Runtime(In)VisisbleAnnotations_attribute</code>. | ||||
* A new annotation can be later added to the created attribute | |||||
* by <code>setAnnotations()</code>. | |||||
* | * | ||||
* @param cp constant pool | * @param cp constant pool | ||||
* @param attrname attribute name (<code>visibleTag</code> or | * @param attrname attribute name (<code>visibleTag</code> or | ||||
* <code>invisibleTag</code>). | * <code>invisibleTag</code>). | ||||
* @see #setAnnotations(Annotations[]) | |||||
*/ | */ | ||||
public AnnotationsAttribute(ConstPool cp, String attrname) { | public AnnotationsAttribute(ConstPool cp, String attrname) { | ||||
this(cp, attrname, new byte[] { 0, 0 }); | this(cp, attrname, new byte[] { 0, 0 }); | ||||
/** | /** | ||||
* Copies this attribute and returns a new copy. | * Copies this attribute and returns a new copy. | ||||
* This method works even if this object is an instance of | |||||
* <code>ParameterAnnotationsAttribute</code>. | |||||
*/ | */ | ||||
public AttributeInfo copy(ConstPool newCp, Map classnames) { | public AttributeInfo copy(ConstPool newCp, Map classnames) { | ||||
return new Copier(newCp, classnames).copy(this); | |||||
Copier copier = new Copier(info, constPool, newCp, classnames); | |||||
try { | |||||
copier.annotationArray(); | |||||
return new AnnotationsAttribute(newCp, getName(), copier.close()); | |||||
} | |||||
catch (Exception e) { | |||||
throw new RuntimeException(e.toString()); | |||||
} | |||||
} | } | ||||
AnnotationsAttribute makeCopy(ConstPool newCp, byte[] info) { | |||||
return new AnnotationsAttribute(newCp, getName(), info); | |||||
/** | |||||
* Parses the annotations and returns a data structure representing | |||||
* that parsed annotations. Note that changes of the node values of the | |||||
* returned tree are not reflected on the annotations represented by | |||||
* this object unless the tree is copied back to this object by | |||||
* <code>setAnnotations()</code>. | |||||
* | |||||
* @see #setAnnotations() | |||||
*/ | |||||
public Annotation[] getAnnotations() { | |||||
try { | |||||
return new Parser(info, constPool).parseAnnotations(); | |||||
} | |||||
catch (Exception e) { | |||||
throw new RuntimeException(e.toString()); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Runs the parser to analyze this annotation. | |||||
* It invokes methods on the given visitor object while parsing. | |||||
* Changes the annotations represented by this object according to | |||||
* the given array of <code>Annotation</code> objects. | |||||
* | * | ||||
* @see AnnotationsWriter | |||||
* @param annotations the data structure representing the | |||||
* new annotations. | |||||
*/ | */ | ||||
public void accept(AnnotationsVisitor visitor) throws Exception { | |||||
int num = numAnnotations(); | |||||
int pos = 2; | |||||
visitor.beginAnnotationsArray(num); | |||||
for (int i = 0; i < num; ++i) | |||||
pos = readAnnotation(visitor, pos); | |||||
visitor.endAnnotationsArray(); | |||||
} | |||||
public void setAnnotations(Annotation[] annotations) { | |||||
ByteArrayOutputStream output = new ByteArrayOutputStream(); | |||||
AnnotationsWriter writer = new AnnotationsWriter(output, constPool); | |||||
try { | |||||
int n = annotations.length; | |||||
writer.numAnnotations(n); | |||||
for (int i = 0; i < n; ++i) | |||||
annotations[i].write(writer); | |||||
int readAnnotation(AnnotationsVisitor visitor, int pos) throws Exception { | |||||
int type = ByteArray.readU16bit(info, pos); | |||||
int numPairs = ByteArray.readU16bit(info, pos + 2); | |||||
visitor.beginAnnotation(constPool, type, numPairs); | |||||
pos += 4; | |||||
for (int j = 0; j < numPairs; ++j) | |||||
pos = readMemberValuePair(visitor, pos); | |||||
writer.close(); | |||||
} | |||||
catch (IOException e) { | |||||
throw new RuntimeException(e); // should never reach here. | |||||
} | |||||
visitor.endAnnotation(); | |||||
return pos; | |||||
set(output.toByteArray()); | |||||
} | } | ||||
private int readMemberValuePair(AnnotationsVisitor visitor, int pos) | |||||
throws Exception | |||||
{ | |||||
int nameIndex = ByteArray.readU16bit(info, pos); | |||||
visitor.beginMemberValuePair(constPool, nameIndex); | |||||
pos = readMemberValue(visitor, pos + 2); | |||||
visitor.endMemberValuePair(); | |||||
return pos; | |||||
/** | |||||
* Changes the annotations. A call to this method is equivalent to: | |||||
* <ul><pre>setAnnotations(new Annotation[] { annotation })</pre></ul> | |||||
* | |||||
* @param annotation the data structure representing | |||||
* the new annotation. | |||||
*/ | |||||
public void setAnnotation(Annotation annotation) { | |||||
setAnnotations(new Annotation[] { annotation }); | |||||
} | } | ||||
private int readMemberValue(AnnotationsVisitor visitor, int pos) | |||||
throws Exception | |||||
{ | |||||
int tag = info[pos] & 0xff; | |||||
if (tag == 'e') { | |||||
int typeNameIndex = ByteArray.readU16bit(info, pos + 1); | |||||
int constNameIndex = ByteArray.readU16bit(info, pos + 3); | |||||
visitor.enumConstValue(constPool, typeNameIndex, constNameIndex); | |||||
return pos + 5; | |||||
} | |||||
else if (tag == 'c') { | |||||
int index = ByteArray.readU16bit(info, pos + 1); | |||||
visitor.classInfoIndex(constPool, index); | |||||
return pos + 3; | |||||
} | |||||
else if (tag == '@') { | |||||
visitor.beginAnnotationValue(); | |||||
pos = readAnnotation(visitor, pos + 1); | |||||
visitor.endAnnotationValue(); | |||||
/** | |||||
* Returns a string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
Annotation[] a = getAnnotations(); | |||||
StringBuffer sbuf = new StringBuffer(); | |||||
int i = 0; | |||||
while (i < a.length) { | |||||
sbuf.append(a[i++].toString()); | |||||
if (i != a.length) | |||||
sbuf.append(", "); | |||||
} | |||||
return sbuf.toString(); | |||||
} | |||||
static class Walker { | |||||
byte[] info; | |||||
Walker(byte[] attrInfo) { | |||||
info = attrInfo; | |||||
} | |||||
final void parameters() throws Exception { | |||||
int numParam = info[0] & 0xff; | |||||
parameters(numParam, 1); | |||||
} | |||||
void parameters(int numParam, int pos) throws Exception { | |||||
for (int i = 0; i < numParam; ++i) | |||||
pos = annotationArray(pos); | |||||
} | |||||
final void annotationArray() throws Exception { | |||||
annotationArray(0); | |||||
} | |||||
final int annotationArray(int pos) throws Exception { | |||||
int num = ByteArray.readU16bit(info, pos); | |||||
return annotationArray(pos + 2, num); | |||||
} | |||||
int annotationArray(int pos, int num) throws Exception { | |||||
for (int i = 0; i < num; ++i) | |||||
pos = annotation(pos); | |||||
return pos; | return pos; | ||||
} | } | ||||
else if (tag == '[') { | |||||
int num = ByteArray.readU16bit(info, pos + 1); | |||||
pos += 3; | |||||
visitor.beginArrayValue(num); | |||||
for (int i = 0; i < num; ++i) { | |||||
pos = readMemberValue(visitor, pos); | |||||
visitor.arrayElement(i); | |||||
} | |||||
visitor.endArrayValue(); | |||||
final int annotation(int pos) throws Exception { | |||||
int type = ByteArray.readU16bit(info, pos); | |||||
int numPairs = ByteArray.readU16bit(info, pos + 2); | |||||
return annotation(pos + 4, type, numPairs); | |||||
} | |||||
int annotation(int pos, int type, int numPairs) throws Exception { | |||||
for (int j = 0; j < numPairs; ++j) | |||||
pos = memberValuePair(pos); | |||||
return pos; | return pos; | ||||
} | } | ||||
else { // primitive types or String. | |||||
int index = ByteArray.readU16bit(info, pos + 1); | |||||
visitor.constValueIndex(constPool, tag, index); | |||||
return pos + 3; | |||||
final int memberValuePair(int pos) throws Exception { | |||||
int nameIndex = ByteArray.readU16bit(info, pos); | |||||
return memberValuePair(pos + 2, nameIndex); | |||||
} | } | ||||
} | |||||
/** | |||||
* A visitor for copying the contents of an | |||||
* <code>AnnotationsAttribute</code>. | |||||
* | |||||
* <p>This class is typically used as following: | |||||
* <ul><pre> | |||||
* new Copier(dest, map).copy(src) | |||||
* </pre></ul> | |||||
* | |||||
* <p>This expression returns a copy of the source annotations attribute. | |||||
* | |||||
* @see AnnotationsAttribute#accept(AnnotationsVisitor) | |||||
* @see AnnotationsWriter | |||||
*/ | |||||
public static class Copier extends AnnotationsVisitor { | |||||
protected ByteArrayOutputStream output; | |||||
protected AnnotationsWriter writer; | |||||
protected ConstPool destPool; | |||||
protected Map classnames; | |||||
int memberValuePair(int pos, int nameIndex) throws Exception { | |||||
return memberValue(pos); | |||||
} | |||||
/** | |||||
* Copies a constant pool entry into the destination constant pool | |||||
* and returns the index of the copied entry. | |||||
* | |||||
* @param srcIndex the index of the copied entry into the source | |||||
* constant pool. | |||||
* @return the index of the copied item into the destination | |||||
* constant pool. | |||||
*/ | |||||
protected int copy(ConstPool srcPool, int srcIndex) { | |||||
return srcPool.copy(srcIndex, destPool, classnames); | |||||
final int memberValue(int pos) throws Exception { | |||||
int tag = info[pos] & 0xff; | |||||
if (tag == 'e') { | |||||
int typeNameIndex = ByteArray.readU16bit(info, pos + 1); | |||||
int constNameIndex = ByteArray.readU16bit(info, pos + 3); | |||||
enumMemberValue(typeNameIndex, constNameIndex); | |||||
return pos + 5; | |||||
} | |||||
else if (tag == 'c') { | |||||
int index = ByteArray.readU16bit(info, pos + 1); | |||||
classMemberValue(index); | |||||
return pos + 3; | |||||
} | |||||
else if (tag == '@') | |||||
return annotationMemberValue(pos + 1); | |||||
else if (tag == '[') { | |||||
int num = ByteArray.readU16bit(info, pos + 1); | |||||
return arrayMemberValue(pos + 3, num); | |||||
} | |||||
else { // primitive types or String. | |||||
int index = ByteArray.readU16bit(info, pos + 1); | |||||
constValueMember(tag, index); | |||||
return pos + 3; | |||||
} | |||||
} | |||||
void constValueMember(int tag, int index) throws Exception {} | |||||
void enumMemberValue(int typeNameIndex, int constNameIndex) | |||||
throws Exception {} | |||||
void classMemberValue(int index) throws Exception {} | |||||
int annotationMemberValue(int pos) throws Exception { | |||||
return annotation(pos); | |||||
} | |||||
int arrayMemberValue(int pos, int num) throws Exception { | |||||
for (int i = 0; i < num; ++i) { | |||||
pos = memberValue(pos); | |||||
} | |||||
return pos; | |||||
} | } | ||||
} | |||||
static class Copier extends Walker { | |||||
ByteArrayOutputStream output; | |||||
AnnotationsWriter writer; | |||||
ConstPool srcPool, destPool; | |||||
Map classnames; | |||||
/** | /** | ||||
* Constructs a copier. This copier renames some class names | * Constructs a copier. This copier renames some class names | ||||
* into the new names specified by <code>map</code> when it copies | * into the new names specified by <code>map</code> when it copies | ||||
* an annotation attribute. | * an annotation attribute. | ||||
* | * | ||||
* @param info the source attribute. | |||||
* @param src the constant pool of the source class. | * @param src the constant pool of the source class. | ||||
* @param dest the constant pool of the destination class. | * @param dest the constant pool of the destination class. | ||||
* @param map pairs of replaced and substituted class names. | * @param map pairs of replaced and substituted class names. | ||||
* It can be null. | * It can be null. | ||||
*/ | */ | ||||
public Copier(ConstPool dest, Map map) { | |||||
Copier(byte[] info, ConstPool src, ConstPool dest, Map map) { | |||||
super(info); | |||||
output = new ByteArrayOutputStream(); | output = new ByteArrayOutputStream(); | ||||
writer = new AnnotationsWriter(output, dest); | writer = new AnnotationsWriter(output, dest); | ||||
srcPool = src; | |||||
destPool = dest; | destPool = dest; | ||||
classnames = map; | classnames = map; | ||||
} | } | ||||
/** | |||||
* Does copying. This calls <code>accept()</code> | |||||
* on <code>src</code> with this visitor object. | |||||
* | |||||
* @param src the source attribute. It can be an instance | |||||
* of <code>ParameterAnnotationsAttribute</code>. | |||||
* @return a copy of the source attribute. | |||||
*/ | |||||
public AnnotationsAttribute copy(AnnotationsAttribute src) { | |||||
try { | |||||
src.accept(this); | |||||
writer.close(); | |||||
} | |||||
catch (Exception e) { | |||||
throw new RuntimeException(e.toString()); | |||||
} | |||||
return src.makeCopy(destPool, output.toByteArray()); | |||||
byte[] close() throws IOException { | |||||
writer.close(); | |||||
return output.toByteArray(); | |||||
} | } | ||||
/** | |||||
* Writes <code>num_parameters</code>. | |||||
*/ | |||||
public void beginParameters(int num) throws IOException { | |||||
writer.numParameters(num); | |||||
void parameters(int numParam, int pos) throws Exception { | |||||
writer.numParameters(numParam); | |||||
super.parameters(numParam, pos); | |||||
} | } | ||||
/** | |||||
* Does nothing. | |||||
*/ | |||||
public void endParameters() {} | |||||
/** | |||||
* Writes <code>num_annotations</code>. | |||||
*/ | |||||
public void beginAnnotationsArray(int num) throws IOException { | |||||
int annotationArray(int pos, int num) throws Exception { | |||||
writer.numAnnotations(num); | writer.numAnnotations(num); | ||||
return super.annotationArray(pos, num); | |||||
} | } | ||||
/** | |||||
* Does nothing. | |||||
*/ | |||||
public void endAnnotationsArray() {} | |||||
/** | |||||
* Writes <code>type_index</code> and | |||||
* <code>num_member_value_pairs</code>. | |||||
*/ | |||||
public void beginAnnotation(ConstPool cp, | |||||
int typeIndex, int numMemberValuePairs) | |||||
throws IOException | |||||
{ | |||||
writer.annotation(copy(cp, typeIndex), numMemberValuePairs); | |||||
int annotation(int pos, int type, int numPairs) throws Exception { | |||||
writer.annotation(copy(type), numPairs); | |||||
return super.annotation(pos, type, numPairs); | |||||
} | } | ||||
/** | |||||
* Does nothing. | |||||
*/ | |||||
public void endAnnotation() {} | |||||
/** | |||||
* Writes <code>member_name_index</code>. | |||||
*/ | |||||
public void beginMemberValuePair(ConstPool cp, int memberNameIndex) | |||||
throws IOException | |||||
{ | |||||
writer.memberValuePair(copy(cp, memberNameIndex)); | |||||
int memberValuePair(int pos, int nameIndex) throws Exception { | |||||
writer.memberValuePair(copy(nameIndex)); | |||||
return super.memberValuePair(pos, nameIndex); | |||||
} | } | ||||
/** | |||||
* Does nothing. | |||||
*/ | |||||
public void endMemberValuePair() {} | |||||
/** | |||||
* Writes <code>tag</code> and <code>const_value_index</code>. | |||||
*/ | |||||
public void constValueIndex(ConstPool cp, int tag, int index) | |||||
throws IOException | |||||
{ | |||||
writer.constValueIndex(tag, copy(cp, index)); | |||||
} | |||||
void constValueMember(int tag, int index) throws Exception { | |||||
writer.constValueIndex(tag, copy(index)); | |||||
super.constValueMember(tag, index); | |||||
} | |||||
/** | |||||
* Writes <code>tag</code> and <code>enum_const_value</code>. | |||||
*/ | |||||
public void enumConstValue(ConstPool cp, int typeNameIndex, | |||||
int constNameIndex) | |||||
throws IOException | |||||
void enumMemberValue(int typeNameIndex, int constNameIndex) | |||||
throws Exception | |||||
{ | { | ||||
writer.enumConstValue(copy(cp, typeNameIndex), | |||||
copy(cp, constNameIndex)); | |||||
writer.enumConstValue(copy(typeNameIndex), copy(constNameIndex)); | |||||
super.enumMemberValue(typeNameIndex, constNameIndex); | |||||
} | } | ||||
/** | |||||
* Writes <code>tag</code> and <code>class_info_index</code>. | |||||
*/ | |||||
public void classInfoIndex(ConstPool cp, int index) throws IOException { | |||||
writer.classInfoIndex(copy(cp, index)); | |||||
void classMemberValue(int index) throws Exception { | |||||
writer.classInfoIndex(copy(index)); | |||||
super.classMemberValue(index); | |||||
} | } | ||||
/** | |||||
* Writes <code>tag</code>. | |||||
*/ | |||||
public void beginAnnotationValue() throws IOException { | |||||
int annotationMemberValue(int pos) throws Exception { | |||||
writer.annotationValue(); | writer.annotationValue(); | ||||
return super.annotationMemberValue(pos); | |||||
} | } | ||||
/** | |||||
* Does nothing. | |||||
*/ | |||||
public void endAnnotationValue() {} | |||||
int arrayMemberValue(int pos, int num) throws Exception { | |||||
writer.arrayValue(num); | |||||
return super.arrayMemberValue(pos, num); | |||||
} | |||||
/** | /** | ||||
* Writes <code>num_values</code> in <code>array_value</code>. | |||||
* Copies a constant pool entry into the destination constant pool | |||||
* and returns the index of the copied entry. | |||||
* | |||||
* @param srcIndex the index of the copied entry into the source | |||||
* constant pool. | |||||
* @return the index of the copied item into the destination | |||||
* constant pool. | |||||
*/ | */ | ||||
public void beginArrayValue(int numValues) throws IOException { | |||||
writer.arrayValue(numValues); | |||||
int copy(int srcIndex) { | |||||
return srcPool.copy(srcIndex, destPool, classnames); | |||||
} | } | ||||
} | |||||
/** | |||||
* Does nothing. | |||||
*/ | |||||
public void arrayElement(int i) {} | |||||
static class Parser extends Walker { | |||||
ConstPool pool; | |||||
Annotation[][] allParams; // all parameters | |||||
Annotation[] allAnno; // all annotations | |||||
Annotation currentAnno; // current annotation | |||||
MemberValue memberValue; | |||||
/** | /** | ||||
* Invoked when the parser ends parsing <code>array_value</code> | |||||
* in <code>member_value</code>. | |||||
* Constructs a parser. This parser constructs a parse tree of | |||||
* the annotations. | |||||
* | |||||
* @param info the attribute. | |||||
* @param src the constant pool. | |||||
*/ | */ | ||||
public void endArrayValue() {} | |||||
} | |||||
/** | |||||
* Returns a string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return getName() + ":" + new Printer().toString(this); | |||||
} | |||||
static class Printer extends AnnotationsVisitor { | |||||
private StringBuffer sbuf; | |||||
public Printer() { | |||||
sbuf = new StringBuffer(); | |||||
} | |||||
public String toString(AnnotationsAttribute src) { | |||||
try { | |||||
src.accept(this); | |||||
return sbuf.toString(); | |||||
} | |||||
catch (RuntimeException e) { | |||||
throw e; | |||||
} | |||||
catch (Exception e) { | |||||
throw new RuntimeException(e.toString()); | |||||
} | |||||
Parser(byte[] info, ConstPool cp) { | |||||
super(info); | |||||
pool = cp; | |||||
} | } | ||||
public void beginParameters(int num) { | |||||
sbuf.append("parameters[").append(num).append("]{"); | |||||
Annotation[][] parseParameters() throws Exception { | |||||
parameters(); | |||||
return allParams; | |||||
} | } | ||||
public void endParameters() { | |||||
sbuf.append('}'); | |||||
Annotation[] parseAnnotations() throws Exception { | |||||
annotationArray(); | |||||
return allAnno; | |||||
} | } | ||||
public void beginAnnotationsArray(int num) { | |||||
sbuf.append("annotations[").append(num).append("]{"); | |||||
} | |||||
void parameters(int numParam, int pos) throws Exception { | |||||
Annotation[][] params = new Annotation[numParam][]; | |||||
for (int i = 0; i < numParam; ++i) { | |||||
pos = annotationArray(pos); | |||||
params[i] = allAnno; | |||||
} | |||||
public void endAnnotationsArray() { | |||||
sbuf.append('}'); | |||||
allParams = params; | |||||
} | } | ||||
public void beginAnnotation(ConstPool cp, | |||||
int typeIndex, int numMemberValuePairs) { | |||||
String name = Descriptor.toClassName(cp.getUtf8Info(typeIndex)); | |||||
sbuf.append('@').append(name).append('{'); | |||||
} | |||||
int annotationArray(int pos, int num) throws Exception { | |||||
Annotation[] array = new Annotation[num]; | |||||
for (int i = 0; i < num; ++i) { | |||||
pos = annotation(pos); | |||||
array[i] = currentAnno; | |||||
} | |||||
public void endAnnotation() { | |||||
sbuf.append('}'); | |||||
allAnno = array; | |||||
return pos; | |||||
} | } | ||||
public void beginMemberValuePair(ConstPool cp, int memberNameIndex) { | |||||
sbuf.append(cp.getUtf8Info(memberNameIndex)).append('='); | |||||
int annotation(int pos, int type, int numPairs) throws Exception { | |||||
currentAnno = new Annotation(type, pool); | |||||
return super.annotation(pos, type, numPairs); | |||||
} | } | ||||
public void endMemberValuePair() { | |||||
sbuf.append(", "); | |||||
int memberValuePair(int pos, int nameIndex) throws Exception { | |||||
pos = super.memberValuePair(pos, nameIndex); | |||||
currentAnno.addMemberValue(nameIndex, memberValue); | |||||
return pos; | |||||
} | } | ||||
public void constValueIndex(ConstPool cp, int tag, int index) { | |||||
if (tag == 'Z' || tag == 'B' || tag == 'C' || tag == 'S' | |||||
|| tag == 'I') | |||||
sbuf.append(cp.getIntegerInfo(index)); | |||||
else if (tag == 'J') | |||||
sbuf.append(cp.getLongInfo(index)); | |||||
else if (tag == 'F') | |||||
sbuf.append(cp.getFloatInfo(index)); | |||||
else if (tag == 'D') | |||||
sbuf.append(cp.getDoubleInfo(index)); | |||||
else if (tag == 's') | |||||
sbuf.append('"').append(cp.getUtf8Info(index)).append('"'); | |||||
else | |||||
throw new RuntimeException("unknown tag:" + tag ); | |||||
} | |||||
void constValueMember(int tag, int index) throws Exception { | |||||
MemberValue m; | |||||
ConstPool cp = pool; | |||||
switch (tag) { | |||||
case 'B' : | |||||
m = new ByteMemberValue(index, cp); | |||||
break; | |||||
case 'C' : | |||||
m = new CharMemberValue(index, cp); | |||||
break; | |||||
case 'D' : | |||||
m = new DoubleMemberValue(index, cp); | |||||
break; | |||||
case 'F' : | |||||
m = new FloatMemberValue(index, cp); | |||||
break; | |||||
case 'I' : | |||||
m = new IntegerMemberValue(index, cp); | |||||
break; | |||||
case 'J' : | |||||
m = new LongMemberValue(index, cp); | |||||
break; | |||||
case 'S' : | |||||
m = new ShortMemberValue(index, cp); | |||||
break; | |||||
case 'Z' : | |||||
m = new BooleanMemberValue(index, cp); | |||||
break; | |||||
case 's' : | |||||
m = new StringMemberValue(index, cp); | |||||
break; | |||||
default : | |||||
throw new RuntimeException("unknown tag:" + tag); | |||||
} | |||||
public void enumConstValue(ConstPool cp, int typeNameIndex, | |||||
int constNameIndex) { | |||||
String name | |||||
= Descriptor.toClassName(cp.getUtf8Info(typeNameIndex)); | |||||
sbuf.append(name) | |||||
.append('.').append(cp.getUtf8Info(constNameIndex)); | |||||
} | |||||
memberValue = m; | |||||
super.constValueMember(tag, index); | |||||
} | |||||
public void classInfoIndex(ConstPool cp, int index) | |||||
throws IOException | |||||
void enumMemberValue(int typeNameIndex, int constNameIndex) | |||||
throws Exception | |||||
{ | { | ||||
sbuf.append(Descriptor.toClassName(cp.getUtf8Info(index))) | |||||
.append(" class"); | |||||
memberValue = new EnumMemberValue(typeNameIndex, | |||||
constNameIndex, pool); | |||||
super.enumMemberValue(typeNameIndex, constNameIndex); | |||||
} | } | ||||
public void beginAnnotationValue() {} | |||||
public void endAnnotationValue() {} | |||||
public void beginArrayValue(int numValues) { | |||||
sbuf.append("array[").append(numValues).append("]{"); | |||||
void classMemberValue(int index) throws Exception { | |||||
memberValue = new ClassMemberValue(index, pool); | |||||
super.classMemberValue(index); | |||||
} | } | ||||
public void arrayElement(int i) { | |||||
sbuf.append(", "); | |||||
int annotationMemberValue(int pos) throws Exception { | |||||
Annotation anno = currentAnno; | |||||
pos = super.annotationMemberValue(pos); | |||||
memberValue = new AnnotationMemberValue(currentAnno, pool); | |||||
currentAnno = anno; | |||||
return pos; | |||||
} | } | ||||
public void endArrayValue() { | |||||
sbuf.append('}'); | |||||
int arrayMemberValue(int pos, int num) throws Exception { | |||||
ArrayMemberValue amv = new ArrayMemberValue(pool); | |||||
MemberValue[] elements = new MemberValue[num]; | |||||
for (int i = 0; i < num; ++i) { | |||||
pos = memberValue(pos); | |||||
elements[i] = memberValue; | |||||
} | |||||
amv.setValue(elements); | |||||
memberValue = amv; | |||||
return pos; | |||||
} | } | ||||
} | } | ||||
} | } |
} | } | ||||
static AttributeInfo read(ConstPool cp, DataInputStream in) | static AttributeInfo read(ConstPool cp, DataInputStream in) | ||||
throws IOException | |||||
{ | |||||
throws IOException { | |||||
int name = in.readUnsignedShort(); | int name = in.readUnsignedShort(); | ||||
String nameStr = cp.getUtf8Info(name); | String nameStr = cp.getUtf8Info(name); | ||||
if (nameStr.equals(CodeAttribute.tag)) | |||||
return new CodeAttribute(cp, name, in); | |||||
else if (nameStr.equals(ExceptionsAttribute.tag)) | |||||
return new ExceptionsAttribute(cp, name, in); | |||||
else if (nameStr.equals(ConstantAttribute.tag)) | |||||
return new ConstantAttribute(cp, name, in); | |||||
else if (nameStr.equals(SourceFileAttribute.tag)) | |||||
return new SourceFileAttribute(cp, name, in); | |||||
else if (nameStr.equals(LineNumberAttribute.tag)) | |||||
return new LineNumberAttribute(cp, name, in); | |||||
else if (nameStr.equals(LocalVariableAttribute.tag)) | |||||
return new LocalVariableAttribute(cp, name, in); | |||||
else if (nameStr.equals(SyntheticAttribute.tag)) | |||||
return new SyntheticAttribute(cp, name, in); | |||||
else if (nameStr.equals(DeprecatedAttribute.tag)) | |||||
return new DeprecatedAttribute(cp, name, in); | |||||
else if (nameStr.equals(InnerClassesAttribute.tag)) | |||||
return new InnerClassesAttribute(cp, name, in); | |||||
else if (nameStr.equals(AnnotationsAttribute.visibleTag) | |||||
|| nameStr.equals(AnnotationsAttribute.invisibleTag)) | |||||
return new AnnotationsAttribute(cp, name, in); | |||||
else if (nameStr.equals(ParameterAnnotationsAttribute.visibleTag) | |||||
|| nameStr.equals(ParameterAnnotationsAttribute.invisibleTag)) | |||||
return new ParameterAnnotationsAttribute(cp, name, in); | |||||
else | |||||
return new AttributeInfo(cp, name, in); | |||||
if (nameStr.charAt(0) < 'L') { | |||||
if (nameStr.equals(CodeAttribute.tag)) | |||||
return new CodeAttribute(cp, name, in); | |||||
else if (nameStr.equals(ConstantAttribute.tag)) | |||||
return new ConstantAttribute(cp, name, in); | |||||
else if (nameStr.equals(DeprecatedAttribute.tag)) | |||||
return new DeprecatedAttribute(cp, name, in); | |||||
else if (nameStr.equals(ExceptionsAttribute.tag)) | |||||
return new ExceptionsAttribute(cp, name, in); | |||||
else if (nameStr.equals(InnerClassesAttribute.tag)) | |||||
return new InnerClassesAttribute(cp, name, in); | |||||
} | |||||
else { | |||||
/* Note that the names of Annotations attributes begin with 'R'. | |||||
*/ | |||||
if (nameStr.equals(LineNumberAttribute.tag)) | |||||
return new LineNumberAttribute(cp, name, in); | |||||
else if (nameStr.equals(LocalVariableAttribute.tag)) | |||||
return new LocalVariableAttribute(cp, name, in); | |||||
else if (nameStr.equals(AnnotationsAttribute.visibleTag) | |||||
|| nameStr.equals(AnnotationsAttribute.invisibleTag)) | |||||
return new AnnotationsAttribute(cp, name, in); | |||||
else if (nameStr.equals(ParameterAnnotationsAttribute.visibleTag) | |||||
|| nameStr.equals(ParameterAnnotationsAttribute.invisibleTag)) | |||||
return new ParameterAnnotationsAttribute(cp, name, in); | |||||
else if (nameStr.equals(SourceFileAttribute.tag)) | |||||
return new SourceFileAttribute(cp, name, in); | |||||
else if (nameStr.equals(SyntheticAttribute.tag)) | |||||
return new SyntheticAttribute(cp, name, in); | |||||
} | |||||
return new AttributeInfo(cp, name, in); | |||||
} | } | ||||
/** | /** | ||||
return null; // no such attribute | return null; // no such attribute | ||||
} | } | ||||
static AttributeInfo lookup(LinkedList list, Class type) { | |||||
if (list == null) | |||||
return null; | |||||
ListIterator iterator = list.listIterator(); | |||||
while (iterator.hasNext()) { | |||||
Object obj = iterator.next(); | |||||
if (type.isInstance(obj)) | |||||
return (AttributeInfo)obj; | |||||
} | |||||
return null; // no such attribute | |||||
} | |||||
static synchronized void remove(LinkedList list, String name) { | static synchronized void remove(LinkedList list, String name) { | ||||
if (list == null) | if (list == null) | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
static synchronized void remove(LinkedList list, Class type) { | |||||
if (list == null) | |||||
return; | |||||
ListIterator iterator = list.listIterator(); | |||||
while (iterator.hasNext()) { | |||||
Object obj = iterator.next(); | |||||
if (type.isInstance(obj)) | |||||
iterator.remove(); | |||||
} | |||||
} | |||||
static void writeAll(LinkedList list, DataOutputStream out) | static void writeAll(LinkedList list, DataOutputStream out) | ||||
throws IOException | throws IOException | ||||
{ | { |
import java.util.List; | import java.util.List; | ||||
import javassist.CannotCompileException; | import javassist.CannotCompileException; | ||||
import javassist.bytecode.annotation.AnnotationGroup; | |||||
/** | /** | ||||
* <code>ClassFile</code> represents a Java <code>.class</code> file, | * <code>ClassFile</code> represents a Java <code>.class</code> file, | ||||
ArrayList fields; | ArrayList fields; | ||||
ArrayList methods; | ArrayList methods; | ||||
LinkedList attributes; | LinkedList attributes; | ||||
AnnotationGroup runtimeInvisible; | |||||
AnnotationGroup runtimeVisible; | |||||
String thisclassname; // not JVM-internal name | String thisclassname; // not JVM-internal name | ||||
return attributes; | return attributes; | ||||
} | } | ||||
/** | |||||
* Create an empty (null) attribute "RuntimeInvisibleAnnotations" | |||||
* Usually used so that you can start adding annotations to a particular thing | |||||
*/ | |||||
public void createRuntimeInvisibleGroup() { | |||||
if (runtimeInvisible == null) { | |||||
AttributeInfo attr = | |||||
new AttributeInfo(constPool, "RuntimeInvisibleAnnotations"); | |||||
addAttribute(attr); | |||||
runtimeInvisible = new AnnotationGroup(attr); | |||||
} | |||||
} | |||||
/** | |||||
* Create an empty (null) attribute "RuntimeVisibleAnnotations" | |||||
* Usually used so that you can start adding annotations to a particular thing | |||||
*/ | |||||
public void createRuntimeVisibleGroup() { | |||||
if (runtimeVisible == null) { | |||||
AttributeInfo attr = | |||||
new AttributeInfo(constPool, "RuntimeVisibleAnnotations"); | |||||
addAttribute(attr); | |||||
runtimeVisible = new AnnotationGroup(attr); | |||||
} | |||||
} | |||||
/** | |||||
* Return access object for getting info about annotations | |||||
* This returns runtime invisible annotations as pertains to the | |||||
* CLASS RetentionPolicy | |||||
* @return | |||||
*/ | |||||
public AnnotationGroup getRuntimeInvisibleAnnotations() { | |||||
if (runtimeInvisible != null) | |||||
return runtimeInvisible; | |||||
AttributeInfo invisible = getAttribute("RuntimeInvisibleAnnotations"); | |||||
if (invisible == null) | |||||
return null; | |||||
runtimeInvisible = new AnnotationGroup(invisible); | |||||
return runtimeInvisible; | |||||
} | |||||
/** | |||||
* Return access object for getting info about annotations | |||||
* This returns runtime visible annotations as pertains to the | |||||
* RUNTIME RetentionPolicy | |||||
* @return | |||||
*/ | |||||
public AnnotationGroup getRuntimeVisibleAnnotations() { | |||||
if (runtimeVisible != null) | |||||
return runtimeVisible; | |||||
AttributeInfo visible = getAttribute("RuntimeVisibleAnnotations"); | |||||
if (visible == null) | |||||
return null; | |||||
runtimeVisible = new AnnotationGroup(visible); | |||||
return runtimeVisible; | |||||
} | |||||
/** | /** | ||||
* Returns the attribute with the specified name. | * Returns the attribute with the specified name. | ||||
* | * |
package javassist.bytecode; | package javassist.bytecode; | ||||
import javassist.bytecode.annotation.AnnotationGroup; | |||||
import java.io.DataInputStream; | import java.io.DataInputStream; | ||||
import java.io.DataOutputStream; | import java.io.DataOutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
int name; | int name; | ||||
int descriptor; | int descriptor; | ||||
LinkedList attribute; // may be null. | LinkedList attribute; // may be null. | ||||
AnnotationGroup runtimeInvisible; | |||||
AnnotationGroup runtimeVisible; | |||||
private FieldInfo(ConstPool cp) { | private FieldInfo(ConstPool cp) { | ||||
constPool = cp; | constPool = cp; | ||||
attribute.add(info); | attribute.add(info); | ||||
} | } | ||||
/** | |||||
* Create an empty (null) attribute "RuntimeInvisibleAnnotations" | |||||
* Usually used so that you can start adding annotations to a particular thing | |||||
*/ | |||||
public void createRuntimeInvisibleGroup() { | |||||
if (runtimeInvisible == null) { | |||||
AttributeInfo attr = | |||||
new AttributeInfo(constPool, "RuntimeInvisibleAnnotations"); | |||||
addAttribute(attr); | |||||
runtimeInvisible = new AnnotationGroup(attr); | |||||
} | |||||
} | |||||
/** | |||||
* Create an empty (null) attribute "RuntimeVisibleAnnotations" | |||||
* Usually used so that you can start adding annotations to a particular thing | |||||
*/ | |||||
public void createRuntimeVisibleGroup() { | |||||
if (runtimeVisible == null) { | |||||
AttributeInfo attr = | |||||
new AttributeInfo(constPool, "RuntimeVisibleAnnotations"); | |||||
addAttribute(attr); | |||||
runtimeVisible = new AnnotationGroup(attr); | |||||
} | |||||
} | |||||
/** | |||||
* Return access object for getting info about annotations | |||||
* This returns runtime invisible annotations as pertains to the | |||||
* CLASS RetentionPolicy | |||||
* @return | |||||
*/ | |||||
public AnnotationGroup getRuntimeInvisibleAnnotations() { | |||||
if (runtimeInvisible != null) | |||||
return runtimeInvisible; | |||||
AttributeInfo invisible = getAttribute("RuntimeInvisibleAnnotations"); | |||||
if (invisible == null) | |||||
return null; | |||||
runtimeInvisible = new AnnotationGroup(invisible); | |||||
return runtimeInvisible; | |||||
} | |||||
/** | |||||
* Return access object for getting info about annotations | |||||
* This returns runtime visible annotations as pertains to the | |||||
* RUNTIME RetentionPolicy | |||||
* @return | |||||
*/ | |||||
public AnnotationGroup getRuntimeVisibleAnnotations() { | |||||
if (runtimeVisible != null) | |||||
return runtimeVisible; | |||||
AttributeInfo visible = getAttribute("RuntimeVisibleAnnotations"); | |||||
if (visible == null) | |||||
return null; | |||||
runtimeVisible = new AnnotationGroup(visible); | |||||
return runtimeVisible; | |||||
} | |||||
private void read(DataInputStream in) throws IOException { | private void read(DataInputStream in) throws IOException { | ||||
accessFlags = in.readUnsignedShort(); | accessFlags = in.readUnsignedShort(); | ||||
name = in.readUnsignedShort(); | name = in.readUnsignedShort(); |
package javassist.bytecode; | package javassist.bytecode; | ||||
import javassist.bytecode.annotation.AnnotationGroup; | |||||
import java.io.DataInputStream; | import java.io.DataInputStream; | ||||
import java.io.DataOutputStream; | import java.io.DataOutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
int name; | int name; | ||||
int descriptor; | int descriptor; | ||||
LinkedList attribute; // may be null | LinkedList attribute; // may be null | ||||
AnnotationGroup runtimeInvisible; | |||||
AnnotationGroup runtimeVisible; | |||||
/** | /** | ||||
* The name of constructors: <code><init></code>. | * The name of constructors: <code><init></code>. | ||||
attribute.add(info); | attribute.add(info); | ||||
} | } | ||||
/** | |||||
* Create an empty (null) attribute "RuntimeInvisibleAnnotations" | |||||
* Usually used so that you can start adding annotations to a particular thing | |||||
*/ | |||||
public void createRuntimeInvisibleGroup() { | |||||
if (runtimeInvisible == null) { | |||||
AttributeInfo attr = | |||||
new AttributeInfo(constPool, "RuntimeInvisibleAnnotations"); | |||||
addAttribute(attr); | |||||
runtimeInvisible = new AnnotationGroup(attr); | |||||
} | |||||
} | |||||
/** | |||||
* Create an empty (null) attribute "RuntimeVisibleAnnotations" | |||||
* Usually used so that you can start adding annotations to a particular thing | |||||
*/ | |||||
public void createRuntimeVisibleGroup() { | |||||
if (runtimeVisible == null) { | |||||
AttributeInfo attr = | |||||
new AttributeInfo(constPool, "RuntimeVisibleAnnotations"); | |||||
addAttribute(attr); | |||||
runtimeVisible = new AnnotationGroup(attr); | |||||
} | |||||
} | |||||
/** | |||||
* Return access object for getting info about annotations | |||||
* This returns runtime invisible annotations as pertains to the | |||||
* CLASS RetentionPolicy | |||||
* @return | |||||
*/ | |||||
public AnnotationGroup getRuntimeInvisibleAnnotations() { | |||||
if (runtimeInvisible != null) | |||||
return runtimeInvisible; | |||||
AttributeInfo invisible = getAttribute("RuntimeInvisibleAnnotations"); | |||||
if (invisible == null) | |||||
return null; | |||||
runtimeInvisible = new AnnotationGroup(invisible); | |||||
return runtimeInvisible; | |||||
} | |||||
/** | |||||
* Return access object for getting info about annotations | |||||
* This returns runtime visible annotations as pertains to the | |||||
* RUNTIME RetentionPolicy | |||||
* @return | |||||
*/ | |||||
public AnnotationGroup getRuntimeVisibleAnnotations() { | |||||
if (runtimeVisible != null) | |||||
return runtimeVisible; | |||||
AttributeInfo visible = getAttribute("RuntimeVisibleAnnotations"); | |||||
if (visible == null) | |||||
return null; | |||||
runtimeVisible = new AnnotationGroup(visible); | |||||
return runtimeVisible; | |||||
} | |||||
/** | /** | ||||
* Returns an Exceptions attribute. | * Returns an Exceptions attribute. | ||||
* | * | ||||
*/ | */ | ||||
public ExceptionsAttribute getExceptionsAttribute() { | public ExceptionsAttribute getExceptionsAttribute() { | ||||
AttributeInfo info | AttributeInfo info | ||||
= AttributeInfo.lookup(attribute, ExceptionsAttribute.class); | |||||
= AttributeInfo.lookup(attribute, ExceptionsAttribute.tag); | |||||
return (ExceptionsAttribute)info; | return (ExceptionsAttribute)info; | ||||
} | } | ||||
*/ | */ | ||||
public CodeAttribute getCodeAttribute() { | public CodeAttribute getCodeAttribute() { | ||||
AttributeInfo info | AttributeInfo info | ||||
= AttributeInfo.lookup(attribute, CodeAttribute.class); | |||||
= AttributeInfo.lookup(attribute, CodeAttribute.tag); | |||||
return (CodeAttribute)info; | return (CodeAttribute)info; | ||||
} | } | ||||
* Removes an Exception attribute. | * Removes an Exception attribute. | ||||
*/ | */ | ||||
public void removeExceptionsAttribute() { | public void removeExceptionsAttribute() { | ||||
AttributeInfo.remove(attribute, ExceptionsAttribute.class); | |||||
AttributeInfo.remove(attribute, ExceptionsAttribute.tag); | |||||
} | } | ||||
/** | /** | ||||
* Removes a Code attribute. | * Removes a Code attribute. | ||||
*/ | */ | ||||
public void removeCodeAttribute() { | public void removeCodeAttribute() { | ||||
AttributeInfo.remove(attribute, CodeAttribute.class); | |||||
AttributeInfo.remove(attribute, CodeAttribute.tag); | |||||
} | } | ||||
/** | /** |
package javassist.bytecode; | package javassist.bytecode; | ||||
import java.util.Map; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.DataInputStream; | import java.io.DataInputStream; | ||||
import java.io.ByteArrayOutputStream; | |||||
import javassist.bytecode.AnnotationsAttribute.Copier; | |||||
import javassist.bytecode.AnnotationsAttribute.Parser; | |||||
import javassist.bytecode.annotation.*; | import javassist.bytecode.annotation.*; | ||||
/** | /** | ||||
* A class representing <code>RuntimeVisibleAnnotations_attribute</code> and | * A class representing <code>RuntimeVisibleAnnotations_attribute</code> and | ||||
* <code>RuntimeInvisibleAnnotations_attribute</code>. | * <code>RuntimeInvisibleAnnotations_attribute</code>. | ||||
* | |||||
* <p>To obtain an ParameterAnnotationAttribute object, invoke | |||||
* <code>getAttribute(ParameterAnnotationsAttribute.invisibleTag)</code> | |||||
* in <code>MethodInfo</code>. | |||||
* The obtained attribute is a | |||||
* runtime invisible annotations attribute. | |||||
* If the parameter is | |||||
* <code>ParameterAnnotationAttribute.visibleTag</code>, then the obtained | |||||
* attribute is a runtime visible one. | |||||
*/ | */ | ||||
public class ParameterAnnotationsAttribute extends AnnotationsAttribute { | |||||
public class ParameterAnnotationsAttribute extends AttributeInfo { | |||||
/** | /** | ||||
* The name of the <code>RuntimeVisibleParameterAnnotations</code> | * The name of the <code>RuntimeVisibleParameterAnnotations</code> | ||||
* attribute. | * attribute. | ||||
/** | /** | ||||
* Constructs an empty | * Constructs an empty | ||||
* <code>Runtime(In)VisisbleParameterAnnotations_attribute</code>. | * <code>Runtime(In)VisisbleParameterAnnotations_attribute</code>. | ||||
* A new annotation can be later added to the created attribute | |||||
* by <code>setAnnotations()</code>. | |||||
* | * | ||||
* @param cp constant pool | * @param cp constant pool | ||||
* @param attrname attribute name (<code>visibleTag</code> or | * @param attrname attribute name (<code>visibleTag</code> or | ||||
* <code>invisibleTag</code>). | * <code>invisibleTag</code>). | ||||
* @see #setAnnotations(Annotation[][]) | |||||
*/ | */ | ||||
public ParameterAnnotationsAttribute(ConstPool cp, String attrname) { | public ParameterAnnotationsAttribute(ConstPool cp, String attrname) { | ||||
this(cp, attrname, new byte[] { 0 }); | this(cp, attrname, new byte[] { 0 }); | ||||
return info[0] & 0xff; | return info[0] & 0xff; | ||||
} | } | ||||
AnnotationsAttribute makeCopy(ConstPool newCp, byte[] info) { | |||||
return new ParameterAnnotationsAttribute(newCp, getName(), info); | |||||
/** | |||||
* Copies this attribute and returns a new copy. | |||||
*/ | |||||
public AttributeInfo copy(ConstPool newCp, Map classnames) { | |||||
Copier copier = new Copier(info, constPool, newCp, classnames); | |||||
try { | |||||
copier.parameters(); | |||||
return new ParameterAnnotationsAttribute(newCp, getName(), | |||||
copier.close()); | |||||
} | |||||
catch (Exception e) { | |||||
throw new RuntimeException(e.toString()); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Runs the parser to analyze this annotation. | |||||
* Parses the annotations and returns a data structure representing | |||||
* that parsed annotations. Note that changes of the node values of the | |||||
* returned tree are not reflected on the annotations represented by | |||||
* this object unless the tree is copied back to this object by | |||||
* <code>setAnnotations()</code>. | |||||
* | * | ||||
* @see AnnotationsWriter | |||||
* @return Each element of the returned array represents an array of | |||||
* annotations that are associated with each method parameter. | |||||
* | |||||
* @see #setAnnotations() | |||||
*/ | */ | ||||
public void accept(AnnotationsVisitor visitor) throws Exception { | |||||
int numParam = numParameters(); | |||||
int pos = 1; | |||||
visitor.beginParameters(numParam); | |||||
for (int i = 0; i < numParam; ++i) { | |||||
int num= ByteArray.readU16bit(info, pos); | |||||
visitor.beginAnnotationsArray(num); | |||||
for (int j = 0; j < num; ++j) { | |||||
pos = readAnnotation(visitor, pos); | |||||
public Annotation[][] getAnnotations() { | |||||
try { | |||||
return new Parser(info, constPool).parseParameters(); | |||||
} | |||||
catch (Exception e) { | |||||
throw new RuntimeException(e.toString()); | |||||
} | |||||
} | |||||
/** | |||||
* Changes the annotations represented by this object according to | |||||
* the given array of <code>Annotation</code> objects. | |||||
* | |||||
* @param params the data structure representing the | |||||
* new annotations. Every element of this array | |||||
* is an array of <code>Annotation</code> and | |||||
* it represens annotations of each method parameter. | |||||
*/ | |||||
public void setAnnotations(Annotation[][] params) { | |||||
ByteArrayOutputStream output = new ByteArrayOutputStream(); | |||||
AnnotationsWriter writer = new AnnotationsWriter(output, constPool); | |||||
try { | |||||
int n = params.length; | |||||
writer.numParameters(n); | |||||
for (int i = 0; i < n; ++i) { | |||||
Annotation[] anno = params[i]; | |||||
writer.numAnnotations(anno.length); | |||||
for (int j = 0; j < anno.length; ++j) | |||||
anno[j].write(writer); | |||||
} | } | ||||
visitor.endAnnotationsArray(); | |||||
writer.close(); | |||||
} | |||||
catch (IOException e) { | |||||
throw new RuntimeException(e); // should never reach here. | |||||
} | } | ||||
visitor.endParameters(); | |||||
set(output.toByteArray()); | |||||
} | } | ||||
} | } |
/* | |||||
* Javassist, a Java-bytecode translator toolkit. | |||||
* Copyright (C) 2004 Bill Burke. All Rights Reserved. | |||||
* | |||||
* The contents of this file are subject to the Mozilla Public License Version | |||||
* 1.1 (the "License"); you may not use this file except in compliance with | |||||
* the License. Alternatively, the contents of this file may be used under | |||||
* the terms of the GNU Lesser General Public License Version 2.1 or later. | |||||
* | |||||
* Software distributed under the License is distributed on an "AS IS" basis, | |||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||||
* for the specific language governing rights and limitations under the | |||||
* License. | |||||
*/ | |||||
package javassist.bytecode.annotation; | |||||
import javassist.bytecode.ConstPool; | |||||
import javassist.bytecode.Descriptor; | |||||
import javassist.CtClass; | |||||
import javassist.CtMethod; | |||||
import java.io.IOException; | |||||
import java.util.HashMap; | |||||
import java.util.Set; | |||||
import java.util.Iterator; | |||||
/** | |||||
* The <code>annotation</code> structure. | |||||
* | |||||
* <p>An instance of this class is returned by | |||||
* <code>getAnnotations()</code> in <code>AnnotationsAttribute</code> | |||||
* or in <code>ParameterAnnotationsAttribute</code>. | |||||
* | |||||
* @see javassist.bytecode.AnnotationsAttribute#getAnnotations() | |||||
* @see javassist.bytecode.ParameterAnnotationsAttribute#getAnnotations() | |||||
* | |||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class Annotation { | |||||
static class Pair { | |||||
int name; | |||||
MemberValue value; | |||||
} | |||||
ConstPool pool; | |||||
int typeIndex; | |||||
HashMap members; // this sould be LinkedHashMap | |||||
// but it is not supported by JDK 1.3. | |||||
/** | |||||
* Constructs an annotation including no members. A member can be | |||||
* later added to the created annotation by <code>addMemberValue()</code>. | |||||
* | |||||
* @param type the index into the constant pool table. | |||||
* the entry at that index must be the | |||||
* <code>CONSTANT_Utf8_Info</code> structure | |||||
* repreenting the name of the annotation interface type. | |||||
* @param cp the constant pool table. | |||||
* | |||||
* @see #addMemberValue(String, MemberValue) | |||||
*/ | |||||
public Annotation(int type, ConstPool cp) { | |||||
pool = cp; | |||||
typeIndex = type; | |||||
members = null; | |||||
} | |||||
/** | |||||
* Constructs an annotation including no members. A member can be | |||||
* later added to the created annotation by <code>addMemberValue()</code>. | |||||
* | |||||
* @param typeName the name of the annotation interface type. | |||||
* @param cp the constant pool table. | |||||
* | |||||
* @see #addMemberValue(String, MemberValue) | |||||
*/ | |||||
public Annotation(String typeName, ConstPool cp) { | |||||
this(cp.addUtf8Info(Descriptor.of(typeName)), cp); | |||||
} | |||||
/** | |||||
* Constructs an annotation that can be accessed through the interface | |||||
* represented by <code>clazz</code>. The values of the members are | |||||
* not specified. | |||||
* | |||||
* @param cp the constant pool table. | |||||
* @param clazz the interface. | |||||
*/ | |||||
public Annotation(ConstPool cp, CtClass clazz) | |||||
throws javassist.NotFoundException | |||||
{ | |||||
// todo Enums are not supported right now. | |||||
this(cp.addUtf8Info(Descriptor.of(clazz.getName())), cp); | |||||
if (!clazz.isInterface()) | |||||
throw new RuntimeException( | |||||
"Only interfaces are allowed for Annotation creation."); | |||||
CtMethod methods[] = clazz.getDeclaredMethods(); | |||||
if (methods.length > 0) | |||||
members = new HashMap(); | |||||
for (int i = 0; i < methods.length; i++) { | |||||
CtClass returnType = methods[i].getReturnType(); | |||||
addMemberValue(methods[i].getName(), | |||||
createMemberValue(cp, returnType)); | |||||
} | |||||
} | |||||
private MemberValue createMemberValue(ConstPool cp, CtClass returnType) | |||||
throws javassist.NotFoundException | |||||
{ | |||||
if (returnType == CtClass.booleanType) | |||||
return new BooleanMemberValue(cp); | |||||
else if (returnType == CtClass.byteType) | |||||
return new ByteMemberValue(cp); | |||||
else if (returnType == CtClass.charType) | |||||
return new CharMemberValue(cp); | |||||
else if (returnType == CtClass.shortType) | |||||
return new ShortMemberValue(cp); | |||||
else if (returnType == CtClass.intType) | |||||
return new IntegerMemberValue(cp); | |||||
else if (returnType == CtClass.longType) | |||||
return new LongMemberValue(cp); | |||||
else if (returnType == CtClass.floatType) | |||||
return new FloatMemberValue(cp); | |||||
else if (returnType == CtClass.doubleType) | |||||
return new DoubleMemberValue(cp); | |||||
else if (returnType.getName().equals("java.lang.Class")) | |||||
return new ClassMemberValue(cp); | |||||
else if (returnType.getName().equals("java.lang.String")) | |||||
return new StringMemberValue(cp); | |||||
else if (returnType.isArray()) { | |||||
CtClass arrayType = returnType.getComponentType(); | |||||
MemberValue type = createMemberValue(cp, arrayType); | |||||
return new ArrayMemberValue(type, cp); | |||||
} | |||||
else if (returnType.isInterface()) { | |||||
Annotation info = new Annotation(cp, returnType); | |||||
return new AnnotationMemberValue(info, cp); | |||||
} | |||||
else { | |||||
// treat as enum. I know this is not typed, | |||||
// but JBoss has an Annotation Compiler for JDK 1.4 | |||||
// and I want it to work with that. - Bill Burke | |||||
EnumMemberValue emv = new EnumMemberValue(cp); | |||||
emv.setType(returnType.getName()); | |||||
return emv; | |||||
} | |||||
} | |||||
/** | |||||
* Adds a new member. | |||||
* | |||||
* @param nameIndex the index into the constant pool table. | |||||
* The entry at that index must be | |||||
* a <code>CONSTANT_Utf8_info</code> structure. | |||||
* structure representing the member name. | |||||
* @param value the member value. | |||||
*/ | |||||
public void addMemberValue(int nameIndex, MemberValue value) { | |||||
Pair p = new Pair(); | |||||
p.name = nameIndex; | |||||
p.value = value; | |||||
addMemberValue(p); | |||||
} | |||||
/** | |||||
* Adds a new member. | |||||
* | |||||
* @param name the member name. | |||||
* @param value the member value. | |||||
*/ | |||||
public void addMemberValue(String name, MemberValue value) { | |||||
Pair p = new Pair(); | |||||
p.name = pool.addUtf8Info(name); | |||||
p.value = value; | |||||
if (members == null) | |||||
members = new HashMap(); | |||||
members.put(name, p); | |||||
} | |||||
private void addMemberValue(Pair pair) { | |||||
String name = pool.getUtf8Info(pair.name); | |||||
if (members == null) | |||||
members = new HashMap(); | |||||
members.put(name, pair); | |||||
} | |||||
/** | |||||
* Returns a string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
StringBuffer buf = new StringBuffer("@"); | |||||
buf.append(getTypeName()); | |||||
if (members != null) { | |||||
buf.append("("); | |||||
Iterator mit = members.keySet().iterator(); | |||||
while (mit.hasNext()) { | |||||
String name = (String)mit.next(); | |||||
buf.append(name).append("=").append(getMemberValue(name)); | |||||
if (mit.hasNext()) | |||||
buf.append(", "); | |||||
} | |||||
buf.append(")"); | |||||
} | |||||
return buf.toString(); | |||||
} | |||||
/** | |||||
* Obtains the name of the annotation type. | |||||
*/ | |||||
public String getTypeName() { | |||||
return Descriptor.toClassName(pool.getUtf8Info(typeIndex)); | |||||
} | |||||
/** | |||||
* Obtains all the member names. | |||||
* | |||||
* @return null if no members are defined. | |||||
*/ | |||||
public Set getMemberNames() { | |||||
if (members == null) | |||||
return null; | |||||
else | |||||
return members.keySet(); | |||||
} | |||||
/** | |||||
* Obtains the member value with the given name. | |||||
* | |||||
* @return null if the member cannot be found. | |||||
*/ | |||||
public MemberValue getMemberValue(String name) { | |||||
if (members == null) | |||||
return null; | |||||
else { | |||||
Pair p = (Pair)members.get(name); | |||||
if (p == null) | |||||
return null; | |||||
else | |||||
return p.value; | |||||
} | |||||
} | |||||
/** | |||||
* Writes this annotation. | |||||
* | |||||
* @param writer the output. | |||||
*/ | |||||
public void write(AnnotationsWriter writer) throws IOException { | |||||
if (members == null) { | |||||
writer.annotation(typeIndex, 0); | |||||
return; | |||||
} | |||||
writer.annotation(typeIndex, members.size()); | |||||
Iterator it = members.values().iterator(); | |||||
while (it.hasNext()) { | |||||
Pair pair = (Pair)it.next(); | |||||
writer.memberValuePair(pair.name); | |||||
pair.value.write(writer); | |||||
} | |||||
} | |||||
} |
/* | |||||
* Javassist, a Java-bytecode translator toolkit. | |||||
* Copyright (C) 2004 Bill Burke. All Rights Reserved. | |||||
* | |||||
* The contents of this file are subject to the Mozilla Public License Version | |||||
* 1.1 (the "License"); you may not use this file except in compliance with | |||||
* the License. Alternatively, the contents of this file may be used under | |||||
* the terms of the GNU Lesser General Public License Version 2.1 or later. | |||||
* | |||||
* Software distributed under the License is distributed on an "AS IS" basis, | |||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||||
* for the specific language governing rights and limitations under the | |||||
* License. | |||||
*/ | |||||
package javassist.bytecode.annotation; | |||||
import javassist.bytecode.AttributeInfo; | |||||
import javassist.bytecode.ConstPool; | |||||
import java.io.DataInputStream; | |||||
import java.io.ByteArrayInputStream; | |||||
import java.io.ByteArrayOutputStream; | |||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.Collection; | |||||
import java.util.Iterator; | |||||
/** | |||||
* Comment | |||||
* | |||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | |||||
* @version $Revision: 1.2 $ | |||||
* | |||||
**/ | |||||
public class AnnotationGroup | |||||
{ | |||||
AttributeInfo parent; | |||||
LinkedHashMap annotations = new LinkedHashMap(); | |||||
public AnnotationGroup(AttributeInfo parent) | |||||
{ | |||||
this.parent = parent; | |||||
if (!parent.getName().equals("RuntimeInvisibleAnnotations") && | |||||
!parent.getName().equals("RuntimeVisibleAnnotations")) | |||||
throw new RuntimeException("Annotation group must be RuntimeInvisibleAnnotations or RuntimeVisibleAnnotations, it was: " + parent.getName()); | |||||
try | |||||
{ | |||||
initialize(); | |||||
} | |||||
catch (java.io.IOException e) | |||||
{ | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
public String getName() | |||||
{ | |||||
return parent.getName(); | |||||
} | |||||
public Collection getAnnotations() | |||||
{ | |||||
if (annotations == null) return null; | |||||
return annotations.values(); | |||||
} | |||||
public AnnotationInfo getAnnotation(String type) | |||||
{ | |||||
if (annotations == null) return null; | |||||
return (AnnotationInfo)annotations.get(type); | |||||
} | |||||
private void initialize() throws java.io.IOException | |||||
{ | |||||
ConstPool cp = parent.getConstPool(); | |||||
byte[] bytes = parent.get(); | |||||
if (bytes == null) return; | |||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes); | |||||
DataInputStream di = new DataInputStream(bais); | |||||
short num_annotations = di.readShort(); | |||||
for (int i = 0; i < num_annotations; i++) | |||||
{ | |||||
AnnotationInfo info = AnnotationInfo.readAnnotationInfo(cp, di); | |||||
annotations.put(info.getAnnotationType(), info); | |||||
} | |||||
} | |||||
public void addAnnotation(AnnotationInfo info) | |||||
{ | |||||
annotations.put(info.getAnnotationType(), info); | |||||
try | |||||
{ | |||||
parent.set(convertToBytes()); | |||||
} | |||||
catch (IOException e) | |||||
{ | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
public void removeAnnotation(String name) | |||||
{ | |||||
annotations.remove(name); | |||||
try | |||||
{ | |||||
parent.set(convertToBytes()); | |||||
} | |||||
catch (IOException e) | |||||
{ | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
private byte[] convertToBytes() throws IOException | |||||
{ | |||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||||
DataOutputStream dos = new DataOutputStream(baos); | |||||
short num_annotations = (short)annotations.size(); | |||||
dos.writeShort(num_annotations); | |||||
Iterator it = annotations.values().iterator(); | |||||
while (it.hasNext()) | |||||
{ | |||||
AnnotationInfo info = (AnnotationInfo)it.next(); | |||||
info.write(dos); | |||||
} | |||||
dos.flush(); | |||||
return baos.toByteArray(); | |||||
} | |||||
} |
/* | |||||
* Javassist, a Java-bytecode translator toolkit. | |||||
* Copyright (C) 2004 Bill Burke. All Rights Reserved. | |||||
* | |||||
* The contents of this file are subject to the Mozilla Public License Version | |||||
* 1.1 (the "License"); you may not use this file except in compliance with | |||||
* the License. Alternatively, the contents of this file may be used under | |||||
* the terms of the GNU Lesser General Public License Version 2.1 or later. | |||||
* | |||||
* Software distributed under the License is distributed on an "AS IS" basis, | |||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||||
* for the specific language governing rights and limitations under the | |||||
* License. | |||||
*/ | |||||
package javassist.bytecode.annotation; | |||||
import javassist.bytecode.ConstPool; | |||||
import javassist.bytecode.Descriptor; | |||||
import javassist.CtClass; | |||||
import javassist.CtMethod; | |||||
import javassist.CtPrimitiveType; | |||||
import java.io.DataInput; | |||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.HashMap; | |||||
import java.util.Set; | |||||
import java.util.Iterator; | |||||
/** | |||||
* Comment | |||||
* | |||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | |||||
* @version $Revision: 1.5 $ | |||||
* | |||||
**/ | |||||
public class AnnotationInfo | |||||
{ | |||||
short type_index; | |||||
LinkedHashMap members; | |||||
HashMap memberName2Index; | |||||
ConstPool cp; | |||||
private AnnotationInfo() | |||||
{ | |||||
} | |||||
private MemberValue createMemberValue(ConstPool cp, CtClass returnType) throws javassist.NotFoundException | |||||
{ | |||||
if (returnType.equals(CtPrimitiveType.booleanType)) | |||||
{ | |||||
return new BooleanMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.byteType)) | |||||
{ | |||||
return new ByteMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.charType)) | |||||
{ | |||||
return new CharMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.doubleType)) | |||||
{ | |||||
return new DoubleMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.floatType)) | |||||
{ | |||||
return new FloatMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.intType)) | |||||
{ | |||||
return new IntegerMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.longType)) | |||||
{ | |||||
return new LongMemberValue(cp); | |||||
} | |||||
else if (returnType.equals(CtPrimitiveType.shortType)) | |||||
{ | |||||
return new ShortMemberValue(cp); | |||||
} | |||||
else if (returnType.getName().equals("java.lang.Class")) | |||||
{ | |||||
return new ClassMemberValue(cp); | |||||
} | |||||
else if (returnType.getName().equals("java.lang.String") || returnType.getName().equals("String")) | |||||
{ | |||||
return new StringMemberValue(cp); | |||||
} | |||||
else if (returnType.isArray()) | |||||
{ | |||||
CtClass arrayType = returnType.getComponentType(); | |||||
MemberValue type = createMemberValue(cp, arrayType); | |||||
return new ArrayMemberValue(type, cp); | |||||
} | |||||
else if (returnType.isInterface()) | |||||
{ | |||||
AnnotationInfo info = new AnnotationInfo(cp, returnType); | |||||
return new AnnotationMemberValue(info, cp); | |||||
} | |||||
else | |||||
{ | |||||
// treat as enum. I know this is not typed, but JBoss has an Annotation Compiler for JDK 1.4 | |||||
// and I want it to work with that. - Bill Burke | |||||
return new EnumMemberValue(returnType.getName(), cp); | |||||
} | |||||
} | |||||
/** | |||||
* todo Enums are not supported right now. | |||||
* This is for creation at runtime | |||||
* @param clazz | |||||
*/ | |||||
public AnnotationInfo(ConstPool cp, CtClass clazz) throws javassist.NotFoundException | |||||
{ | |||||
if (!clazz.isInterface()) throw new RuntimeException("Only interfaces are allowed for AnnotationInfo creation."); | |||||
this.cp = cp; | |||||
// beta1 type_index = (short) cp.addClassInfo(clazz); | |||||
type_index = (short)cp.addUtf8Info(Descriptor.of(clazz.getName())); | |||||
CtMethod methods[] = clazz.getDeclaredMethods(); | |||||
if (methods.length > 0) | |||||
{ | |||||
members = new LinkedHashMap(); | |||||
memberName2Index = new HashMap(); | |||||
} | |||||
for (int i = 0; i < methods.length; i++) | |||||
{ | |||||
CtClass returnType = methods[i].getReturnType(); | |||||
addMemberValue(methods[i].getName(), createMemberValue(cp, returnType)); | |||||
} | |||||
} | |||||
private void addMemberValue(String name, MemberValue value) | |||||
{ | |||||
short index = (short) cp.addUtf8Info(name); | |||||
members.put(name, value); | |||||
memberName2Index.put(name, new Short(index)); | |||||
value.cp = this.cp; | |||||
} | |||||
public String getAnnotationType() | |||||
{ | |||||
String name = Descriptor.toClassName(cp.getUtf8Info(type_index)); | |||||
return name; | |||||
} | |||||
public Set getMemberNames() | |||||
{ | |||||
if (members == null) return null; | |||||
return members.keySet(); | |||||
} | |||||
public MemberValue getMemberValue(String member) | |||||
{ | |||||
if (members == null) return null; | |||||
return (MemberValue) members.get(member); | |||||
} | |||||
public static AnnotationInfo readAnnotationInfo(ConstPool cp, DataInput di) throws java.io.IOException | |||||
{ | |||||
AnnotationInfo info = new AnnotationInfo(); | |||||
info.cp = cp; | |||||
short type_index = di.readShort(); | |||||
info.type_index = type_index; | |||||
short num_member_value_pairs = di.readShort(); | |||||
if (num_member_value_pairs > 0) | |||||
{ | |||||
info.members = new LinkedHashMap(); | |||||
info.memberName2Index = new HashMap(); | |||||
} | |||||
for (int j = 0; j < num_member_value_pairs; j++) | |||||
{ | |||||
short member_name_index = di.readShort(); | |||||
String memberName = cp.getUtf8Info(member_name_index); | |||||
MemberValue value = MemberValue.readMemberValue(cp, di); | |||||
info.members.put(memberName, value); | |||||
info.memberName2Index.put(memberName, new Short(member_name_index)); | |||||
} | |||||
return info; | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
dos.writeShort(type_index); | |||||
if (members == null) | |||||
{ | |||||
dos.writeShort((short)0); | |||||
return; | |||||
} | |||||
dos.writeShort(members.size()); | |||||
Iterator it = members.keySet().iterator(); | |||||
while (it.hasNext()) | |||||
{ | |||||
String name = (String) it.next(); | |||||
Short index = (Short) memberName2Index.get(name); | |||||
dos.writeShort(index.shortValue()); | |||||
MemberValue value = (MemberValue) members.get(name); | |||||
value.write(dos); | |||||
} | |||||
} | |||||
public String toString() | |||||
{ | |||||
StringBuffer buf = new StringBuffer("@"); | |||||
buf.append(getAnnotationType()); | |||||
if (members != null) | |||||
{ | |||||
buf.append("("); | |||||
Iterator mit = members.keySet().iterator(); | |||||
while (mit.hasNext()) | |||||
{ | |||||
String name = (String) mit.next(); | |||||
buf.append(name).append("=").append(getMemberValue(name)); | |||||
if (mit.hasNext()) buf.append(", "); | |||||
} | |||||
buf.append(")"); | |||||
} | |||||
return buf.toString(); | |||||
} | |||||
} | |||||
* for the specific language governing rights and limitations under the | * for the specific language governing rights and limitations under the | ||||
* License. | * License. | ||||
*/ | */ | ||||
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Nested annotation. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class AnnotationMemberValue extends MemberValue | |||||
{ | |||||
AnnotationInfo annotation; | |||||
public AnnotationMemberValue(AnnotationInfo a, ConstPool cp) | |||||
{ | |||||
super('@', cp); | |||||
this.annotation = a; | |||||
} | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class AnnotationMemberValue extends MemberValue { | |||||
Annotation value; | |||||
public AnnotationMemberValue(ConstPool cp) | |||||
{ | |||||
super('@', cp); | |||||
} | |||||
/** | |||||
* Constructs an annotation member. The initial value is not specified. | |||||
*/ | |||||
public AnnotationMemberValue(ConstPool cp) { | |||||
this(null, cp); | |||||
} | |||||
public AnnotationInfo getNestedAnnotation() | |||||
{ | |||||
return annotation; | |||||
} | |||||
/** | |||||
* Constructs an annotation member. The initial value is specified by | |||||
* the first parameter. | |||||
*/ | |||||
public AnnotationMemberValue(Annotation a, ConstPool cp) { | |||||
super('@', cp); | |||||
value = a; | |||||
} | |||||
public void setNestedAnnotation(AnnotationInfo info) | |||||
{ | |||||
annotation = info; | |||||
} | |||||
/** | |||||
* Obtains the value. | |||||
*/ | |||||
public Annotation getValue() { | |||||
return value; | |||||
} | |||||
public String toString() | |||||
{ | |||||
return annotation.toString(); | |||||
} | |||||
/** | |||||
* Sets the value of this member. | |||||
*/ | |||||
public void setValue(Annotation newValue) { | |||||
value = newValue; | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
annotation.write(dos); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return value.toString(); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitAnnotationMemberValue(this); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.annotationValue(); | |||||
value.write(writer); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitAnnotationMemberValue(this); | |||||
} | |||||
} | } |
/* | |||||
* Javassist, a Java-bytecode translator toolkit. | |||||
* Copyright (C) 1999-2004 Shigeru Chiba. All Rights Reserved. | |||||
* | |||||
* The contents of this file are subject to the Mozilla Public License Version | |||||
* 1.1 (the "License"); you may not use this file except in compliance with | |||||
* the License. Alternatively, the contents of this file may be used under | |||||
* the terms of the GNU Lesser General Public License Version 2.1 or later. | |||||
* | |||||
* Software distributed under the License is distributed on an "AS IS" basis, | |||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||||
* for the specific language governing rights and limitations under the | |||||
* License. | |||||
*/ | |||||
package javassist.bytecode.annotation; | |||||
import javassist.bytecode.ConstPool; | |||||
/** | |||||
* Visitor for parsing an annotations attribute. | |||||
* | |||||
* @see AnnotationsAttribute#accept(AnnotationsVisitor) | |||||
* @see ParameterAnnotationsAttribute#accept(AnnotationsVisitor) | |||||
*/ | |||||
public class AnnotationsVisitor { | |||||
/** | |||||
* Invoked when the parser starts parsing a | |||||
* <code>parameter_annotations</code> array. | |||||
* If the annotations attribute is not a parameter annotations attribute, | |||||
* this method is never invoked. | |||||
* | |||||
* @param numParameters <code>num_parameters</code>. | |||||
*/ | |||||
public void beginParameters(int numParameters) throws Exception {} | |||||
/** | |||||
* Invoked when the parser ends parsing a | |||||
* <code>parameter_annotations</code> array. | |||||
* If the annotations attribute is not a parameter annotations attribute, | |||||
* this method is never invoked. | |||||
*/ | |||||
public void endParameters() throws Exception {} | |||||
/** | |||||
* Invoked when the parser starts parsing an | |||||
* <code>annotations</code> array in | |||||
* <code>..Annotations_attribute</code>. | |||||
* | |||||
* @param numAnnotations <code>num_annotations</code>. | |||||
*/ | |||||
public void beginAnnotationsArray(int numAnnotations) | |||||
throws Exception {} | |||||
/** | |||||
* Invoked when the parser ends parsing an | |||||
* <code>annotations</code> array in | |||||
* <code>..Annotations_attribute</code>. | |||||
*/ | |||||
public void endAnnotationsArray() throws Exception {} | |||||
/** | |||||
* Invoked when the parser starts parsing an element of | |||||
* <code>annotations</code> array in | |||||
* <code>Runtime(In)VisibleAnnotations_attribute</code> | |||||
* or <code>parameter_annotations</code> array. | |||||
* | |||||
* @param cp the constant pool. | |||||
* @param typeIndex <code>type_index</code>. | |||||
* @param numMemberValuePairs <code>num_member_value_pairs</code>. | |||||
*/ | |||||
public void beginAnnotation(ConstPool cp, | |||||
int typeIndex, int numMemberValuePairs) throws Exception {} | |||||
/** | |||||
* Invoked when the parser ends parsing an element of | |||||
* <code>annotations</code> array in | |||||
* <code>Runtime(In)VisibleAnnotations_attribute</code> | |||||
* or <code>parameter_annotations</code> array. | |||||
*/ | |||||
public void endAnnotation() throws Exception {} | |||||
/** | |||||
* Invoked when the parser starts parsing an element of | |||||
* <code>member_value_pairs</code> array in <code>annotation</code>. | |||||
* | |||||
* @param cp the constant pool. | |||||
* @param memberNameIndex <code>member_name_index</code>. | |||||
*/ | |||||
public void beginMemberValuePair(ConstPool cp, int memberNameIndex) | |||||
throws Exception {} | |||||
/** | |||||
* Invoked when the parser ends parsing an element of | |||||
* <code>member_value_pairs</code> array in <code>annotation</code>. | |||||
*/ | |||||
public void endMemberValuePair() throws Exception {} | |||||
/** | |||||
* Invoked when the parser parses <code>const_value_index</code> | |||||
* in <code>member_value</code>. | |||||
* | |||||
* @param cp the constant pool. | |||||
* @param tag <code>tag</code>. | |||||
* @param index <code>const_value_index</code>. | |||||
*/ | |||||
public void constValueIndex(ConstPool cp, int tag, int index) | |||||
throws Exception {} | |||||
/** | |||||
* Invoked when the parser parses <code>enum_const_value</code> | |||||
* in <code>member_value</code>. | |||||
* | |||||
* @param cp the constant pool. | |||||
* @param typeNameIndex <code>type_name_index</code>. | |||||
* @param constNameIndex <code>const_name_index</code>. | |||||
*/ | |||||
public void enumConstValue(ConstPool cp, int typeNameIndex, | |||||
int constNameIndex) throws Exception {} | |||||
/** | |||||
* Invoked when the parser parses <code>class_info_index</code> | |||||
* in <code>member_value</code>. | |||||
* | |||||
* @param cp the constant pool. | |||||
* @param index <code>class_info_index</code>. | |||||
*/ | |||||
public void classInfoIndex(ConstPool cp, int index) throws Exception {} | |||||
/** | |||||
* Invoked when the parser starts parsing <code>annotation_value</code> | |||||
* in <code>member_value</code>. | |||||
*/ | |||||
public void beginAnnotationValue() throws Exception {} | |||||
/** | |||||
* Invoked when the parser endss parsing <code>annotation_value</code> | |||||
* in <code>member_value</code>. | |||||
*/ | |||||
public void endAnnotationValue() throws Exception {} | |||||
/** | |||||
* Invoked when the parser starts parsing <code>array_value</code> | |||||
* in <code>member_value</code>. | |||||
* | |||||
* @param numValues <code>num_values</code>. | |||||
*/ | |||||
public void beginArrayValue(int numValues) throws Exception {} | |||||
/** | |||||
* Invoked when the parser ends parsing an element of | |||||
* <code>array_value</code>. | |||||
* | |||||
* @param i the index of that element. | |||||
*/ | |||||
public void arrayElement(int i) throws Exception {} | |||||
/** | |||||
* Invoked when the parser ends parsing <code>array_value</code> | |||||
* in <code>member_value</code>. | |||||
*/ | |||||
public void endArrayValue() throws Exception {} | |||||
} |
pool = cp; | pool = cp; | ||||
} | } | ||||
/** | |||||
* Obtains the constant pool given to the constructor. | |||||
*/ | |||||
public ConstPool getConstPool() { | |||||
return pool; | |||||
} | |||||
/** | /** | ||||
* Closes the output stream. | * Closes the output stream. | ||||
* | * | ||||
/** | /** | ||||
* Writes <code>tag</code> and <code>array_value</code> | * Writes <code>tag</code> and <code>array_value</code> | ||||
* in <code>member_value</code>. | * in <code>member_value</code>. | ||||
* This method must be followed by a <code>numValues</code> | |||||
* call to <code>constValueIndex()</code>, <code>enumConstValue()</code>, | |||||
* This method must be followed by <code>numValues</code> calls | |||||
* to <code>constValueIndex()</code>, <code>enumConstValue()</code>, | |||||
* etc. | * etc. | ||||
* | * | ||||
* @param numValues <code>num_values</code> | * @param numValues <code>num_values</code> |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataInput; | |||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.ArrayList; | |||||
/** | /** | ||||
* Comment | |||||
* Array member. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class ArrayMemberValue extends MemberValue | |||||
{ | |||||
MemberValue[] values; | |||||
MemberValue type; | |||||
private ArrayMemberValue(ConstPool cp) | |||||
{ | |||||
super('[', cp); | |||||
} | |||||
public ArrayMemberValue(MemberValue type, ConstPool cp) | |||||
{ | |||||
this(cp); | |||||
this.type = type; | |||||
} | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class ArrayMemberValue extends MemberValue { | |||||
MemberValue type; | |||||
MemberValue[] values; | |||||
public MemberValue[] getValue() | |||||
{ | |||||
return values; | |||||
} | |||||
/** | |||||
* Constructs an array. The initial value or type are not specified. | |||||
*/ | |||||
public ArrayMemberValue(ConstPool cp) { | |||||
super('[', cp); | |||||
type = null; | |||||
values = null; | |||||
} | |||||
public void setValue(MemberValue[] values) | |||||
{ | |||||
if (values != null && values.length > 0) type = values[0]; | |||||
this.values = values; | |||||
} | |||||
/** | |||||
* Constructs an array. The initial value is not specified. | |||||
* | |||||
* @param t the type of the array elements. | |||||
*/ | |||||
public ArrayMemberValue(MemberValue t, ConstPool cp) { | |||||
super('[', cp); | |||||
type = t; | |||||
values = null; | |||||
} | |||||
public MemberValue getType() | |||||
{ | |||||
return type; | |||||
} | |||||
/** | |||||
* Obtains the type of the elements. | |||||
* | |||||
* @return null if the type is not specified. | |||||
*/ | |||||
public MemberValue getType() { | |||||
return type; | |||||
} | |||||
/** | |||||
* Obtains the elements of the array. | |||||
*/ | |||||
public MemberValue[] getValue() { | |||||
return values; | |||||
} | |||||
public static ArrayMemberValue readArray(ConstPool cp, DataInput di) throws java.io.IOException | |||||
{ | |||||
ArrayMemberValue rtn = new ArrayMemberValue(cp); | |||||
int length = di.readShort(); | |||||
ArrayList values = new ArrayList(length); | |||||
for (int i = 0; i < length; i++) | |||||
{ | |||||
MemberValue type = MemberValue.readMemberValue(cp, di); | |||||
rtn.type = type; | |||||
values.add(type); | |||||
} | |||||
rtn.values = (MemberValue[]) values.toArray(new MemberValue[length]); | |||||
return rtn; | |||||
/** | |||||
* Sets the elements of the array. | |||||
*/ | |||||
public void setValue(MemberValue[] elements) { | |||||
values = elements; | |||||
if (elements != null && elements.length > 0) | |||||
type = elements[0]; | |||||
} | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
StringBuffer buf = new StringBuffer("{"); | |||||
if (values != null) { | |||||
for (int i = 0; i < values.length; i++) { | |||||
buf.append(values[i].toString()); | |||||
if (i + 1 < values.length) | |||||
buf.append(", "); | |||||
} | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
if (values == null) | |||||
{ | |||||
dos.writeShort(0); | |||||
return; | |||||
} | |||||
dos.writeShort(values.length); | |||||
for (int i = 0; i < values.length; i++) | |||||
{ | |||||
values[i].write(dos); | |||||
} | |||||
} | |||||
buf.append("}"); | |||||
return buf.toString(); | |||||
} | |||||
public String toString() | |||||
{ | |||||
StringBuffer buf = new StringBuffer("{"); | |||||
if (values != null) | |||||
{ | |||||
for (int i = 0; i < values.length; i++) | |||||
{ | |||||
buf.append(values[i].toString()); | |||||
if (i + 1 < values.length) buf.append(", "); | |||||
} | |||||
} | |||||
buf.append("}"); | |||||
return buf.toString(); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
int num = values.length; | |||||
writer.arrayValue(num); | |||||
for (int i = 0; i < num; ++i) | |||||
values[i].write(writer); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitArrayMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitArrayMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Boolean constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class BooleanMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class BooleanMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a boolean constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Integer_info structure. | |||||
*/ | |||||
public BooleanMemberValue(int index, ConstPool cp) { | |||||
super('Z', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a boolean constant value. | |||||
* | |||||
* @param b the initial value. | |||||
*/ | |||||
public BooleanMemberValue(boolean b, ConstPool cp) { | |||||
super('Z', cp); | |||||
setValue(b); | |||||
} | |||||
/** | |||||
* Constructs a boolean constant value. The initial value is false. | |||||
*/ | |||||
public BooleanMemberValue(ConstPool cp) { | |||||
super('Z', cp); | |||||
setValue(false); | |||||
} | |||||
public BooleanMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('Z', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public boolean getValue() { | |||||
return cp.getIntegerInfo(valueIndex) != 0; | |||||
} | |||||
public BooleanMemberValue(ConstPool cp) | |||||
{ | |||||
super('Z', cp); | |||||
setValue(false); | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(boolean newValue) { | |||||
valueIndex = cp.addIntegerInfo(newValue ? 1 : 0); | |||||
} | |||||
public boolean getValue() | |||||
{ | |||||
return cp.getIntegerInfo(const_value_index) == 1; | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return getValue() ? "true" : "false"; | |||||
} | |||||
public void setValue(boolean newVal) | |||||
{ | |||||
const_value_index = (short)cp.addIntegerInfo(newVal ? 1 : 0); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitBooleanMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitBooleanMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Byte constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class ByteMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class ByteMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a byte constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Integer_info structure. | |||||
*/ | |||||
public ByteMemberValue(int index, ConstPool cp) { | |||||
super('B', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a byte constant value. | |||||
* | |||||
* @param b the initial value. | |||||
*/ | |||||
public ByteMemberValue(byte b, ConstPool cp) { | |||||
super('B', cp); | |||||
setValue(b); | |||||
} | |||||
/** | |||||
* Constructs a byte constant value. The initial value is 0. | |||||
*/ | |||||
public ByteMemberValue(ConstPool cp) { | |||||
super('B', cp); | |||||
setValue((byte)0); | |||||
} | |||||
public ByteMemberValue(short const_value_index, ConstPool cp) | |||||
{ | |||||
super('B', cp); | |||||
this.const_value_index = const_value_index; | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public byte getValue() { | |||||
return (byte)cp.getIntegerInfo(valueIndex); | |||||
} | |||||
public ByteMemberValue(ConstPool cp) | |||||
{ | |||||
super('B', cp); | |||||
setValue((byte)0); | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(byte newValue) { | |||||
valueIndex = cp.addIntegerInfo(newValue); | |||||
} | |||||
public byte getValue() | |||||
{ | |||||
return (byte)cp.getIntegerInfo(const_value_index); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Byte.toString(getValue()); | |||||
} | |||||
public void setValue(byte newVal) | |||||
{ | |||||
const_value_index = (short)cp.addIntegerInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitByteMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitByteMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Char constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class CharMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class CharMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a char constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Integer_info structure. | |||||
*/ | |||||
public CharMemberValue(int index, ConstPool cp) { | |||||
super('C', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a char constant value. | |||||
* | |||||
* @param c the initial value. | |||||
*/ | |||||
public CharMemberValue(char c, ConstPool cp) { | |||||
super('C', cp); | |||||
setValue(c); | |||||
} | |||||
/** | |||||
* Constructs a char constant value. The initial value is '\0'. | |||||
*/ | |||||
public CharMemberValue(ConstPool cp) { | |||||
super('C', cp); | |||||
setValue('\0'); | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public char getValue() { | |||||
return (char)cp.getIntegerInfo(valueIndex); | |||||
} | |||||
public CharMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('C', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(char newValue) { | |||||
valueIndex = cp.addIntegerInfo(newValue); | |||||
} | |||||
public CharMemberValue(ConstPool cp) | |||||
{ | |||||
super('C', cp); | |||||
setValue('\0'); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Character.toString(getValue()); | |||||
} | |||||
public char getValue() | |||||
{ | |||||
return (char)cp.getIntegerInfo(const_value_index); | |||||
} | |||||
public void setValue(char newVal) | |||||
{ | |||||
const_value_index = (short)cp.addIntegerInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitCharMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitCharMemberValue(this); | |||||
} | |||||
} | } |
* for the specific language governing rights and limitations under the | * for the specific language governing rights and limitations under the | ||||
* License. | * License. | ||||
*/ | */ | ||||
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import javassist.bytecode.Descriptor; | import javassist.bytecode.Descriptor; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* String constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.5 $ | |||||
* | |||||
**/ | |||||
public class ClassMemberValue extends MemberValue | |||||
{ | |||||
short class_info_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class ClassMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a string constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Utf8_info structure. | |||||
*/ | |||||
public ClassMemberValue(int index, ConstPool cp) { | |||||
super('c', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a string constant value. | |||||
* | |||||
* @param className the initial value. | |||||
*/ | |||||
public ClassMemberValue(String className, ConstPool cp) { | |||||
super('c', cp); | |||||
setValue(className); | |||||
} | |||||
/** | |||||
* Constructs a string constant value. | |||||
* The initial value is java.lang.Class. | |||||
*/ | |||||
public ClassMemberValue(ConstPool cp) { | |||||
super('c', cp); | |||||
setValue("java.lang.Class"); | |||||
} | |||||
public ClassMemberValue(short cii, ConstPool cp) | |||||
{ | |||||
super('c', cp); | |||||
this.class_info_index = cii; | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
* | |||||
* @return fully-qualified class name. | |||||
*/ | |||||
public String getValue() { | |||||
return Descriptor.toClassName(cp.getUtf8Info(valueIndex)); | |||||
} | |||||
public ClassMemberValue(ConstPool cp) | |||||
{ | |||||
super('c', cp); | |||||
setClassName("java.lang.Class"); | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
* | |||||
* @param newClassName fully-qualified class name. | |||||
*/ | |||||
public void setValue(String newClassName) { | |||||
valueIndex = cp.addUtf8Info(Descriptor.of(newClassName)); | |||||
} | |||||
public String getClassName() | |||||
{ | |||||
// beta1 return cp.getClassInfo(class_info_index); | |||||
return Descriptor.toClassName(cp.getUtf8Info(class_info_index)); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return "<" + getValue() + " class>"; | |||||
} | |||||
public void setClassName(String name) | |||||
{ | |||||
// beta1 class_info_index = (short)cp.addClassInfo(name); | |||||
class_info_index = (short)cp.addUtf8Info(Descriptor.of(name)); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return getClassName(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(class_info_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitClassMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitClassMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Double floating-point number constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class DoubleMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
* @version $Revision: 1.4 $ | |||||
*/ | |||||
public class DoubleMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a double constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Double_info structure. | |||||
*/ | |||||
public DoubleMemberValue(int index, ConstPool cp) { | |||||
super('D', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a double constant value. | |||||
* | |||||
* @param d the initial value. | |||||
*/ | |||||
public DoubleMemberValue(double d, ConstPool cp) { | |||||
super('D', cp); | |||||
setValue(d); | |||||
} | |||||
/** | |||||
* Constructs a double constant value. The initial value is 0.0. | |||||
*/ | |||||
public DoubleMemberValue(ConstPool cp) { | |||||
super('D', cp); | |||||
setValue(0.0); | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public double getValue() { | |||||
return cp.getDoubleInfo(valueIndex); | |||||
} | |||||
public DoubleMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('D', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(double newValue) { | |||||
valueIndex = cp.addDoubleInfo(newValue); | |||||
} | |||||
public DoubleMemberValue(ConstPool cp) | |||||
{ | |||||
super('D', cp); | |||||
setValue(0); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Double.toString(getValue()); | |||||
} | |||||
public double getValue() | |||||
{ | |||||
return cp.getDoubleInfo(const_value_index); | |||||
} | |||||
public void setValue(double newVal) | |||||
{ | |||||
const_value_index = (short)cp.addDoubleInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitDoubleMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitDoubleMemberValue(this); | |||||
} | |||||
} | } |
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import javassist.bytecode.Descriptor; | import javassist.bytecode.Descriptor; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Enum constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.5 $ | |||||
* | |||||
**/ | |||||
public class EnumMemberValue extends MemberValue | |||||
{ | |||||
short type_name_index; | |||||
short const_name_index; | |||||
public EnumMemberValue(short type, short cni, ConstPool cp) | |||||
{ | |||||
super('e', cp); | |||||
this.type_name_index = type; | |||||
this.const_name_index = cni; | |||||
} | |||||
public EnumMemberValue(String type, ConstPool cp) | |||||
{ | |||||
super('e', cp); | |||||
setEnumType(type); | |||||
} | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class EnumMemberValue extends MemberValue { | |||||
int typeIndex, valueIndex; | |||||
public EnumMemberValue(ConstPool cp) | |||||
{ | |||||
super('e', cp); | |||||
} | |||||
/** | |||||
* Constructs an enum constant value. The initial value is specified | |||||
* by the constant pool entries at the given indexes. | |||||
* | |||||
* @param type the index of a CONSTANT_Utf8_info structure | |||||
* representing the enum type. | |||||
* @param value the index of a CONSTANT_Utf8_info structure. | |||||
* representing the enum value. | |||||
*/ | |||||
public EnumMemberValue(int type, int value, ConstPool cp) { | |||||
super('e', cp); | |||||
this.typeIndex = type; | |||||
this.valueIndex = value; | |||||
} | |||||
/** | |||||
* @return tring representing the classname | |||||
*/ | |||||
public String getEnumType() | |||||
{ | |||||
return Descriptor.toClassName(cp.getUtf8Info(type_name_index)); | |||||
} | |||||
/** | |||||
* Constructs an enum constant value. | |||||
* The initial value is not specified. | |||||
*/ | |||||
public EnumMemberValue(ConstPool cp) { | |||||
super('e', cp); | |||||
typeIndex = valueIndex = 0; | |||||
} | |||||
/** | |||||
* | |||||
* @param classname FQN classname | |||||
*/ | |||||
public void setEnumType(String classname) | |||||
{ | |||||
type_name_index = (short)cp.addUtf8Info(Descriptor.of(classname)); | |||||
} | |||||
/** | |||||
* Obtains the enum type name. | |||||
* | |||||
* @return a fully-qualified type name. | |||||
*/ | |||||
public String getType() { | |||||
return Descriptor.toClassName(cp.getUtf8Info(typeIndex)); | |||||
} | |||||
public String getEnumVal() | |||||
{ | |||||
return cp.getUtf8Info(const_name_index); | |||||
} | |||||
/** | |||||
* Changes the enum type name. | |||||
* | |||||
* @param classname a fully-qualified type name. | |||||
*/ | |||||
public void setType(String typename) { | |||||
typeIndex = cp.addUtf8Info(Descriptor.of(typename)); | |||||
} | |||||
public void setEnumVal(String name) | |||||
{ | |||||
const_name_index = (short)cp.addUtf8Info(name); | |||||
} | |||||
/** | |||||
* Obtains the name of the enum constant value. | |||||
*/ | |||||
public String getValue() { | |||||
return cp.getUtf8Info(valueIndex); | |||||
} | |||||
/** | |||||
* Changes the name of the enum constant value. | |||||
*/ | |||||
public void setValue(String name) { | |||||
valueIndex = cp.addUtf8Info(name); | |||||
} | |||||
public String toString() { | |||||
return getType() + "." + getValue(); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return getEnumType() + "." + getEnumVal(); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.enumConstValue(getType(), getValue()); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(type_name_index); | |||||
dos.writeShort(const_name_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitEnumMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitEnumMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Floating-point number constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class FloatMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
* @version $Revision: 1.4 $ | |||||
*/ | |||||
public class FloatMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a float constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Float_info structure. | |||||
*/ | |||||
public FloatMemberValue(int index, ConstPool cp) { | |||||
super('F', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a float constant value. | |||||
* | |||||
* @param f the initial value. | |||||
*/ | |||||
public FloatMemberValue(float f, ConstPool cp) { | |||||
super('F', cp); | |||||
setValue(f); | |||||
} | |||||
/** | |||||
* Constructs a float constant value. The initial value is 0.0. | |||||
*/ | |||||
public FloatMemberValue(ConstPool cp) { | |||||
super('F', cp); | |||||
setValue(0.0F); | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public float getValue() { | |||||
return cp.getFloatInfo(valueIndex); | |||||
} | |||||
public FloatMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('F', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(float newValue) { | |||||
valueIndex = cp.addFloatInfo(newValue); | |||||
} | |||||
public FloatMemberValue(ConstPool cp) | |||||
{ | |||||
super('F', cp); | |||||
setValue(0); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Float.toString(getValue()); | |||||
} | |||||
public float getValue() | |||||
{ | |||||
return cp.getFloatInfo(const_value_index); | |||||
} | |||||
public void setValue(float newVal) | |||||
{ | |||||
const_value_index = (short)cp.addFloatInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitFloatMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitFloatMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Integer constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class IntegerMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class IntegerMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs an int constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Integer_info structure. | |||||
*/ | |||||
public IntegerMemberValue(int index, ConstPool cp) { | |||||
super('I', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs an int constant value. | |||||
* Note that this constructor receives <b>the initial value | |||||
* as the second parameter</b> | |||||
* unlike the corresponding constructors in the sibling classes. | |||||
* This is for making a difference from the constructor that receives | |||||
* an index into the constant pool table as the first parameter. | |||||
* Note that the index is also int type. | |||||
* | |||||
* @param value the initial value. | |||||
*/ | |||||
public IntegerMemberValue(ConstPool cp, int value) { | |||||
super('I', cp); | |||||
setValue(value); | |||||
} | |||||
/** | |||||
* Constructs an int constant value. The initial value is 0. | |||||
*/ | |||||
public IntegerMemberValue(ConstPool cp) { | |||||
super('I', cp); | |||||
setValue(0); | |||||
} | |||||
public IntegerMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('I', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public int getValue() { | |||||
return cp.getIntegerInfo(valueIndex); | |||||
} | |||||
public IntegerMemberValue(ConstPool cp) | |||||
{ | |||||
super('I', cp); | |||||
setValue(0); | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(int newValue) { | |||||
valueIndex = cp.addIntegerInfo(newValue); | |||||
} | |||||
public int getValue() | |||||
{ | |||||
return cp.getIntegerInfo(const_value_index); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Integer.toString(getValue()); | |||||
} | |||||
public void setValue(int newVal) | |||||
{ | |||||
const_value_index = (short)cp.addIntegerInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitIntegerMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitIntegerMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Long integer constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class LongMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class LongMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a long constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Long_info structure. | |||||
*/ | |||||
public LongMemberValue(int index, ConstPool cp) { | |||||
super('J', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a long constant value. | |||||
* | |||||
* @param j the initial value. | |||||
*/ | |||||
public LongMemberValue(long j, ConstPool cp) { | |||||
super('J', cp); | |||||
setValue(j); | |||||
} | |||||
/** | |||||
* Constructs a long constant value. The initial value is 0. | |||||
*/ | |||||
public LongMemberValue(ConstPool cp) { | |||||
super('J', cp); | |||||
setValue(0L); | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public long getValue() { | |||||
return cp.getLongInfo(valueIndex); | |||||
} | |||||
public LongMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('J', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(long newValue) { | |||||
valueIndex = cp.addLongInfo(newValue); | |||||
} | |||||
public LongMemberValue(ConstPool cp) | |||||
{ | |||||
super('J', cp); | |||||
setValue(0); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Long.toString(getValue()); | |||||
} | |||||
public long getValue() | |||||
{ | |||||
return cp.getLongInfo(const_value_index); | |||||
} | |||||
public void setValue(long newVal) | |||||
{ | |||||
const_value_index = (short)cp.addLongInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitLongMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitLongMemberValue(this); | |||||
} | |||||
} | } |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataInput; | |||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* The value of a member declared in an annotation. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public abstract class MemberValue | |||||
{ | |||||
ConstPool cp; | |||||
char tag; | |||||
protected MemberValue(char tag, ConstPool cp) | |||||
{ | |||||
this.cp = cp; | |||||
this.tag = tag; | |||||
} | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public abstract class MemberValue { | |||||
ConstPool cp; | |||||
char tag; | |||||
public abstract void accept(MemberValueVisitor visitor); | |||||
MemberValue(char tag, ConstPool cp) { | |||||
this.cp = cp; | |||||
this.tag = tag; | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
byte btag = (byte)tag; | |||||
dos.writeByte(btag); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public abstract void accept(MemberValueVisitor visitor); | |||||
public static MemberValue readMemberValue(ConstPool cp, DataInput di) throws java.io.IOException | |||||
{ | |||||
byte btag = di.readByte(); | |||||
char tag = (char) btag; | |||||
MemberValue rtn = null; | |||||
switch (tag) | |||||
{ | |||||
case 'B': | |||||
rtn = new ByteMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'C': | |||||
rtn = new CharMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'D': | |||||
rtn = new DoubleMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'F': | |||||
rtn = new FloatMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'I': | |||||
rtn = new IntegerMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'J': | |||||
rtn = new LongMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'S': | |||||
rtn = new ShortMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'Z': | |||||
rtn = new BooleanMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 's': | |||||
rtn = new StringMemberValue(di.readShort(), cp); | |||||
break; | |||||
case 'e': | |||||
rtn = new EnumMemberValue(di.readShort(), di.readShort(), cp); | |||||
break; | |||||
case 'c': | |||||
rtn = new ClassMemberValue(di.readShort(), cp); | |||||
break; | |||||
case '@': | |||||
rtn = new AnnotationMemberValue(AnnotationInfo.readAnnotationInfo(cp, di), cp); | |||||
break; | |||||
case '[': | |||||
rtn = ArrayMemberValue.readArray(cp, di); | |||||
break; | |||||
} | |||||
rtn.cp = cp; | |||||
rtn.tag = tag; | |||||
return rtn; | |||||
} | |||||
abstract void write(AnnotationsWriter w) throws IOException; | |||||
} | } | ||||
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
/** | /** | ||||
* Comment | |||||
* Visitor for traversing member values included in an annotation. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.2 $ | |||||
* | |||||
**/ | |||||
*/ | |||||
public interface MemberValueVisitor | public interface MemberValueVisitor | ||||
{ | { | ||||
public void visitAnnotationMemberValue(AnnotationMemberValue node); | public void visitAnnotationMemberValue(AnnotationMemberValue node); |
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* Short integer constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class ShortMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class ShortMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a short constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Integer_info structure. | |||||
*/ | |||||
public ShortMemberValue(int index, ConstPool cp) { | |||||
super('S', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a short constant value. | |||||
* | |||||
* @param s the initial value. | |||||
*/ | |||||
public ShortMemberValue(short s, ConstPool cp) { | |||||
super('S', cp); | |||||
setValue(s); | |||||
} | |||||
/** | |||||
* Constructs a short constant value. The initial value is 0. | |||||
*/ | |||||
public ShortMemberValue(ConstPool cp) { | |||||
super('S', cp); | |||||
setValue((short)0); | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public short getValue() { | |||||
return (short)cp.getIntegerInfo(valueIndex); | |||||
} | |||||
public ShortMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('S', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(short newValue) { | |||||
valueIndex = cp.addIntegerInfo(newValue); | |||||
} | |||||
public ShortMemberValue(ConstPool cp) | |||||
{ | |||||
super('S', cp); | |||||
setValue((short)0); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return Short.toString(getValue()); | |||||
} | |||||
public short getValue() | |||||
{ | |||||
return (short)cp.getIntegerInfo(const_value_index); | |||||
} | |||||
public void setValue(short newVal) | |||||
{ | |||||
const_value_index = (short)cp.addIntegerInfo(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "" + getValue(); | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitShortMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitShortMemberValue(this); | |||||
} | |||||
} | } |
* for the specific language governing rights and limitations under the | * for the specific language governing rights and limitations under the | ||||
* License. | * License. | ||||
*/ | */ | ||||
package javassist.bytecode.annotation; | package javassist.bytecode.annotation; | ||||
import javassist.bytecode.ConstPool; | import javassist.bytecode.ConstPool; | ||||
import java.io.DataOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
/** | /** | ||||
* Comment | |||||
* String constant value. | |||||
* | * | ||||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | * @author <a href="mailto:bill@jboss.org">Bill Burke</a> | ||||
* @version $Revision: 1.3 $ | |||||
* | |||||
**/ | |||||
public class StringMemberValue extends MemberValue | |||||
{ | |||||
short const_value_index; | |||||
* @author Shigeru Chiba | |||||
*/ | |||||
public class StringMemberValue extends MemberValue { | |||||
int valueIndex; | |||||
/** | |||||
* Constructs a string constant value. The initial value is specified | |||||
* by the constant pool entry at the given index. | |||||
* | |||||
* @param index the index of a CONSTANT_Utf8_info structure. | |||||
*/ | |||||
public StringMemberValue(int index, ConstPool cp) { | |||||
super('s', cp); | |||||
this.valueIndex = index; | |||||
} | |||||
/** | |||||
* Constructs a string constant value. | |||||
* | |||||
* @param str the initial value. | |||||
*/ | |||||
public StringMemberValue(String str, ConstPool cp) { | |||||
super('s', cp); | |||||
setValue(str); | |||||
} | |||||
/** | |||||
* Constructs a string constant value. The initial value is "". | |||||
*/ | |||||
public StringMemberValue(ConstPool cp) { | |||||
super('s', cp); | |||||
setValue(""); | |||||
} | |||||
/** | |||||
* Obtains the value of the member. | |||||
*/ | |||||
public String getValue() { | |||||
return cp.getUtf8Info(valueIndex); | |||||
} | |||||
public StringMemberValue(short cvi, ConstPool cp) | |||||
{ | |||||
super('s', cp); | |||||
this.const_value_index = cvi; | |||||
} | |||||
/** | |||||
* Sets the value of the member. | |||||
*/ | |||||
public void setValue(String newValue) { | |||||
valueIndex = cp.addUtf8Info(newValue); | |||||
} | |||||
public StringMemberValue(ConstPool cp) | |||||
{ | |||||
super('s', cp); | |||||
setValue(""); | |||||
} | |||||
/** | |||||
* Obtains the string representation of this object. | |||||
*/ | |||||
public String toString() { | |||||
return "\"" + getValue() + "\""; | |||||
} | |||||
public String getValue() | |||||
{ | |||||
return cp.getUtf8Info(const_value_index); | |||||
} | |||||
public void setValue(String newVal) | |||||
{ | |||||
const_value_index = (short)cp.addUtf8Info(newVal); | |||||
} | |||||
void write(AnnotationsWriter writer) throws IOException { | |||||
writer.constValueIndex(getValue()); | |||||
} | |||||
public String toString() | |||||
{ | |||||
return "\"" + getValue() + "\""; | |||||
} | |||||
public void write(DataOutputStream dos) throws IOException | |||||
{ | |||||
super.write(dos); | |||||
dos.writeShort(const_value_index); | |||||
} | |||||
public void accept(MemberValueVisitor visitor) | |||||
{ | |||||
visitor.visitStringMemberValue(this); | |||||
} | |||||
/** | |||||
* Accepts a visitor. | |||||
*/ | |||||
public void accept(MemberValueVisitor visitor) { | |||||
visitor.visitStringMemberValue(this); | |||||
} | |||||
} | } |