/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.axis.utils.cache;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.axis.utils.ClassUtils;

/**
 * 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 <dims@yahoo.com>
 * @author Sebastian Dietrich <sebastian.dietrich@anecon.com>
 */
public class MethodCache {
    /**
     * The only instance of this class
     */
    transient private static MethodCache instance;

    /**
     * Cache for Methods
     * In fact this is a map (with classes as keys) of a map (with method-names as keys)
     */
    transient private static ThreadLocal cache;

    /**
     * The <i>private</i> constructor for this class.
     * Use getInstance to get an instance (the only one).
     */
    private MethodCache() {
        cache = new ThreadLocal();
    }

    /**
     * Gets the only instance of this class
     * @return the only instance of this class
     */
    public static MethodCache getInstance() {
        if (instance == null) {
            instance = new MethodCache();
        }
        return instance;
    }

    /**
     * Returns the per thread hashmap (for method caching)
     */
    private Map getMethodCache() {
        Map map = (Map) cache.get();
        if (map == null) {
            map = new HashMap();
            cache.set(map);
        }
        return map;
    }

    /**
     * Class used as the key for the method cache table.
     *
     */
    static class MethodKey {
        /** the name of the method in the cache */
        private final String methodName;
        /** the list of types accepted by the method as arguments */
        private final Class[] parameterTypes;

        /**
         * Creates a new <code>MethodKey</code> instance.
         *
         * @param methodName a <code>String</code> value
         * @param parameterTypes a <code>Class[]</code> value
         */
        MethodKey(String methodName, Class[] parameterTypes) {
            this.methodName = methodName;
            this.parameterTypes = parameterTypes;
        }

        public boolean equals(Object other) {
            MethodKey that = (MethodKey) other;
            return this.methodName.equals(that.methodName)
                && Arrays.equals(this.parameterTypes,
                                 that.parameterTypes);
        }

        public int hashCode() {
            // allow overloaded methods to collide; we'll sort it out
            // in equals().  Note that String's implementation of
            // hashCode already caches its value, so there's no point
            // in doing so here.
            return methodName.hashCode();
        }
    }

    /** used to track methods we've sought but not found in the past */
    private static final Object NULL_OBJECT = new Object();

    /**
     * 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
     */
    public Method getMethod(Class clazz,
                            String methodName,
                            Class[] parameterTypes)
        throws NoSuchMethodException {
        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;
    }
}
