1 61 62 package com.opensymphony.workflow.designer.beanutils; 63 64 65 import java.lang.reflect.InvocationTargetException ; 66 import java.lang.reflect.Method ; 67 import java.lang.reflect.Modifier ; 68 69 import java.util.WeakHashMap ; 70 71 94 95 public class MethodUtils { 96 97 99 100 private static boolean loggedAccessibleWarning = false; 101 102 103 private static final Class [] emptyClassArray = new Class [0]; 104 105 private static final Object [] emptyObjectArray = new Object [0]; 106 107 110 private static WeakHashMap cache = new WeakHashMap (); 111 112 114 140 public static Object invokeMethod( 141 Object object, 142 String methodName, 143 Object arg) 144 throws 145 NoSuchMethodException , 146 IllegalAccessException , 147 InvocationTargetException { 148 149 Object [] args = {arg}; 150 return invokeMethod(object, methodName, args); 151 152 } 153 154 155 181 public static Object invokeMethod( 182 Object object, 183 String methodName, 184 Object [] args) 185 throws 186 NoSuchMethodException , 187 IllegalAccessException , 188 InvocationTargetException { 189 190 if (args == null) { 191 args = emptyObjectArray; 192 } 193 int arguments = args.length; 194 Class parameterTypes [] = new Class [arguments]; 195 for (int i = 0; i < arguments; i++) { 196 parameterTypes[i] = args[i].getClass(); 197 } 198 return invokeMethod(object, methodName, args, parameterTypes); 199 200 } 201 202 203 228 public static Object invokeMethod( 229 Object object, 230 String methodName, 231 Object [] args, 232 Class [] parameterTypes) 233 throws 234 NoSuchMethodException , 235 IllegalAccessException , 236 InvocationTargetException { 237 238 if (parameterTypes == null) { 239 parameterTypes = emptyClassArray; 240 } 241 if (args == null) { 242 args = emptyObjectArray; 243 } 244 245 Method method = getMatchingAccessibleMethod( 246 object.getClass(), 247 methodName, 248 parameterTypes); 249 if (method == null) 250 throw new NoSuchMethodException ("No such accessible method: " + 251 methodName + "() on object: " + object.getClass().getName()); 252 return method.invoke(object, args); 253 } 254 255 256 274 public static Object invokeExactMethod( 275 Object object, 276 String methodName, 277 Object arg) 278 throws 279 NoSuchMethodException , 280 IllegalAccessException , 281 InvocationTargetException { 282 283 Object [] args = {arg}; 284 return invokeExactMethod(object, methodName, args); 285 286 } 287 288 289 306 public static Object invokeExactMethod( 307 Object object, 308 String methodName, 309 Object [] args) 310 throws 311 NoSuchMethodException , 312 IllegalAccessException , 313 InvocationTargetException { 314 if (args == null) { 315 args = emptyObjectArray; 316 } 317 int arguments = args.length; 318 Class parameterTypes [] = new Class [arguments]; 319 for (int i = 0; i < arguments; i++) { 320 parameterTypes[i] = args[i].getClass(); 321 } 322 return invokeExactMethod(object, methodName, args, parameterTypes); 323 324 } 325 326 327 345 public static Object invokeExactMethod( 346 Object object, 347 String methodName, 348 Object [] args, 349 Class [] parameterTypes) 350 throws 351 NoSuchMethodException , 352 IllegalAccessException , 353 InvocationTargetException { 354 355 if (args == null) { 356 args = emptyObjectArray; 357 } 358 359 if (parameterTypes == null) { 360 parameterTypes = emptyClassArray; 361 } 362 363 Method method = getAccessibleMethod( 364 object.getClass(), 365 methodName, 366 parameterTypes); 367 if (method == null) 368 throw new NoSuchMethodException ("No such accessible method: " + 369 methodName + "() on object: " + object.getClass().getName()); 370 return method.invoke(object, args); 371 372 } 373 374 375 386 public static Method getAccessibleMethod( 387 Class clazz, 388 String methodName, 389 Class parameterType) { 390 391 Class [] parameterTypes = {parameterType}; 392 return getAccessibleMethod(clazz, methodName, parameterTypes); 393 394 } 395 396 397 408 public static Method getAccessibleMethod( 409 Class clazz, 410 String methodName, 411 Class [] parameterTypes) { 412 413 try { 414 MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, true); 415 Method method = (Method )cache.get(md); 417 if (method != null) { 418 return method; 419 } 420 421 method = getAccessibleMethod 422 (clazz.getMethod(methodName, parameterTypes)); 423 cache.put(md, method); 424 return method; 425 } catch (NoSuchMethodException e) { 426 return (null); 427 } 428 429 } 430 431 432 439 public static Method getAccessibleMethod(Method method) { 440 441 if (method == null) { 443 return (null); 444 } 445 446 if (!Modifier.isPublic(method.getModifiers())) { 448 return (null); 449 } 450 451 Class clazz = method.getDeclaringClass(); 453 if (Modifier.isPublic(clazz.getModifiers())) { 454 return (method); 455 } 456 457 method = 459 getAccessibleMethodFromInterfaceNest(clazz, 460 method.getName(), 461 method.getParameterTypes()); 462 return (method); 463 464 } 465 466 467 469 483 private static Method getAccessibleMethodFromInterfaceNest 484 (Class clazz, String methodName, Class parameterTypes[]) { 485 486 Method method = null; 487 488 for (; clazz != null; clazz = clazz.getSuperclass()) { 490 491 Class interfaces[] = clazz.getInterfaces(); 493 for (int i = 0; i < interfaces.length; i++) { 494 495 if (!Modifier.isPublic(interfaces[i].getModifiers())) 497 continue; 498 499 try { 501 method = interfaces[i].getDeclaredMethod(methodName, 502 parameterTypes); 503 } catch (NoSuchMethodException e) { 504 ; 505 } 506 if (method != null) 507 break; 508 509 method = 511 getAccessibleMethodFromInterfaceNest(interfaces[i], 512 methodName, 513 parameterTypes); 514 if (method != null) 515 break; 516 517 } 518 519 } 520 521 if (method != null) 523 return (method); 524 525 return (null); 527 528 } 529 530 552 public static Method getMatchingAccessibleMethod( 553 Class clazz, 554 String methodName, 555 Class [] parameterTypes) { 556 MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, false); 557 558 try { 561 Method method = (Method )cache.get(md); 563 if (method != null) { 564 return method; 565 } 566 567 method = clazz.getMethod(methodName, parameterTypes); 568 569 try { 570 method.setAccessible(true); 587 588 } catch (SecurityException se) { 589 if (!loggedAccessibleWarning) { 591 boolean vunerableJVM = false; 592 try { 593 String specVersion = System.getProperty("java.specification.version"); 594 if (specVersion.charAt(0) == '1' && 595 (specVersion.charAt(0) == '0' || 596 specVersion.charAt(0) == '1' || 597 specVersion.charAt(0) == '2' || 598 specVersion.charAt(0) == '3')) { 599 600 vunerableJVM = true; 601 } 602 } catch (SecurityException e) { 603 vunerableJVM = true; 605 } 606 loggedAccessibleWarning = true; 607 } 608 } 609 cache.put(md, method); 610 return method; 611 612 } catch (NoSuchMethodException e) { } 613 614 int paramSize = parameterTypes.length; 616 Method [] methods = clazz.getMethods(); 617 for (int i = 0, size = methods.length; i < size ; i++) { 618 if (methods[i].getName().equals(methodName)) { 619 620 Class [] methodsParams = methods[i].getParameterTypes(); 622 int methodParamSize = methodsParams.length; 623 if (methodParamSize == paramSize) { 624 boolean match = true; 625 for (int n = 0 ; n < methodParamSize; n++) { 626 if (!isAssignmentCompatible(methodsParams[n], parameterTypes[n])) { 627 match = false; 628 break; 629 } 630 } 631 632 if (match) { 633 Method method = getAccessibleMethod(methods[i]); 635 if (method != null) { 636 try { 637 method.setAccessible(true); 642 643 } catch (SecurityException se) { 644 } 646 cache.put(md, method); 647 return method; 648 } 649 650 } 651 } 652 } 653 } 654 655 return null; 657 } 658 659 676 public static final boolean isAssignmentCompatible(Class parameterType, Class parameterization) { 677 if (parameterType.isAssignableFrom(parameterization)) { 679 return true; 680 } 681 682 if (parameterType.isPrimitive()) { 683 Class parameterWrapperClazz = getPrimitiveWrapper(parameterType); 686 if (parameterWrapperClazz != null) { 687 return parameterWrapperClazz.equals(parameterization); 688 } 689 } 690 691 return false; 692 } 693 694 701 public static Class getPrimitiveWrapper(Class primitiveType) { 702 if (boolean.class.equals(primitiveType)) { 704 return Boolean .class; 705 } else if (float.class.equals(primitiveType)) { 706 return Float .class; 707 } else if (long.class.equals(primitiveType)) { 708 return Long .class; 709 } else if (int.class.equals(primitiveType)) { 710 return Integer .class; 711 } else if (short.class.equals(primitiveType)) { 712 return Short .class; 713 } else if (byte.class.equals(primitiveType)) { 714 return Byte .class; 715 } else if (double.class.equals(primitiveType)) { 716 return Double .class; 717 } else if (char.class.equals(primitiveType)) { 718 return Character .class; 719 } else { 720 721 return null; 722 } 723 } 724 725 732 public static Class getPrimitiveType(Class wrapperType) { 733 if (Boolean .class.equals(wrapperType)) { 735 return boolean.class; 736 } else if (Float .class.equals(wrapperType)) { 737 return float.class; 738 } else if (Long .class.equals(wrapperType)) { 739 return long.class; 740 } else if (Integer .class.equals(wrapperType)) { 741 return int.class; 742 } else if (Short .class.equals(wrapperType)) { 743 return short.class; 744 } else if (Byte .class.equals(wrapperType)) { 745 return byte.class; 746 } else if (Double .class.equals(wrapperType)) { 747 return double.class; 748 } else if (Character .class.equals(wrapperType)) { 749 return char.class; 750 } else { 751 return null; 752 } 753 } 754 755 761 public static Class toNonPrimitiveClass(Class clazz) { 762 if (clazz.isPrimitive()) { 763 Class primitiveClazz = MethodUtils.getPrimitiveWrapper(clazz); 764 if (primitiveClazz != null) { 766 return primitiveClazz; 767 } else { 768 return clazz; 769 } 770 } else { 771 return clazz; 772 } 773 } 774 775 776 779 private static class MethodDescriptor { 780 private Class cls; 781 private String methodName; 782 private Class [] paramTypes; 783 private boolean exact; 784 private int hashCode; 785 786 794 public MethodDescriptor(Class cls, String methodName, Class [] paramTypes, boolean exact) { 795 if (cls == null) { 796 throw new IllegalArgumentException ("Class cannot be null"); 797 } 798 if (methodName == null) { 799 throw new IllegalArgumentException ("Method Name cannot be null"); 800 } 801 if (paramTypes == null) { 802 paramTypes = emptyClassArray; 803 } 804 805 this.cls = cls; 806 this.methodName = methodName; 807 this.paramTypes = paramTypes; 808 this.exact= exact; 809 810 this.hashCode = methodName.length(); 811 } 812 817 public boolean equals(Object obj) { 818 if (!(obj instanceof MethodDescriptor)) { 819 return false; 820 } 821 MethodDescriptor md = (MethodDescriptor)obj; 822 823 return ( 824 exact == md.exact && 825 methodName.equals(md.methodName) && 826 cls.equals(md.cls) && 827 java.util.Arrays.equals(paramTypes, md.paramTypes) 828 ); 829 } 830 837 public int hashCode() { 838 return hashCode; 839 } 840 } 841 } 842 | Popular Tags |