Coverage Report - org.mule.config.spring.util.ParamReader
 
Classes in this File Line Coverage Branch Coverage Complexity
ParamReader
0%
0/84
0%
0/38
0
ParamReader$MethodInfo
0%
0/3
N/A
0
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements. See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership. The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License. You may obtain a copy of the License at
 9  
  *
 10  
  * http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied. See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 
 20  
 package org.mule.config.spring.util;
 21  
 
 22  
 // import org.apache.axis.utils.Messages;
 23  
 
 24  
 import java.io.IOException;
 25  
 import java.lang.reflect.Constructor;
 26  
 import java.lang.reflect.Member;
 27  
 import java.lang.reflect.Method;
 28  
 import java.lang.reflect.Modifier;
 29  
 import java.lang.reflect.Proxy;
 30  
 import java.util.HashMap;
 31  
 import java.util.Map;
 32  
 
 33  
 /**
 34  
  * This is the class file reader for obtaining the parameter names for declared
 35  
  * methods in a class. The class must have debugging attributes for us to obtain this
 36  
  * information.
 37  
  * <p>
 38  
  * This does not work for inherited methods. To obtain parameter names for inherited
 39  
  * methods, you must use a paramReader for the class that originally declared the
 40  
  * method.
 41  
  * <p>
 42  
  * don't get tricky, it's the bare minimum. Instances of this class are not
 43  
  * threadsafe -- don't share them.
 44  
  * <p>
 45  
  * 
 46  
  * @author Edwin Smith, Macromedia
 47  
  */
 48  
 public class ParamReader extends ClassReader
 49  
 {
 50  
     private String methodName;
 51  0
     private Map<String, MethodInfo> methods = new HashMap<String, MethodInfo>();
 52  
     private Class[] paramTypes;
 53  
 
 54  
     /**
 55  
      * process a class file, given it's class. We'll use the defining classloader to
 56  
      * locate the bytecode.
 57  
      * 
 58  
      * @param c
 59  
      * @throws IOException
 60  
      */
 61  
     public ParamReader(Class c) throws IOException
 62  
     {
 63  0
         this(getBytes(c));
 64  0
     }
 65  
 
 66  
     /**
 67  
      * process the given class bytes directly.
 68  
      * 
 69  
      * @param b
 70  
      * @throws IOException
 71  
      */
 72  
     public ParamReader(byte[] b) throws IOException
 73  
     {
 74  0
         super(b, findAttributeReaders(ParamReader.class));
 75  
 
 76  
         // check the magic number
 77  0
         if (readInt() != 0xCAFEBABE)
 78  
         {
 79  
             // not a class file!
 80  0
             throw new IOException();
 81  
         }
 82  
 
 83  0
         readShort(); // minor version
 84  0
         readShort(); // major version
 85  
 
 86  0
         readCpool(); // slurp in the constant pool
 87  
 
 88  0
         readShort(); // access flags
 89  0
         readShort(); // this class name
 90  0
         readShort(); // super class name
 91  
 
 92  0
         int count = readShort(); // ifaces count
 93  0
         for (int i = 0; i < count; i++)
 94  
         {
 95  0
             readShort(); // interface index
 96  
         }
 97  
 
 98  0
         count = readShort(); // fields count
 99  0
         for (int i = 0; i < count; i++)
 100  
         {
 101  0
             readShort(); // access flags
 102  0
             readShort(); // name index
 103  0
             readShort(); // descriptor index
 104  0
             skipAttributes(); // field attributes
 105  
         }
 106  
 
 107  0
         count = readShort(); // methods count
 108  0
         for (int i = 0; i < count; i++)
 109  
         {
 110  0
             readShort(); // access flags
 111  0
             int m = readShort(); // name index
 112  0
             String name = resolveUtf8(m);
 113  0
             int d = readShort(); // descriptor index
 114  0
             this.methodName = name + resolveUtf8(d);
 115  0
             readAttributes(); // method attributes
 116  
         }
 117  
 
 118  0
     }
 119  
 
 120  
     /**
 121  
      * Retrieve a list of function parameter names from a method Returns null if
 122  
      * unable to read parameter names (i.e. bytecode not built with debug).
 123  
      */
 124  
     public static String[] getParameterNamesFromDebugInfo(Method method)
 125  
     {
 126  
         // Don't worry about it if there are no params.
 127  0
         int numParams = method.getParameterTypes().length;
 128  0
         if (numParams == 0)
 129  
         {
 130  0
             return null;
 131  
         }
 132  
 
 133  
         // get declaring class
 134  0
         Class c = method.getDeclaringClass();
 135  
 
 136  
         // Don't worry about it if the class is a Java dynamic proxy
 137  0
         if (Proxy.isProxyClass(c))
 138  
         {
 139  0
             return null;
 140  
         }
 141  
 
 142  
         try
 143  
         {
 144  
             // get a parameter reader
 145  0
             ParamReader pr = new ParamReader(c);
 146  
             // get the parameter names
 147  0
             return pr.getParameterNames(method);
 148  
         }
 149  0
         catch (IOException e)
 150  
         {
 151  
             // log it and leave
 152  
             // log.info(Messages.getMessage("error00") + ":" + e);
 153  0
             return null;
 154  
         }
 155  
     }
 156  
 
 157  
     public void readCode() throws IOException
 158  
     {
 159  0
         readShort(); // max stack
 160  0
         int maxLocals = readShort(); // max locals
 161  
 
 162  0
         MethodInfo info = new MethodInfo(maxLocals);
 163  0
         if (methods != null && methodName != null)
 164  
         {
 165  0
             methods.put(methodName, info);
 166  
         }
 167  
 
 168  0
         skipFully(readInt()); // code
 169  0
         skipFully(8 * readShort()); // exception table
 170  
         // read the code attributes (recursive). This is where
 171  
         // we will find the LocalVariableTable attribute.
 172  0
         readAttributes();
 173  0
     }
 174  
 
 175  
     /**
 176  
      * return the names of the declared parameters for the given constructor. If we
 177  
      * cannot determine the names, return null. The returned array will have one name
 178  
      * per parameter. The length of the array will be the same as the length of the
 179  
      * Class[] array returned by Constructor.getParameterTypes().
 180  
      * 
 181  
      * @param ctor
 182  
      * @return String[] array of names, one per parameter, or null
 183  
      */
 184  
     public String[] getParameterNames(Constructor ctor)
 185  
     {
 186  0
         paramTypes = ctor.getParameterTypes();
 187  0
         return getParameterNames(ctor, paramTypes);
 188  
     }
 189  
 
 190  
     /**
 191  
      * return the names of the declared parameters for the given method. If we cannot
 192  
      * determine the names, return null. The returned array will have one name per
 193  
      * parameter. The length of the array will be the same as the length of the
 194  
      * Class[] array returned by Method.getParameterTypes().
 195  
      * 
 196  
      * @param method
 197  
      * @return String[] array of names, one per parameter, or null
 198  
      */
 199  
     public String[] getParameterNames(Method method)
 200  
     {
 201  0
         paramTypes = method.getParameterTypes();
 202  0
         return getParameterNames(method, paramTypes);
 203  
     }
 204  
 
 205  
     protected String[] getParameterNames(Member member, Class[] pTypes)
 206  
     {
 207  
         // look up the names for this method
 208  0
         MethodInfo info = (MethodInfo) methods.get(getSignature(member, pTypes));
 209  
 
 210  
         // we know all the local variable names, but we only need to return
 211  
         // the names of the parameters.
 212  
 
 213  0
         if (info != null)
 214  
         {
 215  0
             String[] paramNames = new String[pTypes.length];
 216  0
             int j = Modifier.isStatic(member.getModifiers()) ? 0 : 1;
 217  
 
 218  0
             boolean found = false; // did we find any non-null names
 219  0
             for (int i = 0; i < paramNames.length; i++)
 220  
             {
 221  0
                 if (info.names[j] != null)
 222  
                 {
 223  0
                     found = true;
 224  0
                     paramNames[i] = info.names[j];
 225  
                 }
 226  0
                 j++;
 227  0
                 if (pTypes[i] == double.class || pTypes[i] == long.class)
 228  
                 {
 229  
                     // skip a slot for 64bit params
 230  0
                     j++;
 231  
                 }
 232  
             }
 233  
 
 234  0
             if (found)
 235  
             {
 236  0
                 return paramNames;
 237  
             }
 238  
             else
 239  
             {
 240  0
                 return null;
 241  
             }
 242  
         }
 243  
         else
 244  
         {
 245  0
             return null;
 246  
         }
 247  
     }
 248  
 
 249  
     private static class MethodInfo
 250  
     {
 251  
         String[] names;
 252  
 
 253  
         public MethodInfo(int maxLocals)
 254  0
         {
 255  0
             names = new String[maxLocals];
 256  0
         }
 257  
     }
 258  
 
 259  
     private MethodInfo getMethodInfo()
 260  
     {
 261  0
         MethodInfo info = null;
 262  0
         if (methods != null && methodName != null)
 263  
         {
 264  0
             info = (MethodInfo) methods.get(methodName);
 265  
         }
 266  0
         return info;
 267  
     }
 268  
 
 269  
     /**
 270  
      * this is invoked when a LocalVariableTable attribute is encountered.
 271  
      * 
 272  
      * @throws IOException
 273  
      */
 274  
     public void readLocalVariableTable() throws IOException
 275  
     {
 276  0
         int len = readShort(); // table length
 277  0
         MethodInfo info = getMethodInfo();
 278  0
         for (int j = 0; j < len; j++)
 279  
         {
 280  0
             readShort(); // start pc
 281  0
             readShort(); // length
 282  0
             int nameIndex = readShort(); // name_index
 283  0
             readShort(); // descriptor_index
 284  0
             int index = readShort(); // local index
 285  0
             if (info != null)
 286  
             {
 287  0
                 info.names[index] = resolveUtf8(nameIndex);
 288  
             }
 289  
         }
 290  0
     }
 291  
 }