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: */package org.ejb3unit.asm.tree;
030:
031: import org.ejb3unit.asm.Attribute;
032: import org.ejb3unit.asm.ClassVisitor;
033: import org.ejb3unit.asm.FieldVisitor;
034: import org.ejb3unit.asm.MethodVisitor;
035:
036: import java.util.List;
037: import java.util.ArrayList;
038: import java.util.Arrays;
039:
040: /**
041: * A node that represents a class.
042: *
043: * @author Eric Bruneton
044: */
045: public class ClassNode extends MemberNode implements ClassVisitor {
046:
047: /**
048: * The class version.
049: */
050: public int version;
051:
052: /**
053: * The class's access flags (see {@link org.ejb3unit.asm.Opcodes}). This
054: * field also indicates if the class is deprecated.
055: */
056: public int access;
057:
058: /**
059: * The internal name of the class (see
060: * {@link org.ejb3unit.asm.Type#getInternalName() getInternalName}).
061: */
062: public String name;
063:
064: /**
065: * The signature of the class. Mayt be <tt>null</tt>.
066: */
067: public String signature;
068:
069: /**
070: * The internal of name of the super class (see
071: * {@link org.ejb3unit.asm.Type#getInternalName() getInternalName}). For
072: * interfaces, the super class is {@link Object}. May be <tt>null</tt>,
073: * but only for the {@link Object} class.
074: */
075: public String super Name;
076:
077: /**
078: * The internal names of the class's interfaces (see
079: * {@link org.ejb3unit.asm.Type#getInternalName() getInternalName}). This
080: * list is a list of {@link String} objects.
081: */
082: public List interfaces;
083:
084: /**
085: * The name of the source file from which this class was compiled. May be
086: * <tt>null</tt>.
087: */
088: public String sourceFile;
089:
090: /**
091: * Debug information to compute the correspondance between source and
092: * compiled elements of the class. May be <tt>null</tt>.
093: */
094: public String sourceDebug;
095:
096: /**
097: * The internal name of the enclosing class of the class. May be
098: * <tt>null</tt>.
099: */
100: public String outerClass;
101:
102: /**
103: * The name of the method that contains the class, or <tt>null</tt> if the
104: * class is not enclosed in a method.
105: */
106: public String outerMethod;
107:
108: /**
109: * The descriptor of the method that contains the class, or <tt>null</tt>
110: * if the class is not enclosed in a method.
111: */
112: public String outerMethodDesc;
113:
114: /**
115: * Informations about the inner classes of this class. This list is a list
116: * of {@link InnerClassNode} objects.
117: *
118: * @associates org.objectweb.asm.tree.InnerClassNode
119: */
120: public List innerClasses;
121:
122: /**
123: * The fields of this class. This list is a list of {@link FieldNode}
124: * objects.
125: *
126: * @associates org.objectweb.asm.tree.FieldNode
127: */
128: public List fields;
129:
130: /**
131: * The methods of this class. This list is a list of {@link MethodNode}
132: * objects.
133: *
134: * @associates org.objectweb.asm.tree.MethodNode
135: */
136: public List methods;
137:
138: /**
139: * Constructs a new {@link ClassNode}.
140: */
141: public ClassNode() {
142: this .interfaces = new ArrayList();
143: this .innerClasses = new ArrayList();
144: this .fields = new ArrayList();
145: this .methods = new ArrayList();
146: }
147:
148: // ------------------------------------------------------------------------
149: // Implementation of the ClassVisitor interface
150: // ------------------------------------------------------------------------
151:
152: public void visit(final int version, final int access,
153: final String name, final String signature,
154: final String super Name, final String[] interfaces) {
155: this .version = version;
156: this .access = access;
157: this .name = name;
158: this .signature = signature;
159: this .super Name = super Name;
160: if (interfaces != null) {
161: this .interfaces.addAll(Arrays.asList(interfaces));
162: }
163: }
164:
165: public void visitSource(final String file, final String debug) {
166: sourceFile = file;
167: sourceDebug = debug;
168: }
169:
170: public void visitOuterClass(final String owner, final String name,
171: final String desc) {
172: outerClass = owner;
173: outerMethod = name;
174: outerMethodDesc = desc;
175: }
176:
177: public void visitInnerClass(final String name,
178: final String outerName, final String innerName,
179: final int access) {
180: InnerClassNode icn = new InnerClassNode(name, outerName,
181: innerName, access);
182: innerClasses.add(icn);
183: }
184:
185: public FieldVisitor visitField(final int access, final String name,
186: final String desc, final String signature,
187: final Object value) {
188: FieldNode fn = new FieldNode(access, name, desc, signature,
189: value);
190: fields.add(fn);
191: return fn;
192: }
193:
194: public MethodVisitor visitMethod(final int access,
195: final String name, final String desc,
196: final String signature, final String[] exceptions) {
197: MethodNode mn = new MethodNode(access, name, desc, signature,
198: exceptions);
199: methods.add(mn);
200: return mn;
201: }
202:
203: public void visitEnd() {
204: }
205:
206: // ------------------------------------------------------------------------
207: // Accept method
208: // ------------------------------------------------------------------------
209:
210: /**
211: * Makes the given class visitor visit this class.
212: *
213: * @param cv a class visitor.
214: */
215: public void accept(final ClassVisitor cv) {
216: // visits header
217: String[] interfaces = new String[this .interfaces.size()];
218: this .interfaces.toArray(interfaces);
219: cv.visit(version, access, name, signature, super Name,
220: interfaces);
221: // visits source
222: if (sourceFile != null || sourceDebug != null) {
223: cv.visitSource(sourceFile, sourceDebug);
224: }
225: // visits outer class
226: if (outerClass != null) {
227: cv
228: .visitOuterClass(outerClass, outerMethod,
229: outerMethodDesc);
230: }
231: // visits attributes
232: int i, n;
233: n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
234: for (i = 0; i < n; ++i) {
235: AnnotationNode an = (AnnotationNode) visibleAnnotations
236: .get(i);
237: an.accept(cv.visitAnnotation(an.desc, true));
238: }
239: n = invisibleAnnotations == null ? 0 : invisibleAnnotations
240: .size();
241: for (i = 0; i < n; ++i) {
242: AnnotationNode an = (AnnotationNode) invisibleAnnotations
243: .get(i);
244: an.accept(cv.visitAnnotation(an.desc, false));
245: }
246: n = attrs == null ? 0 : attrs.size();
247: for (i = 0; i < n; ++i) {
248: cv.visitAttribute((Attribute) attrs.get(i));
249: }
250: // visits inner classes
251: for (i = 0; i < innerClasses.size(); ++i) {
252: ((InnerClassNode) innerClasses.get(i)).accept(cv);
253: }
254: // visits fields
255: for (i = 0; i < fields.size(); ++i) {
256: ((FieldNode) fields.get(i)).accept(cv);
257: }
258: // visits methods
259: for (i = 0; i < methods.size(); ++i) {
260: ((MethodNode) methods.get(i)).accept(cv);
261: }
262: // visits end
263: cv.visitEnd();
264: }
265: }
|