1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.extensions.validator.util;
20
21 import java.beans.BeanInfo;
22 import java.beans.IntrospectionException;
23 import java.beans.Introspector;
24 import java.beans.PropertyDescriptor;
25 import java.lang.reflect.Field;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.StringTokenizer;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31
32 import org.apache.myfaces.extensions.validator.core.ExtValContext;
33 import org.apache.myfaces.extensions.validator.core.storage.PropertyStorage;
34 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
35 import org.apache.myfaces.extensions.validator.internal.UsageInformation;
36
37
38
39
40 @UsageInformation(UsageCategory.INTERNAL)
41 public class ReflectionUtils
42 {
43 private static final Logger LOGGER = Logger.getLogger(ReflectionUtils.class.getName());
44
45 public static Method tryToGetMethod(Class targetClass, String targetMethodName)
46 {
47 return tryToGetMethod(targetClass, targetMethodName, null);
48 }
49
50 public static Method tryToGetMethod(Class targetClass, String targetMethodName, Class... parameterTypes)
51 {
52 try
53 {
54 return getMethod(targetClass, targetMethodName, parameterTypes);
55 }
56 catch (Exception e)
57 {
58
59 return null;
60 }
61 }
62
63 public static Method getMethod(Class targetClass, String targetMethodName)
64 throws NoSuchMethodException
65 {
66 return getMethod(targetClass, targetMethodName, null);
67 }
68
69 public static Method getMethod(Class targetClass, String targetMethodName, Class... parameterTypes)
70 throws NoSuchMethodException
71 {
72 Class currentClass = targetClass;
73 Method targetMethod = null;
74
75 while (!Object.class.getName().equals(currentClass.getName()))
76 {
77 try
78 {
79 targetMethod = currentClass.getDeclaredMethod(targetMethodName, parameterTypes);
80 break;
81 }
82 catch (NoSuchMethodException e)
83 {
84 currentClass = currentClass.getSuperclass();
85 }
86 }
87
88 if(targetMethod == null)
89 {
90 for (Class currentInterface : targetClass.getInterfaces())
91 {
92 currentClass = currentInterface;
93
94 while (currentClass != null)
95 {
96 try
97 {
98 targetMethod = currentClass.getDeclaredMethod(targetMethodName, parameterTypes);
99 break;
100 }
101 catch (NoSuchMethodException e)
102 {
103 currentClass = currentClass.getSuperclass();
104 }
105 }
106 }
107 }
108
109 if(targetMethod != null)
110 {
111 return targetMethod;
112 }
113
114 throw new NoSuchMethodException("there is no method with the name '" + targetMethodName + "'" +
115 " class: " + targetClass.getName());
116 }
117
118 public static Object tryToInvokeMethod(Object target, Method method)
119 {
120 return tryToInvokeMethod(target, method, null);
121 }
122
123 public static Object tryToInvokeMethodOfClass(Class target, Method method)
124 {
125 return tryToInvokeMethodOfClass(target, method, null);
126 }
127
128 public static Object tryToInvokeMethodOfClass(Class target, Method method, Object[] args)
129 {
130 try
131 {
132 return invokeMethodOfClass(target, method, args);
133 }
134 catch (Exception e)
135 {
136
137 return null;
138 }
139 }
140
141 public static Object invokeMethodOfClass(Class target, Method method)
142 throws IllegalAccessException, InstantiationException, InvocationTargetException
143 {
144 return invokeMethod(target.newInstance(), method, null);
145 }
146
147 public static Object invokeMethodOfClass(Class target, Method method, Object... args)
148 throws IllegalAccessException, InstantiationException, InvocationTargetException
149 {
150 return invokeMethod(target.newInstance(), method, args);
151 }
152
153 public static Object tryToInvokeMethod(Object target, Method method, Object... args)
154 {
155 try
156 {
157 return invokeMethod(target, method, args);
158 }
159 catch (Exception e)
160 {
161
162 return null;
163 }
164 }
165
166 public static Object invokeMethod(Object target, Method method)
167 throws InvocationTargetException, IllegalAccessException
168 {
169 return invokeMethod(target, method, null);
170 }
171
172 public static Object invokeMethod(Object target, Method method, Object... args)
173 throws InvocationTargetException, IllegalAccessException
174 {
175 method.setAccessible(true);
176 return method.invoke(target, args);
177 }
178
179 public static Object getBaseOfPropertyChain(Object baseObject, String propertyChain)
180 {
181 StringTokenizer tokenizer = new StringTokenizer(propertyChain, ".");
182
183 Object currentBase = baseObject;
184 String currentProperty;
185 Method currentMethod;
186
187 while(tokenizer.hasMoreTokens())
188 {
189 currentProperty = tokenizer.nextToken();
190
191
192 if(!tokenizer.hasMoreTokens())
193 {
194 break;
195 }
196
197
198 currentMethod = tryToGetMethod(ProxyUtils.getUnproxiedClass(currentBase.getClass()),
199 "get" + currentProperty.substring(0, 1).toUpperCase() + currentProperty.substring(1));
200 currentBase = tryToInvokeMethod(currentBase, currentMethod);
201 }
202
203 return currentBase;
204 }
205
206 public static PropertyStorage getPropertyStorage()
207 {
208 return ExtValUtils.getStorage(PropertyStorage.class, PropertyStorage.class.getName());
209 }
210
211 @Deprecated
212 public static Method tryToGetMethodOfProperty(Class entity, String property)
213 {
214 return tryToGetMethodOfProperty(getPropertyStorage(), entity, property);
215 }
216
217 public static Method tryToGetMethodOfProperty(PropertyStorage storage, Class entity, String property)
218 {
219 if (isCachedMethod(storage, entity, property))
220 {
221 return getCachedMethod(storage, entity, property);
222 }
223
224 Method method = tryToGetReadMethod(entity, property);
225
226 tryToCacheMethod(storage, entity, property, method);
227
228 return method;
229 }
230
231 @Deprecated
232 public static Field tryToGetFieldOfProperty(Class entity, String property)
233 {
234 return tryToGetFieldOfProperty(getPropertyStorage(), entity, property);
235 }
236
237 public static Field tryToGetFieldOfProperty(PropertyStorage storage, Class entity, String property)
238 {
239 if (isCachedField(storage, entity, property))
240 {
241 return getCachedField(storage, entity, property);
242 }
243
244 Field field = null;
245
246 try
247 {
248 field = entity.getDeclaredField(property);
249 }
250 catch (Exception e)
251 {
252 try
253 {
254 try
255 {
256 field = entity.getDeclaredField("_" + property);
257 }
258 catch (Exception e1)
259 {
260 if (property.length() > 1
261 && Character.isUpperCase(property.charAt(0))
262 && Character.isUpperCase(property.charAt(1)))
263 {
264
265 field = entity.getDeclaredField(property.substring(0, 1).toLowerCase() + property.substring(1));
266 }
267 else
268 {
269 field = entity.getDeclaredField(Introspector.decapitalize(property));
270 }
271 }
272 }
273 catch (NoSuchFieldException e1)
274 {
275 LOGGER.log(Level.FINEST, "field " + property + " or _" + property + " not found", e1);
276 }
277 }
278
279 tryToCacheField(storage, entity, property, field);
280
281 return field;
282 }
283
284 private static void tryToCacheField(PropertyStorage storage, Class entity, String property, Field field)
285 {
286 if (!storage.containsField(entity, property))
287 {
288 storage.storeField(entity, property, field);
289 }
290 }
291
292 private static boolean isCachedField(PropertyStorage storage, Class entity, String property)
293 {
294 return storage.containsField(entity, property);
295 }
296
297 private static Method tryToGetReadMethod(Class baseBeanClass, String property)
298 {
299 Method method = ReflectionUtils.tryToGetReadMethodViaBeanInfo(baseBeanClass, property);
300
301 if (method == null)
302 {
303 method = ReflectionUtils.tryToGetReadMethodManually(baseBeanClass, property);
304 }
305 return method;
306 }
307
308 private static Method tryToGetReadMethodViaBeanInfo(Class entity, String property)
309 {
310 if (useBeanInfo())
311 {
312 try
313 {
314 BeanInfo beanInfo = Introspector.getBeanInfo(entity);
315 for (PropertyDescriptor propertyDescriptor : beanInfo
316 .getPropertyDescriptors())
317 {
318 if (property.equals(propertyDescriptor.getName())
319 && propertyDescriptor.getReadMethod() != null)
320 {
321 return propertyDescriptor.getReadMethod();
322 }
323 }
324 }
325 catch (IntrospectionException e)
326 {
327
328 }
329 }
330 return null;
331 }
332
333 private static boolean useBeanInfo()
334 {
335 return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty(BeanInfo.class.getName()));
336 }
337
338 private static Method tryToGetReadMethodManually(Class entity, String property)
339 {
340 property = property.substring(0, 1).toUpperCase() + property.substring(1);
341
342 try
343 {
344
345 return entity.getDeclaredMethod("is" + property);
346 }
347 catch (NoSuchMethodException e)
348 {
349 try
350 {
351 return entity.getDeclaredMethod("get" + property);
352 }
353 catch (NoSuchMethodException e1)
354 {
355 LOGGER.finest("method not found - class: " + entity.getName()
356 + " - methods: " + "get" + property + " " + "is" + property);
357
358 return null;
359 }
360 }
361 }
362
363 private static Field getCachedField(PropertyStorage storage, Class entity, String property)
364 {
365 return storage.getField(entity, property);
366 }
367
368 private static boolean isCachedMethod(PropertyStorage storage, Class entity, String property)
369 {
370 return storage.containsMethod(entity, property);
371 }
372
373 private static void tryToCacheMethod(PropertyStorage storage, Class entity, String property, Method method)
374 {
375 if (!storage.containsMethod(entity, property))
376 {
377 storage.storeMethod(entity, property, method);
378 }
379 }
380
381 private static Method getCachedMethod(PropertyStorage storage, Class entity, String property)
382 {
383 return storage.getMethod(entity, property);
384 }
385 }