1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInputStream;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.io.Serializable;
23 import org.apache.bcel.Constants;
24
25 /***
26 * This class represents a inner class attribute, i.e., the class
27 * indices of the inner and outer classes, the name and the attributes
28 * of the inner class.
29 *
30 * @version $Id: InnerClass.java 386056 2006-03-15 11:31:56Z tcurdt $
31 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
32 * @see InnerClasses
33 */
34 public final class InnerClass implements Cloneable, Node, Serializable {
35
36 private int inner_class_index;
37 private int outer_class_index;
38 private int inner_name_index;
39 private int inner_access_flags;
40
41
42 /***
43 * Initialize from another object.
44 */
45 public InnerClass(InnerClass c) {
46 this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c
47 .getInnerAccessFlags());
48 }
49
50
51 /***
52 * Construct object from file stream.
53 * @param file Input stream
54 * @throws IOException
55 */
56 InnerClass(DataInputStream file) throws IOException {
57 this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
58 .readUnsignedShort());
59 }
60
61
62 /***
63 * @param inner_class_index Class index in constant pool of inner class
64 * @param outer_class_index Class index in constant pool of outer class
65 * @param inner_name_index Name index in constant pool of inner class
66 * @param inner_access_flags Access flags of inner class
67 */
68 public InnerClass(int inner_class_index, int outer_class_index, int inner_name_index,
69 int inner_access_flags) {
70 this.inner_class_index = inner_class_index;
71 this.outer_class_index = outer_class_index;
72 this.inner_name_index = inner_name_index;
73 this.inner_access_flags = inner_access_flags;
74 }
75
76
77 /***
78 * Called by objects that are traversing the nodes of the tree implicitely
79 * defined by the contents of a Java class. I.e., the hierarchy of methods,
80 * fields, attributes, etc. spawns a tree of objects.
81 *
82 * @param v Visitor object
83 */
84 public void accept( Visitor v ) {
85 v.visitInnerClass(this);
86 }
87
88
89 /***
90 * Dump inner class attribute to file stream in binary format.
91 *
92 * @param file Output file stream
93 * @throws IOException
94 */
95 public final void dump( DataOutputStream file ) throws IOException {
96 file.writeShort(inner_class_index);
97 file.writeShort(outer_class_index);
98 file.writeShort(inner_name_index);
99 file.writeShort(inner_access_flags);
100 }
101
102
103 /***
104 * @return access flags of inner class.
105 */
106 public final int getInnerAccessFlags() {
107 return inner_access_flags;
108 }
109
110
111 /***
112 * @return class index of inner class.
113 */
114 public final int getInnerClassIndex() {
115 return inner_class_index;
116 }
117
118
119 /***
120 * @return name index of inner class.
121 */
122 public final int getInnerNameIndex() {
123 return inner_name_index;
124 }
125
126
127 /***
128 * @return class index of outer class.
129 */
130 public final int getOuterClassIndex() {
131 return outer_class_index;
132 }
133
134
135 /***
136 * @param inner_access_flags access flags for this inner class
137 */
138 public final void setInnerAccessFlags( int inner_access_flags ) {
139 this.inner_access_flags = inner_access_flags;
140 }
141
142
143 /***
144 * @param inner_class_index index into the constant pool for this class
145 */
146 public final void setInnerClassIndex( int inner_class_index ) {
147 this.inner_class_index = inner_class_index;
148 }
149
150
151 /***
152 * @param inner_name_index index into the constant pool for this class's name
153 */
154 public final void setInnerNameIndex( int inner_name_index ) {
155 this.inner_name_index = inner_name_index;
156 }
157
158
159 /***
160 * @param outer_class_index index into the constant pool for the owning class
161 */
162 public final void setOuterClassIndex( int outer_class_index ) {
163 this.outer_class_index = outer_class_index;
164 }
165
166
167 /***
168 * @return String representation.
169 */
170 public final String toString() {
171 return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", "
172 + inner_name_index + ", " + inner_access_flags + ")";
173 }
174
175
176 /***
177 * @return Resolved string representation
178 */
179 public final String toString( ConstantPool constant_pool ) {
180 String inner_class_name, outer_class_name, inner_name, access;
181 inner_class_name = constant_pool.getConstantString(inner_class_index,
182 Constants.CONSTANT_Class);
183 inner_class_name = Utility.compactClassName(inner_class_name);
184 if (outer_class_index != 0) {
185 outer_class_name = constant_pool.getConstantString(outer_class_index,
186 Constants.CONSTANT_Class);
187 outer_class_name = Utility.compactClassName(outer_class_name);
188 } else {
189 outer_class_name = "<not a member>";
190 }
191 if (inner_name_index != 0) {
192 inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index,
193 Constants.CONSTANT_Utf8)).getBytes();
194 } else {
195 inner_name = "<anonymous>";
196 }
197 access = Utility.accessToString(inner_access_flags, true);
198 access = access.equals("") ? "" : (access + " ");
199 return "InnerClass:" + access + inner_class_name + "(\"" + outer_class_name + "\", \""
200 + inner_name + "\")";
201 }
202
203
204 /***
205 * @return deep copy of this object
206 */
207 public InnerClass copy() {
208 try {
209 return (InnerClass) clone();
210 } catch (CloneNotSupportedException e) {
211 }
212 return null;
213 }
214 }