commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rdon...@apache.org
Subject cvs commit: jakarta-commons/beanutils/src/java/org/apache/commons/beanutils MethodUtils.java
Date Tue, 20 May 2003 20:36:59 GMT
rdonkin     2003/05/20 13:36:58

  Modified:    beanutils/src/java/org/apache/commons/beanutils
                        MethodUtils.java
  Log:
  Applied enhancement #18960. This improves MethodUtils performance by caching methods. Submitted
by Mohan Kishore.
  
  Revision  Changes    Path
  1.21      +92 -2     jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/MethodUtils.java
  
  Index: MethodUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/MethodUtils.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- MethodUtils.java	9 May 2003 14:27:06 -0000	1.20
  +++ MethodUtils.java	20 May 2003 20:36:57 -0000	1.21
  @@ -63,6 +63,7 @@
   import java.lang.reflect.Method;
   import java.lang.reflect.Modifier;
   
  +import java.util.WeakHashMap;
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -108,6 +109,11 @@
       private static final Class[] emptyClassArray = new Class[0];
       /** An empty object array */
       private static final Object[] emptyObjectArray = new Object[0];
  +
  +    /**
  +     * Stores a cache of Methods against MethodDescriptors, in a WeakHashMap.
  +     */
  +    private static WeakHashMap cache = new WeakHashMap();
       
       // --------------------------------------------------------- Public Methods
       
  @@ -411,8 +417,17 @@
               Class[] parameterTypes) {
   
           try {
  -            return getAccessibleMethod
  +            MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes,
true);
  +            // Check the cache first
  +            Method method = (Method)cache.get(md);
  +            if (method != null) {
  +                return method;
  +            }
  +            
  +            method =  getAccessibleMethod
                       (clazz.getMethod(methodName, parameterTypes));
  +            cache.put(md, method);
  +            return method;
           } catch (NoSuchMethodException e) {
               return (null);
           }
  @@ -548,11 +563,18 @@
           if (log.isTraceEnabled()) {
               log.trace("Matching name=" + methodName + " on " + clazz);
           }
  +        MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, false);
           
           // see if we can find the method directly
           // most of the time this works and it's much faster
           try {
  -            Method method = clazz.getMethod(methodName, parameterTypes);
  +            // Check the cache first
  +            Method method = (Method)cache.get(md);
  +            if (method != null) {
  +                return method;
  +            }
  +
  +            method = clazz.getMethod(methodName, parameterTypes);
               if (log.isTraceEnabled()) {
                   log.trace("Found straight match: " + method);
                   log.trace("isPublic:" + Modifier.isPublic(method.getModifiers()));
  @@ -606,6 +628,7 @@
                           "Cannot setAccessible on method. Therefore cannot use jvm access
bug workaround.", 
                           se);
               }
  +            cache.put(md, method);
               return method;
               
           } catch (NoSuchMethodException e) { /* SWALLOW */ }
  @@ -667,6 +690,7 @@
               "Cannot setAccessible on method. Therefore cannot use jvm access bug workaround.",

                                           se);
                               }
  +                            cache.put(md, method);
                               return method;
                           }
                           
  @@ -726,5 +750,71 @@
           }
           
           return false;
  +    }
  +
  +    /**
  +     * Represents the key to looking up a Method by reflection.
  +     */
  +    private static class MethodDescriptor {
  +        private Class cls;
  +        private String methodName;
  +        private Class[] paramTypes;
  +        private boolean exact;
  +        private int hashCode;
  +
  +        /**
  +         * The sole constructor.
  +         *
  +         * @param cls  the class to reflect, must not be null
  +         * @param methodName  the method name to obtain
  +         * @param paramTypes the array of classes representing the paramater types
  +         * @param exact whether the match has to be exact.
  +         */
  +        public MethodDescriptor(Class cls, String methodName, Class[] paramTypes, boolean
exact) {
  +            if (cls == null) {
  +                throw new IllegalArgumentException("Class cannot be null");
  +            }
  +            if (methodName == null) {
  +                throw new IllegalArgumentException("Method Name cannot be null");
  +            }
  +            if (paramTypes == null) {
  +                paramTypes = emptyClassArray;
  +            }
  +
  +            this.cls = cls;
  +            this.methodName = methodName;
  +            this.paramTypes = paramTypes;
  +            this.exact= exact;
  +
  +            this.hashCode = methodName.length();
  +        }
  +        /**
  +         * Checks for equality.
  +         * @param obj object to be tested for equality
  +         * @return true, if the object describes the same Method.
  +         */
  +        public boolean equals(Object obj) {
  +            if (!(obj instanceof MethodDescriptor)) {
  +                return false;
  +            }
  +            MethodDescriptor md = (MethodDescriptor)obj;
  +
  +            return (
  +                exact == md.exact &&
  +                methodName.equals(md.methodName) &&
  +                cls.equals(md.cls) &&
  +                java.util.Arrays.equals(paramTypes, md.paramTypes)
  +            );
  +        }
  +        /**
  +         * Returns the string length of method name. I.e. if the
  +         * hashcodes are different, the objects are different. If the
  +         * hashcodes are the same, need to use the equals method to
  +         * determine equality.
  +         * @return the string length of method name.
  +         */
  +        public int hashCode() {
  +            return hashCode;
  +        }
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message