summaryrefslogtreecommitdiffstats
path: root/src/main/javassist/bytecode
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2004-06-10 15:56:45 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2004-06-10 15:56:45 +0000
commit6f0d550f399ed4d5bee1d42caccb51b4f460e401 (patch)
tree3d0b9e645be2627252509dc4d9f8395c0e8045b8 /src/main/javassist/bytecode
parent134ee70a9fd4959cbf6b9b6f3b9d1498247ec1e5 (diff)
downloadjavassist-6f0d550f399ed4d5bee1d42caccb51b4f460e401.tar.gz
javassist-6f0d550f399ed4d5bee1d42caccb51b4f460e401.zip
Added javassist.bytecode.AnnotationsAttribute and support classes.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@110 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/bytecode')
-rw-r--r--src/main/javassist/bytecode/AnnotationsAttribute.java465
-rw-r--r--src/main/javassist/bytecode/AttributeInfo.java6
-rw-r--r--src/main/javassist/bytecode/ConstPool.java1
-rw-r--r--src/main/javassist/bytecode/Descriptor.java28
-rw-r--r--src/main/javassist/bytecode/ParameterAnnotationsAttribute.java110
-rw-r--r--src/main/javassist/bytecode/annotation/AnnotationInfo.java6
-rw-r--r--src/main/javassist/bytecode/annotation/AnnotationsVisitor.java163
-rw-r--r--src/main/javassist/bytecode/annotation/AnnotationsWriter.java348
-rw-r--r--src/main/javassist/bytecode/annotation/ClassMemberValue.java6
-rw-r--r--src/main/javassist/bytecode/annotation/EnumMemberValue.java6
-rw-r--r--src/main/javassist/bytecode/annotation/package.html8
11 files changed, 1124 insertions, 23 deletions
diff --git a/src/main/javassist/bytecode/AnnotationsAttribute.java b/src/main/javassist/bytecode/AnnotationsAttribute.java
new file mode 100644
index 00000000..ba593bb6
--- /dev/null
+++ b/src/main/javassist/bytecode/AnnotationsAttribute.java
@@ -0,0 +1,465 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javassist.bytecode.annotation.*;
+
+/**
+ * A class representing
+ * <code>RuntimeVisibleAnnotations_attribute</code> and
+ * <code>RuntimeInvisibleAnnotations_attribute</code>.
+ */
+public class AnnotationsAttribute extends AttributeInfo {
+ /**
+ * The name of the <code>RuntimeVisibleAnnotations</code> attribute.
+ */
+ public static final String visibleTag = "RuntimeVisibleAnnotations";
+
+ /**
+ * The name of the <code>RuntimeInvisibleAnnotations</code> attribute.
+ */
+ public static final String invisibleTag = "RuntimeInvisibleAnnotations";
+
+ /**
+ * Constructs a <code>Runtime(In)VisisbleAnnotations_attribute</code>.
+ *
+ * @param cp constant pool
+ * @param attrname attribute name (<code>visibleTag</code> or
+ * <code>invisibleTag</code>).
+ * @param info the contents of this attribute. It does not
+ * include <code>attribute_name_index</code> or
+ * <code>attribute_length</code>.
+ */
+ public AnnotationsAttribute(ConstPool cp, String attrname, byte[] info) {
+ super(cp, attrname, info);
+ }
+
+ /**
+ * Constructs an empty
+ * <code>Runtime(In)VisisbleAnnotations_attribute</code>.
+ *
+ * @param cp constant pool
+ * @param attrname attribute name (<code>visibleTag</code> or
+ * <code>invisibleTag</code>).
+ */
+ public AnnotationsAttribute(ConstPool cp, String attrname) {
+ this(cp, attrname, new byte[] { 0, 0 });
+ }
+
+ /**
+ * @param n the attribute name.
+ */
+ AnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
+ throws IOException
+ {
+ super(cp, n, in);
+ }
+
+ /**
+ * Returns <code>num_annotations</code>.
+ */
+ public int numAnnotations() {
+ return ByteArray.readU16bit(info, 0);
+ }
+
+ /**
+ * 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);
+ }
+
+ AnnotationsAttribute makeCopy(ConstPool newCp, byte[] info) {
+ return new AnnotationsAttribute(newCp, getName(), info);
+ }
+
+ /**
+ * Runs the parser to analyze this annotation.
+ * It invokes methods on the given visitor object while parsing.
+ *
+ * @see AnnotationsWriter
+ */
+ 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();
+ }
+
+ 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);
+
+ visitor.endAnnotation();
+ return pos;
+ }
+
+ 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;
+ }
+
+ 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();
+ 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();
+ return pos;
+ }
+ else { // primitive types or String.
+ int index = ByteArray.readU16bit(info, pos + 1);
+ visitor.constValueIndex(constPool, tag, index);
+ return pos + 3;
+ }
+ }
+
+ /**
+ * 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;
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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 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) {
+ output = new ByteArrayOutputStream();
+ writer = new AnnotationsWriter(output, dest);
+ 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());
+ }
+
+ /**
+ * Writes <code>num_parameters</code>.
+ */
+ public void beginParameters(int num) throws IOException {
+ writer.numParameters(num);
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void endParameters() {}
+
+ /**
+ * Writes <code>num_annotations</code>.
+ */
+ public void beginAnnotationsArray(int num) throws IOException {
+ writer.numAnnotations(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);
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>enum_const_value</code>.
+ */
+ public void enumConstValue(ConstPool cp, int typeNameIndex,
+ int constNameIndex)
+ throws IOException
+ {
+ writer.enumConstValue(copy(cp, typeNameIndex),
+ copy(cp, 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));
+ }
+
+ /**
+ * Writes <code>tag</code>.
+ */
+ public void beginAnnotationValue() throws IOException {
+ writer.annotationValue();
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void endAnnotationValue() {}
+
+ /**
+ * Writes <code>num_values</code> in <code>array_value</code>.
+ */
+ public void beginArrayValue(int numValues) throws IOException {
+ writer.arrayValue(numValues);
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void arrayElement(int i) {}
+
+ /**
+ * Invoked when the parser ends parsing <code>array_value</code>
+ * in <code>member_value</code>.
+ */
+ 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());
+ }
+ }
+
+ public void beginParameters(int num) {
+ sbuf.append("parameters[").append(num).append("]{");
+ }
+
+ public void endParameters() {
+ sbuf.append('}');
+ }
+
+ public void beginAnnotationsArray(int num) {
+ sbuf.append("annotations[").append(num).append("]{");
+ }
+
+ public void endAnnotationsArray() {
+ sbuf.append('}');
+ }
+
+ public void beginAnnotation(ConstPool cp,
+ int typeIndex, int numMemberValuePairs) {
+ String name = Descriptor.toClassName(cp.getUtf8Info(typeIndex));
+ sbuf.append('@').append(name).append('{');
+ }
+
+ public void endAnnotation() {
+ sbuf.append('}');
+ }
+
+ public void beginMemberValuePair(ConstPool cp, int memberNameIndex) {
+ sbuf.append(cp.getUtf8Info(memberNameIndex)).append('=');
+ }
+
+ public void endMemberValuePair() {
+ sbuf.append(", ");
+ }
+
+ 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 );
+ }
+
+ public void enumConstValue(ConstPool cp, int typeNameIndex,
+ int constNameIndex) {
+ String name
+ = Descriptor.toClassName(cp.getUtf8Info(typeNameIndex));
+ sbuf.append(name)
+ .append('.').append(cp.getUtf8Info(constNameIndex));
+ }
+
+ public void classInfoIndex(ConstPool cp, int index)
+ throws IOException
+ {
+ sbuf.append(Descriptor.toClassName(cp.getUtf8Info(index)))
+ .append(" class");
+ }
+
+ public void beginAnnotationValue() {}
+
+ public void endAnnotationValue() {}
+
+ public void beginArrayValue(int numValues) {
+ sbuf.append("array[").append(numValues).append("]{");
+ }
+
+ public void arrayElement(int i) {
+ sbuf.append(", ");
+ }
+
+ public void endArrayValue() {
+ sbuf.append('}');
+ }
+ }
+
+}
diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java
index 82fa7087..b3f02873 100644
--- a/src/main/javassist/bytecode/AttributeInfo.java
+++ b/src/main/javassist/bytecode/AttributeInfo.java
@@ -89,6 +89,12 @@ public class AttributeInfo {
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);
}
diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java
index d517b531..6a024dbf 100644
--- a/src/main/javassist/bytecode/ConstPool.java
+++ b/src/main/javassist/bytecode/ConstPool.java
@@ -578,6 +578,7 @@ public final class ConstPool {
* @param n the <i>n</i>-th item
* @param dest destination constant pool table
* @param classnames the map or null.
+ * @return the index of the copied item into the destination ClassPool.
*/
public int copy(int n, ConstPool dest, Map classnames) {
if (n == 0)
diff --git a/src/main/javassist/bytecode/Descriptor.java b/src/main/javassist/bytecode/Descriptor.java
index 9590d632..9c5b69c7 100644
--- a/src/main/javassist/bytecode/Descriptor.java
+++ b/src/main/javassist/bytecode/Descriptor.java
@@ -47,29 +47,29 @@ public class Descriptor {
}
/**
- * Converts to a classname from a descriptor
+ * Returns the internal representation of the class name in the
+ * JVM.
*/
- public static String fromDescriptor(String descriptor) {
- String newname = toJavaName(descriptor).substring(1);
- return newname.substring(0, newname.length() - 1);
+ public static String toJvmName(CtClass clazz) {
+ if (clazz.isArray())
+ return of(clazz);
+ else
+ return toJvmName(clazz.getName());
}
/**
- * Converts to a descriptor from a classname
+ * Converts to a Java class name from a descriptor
*/
- public static String toDescriptor(String classname) {
- return "L" + toJvmName(classname) + ";";
+ public static String toClassName(String descriptor) {
+ String newname = toJavaName(descriptor);
+ return newname.substring(1, newname.length() - 1);
}
/**
- * Returns the internal representation of the class name in the
- * JVM.
+ * Converts to a descriptor from a Java class name
*/
- public static String toJvmName(CtClass clazz) {
- if (clazz.isArray())
- return of(clazz);
- else
- return toJvmName(clazz.getName());
+ public static String of(String classname) {
+ return "L" + toJvmName(classname) + ";";
}
/**
diff --git a/src/main/javassist/bytecode/ParameterAnnotationsAttribute.java b/src/main/javassist/bytecode/ParameterAnnotationsAttribute.java
new file mode 100644
index 00000000..932be9ee
--- /dev/null
+++ b/src/main/javassist/bytecode/ParameterAnnotationsAttribute.java
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.DataInputStream;
+
+import javassist.bytecode.annotation.*;
+
+/**
+ * A class representing <code>RuntimeVisibleAnnotations_attribute</code> and
+ * <code>RuntimeInvisibleAnnotations_attribute</code>.
+ */
+public class ParameterAnnotationsAttribute extends AnnotationsAttribute {
+ /**
+ * The name of the <code>RuntimeVisibleParameterAnnotations</code>
+ * attribute.
+ */
+ public static final String visibleTag
+ = "RuntimeVisibleParameterAnnotations";
+
+ /**
+ * The name of the <code>RuntimeInvisibleParameterAnnotations</code>
+ * attribute.
+ */
+ public static final String invisibleTag
+ = "RuntimeInvisibleParameterAnnotations";
+ /**
+ * Constructs
+ * a <code>Runtime(In)VisisbleParameterAnnotations_attribute</code>.
+ *
+ * @param cp constant pool
+ * @param attrname attribute name (<code>visibleTag</code> or
+ * <code>invisibleTag</code>).
+ * @param info the contents of this attribute. It does not
+ * include <code>attribute_name_index</code> or
+ * <code>attribute_length</code>.
+ */
+ public ParameterAnnotationsAttribute(ConstPool cp, String attrname,
+ byte[] info) {
+ super(cp, attrname, info);
+ }
+
+ /**
+ * Constructs an empty
+ * <code>Runtime(In)VisisbleParameterAnnotations_attribute</code>.
+ *
+ * @param cp constant pool
+ * @param attrname attribute name (<code>visibleTag</code> or
+ * <code>invisibleTag</code>).
+ */
+ public ParameterAnnotationsAttribute(ConstPool cp, String attrname) {
+ this(cp, attrname, new byte[] { 0 });
+ }
+
+ /**
+ * @param n the attribute name.
+ */
+ ParameterAnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
+ throws IOException
+ {
+ super(cp, n, in);
+ }
+
+ /**
+ * Returns <code>num_parameters</code>.
+ */
+ public int numParameters() {
+ return info[0] & 0xff;
+ }
+
+ AnnotationsAttribute makeCopy(ConstPool newCp, byte[] info) {
+ return new ParameterAnnotationsAttribute(newCp, getName(), info);
+ }
+
+ /**
+ * Runs the parser to analyze this annotation.
+ *
+ * @see AnnotationsWriter
+ */
+ 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);
+ }
+
+ visitor.endAnnotationsArray();
+ }
+
+ visitor.endParameters();
+ }
+}
diff --git a/src/main/javassist/bytecode/annotation/AnnotationInfo.java b/src/main/javassist/bytecode/annotation/AnnotationInfo.java
index aac523d9..bdb53352 100644
--- a/src/main/javassist/bytecode/annotation/AnnotationInfo.java
+++ b/src/main/javassist/bytecode/annotation/AnnotationInfo.java
@@ -33,7 +33,7 @@ import java.util.Iterator;
* Comment
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*
**/
public class AnnotationInfo
@@ -120,7 +120,7 @@ public class AnnotationInfo
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.toDescriptor(clazz.getName()));
+ type_index = (short)cp.addUtf8Info(Descriptor.of(clazz.getName()));
CtMethod methods[] = clazz.getDeclaredMethods();
if (methods.length > 0)
{
@@ -144,7 +144,7 @@ public class AnnotationInfo
public String getAnnotationType()
{
- String name = Descriptor.fromDescriptor(cp.getUtf8Info(type_index));
+ String name = Descriptor.toClassName(cp.getUtf8Info(type_index));
return name;
}
diff --git a/src/main/javassist/bytecode/annotation/AnnotationsVisitor.java b/src/main/javassist/bytecode/annotation/AnnotationsVisitor.java
new file mode 100644
index 00000000..18c7c74f
--- /dev/null
+++ b/src/main/javassist/bytecode/annotation/AnnotationsVisitor.java
@@ -0,0 +1,163 @@
+/*
+ * 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 {}
+}
diff --git a/src/main/javassist/bytecode/annotation/AnnotationsWriter.java b/src/main/javassist/bytecode/annotation/AnnotationsWriter.java
new file mode 100644
index 00000000..791fbb39
--- /dev/null
+++ b/src/main/javassist/bytecode/annotation/AnnotationsWriter.java
@@ -0,0 +1,348 @@
+/*
+ * 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 java.io.*;
+
+import javassist.bytecode.ByteArray;
+import javassist.bytecode.ConstPool;
+
+/**
+ * A convenience class for constructing a
+ * <code>..Annotations_attribute</code>.
+ * It is typically used together with <code>AnnotationsVisitor</code>.
+ * See the source code of the <code>AnnotationsAttribute.Copier</code> class.
+ *
+ * <p>The following code snippet is an example of use of this class:
+ *
+ * <ul><pre>
+ * ConstPool pool = ...;
+ * output = new ByteArrayOutputStream();
+ * writer = new AnnotationsWriter(output, pool);
+ *
+ * writer.numAnnotations(1);
+ * writer.annotation("Author", 2);
+ * writer.memberValuePair("name");
+ * writer.constValueIndex("chiba");
+ * writer.memberValuePair("address");
+ * writer.constValueIndex("tokyo");
+ *
+ * writer.close();
+ * byte[] attribute_info = output.toByteArray();
+ * AnnotationsAttribute anno
+ * = new AnnotationsAttribute(pool, AnnotationsAttribute.visibleTag,
+ * attribute_info);
+ * </pre></ul>
+ *
+ * <p>The code snippet above generates the annotation attribute
+ * corresponding to this annotation:
+ *
+ * <ul><pre>
+ * @Author(name = "chiba", address = "tokyo")
+ * </pre></ul>
+ *
+ * @see AnnotationsAttribute
+ * @see ParameterAnnotationsAttribute
+ * @see AnnotationsVisitor
+ */
+public class AnnotationsWriter {
+ private OutputStream output;
+ private ConstPool pool;
+
+ /**
+ * Constructs with the given output stream.
+ *
+ * @param os the output stream.
+ * @param cp the constant pool.
+ */
+ public AnnotationsWriter(OutputStream os, ConstPool cp) {
+ output = os;
+ pool = cp;
+ }
+
+ /**
+ * Closes the output stream.
+ *
+ */
+ public void close() throws IOException {
+ output.close();
+ }
+
+ /**
+ * Writes <code>num_parameters</code> in
+ * <code>Runtime(In)VisibleParameterAnnotations_attribute</code>.
+ * This method must be followed by <code>num</code> calls to
+ * <code>numAnnotations()</code>.
+ */
+ public void numParameters(int num) throws IOException {
+ output.write(num);
+ }
+
+ /**
+ * Writes <code>num_annotations</code> in
+ * <code>Runtime(In)VisibleAnnotations_attribute</code>.
+ * This method must be followed by <code>num</code> calls to
+ * <code>annotation()</code>.
+ */
+ public void numAnnotations(int num) throws IOException {
+ write16bit(num);
+ }
+
+ /**
+ * Writes <code>annotation</code>.
+ * This method must be followed by <code>numMemberValuePairs</code>
+ * calls to <code>memberValuePair()</code>.
+ *
+ * @param type the annotation interface name.
+ * @param numMemberValuePairs <code>num_member_value_pairs</code>
+ * in <code>annotation</code>.
+ */
+ public void annotation(String type, int numMemberValuePairs)
+ throws IOException
+ {
+ annotation(pool.addUtf8Info(type), numMemberValuePairs);
+ }
+
+ /**
+ * Writes <code>annotation</code>.
+ * This method must be followed by <code>numMemberValuePairs</code>
+ * calls to <code>memberValuePair()</code>.
+ *
+ * @param typeIndex <code>type_index</code> in <code>annotation</code>.
+ * @param numMemberValuePairs <code>num_member_value_pairs</code>
+ * in <code>annotation</code>.
+ */
+ public void annotation(int typeIndex, int numMemberValuePairs)
+ throws IOException
+ {
+ write16bit(typeIndex);
+ write16bit(numMemberValuePairs);
+ }
+
+ /**
+ * Writes an element of a <code>member_value_pairs</code> array
+ * in <code>annotation</code>.
+ * This method must be followed by a
+ * call to <code>constValueIndex()</code>, <code>enumConstValue()</code>,
+ * etc.
+ *
+ * @param memberName the name of the annotation type member.
+ */
+ public void memberValuePair(String memberName) throws IOException {
+ memberValuePair(pool.addUtf8Info(memberName));
+ }
+
+ /**
+ * Writes an element of a <code>member_value_pairs</code> array
+ * in <code>annotation</code>.
+ * This method must be followed by a
+ * call to <code>constValueIndex()</code>, <code>enumConstValue()</code>,
+ * etc.
+ *
+ * @param memberNameIndex <code>member_name_index</code>
+ * in <code>member_value_pairs</code> array.
+ */
+ public void memberValuePair(int memberNameIndex) throws IOException {
+ write16bit(memberNameIndex);
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(boolean value) throws IOException {
+ constValueIndex('Z', pool.addIntegerInfo(value ? 1 : 0));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(byte value) throws IOException {
+ constValueIndex('B', pool.addIntegerInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(char value) throws IOException {
+ constValueIndex('C', pool.addIntegerInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(short value) throws IOException {
+ constValueIndex('S', pool.addIntegerInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(int value) throws IOException {
+ constValueIndex('I', pool.addIntegerInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(long value) throws IOException {
+ constValueIndex('J', pool.addLongInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(float value) throws IOException {
+ constValueIndex('F', pool.addFloatInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(double value) throws IOException {
+ constValueIndex('D', pool.addDoubleInfo(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param value the constant value.
+ */
+ public void constValueIndex(String value) throws IOException {
+ constValueIndex('s', pool.addUtf8Info(value));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>const_value_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param tag <code>tag</code> in <code>member_value</code>.
+ * @param index <code>const_value_index</code>
+ * in <code>member_value</code>.
+ */
+ public void constValueIndex(int tag, int index)
+ throws IOException
+ {
+ output.write(tag);
+ write16bit(index);
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>enum_const_value</code>
+ * in <code>member_value</code>.
+ *
+ * @param typeName the type name of the enum constant.
+ * @param constName the simple name of the enum constant.
+ */
+ public void enumConstValue(String typeName, String constName)
+ throws IOException
+ {
+ enumConstValue(pool.addUtf8Info(typeName),
+ pool.addUtf8Info(constName));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>enum_const_value</code>
+ * in <code>member_value</code>.
+ *
+ * @param typeNameIndex <code>type_name_index</code>
+ * in <code>member_value</code>.
+ * @param constNameIndex <code>const_name_index</code>
+ * in <code>member_value</code>.
+ */
+ public void enumConstValue(int typeNameIndex, int constNameIndex)
+ throws IOException
+ {
+ output.write('e');
+ write16bit(typeNameIndex);
+ write16bit(constNameIndex);
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>class_info_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param name the class name.
+ */
+ public void classInfoIndex(String name) throws IOException {
+ classInfoIndex(pool.addUtf8Info(name));
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>class_info_index</code>
+ * in <code>member_value</code>.
+ *
+ * @param index <code>class_info_index</code>
+ */
+ public void classInfoIndex(int index) throws IOException {
+ output.write('c');
+ write16bit(index);
+ }
+
+ /**
+ * Writes <code>tag</code> and <code>annotation_value</code>
+ * in <code>member_value</code>.
+ * This method must be followed by a call to <code>annotation()</code>.
+ */
+ public void annotationValue() throws IOException {
+ output.write('@');
+ }
+
+ /**
+ * 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>,
+ * etc.
+ *
+ * @param numValues <code>num_values</code>
+ * in <code>array_value</code>.
+ */
+ public void arrayValue(int numValues) throws IOException {
+ output.write('[');
+ write16bit(numValues);
+ }
+
+ private void write16bit(int value) throws IOException {
+ byte[] buf = new byte[2];
+ ByteArray.write16bit(value, buf, 0);
+ output.write(buf);
+ }
+}
diff --git a/src/main/javassist/bytecode/annotation/ClassMemberValue.java b/src/main/javassist/bytecode/annotation/ClassMemberValue.java
index 8a075f03..2dedd90f 100644
--- a/src/main/javassist/bytecode/annotation/ClassMemberValue.java
+++ b/src/main/javassist/bytecode/annotation/ClassMemberValue.java
@@ -24,7 +24,7 @@ import java.io.IOException;
* Comment
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*
**/
public class ClassMemberValue extends MemberValue
@@ -46,13 +46,13 @@ public class ClassMemberValue extends MemberValue
public String getClassName()
{
// beta1 return cp.getClassInfo(class_info_index);
- return Descriptor.fromDescriptor(cp.getUtf8Info(class_info_index));
+ return Descriptor.toClassName(cp.getUtf8Info(class_info_index));
}
public void setClassName(String name)
{
// beta1 class_info_index = (short)cp.addClassInfo(name);
- class_info_index = (short)cp.addUtf8Info(Descriptor.toDescriptor(name));
+ class_info_index = (short)cp.addUtf8Info(Descriptor.of(name));
}
public String toString()
diff --git a/src/main/javassist/bytecode/annotation/EnumMemberValue.java b/src/main/javassist/bytecode/annotation/EnumMemberValue.java
index f2c395a0..12247aed 100644
--- a/src/main/javassist/bytecode/annotation/EnumMemberValue.java
+++ b/src/main/javassist/bytecode/annotation/EnumMemberValue.java
@@ -25,7 +25,7 @@ import java.io.IOException;
* Comment
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*
**/
public class EnumMemberValue extends MemberValue
@@ -56,7 +56,7 @@ public class EnumMemberValue extends MemberValue
*/
public String getEnumType()
{
- return Descriptor.fromDescriptor(cp.getUtf8Info(type_name_index));
+ return Descriptor.toClassName(cp.getUtf8Info(type_name_index));
}
/**
@@ -65,7 +65,7 @@ public class EnumMemberValue extends MemberValue
*/
public void setEnumType(String classname)
{
- type_name_index = (short)cp.addUtf8Info(Descriptor.toDescriptor(classname));
+ type_name_index = (short)cp.addUtf8Info(Descriptor.of(classname));
}
public String getEnumVal()
diff --git a/src/main/javassist/bytecode/annotation/package.html b/src/main/javassist/bytecode/annotation/package.html
new file mode 100644
index 00000000..4be4ae9f
--- /dev/null
+++ b/src/main/javassist/bytecode/annotation/package.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+Annotations.
+
+<p>This package provides low-level API for editing annotations attributes.
+
+</body>
+</html>