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                            classesMap, methodsMap, className, methodName, parameterTypes);
055    
056                    return get(methodKey);
057            }
058    
059            public static Method get(MethodKey methodKey)
060                    throws ClassNotFoundException, NoSuchMethodException {
061    
062                    return _instance._get(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(MethodKey methodKey)
075                    throws ClassNotFoundException, NoSuchMethodException {
076    
077                    Map<String, Class<?>> classesMap = methodKey.getClassesMap();
078    
079                    if (classesMap == null) {
080                            classesMap = _classesMap;
081                    }
082    
083                    Map<MethodKey, Method> methodsMap = methodKey.getMethodsMap();
084    
085                    if (methodsMap == null) {
086                            methodsMap = _methodsMap;
087                    }
088    
089                    Method method = methodsMap.get(methodKey);
090    
091                    if (method == null) {
092                            String className = methodKey.getClassName();
093                            String methodName = methodKey.getMethodName();
094                            Class<?>[] parameterTypes = methodKey.getParameterTypes();
095    
096                            Class<?> classObj = classesMap.get(className);
097    
098                            if (classObj == null) {
099                                    Thread currentThread = Thread.currentThread();
100    
101                                    ClassLoader contextClassLoader =
102                                            currentThread.getContextClassLoader();
103    
104                                    classObj = contextClassLoader.loadClass(className);
105    
106                                    classesMap.put(className, classObj);
107                            }
108    
109                            method = classObj.getMethod(methodName, parameterTypes);
110    
111                            methodsMap.put(methodKey, method);
112                    }
113    
114                    return method;
115            }
116    
117            private Method _put(MethodKey methodKey, Method method) {
118                    return _methodsMap.put(methodKey, method);
119            }
120    
121            private static MethodCache _instance = new MethodCache();
122    
123            private Map<String, Class<?>> _classesMap;
124            private Map<MethodKey, Method> _methodsMap;
125    
126    }