001: /*
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2005 INRIA, France Telecom
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.objectweb.asm.util;
031:
032: import org.objectweb.asm.AnnotationVisitor;
033: import org.objectweb.asm.Type;
034:
035: /**
036: * An {@link AnnotationVisitor} that prints a disassembled view of the
037: * annotations it visits.
038: *
039: * @author Eric Bruneton
040: */
041: @SuppressWarnings("unchecked")
042: public class TraceAnnotationVisitor extends TraceAbstractVisitor
043: implements AnnotationVisitor {
044:
045: /**
046: * The {@link AnnotationVisitor} to which this visitor delegates calls. May
047: * be <tt>null</tt>.
048: */
049: protected AnnotationVisitor av;
050:
051: private int valueNumber = 0;
052:
053: /**
054: * Constructs a new {@link TraceAnnotationVisitor}.
055: */
056: public TraceAnnotationVisitor() {
057: // ignore
058: }
059:
060: // ------------------------------------------------------------------------
061: // Implementation of the AnnotationVisitor interface
062: // ------------------------------------------------------------------------
063:
064: public void visit(final String name, final Object value) {
065: buf.setLength(0);
066: appendComa(valueNumber++);
067:
068: if (name != null) {
069: buf.append(name).append('=');
070: }
071:
072: if (value instanceof String) {
073: visitString((String) value);
074: } else if (value instanceof Type) {
075: visitType((Type) value);
076: } else if (value instanceof Byte) {
077: visitByte(((Byte) value).byteValue());
078: } else if (value instanceof Boolean) {
079: visitBoolean(((Boolean) value).booleanValue());
080: } else if (value instanceof Short) {
081: visitShort(((Short) value).shortValue());
082: } else if (value instanceof Character) {
083: visitChar(((Character) value).charValue());
084: } else if (value instanceof Integer) {
085: visitInt(((Integer) value).intValue());
086: } else if (value instanceof Float) {
087: visitFloat(((Float) value).floatValue());
088: } else if (value instanceof Long) {
089: visitLong(((Long) value).longValue());
090: } else if (value instanceof Double) {
091: visitDouble(((Double) value).doubleValue());
092: } else if (value.getClass().isArray()) {
093: buf.append('{');
094: if (value instanceof byte[]) {
095: byte[] v = (byte[]) value;
096: for (int i = 0; i < v.length; i++) {
097: appendComa(i);
098: visitByte(v[i]);
099: }
100: } else if (value instanceof boolean[]) {
101: boolean[] v = (boolean[]) value;
102: for (int i = 0; i < v.length; i++) {
103: appendComa(i);
104: visitBoolean(v[i]);
105: }
106: } else if (value instanceof short[]) {
107: short[] v = (short[]) value;
108: for (int i = 0; i < v.length; i++) {
109: appendComa(i);
110: visitShort(v[i]);
111: }
112: } else if (value instanceof char[]) {
113: char[] v = (char[]) value;
114: for (int i = 0; i < v.length; i++) {
115: appendComa(i);
116: visitChar(v[i]);
117: }
118: } else if (value instanceof int[]) {
119: int[] v = (int[]) value;
120: for (int i = 0; i < v.length; i++) {
121: appendComa(i);
122: visitInt(v[i]);
123: }
124: } else if (value instanceof long[]) {
125: long[] v = (long[]) value;
126: for (int i = 0; i < v.length; i++) {
127: appendComa(i);
128: visitLong(v[i]);
129: }
130: } else if (value instanceof float[]) {
131: float[] v = (float[]) value;
132: for (int i = 0; i < v.length; i++) {
133: appendComa(i);
134: visitFloat(v[i]);
135: }
136: } else if (value instanceof double[]) {
137: double[] v = (double[]) value;
138: for (int i = 0; i < v.length; i++) {
139: appendComa(i);
140: visitDouble(v[i]);
141: }
142: }
143: buf.append('}');
144: }
145:
146: text.add(buf.toString());
147:
148: if (av != null) {
149: av.visit(name, value);
150: }
151: }
152:
153: private void visitInt(final int value) {
154: buf.append(value);
155: }
156:
157: private void visitLong(final long value) {
158: buf.append(value).append('L');
159: }
160:
161: private void visitFloat(final float value) {
162: buf.append(value).append('F');
163: }
164:
165: private void visitDouble(final double value) {
166: buf.append(value).append('D');
167: }
168:
169: private void visitChar(final char value) {
170: buf.append("(char)").append((int) value);
171: }
172:
173: private void visitShort(final short value) {
174: buf.append("(short)").append(value);
175: }
176:
177: private void visitByte(final byte value) {
178: buf.append("(byte)").append(value);
179: }
180:
181: private void visitBoolean(final boolean value) {
182: buf.append(value);
183: }
184:
185: private void visitString(final String value) {
186: appendString(buf, value);
187: }
188:
189: private void visitType(final Type value) {
190: buf.append(value.getClassName()).append(".class");
191: }
192:
193: public void visitEnum(final String name, final String desc,
194: final String value) {
195: buf.setLength(0);
196: appendComa(valueNumber++);
197: if (name != null) {
198: buf.append(name).append('=');
199: }
200: appendDescriptor(FIELD_DESCRIPTOR, desc);
201: buf.append('.').append(value);
202: text.add(buf.toString());
203:
204: if (av != null) {
205: av.visitEnum(name, desc, value);
206: }
207: }
208:
209: public AnnotationVisitor visitAnnotation(final String name,
210: final String desc) {
211: buf.setLength(0);
212: appendComa(valueNumber++);
213: if (name != null) {
214: buf.append(name).append('=');
215: }
216: buf.append('@');
217: appendDescriptor(FIELD_DESCRIPTOR, desc);
218: buf.append('(');
219: text.add(buf.toString());
220: TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
221: text.add(tav.getText());
222: text.add(")");
223: if (av != null) {
224: tav.av = av.visitAnnotation(name, desc);
225: }
226: return tav;
227: }
228:
229: public AnnotationVisitor visitArray(final String name) {
230: buf.setLength(0);
231: appendComa(valueNumber++);
232: if (name != null) {
233: buf.append(name).append('=');
234: }
235: buf.append('{');
236: text.add(buf.toString());
237: TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
238: text.add(tav.getText());
239: text.add("}");
240: if (av != null) {
241: tav.av = av.visitArray(name);
242: }
243: return tav;
244: }
245:
246: public void visitEnd() {
247: if (av != null) {
248: av.visitEnd();
249: }
250: }
251:
252: // ------------------------------------------------------------------------
253: // Utility methods
254: // ------------------------------------------------------------------------
255:
256: private void appendComa(final int i) {
257: if (i != 0) {
258: buf.append(", ");
259: }
260: }
261: }
|