gdaniels    02/03/12 09:41:06

  Modified:    java/src/org/apache/axis/utils JavaUtils.java
               java/src/org/apache/axis/wsdl/fromJava ClassRep.java
  Log:
  Move getParameterNamesFromDebugInfo() into JavaUtils so it can be
  accessed by others, and make the cache a Hashtable for thread-safety.
  
  Thanks to Thomas Borkel for noticing the thread-safety issue!
  
  Revision  Changes    Path
  1.34      +147 -53   xml-axis/java/src/org/apache/axis/utils/JavaUtils.java
  
  Index: JavaUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/JavaUtils.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- JavaUtils.java    27 Feb 2002 13:41:28 -0000      1.33
  +++ JavaUtils.java    12 Mar 2002 17:41:06 -0000      1.34
  @@ -10,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    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
  @@ -18,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    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,
  @@ -26,7 +26,7 @@
    *
    * 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 
  + *    software without prior written permission. For written
    *    permission, please contact [EMAIL PROTECTED]
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -60,6 +60,7 @@
   
   import java.lang.reflect.Array;
   import java.lang.reflect.Field;
  +import java.lang.reflect.Method;
   
   import java.text.Collator;
   import java.text.MessageFormat;
  @@ -70,11 +71,21 @@
   import java.util.Locale;
   import java.util.MissingResourceException;
   import java.util.ResourceBundle;
  +import java.util.Hashtable;
  +import java.util.Vector;
  +import java.io.IOException;
  +
   import org.apache.axis.encoding.Hex;
  +import com.techtrader.modules.tools.bytecode.BCClass;
  +import com.techtrader.modules.tools.bytecode.BCMethod;
  +import com.techtrader.modules.tools.bytecode.Code;
  +import com.techtrader.modules.tools.bytecode.LocalVariableTableAttribute;
  +import com.techtrader.modules.tools.bytecode.Constants;
  +import com.techtrader.modules.tools.bytecode.LocalVariable;
   
   /** Utility class to deal with Java language related issues, such
    * as type conversions.
  - * 
  + *
    * @author Glen Daniels ([EMAIL PROTECTED])
    */
   public class JavaUtils
  @@ -83,10 +94,18 @@
           LogFactory.getLog(JavaUtils.class.getName());
   
       /**
  +     * Cache of tt-bytecode BCClass objects which correspond to particular
  +     * Java classes.
  +     *
  +     * !!! NOTE : AT PRESENT WE DO NOT CLEAN UP THIS CACHE.
  +     */
  +    private static Hashtable ttClassCache = new Hashtable();
  +
  +    /**
        * It the argument to the convert(...) method implements
  -     * the ConvertCache interface, the convert(...) method 
  +     * the ConvertCache interface, the convert(...) method
        * will use the set/get methods to store and retrieve
  -     * converted values.  
  +     * converted values.
        **/
       public interface ConvertCache {
           /**
  @@ -96,12 +115,12 @@
           public Object getConvertedValue(Class cls);
           /**
            * Get the destination array class described by the xml
  -         **/         
  +         **/
           public Class getDestClass();
       }
   
       /** Utility function to convert an Object to some desired Class.
  -     * 
  +     *
        * Right now this works for:
        *     arrays <-> Lists,
        *     Holders <-> held values
  @@ -109,7 +128,7 @@
        * @param destClass the actual class we want
        */
       public static Object convert(Object arg, Class destClass)
  -    {  
  +    {
           if (destClass == null) {
               return arg;
           }
  @@ -136,7 +155,7 @@
           }
   
           // Convert between Axis special purpose Hex and byte[]
  -        if (arg instanceof Hex && 
  +        if (arg instanceof Hex &&
               destClass == byte[].class) {
               return ((Hex) arg).getBytes();
           } else if (arg instanceof byte[] &&
  @@ -146,8 +165,8 @@
   
   
           // Return if no conversion is available
  -        if (!(arg instanceof List || 
  -              (arg != null && arg.getClass().isArray())) && 
  +        if (!(arg instanceof List ||
  +              (arg != null && arg.getClass().isArray())) &&
               ((destHeldType == null && argHeldType == null) ||
                (destHeldType != null && argHeldType != null))) {
               return arg;
  @@ -176,7 +195,7 @@
           }
   
           // Flow to here indicates that neither arg or destClass is a Holder
  -        
  +
           // Check to see if the argument has a prefered destination class.
           if (arg instanceof ConvertCache &&
               (( ConvertCache) arg).getDestClass() != destClass) {
  @@ -191,7 +210,7 @@
                       return destValue;
               }
           }
  -            
  +
           if (arg == null) {
               return arg;
           }
  @@ -205,21 +224,21 @@
           }
           if (destClass.isArray()) {
               if (destClass.getComponentType().isPrimitive()) {
  -                
  +
                   Object array = Array.newInstance(destClass.getComponentType(),
                                                    length);
                   // Assign array elements
                   if (arg.getClass().isArray()) {
                       for (int i = 0; i < length; i++) {
                           Array.set(array, i, Array.get(arg, i));
  -                    }                                
  -                } else {  
  +                    }
  +                } else {
                       for (int i = 0; i < length; i++) {
                           Array.set(array, i, ((List) arg).get(i));
                       }
                   }
                   destValue = array;
  -                
  +
               } else {
                   Object [] array;
                   try {
  @@ -232,15 +251,15 @@
                   // Use convert to assign array elements.
                   if (arg.getClass().isArray()) {
                       for (int i = 0; i < length; i++) {
  -                        array[i] = convert(Array.get(arg, i), 
  +                        array[i] = convert(Array.get(arg, i),
                                              destClass.getComponentType());
  -                    }                                
  -                } else {  
  +                    }
  +                } else {
                       for (int i = 0; i < length; i++) {
  -                        array[i] = convert(((List) arg).get(i), 
  +                        array[i] = convert(((List) arg).get(i),
                                              destClass.getComponentType());
                       }
  -                }   
  +                }
                   destValue = array;
               }
           }
  @@ -256,12 +275,12 @@
               if (arg.getClass().isArray()) {
                   for (int j = 0; j < length; j++) {
                       newList.add(Array.get(arg, j));
  -                }                                
  +                }
               } else {
                   for (int j = 0; j < length; j++) {
                       newList.add(((List) arg).get(j));
  -                }                
  -            }                
  +                }
  +            }
               destValue = newList;
           }
           else {
  @@ -307,7 +326,7 @@
        * @return boolean true/false
        **/
       public static boolean isJavaId(String id) {
  -        if (id == null || id.equals("") || isJavaKeyword(id)) 
  +        if (id == null || id.equals("") || isJavaKeyword(id))
               return false;
           if (!Character.isJavaIdentifierStart(id.charAt(0)))
               return false;
  @@ -338,7 +357,7 @@
        * Foo[] to the proper class name for loading [LFoo
        */
       public static String getLoadableClassName(String text) {
  -        if (text == null || 
  +        if (text == null ||
               text.indexOf("[") < 0 ||
               text.charAt(0) == '[')
               return text;
  @@ -374,7 +393,7 @@
        * [LFoo to the Foo[]
        */
       public static String getTextClassName(String text) {
  -        if (text == null || 
  +        if (text == null ||
               text.indexOf("[") != 0)
               return text;
           String className = "";
  @@ -410,7 +429,7 @@
   
       /**
        * Map an XML name to a Java identifier per
  -     * the mapping rules of JSR 101 (in 
  +     * the mapping rules of JSR 101 (in
        * version 0.7 this is
        * "Chapter 20: Appendix: Mapping of XML Names"
        * @param name is the xml name
  @@ -421,12 +440,12 @@
           // protect ourselves from garbage
           if (name == null || name.equals(""))
               return name;
  -        
  +
           char[] nameArray = name.toCharArray();
           int nameLen = name.length();
           StringBuffer result = new StringBuffer(nameLen);
           boolean wordStart = false;
  -        
  +
           // The mapping indicates to convert first
           // character.
           int i = 0;
  @@ -461,11 +480,11 @@
                   result.append("_" + nameArray.length);
               }
           }
  -        
  +
           // The mapping indicates to skip over
           // all characters that are not letters or
  -        // digits.  The first letter/digit 
  -        // following a skipped character is 
  +        // digits.  The first letter/digit
  +        // following a skipped character is
           // upper-cased.
           for (++i; i < nameLen; ++i) {
               char c = nameArray[i];
  @@ -487,14 +506,14 @@
               // For example:  "22hi" becomes "22Hi"
               wordStart = !Character.isLetter(c);
           }
  -        
  +
           // covert back to a String
           String newName = result.toString();
  -        
  +
           // check for Java keywords
           if (isJavaKeyword(newName))
               newName = makeNonJavaKeyword(newName);
  -        
  +
           return newName;
       } // xmlNameToJava
   
  @@ -580,7 +599,7 @@
        * replace:
        * Like String.replace except that the old new items are strings.
        *
  -     * @param name string 
  +     * @param name string
        * @param oldt old text to replace
        * @param newt new text to use
        * @return replacement string
  @@ -592,13 +611,13 @@
   
           // Create a string buffer that is twice initial length.
           // This is a good starting point.
  -        StringBuffer sb = new StringBuffer(name.length()* 2); 
  +        StringBuffer sb = new StringBuffer(name.length()* 2);
   
           int len = oldT.length ();
           try {
               int start = 0;
               int i = name.indexOf (oldT, start);
  -            
  +
               while (i >= 0) {
                   sb.append(name.substring(start, i));
                   sb.append(newT);
  @@ -649,14 +668,14 @@
       }
   
       /**
  -     * Gets the Holder value. 
  -     * @param holder Holder object            
  -     * @return value object 
  +     * Gets the Holder value.
  +     * @param holder Holder object
  +     * @return value object
        */
       public static Object getHolderValue(Object holder) throws HolderException {
           if (!(holder instanceof javax.xml.rpc.holders.Holder)) {
               throw new HolderException();
  -        }            
  +        }
           try {
               Field valueField = holder.getClass().getField("value");
               return valueField.get(holder);
  @@ -666,14 +685,14 @@
       }
   
       /**
  -     * Sets the Holder value. 
  -     * @param holder Holder object            
  -     * @param value is the object value 
  +     * Sets the Holder value.
  +     * @param holder Holder object
  +     * @param value is the object value
        */
       public static void setHolderValue(Object holder, Object value) throws 
HolderException {
           if (!(holder instanceof javax.xml.rpc.holders.Holder)) {
               throw new HolderException();
  -        }            
  +        }
           try {
               Field valueField = holder.getClass().getField("value");
               if (valueField.getType().isPrimitive()) {
  @@ -691,7 +710,7 @@
       public static class HolderException extends Exception
       {
           public HolderException () {}
  -    }; 
  +    };
   
   
       /**
  @@ -707,7 +726,7 @@
               java.lang.reflect.Method m2 = cls.getMethod("toString", null);
               java.lang.reflect.Method m3 = cls.getMethod("fromString",
                                                           new Class[] 
{java.lang.String.class});
  -            
  +
               if (m != null && m2 != null && m3 != null &&
                   cls.getMethod("fromValue", new Class[] {m.getReturnType()}) != 
null) {
                   try {
  @@ -715,10 +734,85 @@
                           return true;
                       return false;
                   } catch (java.lang.NoSuchMethodException e) {
  -                    return true;  // getValue & fromValue exist.  setValue does not 
exist.  Thus return true. 
  +                    return true;  // getValue & fromValue exist.  setValue does not 
exist.  Thus return true.
                   }
               }
           } catch (java.lang.NoSuchMethodException e) {}
           return false;
  -    }  
  +    }
  +
  +    /**
  +     * Get Parameter Names using tt-bytecode
  +     *
  +     * @param method the Java method we're interested in
  +     * @return list of names or null
  +     */
  +    public static String[] getParameterNamesFromDebugInfo(Method method) {
  +        Class c = method.getDeclaringClass();
  +        int numParams = method.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
  +        BCClass bclass = (BCClass)ttClassCache.get(c);
  +
  +        if(bclass == null) {
  +            try {
  +                bclass = new BCClass(c);
  +                ttClassCache.put(c, bclass);
  +            } catch (IOException e) {
  +                // what now?
  +            }
  +        }
  +
  +        // Obtain the exact method we're interested in.
  +        BCMethod bmeth = bclass.getMethod(method.getName(),
  +                                          method.getParameterTypes());
  +
  +        if (bmeth == null)
  +            return null;
  +
  +        // Get the Code object, which contains the local variable table.
  +        Code code = bmeth.getCode();
  +        if (code == null)
  +            return null;
  +
  +        LocalVariableTableAttribute attr =
  +                
(LocalVariableTableAttribute)code.getAttribute(Constants.ATTR_LOCALS);
  +
  +        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.getLocalVariables();
  +
  +        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;
  +    }
   }
  
  
  
  1.23      +5 -87     xml-axis/java/src/org/apache/axis/wsdl/fromJava/ClassRep.java
  
  Index: ClassRep.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/fromJava/ClassRep.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- ClassRep.java     7 Mar 2002 15:45:51 -0000       1.22
  +++ ClassRep.java     12 Mar 2002 17:41:06 -0000      1.23
  @@ -163,14 +163,6 @@
       private Vector   _stopList    = null;
       
       /**
  -     * Cache of tt-bytecode BCClass objects which correspond to particular
  -     * Java classes.
  -     * 
  -     * !!! NOTE : AT PRESENT WE DO NOT CLEAN UP THIS CACHE.
  -     */ 
  -    private static HashMap ttClassCache = new HashMap();
  -
  -    /**
        * Constructor
        * Create an empty ClassRep
        */ 
  @@ -428,9 +420,9 @@
   
       /**
        * Get the list of parameter names for the specified method.
  -     * This implementation uses Skeleton.getParameterNames or bcel to get the 
parameter names
  -     * from the class file.  If parameter names are not available 
  -     * for the method (perhaps the method is in an interface), the
  +     * This implementation uses Skeleton.getParameterNames or bcel to get the
  +     * parameter names from the class file.  If parameter names are not
  +     * available for the method (perhaps the method is in an interface), the
        * corresponding method in the implClass is queried.
        * @param method is the Method to search.                
        * @param implClass  If the first search fails, the corresponding  
  @@ -446,7 +438,7 @@
               return paramNames;
           }
           
  -        paramNames = getParameterNamesFromDebugInfo(method); 
  +        paramNames = JavaUtils.getParameterNamesFromDebugInfo(method); 
           
           // If failed, try getting a method of the impl class.
           if (paramNames == null && implClass != null) {
  @@ -464,7 +456,7 @@
                   if (paramNames != null) {
                       return paramNames;
                   }
  -                paramNames = getParameterNamesFromDebugInfo(m); 
  +                paramNames = JavaUtils.getParameterNamesFromDebugInfo(m); 
               }
           }            
   
  @@ -509,80 +501,6 @@
           return paramNames;
       }
   
  -    /**
  -     * get Parameter Names using bcel
  -     * @param method
  -     * @return list of names or null
  -     */
  -    public String[] 
  -            getParameterNamesFromDebugInfo(java.lang.reflect.Method method) {
  -        Class c = method.getDeclaringClass();
  -        int numParams = method.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
  -        BCClass bclass = (BCClass)ttClassCache.get(c);
  -                    
  -        if(bclass == null) {
  -            try {
  -                bclass = new BCClass(c);
  -                ttClassCache.put(c, bclass);
  -            } catch (IOException e) {
  -                // what now?
  -            }
  -        }
  -
  -        // Obtain the exact method we're interested in.
  -        BCMethod bmeth = bclass.getMethod(method.getName(), 
  -                                          method.getParameterTypes());
  -
  -        if (bmeth == null)
  -            return null;
  -
  -        // Get the Code object, which contains the local variable table.
  -        Code code = bmeth.getCode();
  -        if (code == null)
  -            return null;
  -
  -        LocalVariableTableAttribute attr = 
  -                
(LocalVariableTableAttribute)code.getAttribute(Constants.ATTR_LOCALS);
  -
  -        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.getLocalVariables();
  -
  -        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;
  -    }
   
       /**
        * Get the list of return/parameter modes for the specified method.
  
  
  


Reply via email to