1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
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              classesMap, methodsMap, className, methodName, parameterTypes);
57  
58          return get(methodKey);
59      }
60  
61      public static Method get(MethodKey methodKey)
62          throws ClassNotFoundException, NoSuchMethodException {
63  
64          return _instance._get(methodKey);
65      }
66  
67      public static Method put(MethodKey methodKey, Method method) {
68          return _instance._put(methodKey, method);
69      }
70  
71      private MethodCache() {
72          _classesMap = new HashMap<String, Class<?>>();
73          _methodsMap = new HashMap<MethodKey, Method>();
74      }
75  
76      private Method _get(MethodKey methodKey)
77          throws ClassNotFoundException, NoSuchMethodException {
78  
79          Map<String, Class<?>> classesMap = methodKey.getClassesMap();
80  
81          if (classesMap == null) {
82              classesMap = _classesMap;
83          }
84  
85          Map<MethodKey, Method> methodsMap = methodKey.getMethodsMap();
86  
87          if (methodsMap == null) {
88              methodsMap = _methodsMap;
89          }
90  
91          Method method = methodsMap.get(methodKey);
92  
93          if (method == null) {
94              String className = methodKey.getClassName();
95              String methodName = methodKey.getMethodName();
96              Class<?>[] types = methodKey.getTypes();
97  
98              Class<?> classObj = classesMap.get(className);
99  
100             if (classObj == null) {
101                 Thread currentThread = Thread.currentThread();
102 
103                 ClassLoader contextClassLoader =
104                     currentThread.getContextClassLoader();
105 
106                 classObj = contextClassLoader.loadClass(className);
107 
108                 classesMap.put(className, classObj);
109             }
110 
111             method = classObj.getMethod(methodName, types);
112 
113             methodsMap.put(methodKey, method);
114         }
115 
116         return method;
117     }
118 
119     private Method _put(MethodKey methodKey, Method method) {
120         return _methodsMap.put(methodKey, method);
121     }
122 
123     private static MethodCache _instance = new MethodCache();
124 
125     private Map<String, Class<?>> _classesMap;
126     private Map<MethodKey, Method> _methodsMap;
127 
128 }