View Javadoc

1   /*
2    * Copyright  2000-2004 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  package org.apache.bcel.classfile;
18  
19  import java.io.DataInputStream;
20  import java.io.IOException;
21  import org.apache.bcel.Constants;
22  import org.apache.bcel.generic.Type;
23  import org.apache.bcel.util.BCELComparator;
24  
25  /***
26   * This class represents the method info structure, i.e., the representation 
27   * for a method in the class. See JVM specification for details.
28   * A method has access flags, a name, a signature and a number of attributes.
29   *
30   * @version $Id: Method.java 386056 2006-03-15 11:31:56Z tcurdt $
31   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
32   */
33  public final class Method extends FieldOrMethod {
34  
35      private static BCELComparator _cmp = new BCELComparator() {
36  
37          public boolean equals( Object o1, Object o2 ) {
38              Method THIS = (Method) o1;
39              Method THAT = (Method) o2;
40              return THIS.getName().equals(THAT.getName())
41                      && THIS.getSignature().equals(THAT.getSignature());
42          }
43  
44  
45          public int hashCode( Object o ) {
46              Method THIS = (Method) o;
47              return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
48          }
49      };
50  
51  
52      /***
53       * Empty constructor, all attributes have to be defined via `setXXX'
54       * methods. Use at your own risk.
55       */
56      public Method() {
57      }
58  
59  
60      /***
61       * Initialize from another object. Note that both objects use the same
62       * references (shallow copy). Use clone() for a physical copy.
63       */
64      public Method(Method c) {
65          super(c);
66      }
67  
68  
69      /***
70       * Construct object from file stream.
71       * @param file Input stream
72       * @throws IOException
73       * @throws ClassFormatException
74       */
75      Method(DataInputStream file, ConstantPool constant_pool) throws IOException,
76              ClassFormatException {
77          super(file, constant_pool);
78      }
79  
80  
81      /***
82       * @param access_flags Access rights of method
83       * @param name_index Points to field name in constant pool
84       * @param signature_index Points to encoded signature
85       * @param attributes Collection of attributes
86       * @param constant_pool Array of constants
87       */
88      public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes,
89              ConstantPool constant_pool) {
90          super(access_flags, name_index, signature_index, attributes, constant_pool);
91      }
92  
93  
94      /***
95       * Called by objects that are traversing the nodes of the tree implicitely
96       * defined by the contents of a Java class. I.e., the hierarchy of methods,
97       * fields, attributes, etc. spawns a tree of objects.
98       *
99       * @param v Visitor object
100      */
101     public void accept( Visitor v ) {
102         v.visitMethod(this);
103     }
104 
105 
106     /***
107      * @return Code attribute of method, if any
108      */
109     public final Code getCode() {
110         for (int i = 0; i < attributes_count; i++) {
111             if (attributes[i] instanceof Code) {
112                 return (Code) attributes[i];
113             }
114         }
115         return null;
116     }
117 
118 
119     /***
120      * @return ExceptionTable attribute of method, if any, i.e., list all
121      * exceptions the method may throw not exception handlers!
122      */
123     public final ExceptionTable getExceptionTable() {
124         for (int i = 0; i < attributes_count; i++) {
125             if (attributes[i] instanceof ExceptionTable) {
126                 return (ExceptionTable) attributes[i];
127             }
128         }
129         return null;
130     }
131 
132 
133     /*** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded
134      * to the Code atribute.
135      */
136     public final LocalVariableTable getLocalVariableTable() {
137         Code code = getCode();
138         if (code == null) {
139             return null;
140         }
141         return code.getLocalVariableTable();
142     }
143 
144 
145     /*** @return LineNumberTable of code attribute if any, i.e. the call is forwarded
146      * to the Code atribute.
147      */
148     public final LineNumberTable getLineNumberTable() {
149         Code code = getCode();
150         if (code == null) {
151             return null;
152         }
153         return code.getLineNumberTable();
154     }
155 
156 
157     /***
158      * Return string representation close to declaration format,
159      * `public static void main(String[] args) throws IOException', e.g.
160      *
161      * @return String representation of the method.
162      */
163     public final String toString() {
164         ConstantUtf8 c;
165         String name, signature, access; // Short cuts to constant pool
166         StringBuffer buf;
167         access = Utility.accessToString(access_flags);
168         // Get name and signature from constant pool
169         c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
170         signature = c.getBytes();
171         c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
172         name = c.getBytes();
173         signature = Utility.methodSignatureToString(signature, name, access, true,
174                 getLocalVariableTable());
175         buf = new StringBuffer(signature);
176         for (int i = 0; i < attributes_count; i++) {
177             Attribute a = attributes[i];
178             if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
179                 buf.append(" [").append(a.toString()).append("]");
180             }
181         }
182         ExceptionTable e = getExceptionTable();
183         if (e != null) {
184             String str = e.toString();
185             if (!str.equals("")) {
186                 buf.append("\n\t\tthrows ").append(str);
187             }
188         }
189         return buf.toString();
190     }
191 
192 
193     /***
194      * @return deep copy of this method
195      */
196     public final Method copy( ConstantPool _constant_pool ) {
197         return (Method) copy_(_constant_pool);
198     }
199 
200 
201     /***
202      * @return return type of method
203      */
204     public Type getReturnType() {
205         return Type.getReturnType(getSignature());
206     }
207 
208 
209     /***
210      * @return array of method argument types
211      */
212     public Type[] getArgumentTypes() {
213         return Type.getArgumentTypes(getSignature());
214     }
215 
216 
217     /***
218      * @return Comparison strategy object
219      */
220     public static BCELComparator getComparator() {
221         return _cmp;
222     }
223 
224 
225     /***
226      * @param comparator Comparison strategy object
227      */
228     public static void setComparator( BCELComparator comparator ) {
229         _cmp = comparator;
230     }
231 
232 
233     /***
234      * Return value as defined by given BCELComparator strategy.
235      * By default two method objects are said to be equal when
236      * their names and signatures are equal.
237      * 
238      * @see java.lang.Object#equals(java.lang.Object)
239      */
240     public boolean equals( Object obj ) {
241         return _cmp.equals(this, obj);
242     }
243 
244 
245     /***
246      * Return value as defined by given BCELComparator strategy.
247      * By default return the hashcode of the method's name XOR signature.
248      * 
249      * @see java.lang.Object#hashCode()
250      */
251     public int hashCode() {
252         return _cmp.hashCode(this);
253     }
254 }