1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.kernel.util;
16  
17  import java.lang.reflect.Method;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  /**
23   * <a href="MethodCache.java.html"><b><i>View Source</i></b></a>
24   *
25   * @author Michael C. Han
26   */
27  public class MethodCache {
28  
29      public static Method get(String className, String methodName)
30          throws ClassNotFoundException, NoSuchMethodException {
31  
32          return get(null, null, className, methodName);
33      }
34  
35      public static Method get(
36              String className, String methodName, Class<?>[] parameterTypes)
37          throws ClassNotFoundException, NoSuchMethodException {
38  
39          return get(null, null, className, methodName, parameterTypes);
40      }
41  
42      public static Method get(
43              Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
44              String className, String methodName)
45          throws ClassNotFoundException, NoSuchMethodException {
46  
47          return get(className, methodName, new Class[0]);
48      }
49  
50      public static Method get(
51              Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
52              String className, String methodName, Class<?>[] parameterTypes)
53          throws ClassNotFoundException, NoSuchMethodException {
54  
55          MethodKey methodKey = new MethodKey(
56              className, methodName, parameterTypes);
57  
58          return _instance._get(classesMap, methodsMap, methodKey);
59      }
60  
61      public static Method get(MethodKey methodKey)
62          throws ClassNotFoundException, NoSuchMethodException {
63  
64          return _instance._get(null, null, methodKey);
65      }
66  
67      public static Method put(MethodKey methodKey, Method method) {
68          return _instance._put(methodKey, method);
69      }
70  
71      public static void remove(Class<?> classObj) {
72          _instance._remove(classObj);
73      }
74  
75      public static void reset() {
76          _instance._reset();
77      }
78  
79      private MethodCache() {
80          _classesMap = new HashMap<String, Class<?>>();
81          _methodsMap = new HashMap<MethodKey, Method>();
82      }
83  
84      private Method _get(
85              Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
86              MethodKey methodKey)
87          throws ClassNotFoundException, NoSuchMethodException {
88  
89          if (classesMap == null) {
90              classesMap = _classesMap;
91          }
92  
93          if (methodsMap == null) {
94              methodsMap = _methodsMap;
95          }
96  
97          Method method = methodsMap.get(methodKey);
98  
99          if (method == null) {
100             String className = methodKey.getClassName();
101             String methodName = methodKey.getMethodName();
102             Class<?>[] parameterTypes = methodKey.getParameterTypes();
103 
104             Class<?> classObj = classesMap.get(className);
105 
106             if (classObj == null) {
107                 Thread currentThread = Thread.currentThread();
108 
109                 ClassLoader contextClassLoader =
110                     currentThread.getContextClassLoader();
111 
112                 classObj = contextClassLoader.loadClass(className);
113 
114                 classesMap.put(className, classObj);
115             }
116 
117             method = classObj.getMethod(methodName, parameterTypes);
118 
119             methodsMap.put(methodKey, method);
120         }
121 
122         return method;
123     }
124 
125     private Method _put(MethodKey methodKey, Method method) {
126         return _methodsMap.put(methodKey, method);
127     }
128 
129     private void _remove(Class<?> classObj) {
130         _classesMap.remove(classObj.getName());
131 
132         for (Method method : classObj.getMethods()) {
133             _methodsMap.remove(new MethodKey(method));
134         }
135     }
136 
137     private void _reset() {
138         _classesMap.clear();
139         _methodsMap.clear();
140     }
141 
142     private static MethodCache _instance = new MethodCache();
143 
144     private Map<String, Class<?>> _classesMap;
145     private Map<MethodKey, Method> _methodsMap;
146 
147 }