View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
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      /* The name of the constructor code */
31      public final static String intializerName = "<init>";
32  
33      /* The name of the static initializer code */
34      public final static String staticIntializerName = "<clinit>";
35  
36      /* access flag bit mask - see VMConstants */
37      private int accessFlags;
38  
39      /* The name of the method */
40      private ConstUtf8 methodName;
41  
42      /* The type signature of the method */
43      private ConstUtf8 methodSignature;
44  
45      /* The attributes associated with the field */
46      private AttributeVector methodAttributes;
47    
48    
49      /* public accessors */
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     //@olsen: added method
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     //@olsen: added method
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     //@olsen: made public
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">/* package local methods *//package-summary.html">class="comment"> package local methods */
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