001    /**
002     * Copyright (c) 2000-2012 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(
028                            Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
029                            String className, String methodName)
030                    throws ClassNotFoundException, NoSuchMethodException {
031    
032                    return get(className, methodName, new Class[0]);
033            }
034    
035            public static Method get(
036                            Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
037                            String className, String methodName, Class<?>[] parameterTypes)
038                    throws ClassNotFoundException, NoSuchMethodException {
039    
040                    MethodKey methodKey = new MethodKey(
041                            className, methodName, parameterTypes);
042    
043                    return _instance._get(classesMap, methodsMap, methodKey);
044            }
045    
046            public static Method get(MethodKey methodKey)
047                    throws ClassNotFoundException, NoSuchMethodException {
048    
049                    return _instance._get(null, null, methodKey);
050            }
051    
052            public static Method get(String className, String methodName)
053                    throws ClassNotFoundException, NoSuchMethodException {
054    
055                    return get(null, null, className, methodName);
056            }
057    
058            public static Method get(
059                            String className, String methodName, Class<?>[] parameterTypes)
060                    throws ClassNotFoundException, NoSuchMethodException {
061    
062                    return get(null, null, className, methodName, parameterTypes);
063            }
064    
065            public static Method put(MethodKey methodKey, Method method) {
066                    return _instance._put(methodKey, method);
067            }
068    
069            public static void remove(Class<?> clazz) {
070                    _instance._remove(clazz);
071            }
072    
073            public static void reset() {
074                    _instance._reset();
075            }
076    
077            private MethodCache() {
078                    _classesMap = new HashMap<String, Class<?>>();
079                    _methodsMap = new HashMap<MethodKey, Method>();
080            }
081    
082            private Method _get(
083                            Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
084                            MethodKey methodKey)
085                    throws ClassNotFoundException, NoSuchMethodException {
086    
087                    if (classesMap == null) {
088                            classesMap = _classesMap;
089                    }
090    
091                    if (methodsMap == null) {
092                            methodsMap = _methodsMap;
093                    }
094    
095                    Method method = methodsMap.get(methodKey);
096    
097                    if (method == null) {
098                            String className = methodKey.getClassName();
099                            String methodName = methodKey.getMethodName();
100                            Class<?>[] parameterTypes = methodKey.getParameterTypes();
101    
102                            Class<?> clazz = classesMap.get(className);
103    
104                            if (clazz == null) {
105                                    Thread currentThread = Thread.currentThread();
106    
107                                    ClassLoader contextClassLoader =
108                                            currentThread.getContextClassLoader();
109    
110                                    clazz = contextClassLoader.loadClass(className);
111    
112                                    classesMap.put(className, clazz);
113                            }
114    
115                            method = clazz.getMethod(methodName, parameterTypes);
116    
117                            methodsMap.put(methodKey, method);
118                    }
119    
120                    return method;
121            }
122    
123            private Method _put(MethodKey methodKey, Method method) {
124                    return _methodsMap.put(methodKey, method);
125            }
126    
127            private void _remove(Class<?> clazz) {
128                    _classesMap.remove(clazz.getName());
129    
130                    for (Method method : clazz.getMethods()) {
131                            _methodsMap.remove(new MethodKey(method));
132                    }
133            }
134    
135            private void _reset() {
136                    _classesMap.clear();
137                    _methodsMap.clear();
138            }
139    
140            private static MethodCache _instance = new MethodCache();
141    
142            private Map<String, Class<?>> _classesMap;
143            private Map<MethodKey, Method> _methodsMap;
144    
145    }