001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import java.lang.reflect.Method;
018    
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    /**
023     * @author Michael C. Han
024     */
025    public class MethodCache {
026    
027            public static Method get(String className, String methodName)
028                    throws ClassNotFoundException, NoSuchMethodException {
029    
030                    return get(null, null, className, methodName);
031            }
032    
033            public static Method get(
034                            String className, String methodName, Class<?>[] parameterTypes)
035                    throws ClassNotFoundException, NoSuchMethodException {
036    
037                    return get(null, null, className, methodName, parameterTypes);
038            }
039    
040            public static Method get(
041                            Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
042                            String className, String methodName)
043                    throws ClassNotFoundException, NoSuchMethodException {
044    
045                    return get(className, methodName, new Class[0]);
046            }
047    
048            public static Method get(
049                            Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
050                            String className, String methodName, Class<?>[] parameterTypes)
051                    throws ClassNotFoundException, NoSuchMethodException {
052    
053                    MethodKey methodKey = new MethodKey(
054                            className, methodName, parameterTypes);
055    
056                    return _instance._get(classesMap, methodsMap, methodKey);
057            }
058    
059            public static Method get(MethodKey methodKey)
060                    throws ClassNotFoundException, NoSuchMethodException {
061    
062                    return _instance._get(null, null, methodKey);
063            }
064    
065            public static Method put(MethodKey methodKey, Method method) {
066                    return _instance._put(methodKey, method);
067            }
068    
069            private MethodCache() {
070                    _classesMap = new HashMap<String, Class<?>>();
071                    _methodsMap = new HashMap<MethodKey, Method>();
072            }
073    
074            private Method _get(
075                            Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
076                            MethodKey methodKey)
077                    throws ClassNotFoundException, NoSuchMethodException {
078    
079                    if (classesMap == null) {
080                            classesMap = _classesMap;
081                    }
082    
083                    if (methodsMap == null) {
084                            methodsMap = _methodsMap;
085                    }
086    
087                    Method method = methodsMap.get(methodKey);
088    
089                    if (method == null) {
090                            String className = methodKey.getClassName();
091                            String methodName = methodKey.getMethodName();
092                            Class<?>[] parameterTypes = methodKey.getParameterTypes();
093    
094                            Class<?> classObj = classesMap.get(className);
095    
096                            if (classObj == null) {
097                                    Thread currentThread = Thread.currentThread();
098    
099                                    ClassLoader contextClassLoader =
100                                            currentThread.getContextClassLoader();
101    
102                                    classObj = contextClassLoader.loadClass(className);
103    
104                                    classesMap.put(className, classObj);
105                            }
106    
107                            method = classObj.getMethod(methodName, parameterTypes);
108    
109                            methodsMap.put(methodKey, method);
110                    }
111    
112                    return method;
113            }
114    
115            private Method _put(MethodKey methodKey, Method method) {
116                    return _methodsMap.put(methodKey, method);
117            }
118    
119            private static MethodCache _instance = new MethodCache();
120    
121            private Map<String, Class<?>> _classesMap;
122            private Map<MethodKey, Method> _methodsMap;
123    
124    }