You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ru...@apache.org on 2001/05/03 01:19:28 UTC

cvs commit: xml-axis/java/src/org/apache/axis/utils/cache JavaClass.java JavaMethod.java

rubys       01/05/02 16:19:28

  Modified:    java/src/org/apache/axis/handlers RPCDispatchHandler.java
               java/src/org/apache/axis/utils AxisClassLoader.java
  Added:       java/src/org/apache/axis/utils/cache JavaClass.java
                        JavaMethod.java
  Log:
  Cache Method lookup information
  
  Also means that java.lang.reflect.Method.invoke will automatically provide
  unwrapping and widening conversions as necessary.
  
  Revision  Changes    Path
  1.31      +14 -16    xml-axis/java/src/org/apache/axis/handlers/RPCDispatchHandler.java
  
  Index: RPCDispatchHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/handlers/RPCDispatchHandler.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- RPCDispatchHandler.java	2001/05/02 14:37:15	1.30
  +++ RPCDispatchHandler.java	2001/05/02 23:19:20	1.31
  @@ -59,6 +59,7 @@
   import java.lang.reflect.* ;
   import org.apache.axis.* ;
   import org.apache.axis.utils.* ;
  +import org.apache.axis.utils.cache.* ;
   import org.apache.axis.message.* ;
   
   /**
  @@ -87,7 +88,8 @@
         /*************************************************************/
         int             i ;
         AxisClassLoader cl     = msgContext.getClassLoader();
  -      Class           cls    = cl.loadClass(clsName); 
  +      JavaClass       jc     = cl.lookup(clsName); 
  +      Class           cls    = jc.getJavaClass();
         Object          obj    = cls.newInstance();
         Message         inMsg  = msgContext.getRequestMessage();
         Message         outMsg = msgContext.getResponseMessage();
  @@ -113,33 +115,29 @@
                                  "Method names don't match\n" +
                                    "Body name=" + mName + "\n" +
                                    "Service name=" + methodName,
  -                               null, null );  // Should they??
  +                               null, null );  // should they??
     
  -        Class[]  argClasses = null ;
  +        Method       method = jc.getMethod(methodName, args.size());
  +        if ( method == null )
  +          throw new AxisFault( "AxisServer.error", 
  +                               "Method not found\n" +
  +                                 "Method name=" + clsName + "\n" +
  +                                 "Service name=" + methodName,
  +                               null, null );
  +  
           Object[] argValues  =  null ;
   
           if ( args != null && args.size() > 0 ) {
  -          argClasses = new Class[ args.size() ];
             argValues = new Object[ args.size()];
             for ( i = 0 ; i < args.size() ; i++ ) {
  -            Object arg  = ((RPCParam)args.get(i)).getValue() ;
  -            if (arg == null) {
  -                argClasses[i] = String.class;
  -            } else {
  -                argValues[i]  = arg;
  -                argClasses[i] = arg.getClass();
  -            }
  +            argValues[i]  = ((RPCParam)args.get(i)).getValue() ;
   
               if (DEBUG_LOG) {
  -              System.out.println("  class: " + argClasses[i] );
  -              System.out.println("  value: " + argValues[i] == null ? 
  -                                             "null" :
  -                                             argValues[i].toString() );
  +              System.out.println("  value: " + argValues[i] );
               }
             }
           }
     
  -        Method method = cls.getMethod( mName, argClasses );
           Object objRes = method.invoke( obj, argValues );
     
           /* Now put the result in the result SOAPEnvelope */
  
  
  
  1.7       +28 -9     xml-axis/java/src/org/apache/axis/utils/AxisClassLoader.java
  
  Index: AxisClassLoader.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/AxisClassLoader.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AxisClassLoader.java	2001/05/02 15:05:20	1.6
  +++ AxisClassLoader.java	2001/05/02 23:19:24	1.7
  @@ -57,6 +57,7 @@
   
   import java.io.* ;
   import java.util.Hashtable ;
  +import org.apache.axis.utils.cache.JavaClass ;
   
   /**
    * This allows us to specify that certain classes, the ones we register
  @@ -70,7 +71,7 @@
   public class AxisClassLoader extends ClassLoader {
     static Hashtable classLoaders = new Hashtable();
   
  -  Hashtable list         = new Hashtable() ;
  +  Hashtable classCache          = new Hashtable() ;
   
     public AxisClassLoader() {
       super();
  @@ -120,34 +121,52 @@
     public synchronized void registerClass( String name, Class cls ) {
       /* And finally register it */
       /***************************/
  -    list.put( name, cls );
  +    JavaClass oldClass = (JavaClass)classCache.get(name);
  +    if (oldClass!=null && oldClass.getJavaClass()==cls) return;
  +    classCache.put( name, new JavaClass(cls) );
     }
   
     public synchronized void deregisterClass( String name ) {
       /* Deregister the passed in className */
       /**************************************/
  -    list.remove( name);
  +    classCache.remove( name);
     }
   
     public boolean isClassRegistered( String name ) {
  -    return( list != null && list.get(name) != null );
  +    return( classCache != null && classCache.get(name) != null );
     }
   
     public Class loadClass(String name) throws ClassNotFoundException {
       Object obj ;
   
  -    /* Check the 'list' for the className - if there just return the */
  -    /* class - if not there use the default class loader.            */
  +    /* Check the classCache for the className - if there just return */
  +    /* the class - if not there use the default class loader.        */
       /*****************************************************************/
  -    if ( list != null ) {
  -      obj = list.get( name );
  +    if ( classCache != null ) {
  +      obj = classCache.get( name );
         if ( obj != null )
  -        return( (Class) obj );
  +        return( ((JavaClass)obj).getJavaClass() );
       }
   
       ClassLoader cl = this.getClass().getClassLoader();
       Class cls = cl.loadClass( name );
       registerClass( name, cls );
       return cls;
  +  }
  +
  +  /**
  +   * Find the cached JavaClass entry for this class, creating one
  +   * if necessary.
  +   * @param className name of the class desired
  +   * @return JavaClass entry
  +   */
  +  public JavaClass lookup(String className) throws ClassNotFoundException {
  +    JavaClass jc = (JavaClass) classCache.get( className );
  +    if ( jc == null ) {
  +        loadClass( className );
  +        jc = (JavaClass) classCache.get( className );
  +    }
  +
  +    return jc;
     }
   };
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/utils/cache/JavaClass.java
  
  Index: JavaClass.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 apache@apache.org.
   *
   * 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.cache;
  
  import java.util.Hashtable;
  import java.lang.reflect.Method;
  
  /**
   * A simple cache of previously loaded classes, and their methods.
   *
   * @author Sam Ruby <ru...@us.ibm.com>
   */
  public class JavaClass {
  
      private Hashtable methods = new Hashtable();
  
      private Class jc;
  
      /**
       * Create a cache entry for this java.lang.Class
       */
      public JavaClass(Class jc) {
          this.jc = jc;
      }
    
      /**
       * Return the java.lang.Class associated with this entry
       */
      public Class getJavaClass() {
          return jc;
      }
  
      /**
       * Lookup a method based on name and number of arguments
       * @param name name of method
       * @param numargs number of arguments
       */
      public Method getMethod(String name, int numargs) {
          JavaMethod jm = (JavaMethod) methods.get(name);
  
          if (jm == null) {
              methods.put(name, jm=new JavaMethod(jc, name));
          }
  
          return jm.getMethod(numargs);
      }
  };
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/utils/cache/JavaMethod.java
  
  Index: JavaMethod.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 apache@apache.org.
   *
   * 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.cache;
  
  import java.util.Vector;
  import java.lang.reflect.Method;
  
  /**
   * A simple cache of previously loaded methods
   *
   * @author Sam Ruby <ru...@us.ibm.com>
   */
  public class JavaMethod {
  
      // at most, one of the following two are non-null, depending
      // on the number of methods by this name found in the class
      private Method unique = null;
      private Method[] methods = null;
  
      /**
       * Create a cache entry for this java.lang.Class
       * @param jc java.lang.Class which will be searched for methods
       * @param name name of the method
       */
      public JavaMethod(Class jc, String name) {
          Method[] methods = jc.getMethods();
          Vector workinglist = null;
  
          // scan for matching names, saving the match if it is unique,
          // otherwise accumulating a list
          for (int i=0; i<methods.length; i++) {
              if (methods[i].getName().equals(name)) {
                  if (unique != null) {
                      workinglist = new Vector();
                      workinglist.addElement(methods[i]);
                      unique = null;
                  } else if (workinglist != null) {
                      workinglist.addElement(methods[i]);
                  } else {
                      unique = methods[i];
                  }
              }
          }
  
          // If a list was found, convert it into an array
          if (workinglist != null) {
              this.methods = new Method[workinglist.size()];
              workinglist.copyInto(this.methods);
          }
      }
    
      /**
       * Attempt to find the closest matching method based on the number
       * of arguments only.  Note: if there are multiple matches, one
       * will be picked randomly.  If the name is unique, it is simply
       * returned without checking as attempts to invoke a method based
       * on this will undoubtably fail anyway.
       * @param numargs number of arguments
       * @return closest match
       */
      public Method getMethod(int numargs) {
          if (methods != null) {
              for (int i=0; i<methods.length; i++) {
                  if (methods[i].getParameterTypes().length == numargs) {
                      return methods[i];
                  }
              }
          } 
  
          return unique;
      }
  };