KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55 package org.jboss.axis.utils.bytecode;
56
57 import org.jboss.axis.utils.Messages;
58
59 import java.io.IOException JavaDoc;
60 import java.lang.reflect.Method JavaDoc;
61 import java.lang.reflect.Modifier JavaDoc;
62 import java.util.HashMap JavaDoc;
63 import java.util.Map JavaDoc;
64
65 /**
66  * This is the class file reader for obtaining the parameter names
67  * for declared methods in a class. The class must have debugging
68  * attributes for us to obtain this information. <p>
69  * <p/>
70  * This does not work for inherited methods. To obtain parameter
71  * names for inherited methods, you must use a paramReader for the
72  * class that originally declared the method. <p>
73  * <p/>
74  * don't get tricky, it's the bare minimum. Instances of this class
75  * are not threadsafe -- don't share them. <p>
76  *
77  * @author Edwin Smith, Macromedia
78  */

79 public class ParamReader
80         extends ClassReader
81 {
82    private String JavaDoc methodName;
83    private Map JavaDoc methods = new HashMap JavaDoc();
84    private Class JavaDoc[] paramTypes;
85
86    /**
87     * process a class file, given it's class. We'll use the defining
88     * classloader to locate the bytecode.
89     *
90     * @param c
91     * @throws IOException
92     */

93    public ParamReader(Class JavaDoc c) throws IOException JavaDoc
94    {
95       this(getBytes(c));
96    }
97
98    /**
99     * process the given class bytes directly.
100     *
101     * @param b
102     * @throws IOException
103     */

104    public ParamReader(byte[] b) throws IOException JavaDoc
105    {
106       super(b, findAttributeReaders(ParamReader.class));
107
108       // check the magic number
109
if (readInt() != 0xCAFEBABE)
110       {
111          // not a class file!
112
throw new IOException JavaDoc(Messages.getMessage("badClassFile00"));
113       }
114
115       readShort(); // minor version
116
readShort(); // major version
117

118       readCpool(); // slurp in the constant pool
119

120       readShort(); // access flags
121
readShort(); // this class name
122
readShort(); // super class name
123

124       int count = readShort(); // ifaces count
125
for (int i = 0; i < count; i++)
126       {
127          readShort(); // interface index
128
}
129
130       count = readShort(); // fields count
131
for (int i = 0; i < count; i++)
132       {
133          readShort(); // access flags
134
readShort(); // name index
135
readShort(); // descriptor index
136
skipAttributes(); // field attributes
137
}
138
139       count = readShort(); // methods count
140
for (int i = 0; i < count; i++)
141       {
142          readShort(); // access flags
143
int m = readShort(); // name index
144
String JavaDoc name = resolveUtf8(m);
145          int d = readShort(); // descriptor index
146
this.methodName = name + resolveUtf8(d);
147          readAttributes(); // method attributes
148
}
149
150    }
151
152    public void readCode() throws IOException JavaDoc
153    {
154       readShort(); // max stack
155
int maxLocals = readShort(); // max locals
156

157       MethodInfo info = new MethodInfo(maxLocals);
158       if (methods != null && methodName != null)
159       {
160          methods.put(methodName, info);
161       }
162
163       skipFully(readInt()); // code
164
skipFully(8 * readShort()); // exception table
165
// read the code attributes (recursive). This is where
166
// we will find the LocalVariableTable attribute.
167
readAttributes();
168    }
169
170    /**
171     * return the names of the declared parameters for the given method.
172     * If we cannot determine the names, return null. The returned array will
173     * have one name per parameter. The length of the array will be the same
174     * as the length of the Class[] array returned by Method.getParameterTypes().
175     *
176     * @param method
177     * @return String[] array of names, one per parameter, or null
178     */

179    public String JavaDoc[] getParameterNames(Method JavaDoc method)
180    {
181       paramTypes = method.getParameterTypes();
182
183       // look up the names for this method
184
MethodInfo info = (MethodInfo)methods.get(getSignature(method, paramTypes));
185
186       // we know all the local variable names, but we only need to return
187
// the names of the parameters.
188

189       if (info != null)
190       {
191          String JavaDoc[] paramNames = new String JavaDoc[paramTypes.length];
192          int j = Modifier.isStatic(method.getModifiers()) ? 0 : 1;
193
194          boolean found = false; // did we find any non-null names
195
for (int i = 0; i < paramNames.length; i++)
196          {
197             if (info.names[j] != null)
198             {
199                found = true;
200                paramNames[i] = info.names[j];
201             }
202             j++;
203             if (paramTypes[i] == double.class || paramTypes[i] == long.class)
204             {
205                // skip a slot for 64bit params
206
j++;
207             }
208          }
209
210          if (found)
211          {
212             return paramNames;
213          }
214          else
215          {
216             return null;
217          }
218       }
219       else
220       {
221          return null;
222       }
223    }
224
225    private static class MethodInfo
226    {
227       String JavaDoc[] names;
228       int maxLocals;
229
230       public MethodInfo(int maxLocals)
231       {
232          this.maxLocals = maxLocals;
233          names = new String JavaDoc[maxLocals];
234       }
235    }
236
237    private MethodInfo getMethodInfo()
238    {
239       MethodInfo info = null;
240       if (methods != null && methodName != null)
241       {
242          info = (MethodInfo)methods.get(methodName);
243       }
244       return info;
245    }
246
247    /**
248     * this is invoked when a LocalVariableTable attribute is encountered.
249     *
250     * @throws IOException
251     */

252    public void readLocalVariableTable() throws IOException JavaDoc
253    {
254       int len = readShort(); // table length
255
MethodInfo info = getMethodInfo();
256       for (int j = 0; j < len; j++)
257       {
258          readShort(); // start pc
259
readShort(); // length
260
int nameIndex = readShort(); // name_index
261
readShort(); // descriptor_index
262
int index = readShort(); // local index
263
if (info != null)
264          {
265             info.names[index] = resolveUtf8(nameIndex);
266          }
267       }
268    }
269 }
270
Popular Tags