git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@111 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -26,6 +26,29 @@ import javassist.bytecode.annotation.*; | |||
* A class representing | |||
* <code>RuntimeVisibleAnnotations_attribute</code> and | |||
* <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 { | |||
/** | |||
@@ -36,7 +59,7 @@ public class AnnotationsAttribute extends AttributeInfo { | |||
/** | |||
* 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>. | |||
@@ -55,10 +78,13 @@ public class AnnotationsAttribute extends AttributeInfo { | |||
/** | |||
* Constructs an empty | |||
* <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 attrname attribute name (<code>visibleTag</code> or | |||
* <code>invisibleTag</code>). | |||
* @see #setAnnotations(Annotations[]) | |||
*/ | |||
public AnnotationsAttribute(ConstPool cp, String attrname) { | |||
this(cp, attrname, new byte[] { 0, 0 }); | |||
@@ -82,384 +108,413 @@ public class AnnotationsAttribute extends AttributeInfo { | |||
/** | |||
* 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) { | |||
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; | |||
} | |||
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; | |||
} | |||
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 | |||
* into the new names specified by <code>map</code> when it copies | |||
* an annotation attribute. | |||
* | |||
* @param info the source attribute. | |||
* @param src the constant pool of the source class. | |||
* @param dest the constant pool of the destination class. | |||
* @param map pairs of replaced and substituted class names. | |||
* It can be null. | |||
*/ | |||
public Copier(ConstPool dest, Map map) { | |||
Copier(byte[] info, ConstPool src, ConstPool dest, Map map) { | |||
super(info); | |||
output = new ByteArrayOutputStream(); | |||
writer = new AnnotationsWriter(output, dest); | |||
srcPool = src; | |||
destPool = dest; | |||
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); | |||
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(); | |||
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; | |||
} | |||
} | |||
} |
@@ -67,36 +67,41 @@ public class AttributeInfo { | |||
} | |||
static AttributeInfo read(ConstPool cp, DataInputStream in) | |||
throws IOException | |||
{ | |||
throws IOException { | |||
int name = in.readUnsignedShort(); | |||
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); | |||
} | |||
/** | |||
@@ -187,20 +192,6 @@ public class AttributeInfo { | |||
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) { | |||
if (list == null) | |||
return; | |||
@@ -213,18 +204,6 @@ public class AttributeInfo { | |||
} | |||
} | |||
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) | |||
throws IOException | |||
{ |
@@ -25,7 +25,6 @@ import java.util.ListIterator; | |||
import java.util.List; | |||
import javassist.CannotCompileException; | |||
import javassist.bytecode.annotation.AnnotationGroup; | |||
/** | |||
* <code>ClassFile</code> represents a Java <code>.class</code> file, | |||
@@ -43,8 +42,6 @@ public final class ClassFile { | |||
ArrayList fields; | |||
ArrayList methods; | |||
LinkedList attributes; | |||
AnnotationGroup runtimeInvisible; | |||
AnnotationGroup runtimeVisible; | |||
String thisclassname; // not JVM-internal name | |||
@@ -434,64 +431,6 @@ public final class ClassFile { | |||
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. | |||
* |
@@ -15,8 +15,6 @@ | |||
package javassist.bytecode; | |||
import javassist.bytecode.annotation.AnnotationGroup; | |||
import java.io.DataInputStream; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
@@ -34,8 +32,6 @@ public final class FieldInfo { | |||
int name; | |||
int descriptor; | |||
LinkedList attribute; // may be null. | |||
AnnotationGroup runtimeInvisible; | |||
AnnotationGroup runtimeVisible; | |||
private FieldInfo(ConstPool cp) { | |||
constPool = cp; | |||
@@ -156,64 +152,6 @@ public final class FieldInfo { | |||
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 { | |||
accessFlags = in.readUnsignedShort(); | |||
name = in.readUnsignedShort(); |
@@ -15,8 +15,6 @@ | |||
package javassist.bytecode; | |||
import javassist.bytecode.annotation.AnnotationGroup; | |||
import java.io.DataInputStream; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
@@ -36,8 +34,6 @@ public final class MethodInfo { | |||
int name; | |||
int descriptor; | |||
LinkedList attribute; // may be null | |||
AnnotationGroup runtimeInvisible; | |||
AnnotationGroup runtimeVisible; | |||
/** | |||
* The name of constructors: <code><init></code>. | |||
@@ -216,64 +212,6 @@ public final class MethodInfo { | |||
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. | |||
* | |||
@@ -282,7 +220,7 @@ public final class MethodInfo { | |||
*/ | |||
public ExceptionsAttribute getExceptionsAttribute() { | |||
AttributeInfo info | |||
= AttributeInfo.lookup(attribute, ExceptionsAttribute.class); | |||
= AttributeInfo.lookup(attribute, ExceptionsAttribute.tag); | |||
return (ExceptionsAttribute)info; | |||
} | |||
@@ -294,7 +232,7 @@ public final class MethodInfo { | |||
*/ | |||
public CodeAttribute getCodeAttribute() { | |||
AttributeInfo info | |||
= AttributeInfo.lookup(attribute, CodeAttribute.class); | |||
= AttributeInfo.lookup(attribute, CodeAttribute.tag); | |||
return (CodeAttribute)info; | |||
} | |||
@@ -302,7 +240,7 @@ public final class MethodInfo { | |||
* Removes an Exception attribute. | |||
*/ | |||
public void removeExceptionsAttribute() { | |||
AttributeInfo.remove(attribute, ExceptionsAttribute.class); | |||
AttributeInfo.remove(attribute, ExceptionsAttribute.tag); | |||
} | |||
/** | |||
@@ -323,7 +261,7 @@ public final class MethodInfo { | |||
* Removes a Code attribute. | |||
*/ | |||
public void removeCodeAttribute() { | |||
AttributeInfo.remove(attribute, CodeAttribute.class); | |||
AttributeInfo.remove(attribute, CodeAttribute.tag); | |||
} | |||
/** |
@@ -15,16 +15,29 @@ | |||
package javassist.bytecode; | |||
import java.util.Map; | |||
import java.io.IOException; | |||
import java.io.DataInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import javassist.bytecode.AnnotationsAttribute.Copier; | |||
import javassist.bytecode.AnnotationsAttribute.Parser; | |||
import javassist.bytecode.annotation.*; | |||
/** | |||
* A class representing <code>RuntimeVisibleAnnotations_attribute</code> and | |||
* <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> | |||
* attribute. | |||
@@ -57,10 +70,13 @@ public class ParameterAnnotationsAttribute extends AnnotationsAttribute { | |||
/** | |||
* Constructs an empty | |||
* <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 attrname attribute name (<code>visibleTag</code> or | |||
* <code>invisibleTag</code>). | |||
* @see #setAnnotations(Annotation[][]) | |||
*/ | |||
public ParameterAnnotationsAttribute(ConstPool cp, String attrname) { | |||
this(cp, attrname, new byte[] { 0 }); | |||
@@ -82,29 +98,70 @@ public class ParameterAnnotationsAttribute extends AnnotationsAttribute { | |||
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()); | |||
} | |||
} |
@@ -0,0 +1,270 @@ | |||
/* | |||
* 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); | |||
} | |||
} | |||
} |
@@ -1,131 +0,0 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -1,225 +0,0 @@ | |||
/* | |||
* 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(); | |||
} | |||
} | |||
@@ -12,59 +12,66 @@ | |||
* for the specific language governing rights and limitations under the | |||
* License. | |||
*/ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Nested annotation. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -1,163 +0,0 @@ | |||
/* | |||
* 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 {} | |||
} |
@@ -73,6 +73,13 @@ public class AnnotationsWriter { | |||
pool = cp; | |||
} | |||
/** | |||
* Obtains the constant pool given to the constructor. | |||
*/ | |||
public ConstPool getConstPool() { | |||
return pool; | |||
} | |||
/** | |||
* Closes the output stream. | |||
* | |||
@@ -328,8 +335,8 @@ public class AnnotationsWriter { | |||
/** | |||
* Writes <code>tag</code> and <code>array_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. | |||
* | |||
* @param numValues <code>num_values</code> |
@@ -15,101 +15,91 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataInput; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
/** | |||
* Comment | |||
* Array member. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -15,54 +15,75 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Boolean constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -15,54 +15,75 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Byte constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -16,53 +16,75 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Char constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -12,60 +12,85 @@ | |||
* for the specific language governing rights and limitations under the | |||
* License. | |||
*/ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import javassist.bytecode.Descriptor; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* String constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -16,53 +16,76 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Double floating-point number constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -17,82 +17,85 @@ package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import javassist.bytecode.Descriptor; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Enum constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -16,53 +16,76 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Floating-point number constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -16,54 +16,81 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Integer constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -16,53 +16,75 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Long integer constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -16,88 +16,29 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataInput; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* The value of a member declared in an annotation. | |||
* | |||
* @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; | |||
} | |||
@@ -16,12 +16,10 @@ | |||
package javassist.bytecode.annotation; | |||
/** | |||
* Comment | |||
* Visitor for traversing member values included in an annotation. | |||
* | |||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | |||
* @version $Revision: 1.2 $ | |||
* | |||
**/ | |||
*/ | |||
public interface MemberValueVisitor | |||
{ | |||
public void visitAnnotationMemberValue(AnnotationMemberValue node); |
@@ -16,53 +16,75 @@ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* Short integer constant value. | |||
* | |||
* @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); | |||
} | |||
} |
@@ -12,56 +12,79 @@ | |||
* for the specific language governing rights and limitations under the | |||
* License. | |||
*/ | |||
package javassist.bytecode.annotation; | |||
import javassist.bytecode.ConstPool; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
/** | |||
* Comment | |||
* String constant value. | |||
* | |||
* @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); | |||
} | |||
} |