dims 2002/06/12 08:02:59 Modified: java build.xml Added: java/src/org/apache/axis/utils/bytecode BCEL.java Log: Adding BCEL based Extractor (Eat our own dogfood). Passed "all-tests" NOTE: - Should we make BCEL the default instead of TechTrader? Revision Changes Path 1.147 +5 -0 xml-axis/java/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/xml-axis/java/build.xml,v retrieving revision 1.146 retrieving revision 1.147 diff -u -r1.146 -r1.147 --- build.xml 11 Jun 2002 18:50:00 -0000 1.146 +++ build.xml 12 Jun 2002 15:02:59 -0000 1.147 @@ -170,6 +170,10 @@ classname="serp.bytecode.Project" classpathref="classpath"/> + <available property="bcel.present" + classname="org.apache.bcel.classfile.JavaClass" + classpathref="classpath"/> + <available property="activation.present" classname="javax.activation.DataHandler" classpathref="classpath"/> @@ -287,6 +291,7 @@ <exclude name="**/org/apache/axis/transport/http/AxisServlet.java" unless="servlet.present"/> <exclude name="**/org/apache/axis/server/JNDIAxisServerFactory.java" unless="servlet.present"/> <exclude name="**/org/apache/axis/security/servlet/*" unless="servlet.present"/> + <exclude name="**/org/apache/axis/utils/bytecode/BCEL*" unless="bcel.present"/> <exclude name="**/org/apache/axis/utils/bytecode/TechTrader*" unless="tt-bytecode.present"/> <exclude name="**/org/apache/axis/utils/bytecode/Serp*" unless="serp.present"/> <exclude name="**/javax/xml/soap/*.java" unless="attachments.present"/> 1.1 xml-axis/java/src/org/apache/axis/utils/bytecode/BCEL.java Index: BCEL.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Axis" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.axis.utils.bytecode; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.LocalVariable; import org.apache.bcel.classfile.LocalVariableTable; import org.apache.bcel.classfile.Method; import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; import java.util.Vector; /** * This class implements an Extractor using BCEL * * @author <a href="mailto:[EMAIL PROTECTED]">Davanum Srinivas</a> * @version $Revision: 1.1 $ $Date: 2002/06/12 15:02:59 $ */ public class BCEL implements Extractor { /** * Cache of BCEL JavaClass objects which correspond to particular * Java classes. * * !!! NOTE : AT PRESENT WE DO NOT CLEAN UP THIS CACHE. */ private static Hashtable clazzCache = new Hashtable(); /** * Get Parameter Names using BCEL * * @param method the Java method we're interested in * @return list of names or null */ public String[] getParameterNamesFromDebugInfo(java.lang.reflect.Method m) { Class c = m.getDeclaringClass(); int numParams = m.getParameterTypes().length; Vector temp = new Vector(); // Don't worry about it if there are no params. if (numParams == 0) return null; // Try to obtain a tt-bytecode class object JavaClass bclass = (JavaClass) clazzCache.get(c); if (bclass == null) { try { String className = c.getName(); String classFile = className.replace('.', '/'); InputStream is = c.getClassLoader().getResourceAsStream(classFile + ".class"); ClassParser parser = new ClassParser(is, className); bclass = parser.parse(); clazzCache.put(c, bclass); } catch (IOException e) { // what now? } } Method[] methods = bclass.getMethods(); Method method = null; // Get the BCEL Method corresponding to the // ava.lang.reflect.Method for (int i = 0; i < methods.length; i++) { if (m.getName().equals(methods[i].getName()) && getSignature(m).equals(methods[i].getSignature())) { method = methods[i]; break; } } // Obtain the exact method we're interested in. if (method == null) return null; // Get the Code object, which contains the local variable table. Code code = method.getCode(); if (code == null) return null; LocalVariableTable attr = method.getLocalVariableTable(); if (attr == null) return null; // OK, found it. Now scan through the local variables and record // the names in the right indices. LocalVariable[] vars = attr.getLocalVariableTable(); String[] argNames = new String[numParams + 1]; argNames[0] = null; // don't know return name // NOTE: we scan through all the variables here, because I have been // told that jikes sometimes produces unpredictable ordering of the // local variable table. for (int j = 0; j < vars.length; j++) { LocalVariable var = vars[j]; if (!var.getName().equals("this")) { if (temp.size() < var.getIndex() + 1) temp.setSize(var.getIndex() + 1); temp.setElementAt(var.getName(), var.getIndex()); } } int k = 0; for (int j = 0; j < temp.size(); j++) { if (temp.elementAt(j) != null) { k++; argNames[k] = (String) temp.elementAt(j); if (k + 1 == argNames.length) break; } } return argNames; } /** * Compute the JVM signature for the class. */ String getSignature(Class clazz) { String type = null; if (clazz.isArray()) { Class cl = clazz; int dimensions = 0; while (cl.isArray()) { dimensions++; cl = cl.getComponentType(); } StringBuffer sb = new StringBuffer(); for (int i = 0; i < dimensions; i++) { sb.append("["); } sb.append(getSignature(cl)); type = sb.toString(); } else if (clazz.isPrimitive()) { if (clazz == Integer.TYPE) { type = "I"; } else if (clazz == Byte.TYPE) { type = "B"; } else if (clazz == Long.TYPE) { type = "J"; } else if (clazz == Float.TYPE) { type = "F"; } else if (clazz == Double.TYPE) { type = "D"; } else if (clazz == Short.TYPE) { type = "S"; } else if (clazz == Character.TYPE) { type = "C"; } else if (clazz == Boolean.TYPE) { type = "Z"; } else if (clazz == Void.TYPE) { type = "V"; } } else { type = "L" + clazz.getName().replace('.', '/') + ";"; } return type; } /* * Compute the JVM method descriptor for the method. */ String getSignature(java.lang.reflect.Method meth) { StringBuffer sb = new StringBuffer(); sb.append("("); Class[] params = meth.getParameterTypes(); // avoid clone for (int j = 0; j < params.length; j++) { sb.append(getSignature(params[j])); } sb.append(")"); sb.append(getSignature(meth.getReturnType())); return sb.toString(); } }