KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > utils > bytecode > ParamReader


1 /*
2  * Copyright 2002-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 package org.apache.axis.utils.bytecode;
17
18 import org.apache.axis.utils.Messages;
19
20 import java.io.IOException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Constructor JavaDoc;
23 import java.lang.reflect.Member JavaDoc;
24 import java.lang.reflect.Modifier JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Map JavaDoc;
27
28 /**
29  * This is the class file reader for obtaining the parameter names
30  * for declared methods in a class. The class must have debugging
31  * attributes for us to obtain this information. <p>
32  *
33  * This does not work for inherited methods. To obtain parameter
34  * names for inherited methods, you must use a paramReader for the
35  * class that originally declared the method. <p>
36  *
37  * don't get tricky, it's the bare minimum. Instances of this class
38  * are not threadsafe -- don't share them. <p>
39  *
40  * @author Edwin Smith, Macromedia
41  */

42 public class ParamReader
43         extends ClassReader {
44     private String JavaDoc methodName;
45     private Map JavaDoc methods = new HashMap JavaDoc();
46     private Class JavaDoc[] paramTypes;
47
48     /**
49      * process a class file, given it's class. We'll use the defining
50      * classloader to locate the bytecode.
51      * @param c
52      * @throws IOException
53      */

54     public ParamReader(Class JavaDoc c) throws IOException JavaDoc {
55         this(getBytes(c));
56     }
57
58     /**
59      * process the given class bytes directly.
60      * @param b
61      * @throws IOException
62      */

63     public ParamReader(byte[] b) throws IOException JavaDoc {
64         super(b, findAttributeReaders(ParamReader.class));
65
66         // check the magic number
67
if (readInt() != 0xCAFEBABE) {
68             // not a class file!
69
throw new IOException JavaDoc(Messages.getMessage("badClassFile00"));
70         }
71
72         readShort(); // minor version
73
readShort(); // major version
74

75         readCpool(); // slurp in the constant pool
76

77         readShort(); // access flags
78
readShort(); // this class name
79
readShort(); // super class name
80

81         int count = readShort(); // ifaces count
82
for (int i = 0; i < count; i++) {
83             readShort(); // interface index
84
}
85
86         count = readShort(); // fields count
87
for (int i = 0; i < count; i++) {
88             readShort(); // access flags
89
readShort(); // name index
90
readShort(); // descriptor index
91
skipAttributes(); // field attributes
92
}
93
94         count = readShort(); // methods count
95
for (int i = 0; i < count; i++) {
96             readShort(); // access flags
97
int m = readShort(); // name index
98
String JavaDoc name = resolveUtf8(m);
99             int d = readShort(); // descriptor index
100
this.methodName = name + resolveUtf8(d);
101             readAttributes(); // method attributes
102
}
103
104     }
105
106     public void readCode() throws IOException JavaDoc
107     {
108         readShort(); // max stack
109
int maxLocals = readShort(); // max locals
110

111         MethodInfo info = new MethodInfo(maxLocals);
112         if (methods != null && methodName != null)
113         {
114             methods.put(methodName, info);
115         }
116
117         skipFully(readInt()); // code
118
skipFully(8 * readShort()); // exception table
119
// read the code attributes (recursive). This is where
120
// we will find the LocalVariableTable attribute.
121
readAttributes();
122     }
123
124     /**
125      * return the names of the declared parameters for the given constructor.
126      * If we cannot determine the names, return null. The returned array will
127      * have one name per parameter. The length of the array will be the same
128      * as the length of the Class[] array returned by Constructor.getParameterTypes().
129      * @param ctor
130      * @return String[] array of names, one per parameter, or null
131      */

132     public String JavaDoc[] getParameterNames(Constructor JavaDoc ctor) {
133         paramTypes = ctor.getParameterTypes();
134         return getParameterNames(ctor, paramTypes);
135     }
136
137     /**
138      * return the names of the declared parameters for the given method.
139      * If we cannot determine the names, return null. The returned array will
140      * have one name per parameter. The length of the array will be the same
141      * as the length of the Class[] array returned by Method.getParameterTypes().
142      * @param method
143      * @return String[] array of names, one per parameter, or null
144      */

145     public String JavaDoc[] getParameterNames(Method JavaDoc method) {
146         paramTypes = method.getParameterTypes();
147         return getParameterNames(method, paramTypes);
148     }
149
150     protected String JavaDoc[] getParameterNames(Member JavaDoc member,Class JavaDoc [] paramTypes) {
151         // look up the names for this method
152
MethodInfo info = (MethodInfo) methods.get(getSignature(member, paramTypes));
153
154         // we know all the local variable names, but we only need to return
155
// the names of the parameters.
156

157         if (info != null) {
158             String JavaDoc[] paramNames = new String JavaDoc[paramTypes.length];
159             int j = Modifier.isStatic(member.getModifiers()) ? 0 : 1;
160
161             boolean found = false; // did we find any non-null names
162
for (int i = 0; i < paramNames.length; i++) {
163                 if (info.names[j] != null) {
164                     found = true;
165                     paramNames[i] = info.names[j];
166                 }
167                 j++;
168                 if (paramTypes[i] == double.class || paramTypes[i] == long.class) {
169                     // skip a slot for 64bit params
170
j++;
171                 }
172             }
173
174             if (found) {
175                 return paramNames;
176             } else {
177                 return null;
178             }
179         } else {
180             return null;
181         }
182     }
183
184     private static class MethodInfo
185     {
186         String JavaDoc[] names;
187         int maxLocals;
188
189         public MethodInfo(int maxLocals)
190         {
191             this.maxLocals = maxLocals;
192             names = new String JavaDoc[maxLocals];
193         }
194     }
195
196     private MethodInfo getMethodInfo()
197     {
198         MethodInfo info = null;
199         if (methods != null && methodName != null)
200         {
201             info = (MethodInfo) methods.get(methodName);
202         }
203         return info;
204     }
205
206     /**
207      * this is invoked when a LocalVariableTable attribute is encountered.
208      * @throws IOException
209      */

210     public void readLocalVariableTable() throws IOException JavaDoc {
211         int len = readShort(); // table length
212
MethodInfo info = getMethodInfo();
213         for (int j = 0; j < len; j++) {
214             readShort(); // start pc
215
readShort(); // length
216
int nameIndex = readShort(); // name_index
217
readShort(); // descriptor_index
218
int index = readShort(); // local index
219
if (info != null) {
220                 info.names[index] = resolveUtf8(nameIndex);
221             }
222         }
223     }
224 }
225
Popular Tags