1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.jdo.impl.enhancer.classfile;
20
21 import java.io.*;
22 import java.util.Vector;
23 import java.util.Stack;
24 import java.util.Enumeration;
25
26 /***
27 * ClassMethod models the static and non-static methods of a class within
28 * a class file. This includes constructors and initializer code.
29 */
30 public class ClassMethod extends ClassMember {
31
32 public final static String intializerName = "<init>";
33
34
35 public final static String staticIntializerName = "<clinit>";
36
37
38 private int accessFlags;
39
40
41 private ConstUtf8 methodName;
42
43
44 private ConstUtf8 methodSignature;
45
46
47 private AttributeVector methodAttributes;
48
49
50
51
52 /***
53 * Return the access flags for the method - see VMConstants
54 */
55 public int access() {
56 return accessFlags;
57 }
58
59 /***
60 * Update the access flags for the field - see VMConstants
61 */
62 public void setAccess(int newFlags) {
63 accessFlags = newFlags;
64 }
65
66 /***
67 * Is the method abstract?
68 */
69 public boolean isAbstract() {
70 return (accessFlags & ACCAbstract) != 0;
71 }
72
73 /***
74 * Is the method native?
75 */
76 public boolean isNative() {
77 return (accessFlags & ACCNative) != 0;
78 }
79
80 /***
81 * Return the name of the method
82 */
83 public ConstUtf8 name() {
84 return methodName;
85 }
86
87 /***
88 * Change the name of the method
89 */
90 public void changeName(ConstUtf8 name) {
91 methodName = name;
92 }
93
94 /***
95 * Return the type signature of the method
96 */
97 public ConstUtf8 signature() {
98 return methodSignature;
99 }
100
101 /***
102 * Change the type signature of the method
103 */
104 public void changeSignature(ConstUtf8 newSig) {
105 methodSignature = newSig;
106 }
107
108 /***
109 * Return the attributes associated with the method
110 */
111 public AttributeVector attributes() {
112 return methodAttributes;
113 }
114
115 /***
116 * Construct a class method object
117 */
118
119 public ClassMethod(int accFlags, ConstUtf8 name, ConstUtf8 sig,
120 AttributeVector methodAttrs) {
121 accessFlags = accFlags;
122 methodName = name;
123 methodSignature = sig;
124 methodAttributes = methodAttrs;
125 }
126
127 /***
128 * Returns the size of the method byteCode (if any)
129 */
130 int codeSize() {
131 CodeAttribute codeAttr = codeAttribute();
132 return (codeAttr == null) ? 0 : codeAttr.codeSize();
133 }
134
135 /***
136 * Returns the CodeAttribute associated with this method (if any)
137 */
138 public CodeAttribute codeAttribute() {
139 Enumeration e = methodAttributes.elements();
140 while (e.hasMoreElements()) {
141 ClassAttribute attr = (ClassAttribute) e.nextElement();
142 if (attr instanceof CodeAttribute)
143 return (CodeAttribute) attr;
144 }
145 return null;
146 }
147
148 /***
149 * Returns the ExceptionsAttribute associated with this method (if any)
150 */
151
152 public ExceptionsAttribute exceptionsAttribute() {
153 Enumeration e = methodAttributes.elements();
154 while (e.hasMoreElements()) {
155 ClassAttribute attr = (ClassAttribute) e.nextElement();
156 if (attr instanceof ExceptionsAttribute)
157 return (ExceptionsAttribute) attr;
158 }
159 return null;
160 }
161
162 /***
163 * Compares this instance with another for structural equality.
164 */
165
166 public boolean isEqual(Stack msg, Object obj) {
167 if (!(obj instanceof ClassMethod)) {
168 msg.push("obj/obj.getClass() = "
169 + (obj == null ? null : obj.getClass()));
170 msg.push("this.getClass() = "
171 + this.getClass());
172 return false;
173 }
174 ClassMethod other = (ClassMethod)obj;
175
176 if (!super.isEqual(msg, other)) {
177 return false;
178 }
179
180 if (this.accessFlags != other.accessFlags) {
181 msg.push(String.valueOf("accessFlags = 0x"
182 + Integer.toHexString(other.accessFlags)));
183 msg.push(String.valueOf("accessFlags = 0x"
184 + Integer.toHexString(this.accessFlags)));
185 return false;
186 }
187 if (!this.methodName.isEqual(msg, other.methodName)) {
188 msg.push(String.valueOf("methodName = "
189 + other.methodName));
190 msg.push(String.valueOf("methodName = "
191 + this.methodName));
192 return false;
193 }
194 if (!this.methodSignature.isEqual(msg, other.methodSignature)) {
195 msg.push(String.valueOf("methodSignature = "
196 + other.methodSignature));
197 msg.push(String.valueOf("methodSignature = "
198 + this.methodSignature));
199 return false;
200 }
201 if (!this.methodAttributes.isEqual(msg, other.methodAttributes)) {
202 msg.push(String.valueOf("methodAttributes = "
203 + other.methodAttributes));
204 msg.push(String.valueOf("methodAttributes = "
205 + this.methodAttributes));
206 return false;
207 }
208 return true;
209 }
210
211
212 public void print(PrintStream out, int indent) {
213 ClassPrint.spaces(out, indent);
214 out.print("'" + methodName.asString() + "'");
215 out.print(" sig = " + methodSignature.asString());
216 out.print(" accessFlags = " + Integer.toString(accessFlags));
217 out.println(" attributes:");
218 methodAttributes.print(out, indent+2);
219 }
220
221 /* package local methods *//package-summary/html">class="comment"> package local methods *//package-summary.html">
222
223 static ClassMethod read(DataInputStream data, ConstantPool pool)
224 throws IOException {
225 int accessFlags = data.readUnsignedShort();
226 int nameIndex = data.readUnsignedShort();
227 int sigIndex = data.readUnsignedShort();
228 ClassMethod f =
229 new ClassMethod(accessFlags,
230 (ConstUtf8) pool.constantAt(nameIndex),
231 (ConstUtf8) pool.constantAt(sigIndex),
232 null);
233
234 f.methodAttributes = AttributeVector.readAttributes(data, pool);
235 return f;
236 }
237
238 void write(DataOutputStream data) throws IOException {
239 CodeAttribute codeAttr = codeAttribute();
240 data.writeShort(accessFlags);
241 data.writeShort(methodName.getIndex());
242 data.writeShort(methodSignature.getIndex());
243 methodAttributes.write(data);
244 }
245 }
246
247