001
014
015 package com.liferay.portal.kernel.util;
016
017 import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
018
019 import java.lang.reflect.Method;
020
021 import java.util.Map;
022 import java.util.concurrent.ConcurrentHashMap;
023
024
027 public class MethodCache {
028
029 public static Method get(
030 Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
031 String className, String methodName)
032 throws ClassNotFoundException, NoSuchMethodException {
033
034 return get(className, methodName, new Class[0]);
035 }
036
037 public static Method get(
038 Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
039 String className, String methodName, Class<?>[] parameterTypes)
040 throws ClassNotFoundException, NoSuchMethodException {
041
042 MethodKey methodKey = new MethodKey(
043 className, methodName, parameterTypes);
044
045 return getInstance()._get(classesMap, methodsMap, methodKey);
046 }
047
048 public static Method get(MethodKey methodKey)
049 throws ClassNotFoundException, NoSuchMethodException {
050
051 return getInstance()._get(null, null, methodKey);
052 }
053
054 public static Method get(String className, String methodName)
055 throws ClassNotFoundException, NoSuchMethodException {
056
057 return get(null, null, className, methodName);
058 }
059
060 public static Method get(
061 String className, String methodName, Class<?>[] parameterTypes)
062 throws ClassNotFoundException, NoSuchMethodException {
063
064 return get(null, null, className, methodName, parameterTypes);
065 }
066
067 public static MethodCache getInstance() {
068 PortalRuntimePermission.checkGetBeanProperty(MethodCache.class);
069
070 return _instance;
071 }
072
073 public static Method put(MethodKey methodKey, Method method) {
074 return getInstance()._put(methodKey, method);
075 }
076
077 public static void remove(Class<?> clazz) {
078 getInstance()._remove(clazz);
079 }
080
081 public static void reset() {
082 getInstance()._reset();
083 }
084
085 private MethodCache() {
086 _classesMap = new ConcurrentHashMap<String, Class<?>>();
087 _methodsMap = new ConcurrentHashMap<MethodKey, Method>();
088 }
089
090 private Method _get(
091 Map<String, Class<?>> classesMap, Map<MethodKey, Method> methodsMap,
092 MethodKey methodKey)
093 throws ClassNotFoundException, NoSuchMethodException {
094
095 if (classesMap == null) {
096 classesMap = _classesMap;
097 }
098
099 if (methodsMap == null) {
100 methodsMap = _methodsMap;
101 }
102
103 Method method = methodsMap.get(methodKey);
104
105 if (method == null) {
106 String className = methodKey.getClassName();
107 String methodName = methodKey.getMethodName();
108 Class<?>[] parameterTypes = methodKey.getParameterTypes();
109
110 Class<?> clazz = classesMap.get(className);
111
112 if (clazz == null) {
113 Thread currentThread = Thread.currentThread();
114
115 ClassLoader contextClassLoader =
116 currentThread.getContextClassLoader();
117
118 clazz = contextClassLoader.loadClass(className);
119
120 classesMap.put(className, clazz);
121 }
122
123 method = clazz.getDeclaredMethod(methodName, parameterTypes);
124
125 if (!method.isAccessible()) {
126 method.setAccessible(true);
127 }
128
129 methodsMap.put(methodKey, method);
130 }
131
132 return method;
133 }
134
135 private Method _put(MethodKey methodKey, Method method) {
136 return _methodsMap.put(methodKey, method);
137 }
138
139 private void _remove(Class<?> clazz) {
140 _classesMap.remove(clazz.getName());
141
142 for (Method method : clazz.getMethods()) {
143 _methodsMap.remove(new MethodKey(method));
144 }
145 }
146
147 private void _reset() {
148 _classesMap.clear();
149 _methodsMap.clear();
150 }
151
152 private static MethodCache _instance = new MethodCache();
153
154 private Map<String, Class<?>> _classesMap;
155 private Map<MethodKey, Method> _methodsMap;
156
157 }