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