FileDocCategorySizeDatePackage
MethodCache.javaAPI DocApache Axis 1.47214Sat Apr 22 18:57:28 BST 2006org.apache.axis.utils.cache

MethodCache

public class MethodCache extends Object
A cache for methods. Used to get methods by their signature and stores them in a local cache for performance reasons. This class is a singleton - so use getInstance to get an instance of it.
author
Davanum Srinivas
author
Sebastian Dietrich

Fields Summary
private static transient MethodCache
instance
The only instance of this class
private static transient ThreadLocal
cache
Cache for Methods In fact this is a map (with classes as keys) of a map (with method-names as keys)
private static final Object
NULL_OBJECT
used to track methods we've sought but not found in the past
Constructors Summary
private MethodCache()
The private constructor for this class. Use getInstance to get an instance (the only one).

        cache = new ThreadLocal();
    
Methods Summary
public static org.apache.axis.utils.cache.MethodCachegetInstance()
Gets the only instance of this class

return
the only instance of this class

        if (instance == null) {
            instance = new MethodCache();
        }
        return instance;
    
public java.lang.reflect.MethodgetMethod(java.lang.Class clazz, java.lang.String methodName, java.lang.Class[] parameterTypes)
Returns the specified method - if any.

param
clazz the class to get the method from
param
methodName the name of the method
param
parameterTypes the parameters of the method
return
the found method
throws
NoSuchMethodException if the method can't be found


                                                   
       
                             
                             
          
        String className = clazz.getName();
        Map cache = getMethodCache();
        Method method = null;
        Map methods = null;

        // Strategy is as follows:
        // construct a MethodKey to represent the name/arguments
        // of a method's signature.
        //
        // use the name of the class to retrieve a map of that
        // class' methods
        //
        // if a map exists, use the MethodKey to find the
        // associated value object.  if that object is a Method
        // instance, return it.  if that object is anything
        // else, then it's a reference to our NULL_OBJECT
        // instance, indicating that we've previously tried
        // and failed to find a method meeting our requirements,
        // so return null
        //
        // if the map of methods for the class doesn't exist,
        // or if no value is associated with our key in that map,
        // then we perform a reflection-based search for the method.
        //
        // if we find a method in that search, we store it in the
        // map using the key; otherwise, we store a reference
        // to NULL_OBJECT using the key.
        
        // Check the cache first.
        MethodKey key = new MethodKey(methodName, parameterTypes);
        methods = (Map) cache.get(clazz);
        if (methods != null) {
            Object o = methods.get(key);
            if (o != null) {  // cache hit
                if (o instanceof Method) { // good cache hit
                    return (Method) o;
                } else {                   // bad cache hit
                    // we hit the NULL_OBJECT, so this is a search
                    // that previously failed; no point in doing
                    // it again as it is a worst case search
                    // through the entire classpath.
                    return null;
                }
            } else {
                // cache miss: fall through to reflective search
            }
        } else {
            // cache miss: fall through to reflective search
        }

        try {
            method = clazz.getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e1) {
            if (!clazz.isPrimitive() && !className.startsWith("java.") && !className.startsWith("javax.")) {
                try {
                    Class helper = ClassUtils.forName(className + "_Helper");
                    method = helper.getMethod(methodName, parameterTypes);
                } catch (ClassNotFoundException e2) {
                }
            }
        }

        // first time we've seen this class: set up its method cache
        if (methods == null) {
            methods = new HashMap();
            cache.put(clazz, methods);
        }

        // when no method is found, cache the NULL_OBJECT
        // so that we don't have to repeat worst-case searches
        // every time.

        if (null == method) {
            methods.put(key, NULL_OBJECT);
        } else {
            methods.put(key, method);
        }
        return method;
    
private java.util.MapgetMethodCache()
Returns the per thread hashmap (for method caching)

        Map map = (Map) cache.get();
        if (map == null) {
            map = new HashMap();
            cache.set(map);
        }
        return map;