1 16 17 package org.springframework.util; 18 19 import java.lang.reflect.Field ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Modifier ; 23 import java.util.Arrays ; 24 import java.util.LinkedList ; 25 import java.util.List ; 26 27 37 public abstract class ReflectionUtils { 38 39 47 public static void handleReflectionException(Exception ex) { 48 if (ex instanceof NoSuchMethodException ) { 49 throw new IllegalStateException ("Method not found: " + ex.getMessage()); 50 } 51 if (ex instanceof IllegalAccessException ) { 52 throw new IllegalStateException ("Could not access method: " + ex.getMessage()); 53 } 54 if (ex instanceof InvocationTargetException ) { 55 handleInvocationTargetException((InvocationTargetException ) ex); 56 } 57 throw new IllegalStateException ( 58 "Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); 59 } 60 61 68 public static void handleInvocationTargetException(InvocationTargetException ex) { 69 if (ex.getTargetException() instanceof RuntimeException ) { 70 throw (RuntimeException ) ex.getTargetException(); 71 } 72 if (ex.getTargetException() instanceof Error ) { 73 throw (Error ) ex.getTargetException(); 74 } 75 throw new IllegalStateException ( 76 "Unexpected exception thrown by method - " + ex.getTargetException().getClass().getName() + 77 ": " + ex.getTargetException().getMessage()); 78 } 79 80 85 public static Method findMethod(Class type, String name, Class [] paramTypes) { 86 Assert.notNull(type, "'type' cannot be null."); 87 Assert.notNull(name, "'name' cannot be null."); 88 Class searchType = type; 89 while(!Object .class.equals(searchType) && searchType != null) { 90 Method [] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods()); 91 for (int i = 0; i < methods.length; i++) { 92 Method method = methods[i]; 93 if(name.equals(method.getName()) && Arrays.equals(paramTypes, method.getParameterTypes())) { 94 return method; 95 } 96 } 97 searchType = searchType.getSuperclass(); 98 } 99 return null; 100 } 101 102 109 public static Object invokeMethod(Method method, Object target) { 110 return invokeMethod(method, target, null); 111 } 112 113 120 public static Object invokeMethod(Method method, Object target, Object [] args) { 121 try { 122 return method.invoke(target, args); 123 } 124 catch (IllegalAccessException ex) { 125 handleReflectionException(ex); 126 throw new IllegalStateException ( 127 "Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); 128 } 129 catch (InvocationTargetException ex) { 130 handleReflectionException(ex); 131 throw new IllegalStateException ( 132 "Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); 133 } 134 } 135 136 140 public static boolean isPublicStaticFinal(Field field) { 141 int modifiers = field.getModifiers(); 142 return (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)); 143 } 144 145 152 public static void makeAccessible(Field field) { 153 if (!Modifier.isPublic(field.getModifiers()) || 154 !Modifier.isPublic(field.getDeclaringClass().getModifiers())) { 155 field.setAccessible(true); 156 } 157 } 158 159 160 169 public static void doWithMethods(Class targetClass, MethodCallback mc) throws IllegalArgumentException { 170 doWithMethods(targetClass, mc, null); 171 } 172 173 182 public static void doWithMethods(Class targetClass, MethodCallback mc, MethodFilter mf) 183 throws IllegalArgumentException { 184 185 do { 187 Method [] methods = targetClass.getDeclaredMethods(); 188 for (int i = 0; i < methods.length; i++) { 189 if (mf != null && !mf.matches(methods[i])) { 190 continue; 191 } 192 try { 193 mc.doWith(methods[i]); 194 } 195 catch (IllegalAccessException ex) { 196 throw new IllegalStateException ( 197 "Shouldn't be illegal to access method '" + methods[i].getName() + "': " + ex); 198 } 199 } 200 targetClass = targetClass.getSuperclass(); 201 } 202 while (targetClass != null); 203 } 204 205 209 public static Method [] getAllDeclaredMethods(Class leafClass) throws IllegalArgumentException { 210 final List l = new LinkedList (); 211 doWithMethods(leafClass, new MethodCallback() { 212 public void doWith(Method m) { 213 l.add(m); 214 } 215 }); 216 return (Method []) l.toArray(new Method [l.size()]); 217 } 218 219 225 public static void doWithFields(Class targetClass, FieldCallback fc) throws IllegalArgumentException { 226 doWithFields(targetClass, fc, null); 227 } 228 229 236 public static void doWithFields(Class targetClass, FieldCallback fc, FieldFilter ff) 237 throws IllegalArgumentException { 238 239 do { 241 Field [] fields = targetClass.getDeclaredFields(); 243 for (int i = 0; i < fields.length; i++) { 244 if (ff != null && !ff.matches(fields[i])) { 246 continue; 247 } 248 try { 249 fc.doWith(fields[i]); 250 } 251 catch (IllegalAccessException ex) { 252 throw new IllegalStateException ( 253 "Shouldn't be illegal to access field '" + fields[i].getName() + "': " + ex); 254 } 255 } 256 targetClass = targetClass.getSuperclass(); 257 } 258 while (targetClass != null && targetClass != Object .class); 259 } 260 261 267 public static void shallowCopyFieldState(final Object src, final Object dest) throws IllegalArgumentException { 268 if (src == null) { 269 throw new IllegalArgumentException ("Source for field copy cannot be null"); 270 } 271 if (dest == null) { 272 throw new IllegalArgumentException ("Destination for field copy cannot be null"); 273 } 274 if (!src.getClass().isAssignableFrom(dest.getClass())) { 275 throw new IllegalArgumentException ("Destination class [" + dest.getClass().getName() + 276 "] must be same or subclass as source class [" + src.getClass().getName() + "]"); 277 } 278 doWithFields(src.getClass(), new ReflectionUtils.FieldCallback() { 279 public void doWith(Field field) throws IllegalArgumentException , IllegalAccessException { 280 makeAccessible(field); 281 Object srcValue = field.get(src); 282 field.set(dest, srcValue); 283 } 284 }, ReflectionUtils.COPYABLE_FIELDS); 285 } 286 287 288 291 public static interface MethodCallback { 292 293 297 void doWith(Method method) throws IllegalArgumentException , IllegalAccessException ; 298 } 299 300 301 304 public static interface MethodFilter { 305 306 310 boolean matches(Method method); 311 } 312 313 314 317 public static interface FieldCallback { 318 319 323 void doWith(Field field) throws IllegalArgumentException , IllegalAccessException ; 324 } 325 326 327 330 public static interface FieldFilter { 331 332 336 boolean matches(Field field); 337 } 338 339 340 343 public static FieldFilter COPYABLE_FIELDS = new FieldFilter() { 344 public boolean matches(Field field) { 345 return !(Modifier.isStatic(field.getModifiers()) || 346 Modifier.isFinal(field.getModifiers())); 347 } 348 }; 349 350 } 351 | Popular Tags |