1
22
23 package com.liferay.portal.kernel.util;
24
25 import com.liferay.portal.kernel.log.Log;
26 import com.liferay.portal.kernel.log.LogFactoryUtil;
27
28 import java.lang.reflect.Array;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31
32 import java.util.ArrayList;
33 import java.util.List;
34
35
42 public class MethodInvoker {
43
44 public static Object invoke(MethodWrapper methodWrapper)
45 throws ClassNotFoundException, IllegalAccessException,
46 InstantiationException, InvocationTargetException,
47 NoSuchFieldException, NoSuchMethodException {
48
49 return invoke(methodWrapper, true);
50 }
51
52 public static Object invoke(
53 MethodWrapper methodWrapper, boolean newInstance)
54 throws ClassNotFoundException, IllegalAccessException,
55 InstantiationException, InvocationTargetException,
56 NoSuchFieldException, NoSuchMethodException {
57
58 Object targetObject = null;
59
60 if (newInstance) {
61 Thread currentThread = Thread.currentThread();
62
63 ClassLoader contextClassLoader =
64 currentThread.getContextClassLoader();
65
66 targetObject = contextClassLoader.loadClass(
67 methodWrapper.getClassName()).newInstance();
68 }
69
70 Object[] methodAndArguments = _lookupMethodAndArguments(
71 methodWrapper, targetObject);
72
73 Object returnObject = null;
74
75 if (methodAndArguments[0] != null) {
76 Method method = (Method)methodAndArguments[0];
77 Object[] arguments = (Object[])methodAndArguments[1];
78
79 returnObject = method.invoke(targetObject, arguments);
80 }
81
82 return returnObject;
83 }
84
85 public static Object invoke(
86 MethodWrapper methodWrapper, Object targetObject)
87 throws ClassNotFoundException, IllegalAccessException,
88 InvocationTargetException, NoSuchFieldException,
89 NoSuchMethodException {
90
91 Object[] methodAndArguments = _lookupMethodAndArguments(
92 methodWrapper, targetObject);
93
94 Object returnObject = null;
95
96 if (methodAndArguments[0] != null) {
97 Method method = (Method)methodAndArguments[0];
98 Object[] arguments = (Object[])methodAndArguments[1];
99
100 returnObject = method.invoke(targetObject, arguments);
101 }
102
103 return returnObject;
104 }
105
106 private static Object[] _lookupMethodAndArguments(
107 MethodWrapper methodWrapper, Object targetObject)
108 throws ClassNotFoundException, IllegalAccessException,
109 InvocationTargetException, NoSuchFieldException,
110 NoSuchMethodException {
111
112 Object[] methodAndArguments = new Object[2];
113
114 Thread currentThread = Thread.currentThread();
115
116 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
117
118 String className = methodWrapper.getClassName();
119 String methodName = methodWrapper.getMethodName();
120 Object[] arguments = methodWrapper.getArguments();
121
122 List<Class<?>> parameterTypes = new ArrayList<Class<?>>();
123
124 for (int i = 0; i < arguments.length; i++) {
125 if (arguments[i] == null) {
126 _log.error(
127 "Cannot invoke " + className + " " + methodName +
128 " on position " + i + " because it is null");
129 }
130
131 Class<?> argClass = arguments[i].getClass();
132
133 if (ClassUtil.isSubclass(argClass, PrimitiveWrapper.class)) {
134 parameterTypes.add(
135 (Class<?>)argClass.getField("TYPE").get(arguments[i]));
136
137 MethodKey methodKey = new MethodKey(
138 argClass.getName(), "getValue", null);
139
140 Method method = MethodCache.get(methodKey);
141
142 arguments[i] = method.invoke(arguments[i], (Object[])null);
143 }
144 else if (arguments[i] instanceof NullWrapper) {
145 NullWrapper nullWrapper = (NullWrapper)arguments[i];
146
147 String wrappedClassName = nullWrapper.getClassName();
148
149 if (wrappedClassName.startsWith(StringPool.OPEN_BRACKET) &&
150 wrappedClassName.endsWith(StringPool.SEMICOLON)) {
151
152 wrappedClassName = wrappedClassName.substring(
153 2, wrappedClassName.length() - 1);
154
155 Class<?> wrappedClass = contextClassLoader.loadClass(
156 wrappedClassName);
157
158 parameterTypes.add(
159 Array.newInstance(wrappedClass, 0).getClass());
160 }
161 else {
162 Class<?> wrappedClass = contextClassLoader.loadClass(
163 wrappedClassName);
164
165 parameterTypes.add(wrappedClass);
166 }
167
168 arguments[i] = null;
169 }
170 else {
171 parameterTypes.add(argClass);
172 }
173 }
174
175 Method method = null;
176
177 try {
178 MethodKey methodKey = new MethodKey(
179 methodWrapper.getClassName(), methodWrapper.getMethodName(),
180 parameterTypes.toArray(new Class[parameterTypes.size()]));
181
182 method = MethodCache.get(methodKey);
183 }
184 catch (NoSuchMethodException nsme) {
185 Class<?> classObject = null;
186
187 if (targetObject == null) {
188 classObject = contextClassLoader.loadClass(className);
189 }
190 else {
191 classObject = targetObject.getClass();
192 }
193
194 Method[] methods = classObject.getMethods();
195
196 for (int i = 0; i < methods.length; i++) {
197 Class<?>[] methodParameterTypes =
198 methods[i].getParameterTypes();
199
200 if (methods[i].getName().equals(methodName) &&
201 methodParameterTypes.length == parameterTypes.size()) {
202
203 boolean correctParams = true;
204
205 for (int j = 0; j < parameterTypes.size(); j++) {
206 Class<?> a = parameterTypes.get(j);
207 Class<?> b = methodParameterTypes[j];
208
209 if (!ClassUtil.isSubclass(a, b)) {
210 correctParams = false;
211
212 break;
213 }
214 }
215
216 if (correctParams) {
217 method = methods[i];
218
219 break;
220 }
221 }
222 }
223
224 if (method == null) {
225 throw nsme;
226 }
227 }
228
229 methodAndArguments[0] = method;
230 methodAndArguments[1] = arguments;
231
232 return methodAndArguments;
233 }
234
235 private static Log _log = LogFactoryUtil.getLog(MethodInvoker.class);
236
237 }