| 1 22 package org.jboss.verifier.strategy; 23 24 26 import org.gjt.lindfors.pattern.StrategyContext; 27 import org.jboss.logging.Logger; 28 import org.jboss.metadata.BeanMetaData; 29 import org.jboss.metadata.EntityMetaData; 30 import org.jboss.metadata.MessageDrivenMetaData; 31 import org.jboss.util.Classes; 32 import org.jboss.verifier.Section; 33 import org.jboss.verifier.event.VerificationEvent; 34 import org.jboss.verifier.factory.DefaultEventFactory; 35 import org.jboss.verifier.factory.VerificationEventFactory; 36 37 import java.lang.reflect.Constructor ; 38 import java.lang.reflect.Field ; 39 import java.lang.reflect.Member ; 40 import java.lang.reflect.Method ; 41 import java.lang.reflect.Modifier ; 42 import java.net.URL ; 43 import java.net.URLClassLoader ; 44 import java.rmi.RemoteException ; 45 import java.util.Arrays ; 46 import java.util.Iterator ; 47 import java.util.LinkedList ; 48 import java.util.List ; 49 50 import javax.jms.Message ; 51 52 53 69 public abstract class AbstractVerifier 70 implements VerificationStrategy 71 { 72 static final Logger log = Logger.getLogger(AbstractVerifier.class); 73 74 protected final static String EJB_OBJECT_INTERFACE = 75 "javax.ejb.EJBObject"; 76 77 protected final static String EJB_HOME_INTERFACE = 78 "javax.ejb.EJBHome"; 79 80 protected final static String EJB_LOCAL_OBJECT_INTERFACE = 81 "javax.ejb.EJBLocalObject"; 82 83 protected final static String EJB_LOCAL_HOME_INTERFACE = 84 "javax.ejb.EJBLocalHome"; 85 86 94 protected ClassLoader classloader = null; 95 96 103 private VerificationEventFactory factory = null; 104 105 112 private VerificationContext context = null; 113 114 119 public AbstractVerifier(VerificationContext context) 120 { 121 this.context = context; 122 this.classloader = context.getClassLoader(); 123 this.factory = new DefaultEventFactory(getMessageBundle()); 124 125 if (this.classloader == null) 126 { 127 URL [] list = {context.getJarLocation()}; 128 129 ClassLoader parent = Thread.currentThread().getContextClassLoader(); 130 this.classloader = new URLClassLoader (list, parent); 131 } 132 } 133 134 135 142 143 public boolean isAssignableFrom(String className, Class assignableFromClass) 144 { 145 try 146 { 147 Class clazz = this.classloader.loadClass(className); 148 return clazz.isAssignableFrom(assignableFromClass); 149 } 150 catch (ClassNotFoundException e) 151 { 152 log.warn("Failed to find class: " + className, e); 153 } 154 return false; 155 } 156 157 public boolean isAssignableFrom(Class clazz, String assignableFromClassName) 158 { 159 try 160 { 161 Class assignableFromClass = this.classloader.loadClass(assignableFromClassName); 162 return clazz.isAssignableFrom(assignableFromClass); 163 } 164 catch (ClassNotFoundException e) 165 { 166 log.warn("Failed to find class: " + assignableFromClassName, e); 167 } 168 return false; 169 } 170 171 public abstract String getMessageBundle(); 172 173 public abstract boolean isCreateMethod(Method m); 174 175 public abstract boolean isEjbCreateMethod(Method m); 176 177 public boolean hasLegalRMIIIOPArguments(Method method) 178 { 179 Class [] params = method.getParameterTypes(); 180 181 for (int i = 0; i < params.length; ++i) 182 { 183 if (!isRMIIIOPType(params[i])) 184 return false; 185 } 186 187 return true; 188 } 189 190 public boolean hasLegalRMIIIOPReturnType(Method method) 191 { 192 return isRMIIIOPType(method.getReturnType()); 193 } 194 195 196 public boolean hasLegalRMIIIOPExceptionTypes(Method method) 197 { 198 205 Iterator it = Arrays.asList(method.getExceptionTypes()).iterator(); 206 while (it.hasNext()) 207 { 208 Class exception = (Class )it.next(); 209 210 if (!isRMIIDLExceptionType(exception)) 211 return false; 212 } 213 214 return true; 215 } 216 217 223 public boolean throwsRemoteException(Method method) 224 { 225 Class [] exception = method.getExceptionTypes(); 226 227 for (int i = 0; i < exception.length; ++i) 228 { 229 if (exception[i].equals(java.io.IOException .class) 232 || exception[i].equals(java.lang.Exception .class)) 233 { 234 continue; 235 } 236 241 if (isAssignableFrom(exception[i], "java.rmi.RemoteException")) 242 { 243 return true; 244 } 245 } 246 247 return false; 248 } 249 250 253 public boolean hasSingleArgument(Method method, Class argClass) 254 { 255 Class [] params = method.getParameterTypes(); 256 if (params.length == 1) 257 { 258 if (params[0].equals(argClass)) 259 return true; 260 } 261 262 return false; 263 } 264 265 268 public boolean hasNoArguments(Method method) 269 { 270 Class [] params = method.getParameterTypes(); 271 return (params.length == 0) ? true : false; 272 } 273 274 277 public boolean throwsNoException(Method method) 278 { 279 boolean hasCheckedException = false; 280 Class [] exceptions = method.getExceptionTypes(); 281 for (int e = 0; e < exceptions.length; e++) 282 { 283 Class ex = exceptions[e]; 284 boolean isError = Error .class.isAssignableFrom(ex); 285 boolean isRuntimeException = RuntimeException .class.isAssignableFrom(ex); 286 boolean isRemoteException = RemoteException .class.isAssignableFrom(ex); 287 if (isError == false && isRuntimeException == false && isRemoteException == false) 288 hasCheckedException = true; 289 } 290 return hasCheckedException == false; 291 } 292 293 297 public boolean throwsCreateException(Method method) 298 { 299 Class [] exception = method.getExceptionTypes(); 300 for (int i = 0; i < exception.length; ++i) 301 { 302 if (isAssignableFrom("javax.ejb.CreateException", exception[i])) 303 return true; 304 } 305 306 return false; 307 } 308 309 313 public boolean throwsFinderException(Method method) 314 { 315 Class [] exception = method.getExceptionTypes(); 316 317 for (int i = 0; i < exception.length; ++i) 318 { 319 if (isAssignableFrom("javax.ejb.FinderException", exception[i])) 320 return true; 321 } 322 323 return false; 324 } 325 326 330 public boolean isStatic(Member member) 331 { 332 return (Modifier.isStatic(member.getModifiers())); 333 } 334 335 338 public boolean isStatic(Class c) 339 { 340 return (Modifier.isStatic(c.getModifiers())); 341 } 342 343 347 public boolean isFinal(Member member) 348 { 349 return (Modifier.isFinal(member.getModifiers())); 350 } 351 352 355 public boolean isFinal(Class c) 356 { 357 return (Modifier.isFinal(c.getModifiers())); 358 } 359 360 364 public boolean isPublic(Member member) 365 { 366 return (Modifier.isPublic(member.getModifiers())); 367 } 368 369 372 public boolean isPublic(Class c) 373 { 374 return (Modifier.isPublic(c.getModifiers())); 375 } 376 377 380 public boolean isAllFieldsPublic(Class c) 381 { 382 try 383 { 384 Field list[] = c.getFields(); 385 for (int i = 0; i < list.length; i++) 386 { 387 if (!Modifier.isPublic(list[i].getModifiers())) 388 return false; 389 } 390 } 391 catch (Exception e) 392 { 393 return false; 394 } 395 396 return true; 397 } 398 399 402 public boolean isAbstract(Class c) 403 { 404 return (Modifier.isAbstract(c.getModifiers())); 405 } 406 407 410 public boolean isAbstract(Method m) 411 { 412 return (Modifier.isAbstract(m.getModifiers())); 413 } 414 415 418 public boolean isSingleObjectFinder(EntityMetaData entity, 419 Method finder) 420 { 421 return hasPrimaryKeyReturnType(entity, finder); 422 } 423 424 427 public boolean isMultiObjectFinder(Method f) 428 { 429 return (java.util.Collection .class.isAssignableFrom(f.getReturnType()) 430 || java.util.Enumeration .class.isAssignableFrom(f.getReturnType())); 431 } 432 433 436 public boolean hasRemoteReturnType(BeanMetaData bean, Method m) 437 { 438 try 439 { 440 Class clazz = classloader.loadClass(bean.getRemote()); 441 return m.getReturnType().isAssignableFrom(clazz); 442 } 443 catch (Exception e) 444 { 445 return false; 447 } 448 } 449 450 453 public boolean hasLocalReturnType(BeanMetaData bean, Method m) 454 { 455 try 456 { 457 Class clazz = classloader.loadClass(bean.getLocal()); 458 return m.getReturnType().isAssignableFrom(clazz); 459 } 460 catch (Exception e) 461 { 462 return false; 464 } 465 } 466 467 470 public boolean hasVoidReturnType(Method method) 471 { 472 return (method.getReturnType() == Void.TYPE); 473 } 474 475 478 public boolean hasMessageDrivenBeanInterface(Class c) 479 { 480 return isAssignableFrom("javax.ejb.MessageDrivenBean", c); 481 } 482 483 486 public boolean hasMessageListenerInterface(Class c) 487 { 488 return isAssignableFrom("javax.jms.MessageListener", c); 489 } 490 491 494 public boolean hasSessionBeanInterface(Class c) 495 { 496 return isAssignableFrom("javax.ejb.SessionBean", c); 497 } 498 499 502 public boolean hasEntityBeanInterface(Class c) 503 { 504 return isAssignableFrom("javax.ejb.EntityBean", c); 505 } 506 507 510 public boolean hasEJBObjectInterface(Class c) 511 { 512 return isAssignableFrom("javax.ejb.EJBObject", c); 513 } 514 515 518 public boolean hasEJBLocalObjectInterface(Class c) 519 { 520 return isAssignableFrom("javax.ejb.EJBLocalObject", c); 521 } 522 523 527 public boolean hasEJBHomeInterface(Class c) 528 { 529 return isAssignableFrom("javax.ejb.EJBHome", c); 530 } 531 532 536 public boolean hasEJBLocalHomeInterface(Class c) 537 { 538 return isAssignableFrom("javax.ejb.EJBLocalHome", c); 539 } 540 541 544 public boolean hasSessionSynchronizationInterface(Class c) 545 { 546 return isAssignableFrom("javax.ejb.SessionSynchronization", c); 547 } 548 549 552 public boolean hasDefaultConstructor(Class c) 553 { 554 try 555 { 556 Constructor ctr = c.getConstructor(new Class [0]); 557 } 558 catch (NoSuchMethodException e) 559 { 560 if( log.isTraceEnabled() ) 561 { 562 StringBuffer tmp = new StringBuffer ("hasDefaultConstructor("); 563 tmp.append(") failure, "); 564 Classes.displayClassInfo(c, tmp); 565 log.trace(tmp.toString(), e); 566 } 567 return false; 568 } 569 570 return true; 571 } 572 573 576 public boolean hasFinalizer(Class c) 577 { 578 try 579 { 580 Method finalizer = c.getDeclaredMethod(FINALIZE_METHOD, new Class [0]); 581 } 582 catch (NoSuchMethodException e) 583 { 584 return false; 585 } 586 587 return true; 588 } 589 590 593 public boolean hasFinderMethod(Class c) 594 { 595 Method [] method = c.getMethods(); 596 for (int i = 0; i < method.length; ++i) 597 { 598 if (method[i].getName().startsWith("ejbFind")) 599 return true; 600 } 601 602 return false; 603 } 604 605 608 public boolean isFinderMethod(Method m) 609 { 610 return (m.getName().startsWith("find")); 611 } 612 613 616 public boolean isOnMessageMethod(Method m) 617 { 618 if ("onMessage".equals(m.getName())) 619 { 620 Class [] paramTypes = m.getParameterTypes(); 621 if (paramTypes.length == 1) 622 { 623 if (Message .class.equals(paramTypes[0])) 624 return true; 625 } 626 } 627 return false; 628 } 629 630 633 public boolean hasANonStaticField(Class c) 634 { 635 try 636 { 637 Field list[] = c.getFields(); 638 for (int i = 0; i < list.length; i++) 639 { 640 if (!Modifier.isStatic(list[i].getModifiers())) 641 return true; 642 } 643 } 644 catch (Exception ignored) 645 { 646 } 647 648 return false; 649 } 650 651 654 public boolean hasOnMessageMethod(Class c) 655 { 656 Method [] method = c.getMethods(); 657 for (int i = 0; i < method.length; ++i) 658 { 659 if (isOnMessageMethod(method[i])) 660 return true; 661 } 662 663 return false; 664 } 665 666 669 public boolean hasCreateMethod(Class c) 670 { 671 Method [] method = c.getMethods(); 672 673 for (int i = 0; i < method.length; ++i) 674 { 675 if (isCreateMethod(method[i])) 676 return true; 677 } 678 679 return false; 680 } 681 682 685 public boolean hasEJBCreateMethod(Class c, boolean isSession) 686 { 687 Method [] method = c.getMethods(); 688 for (int i = 0; i < method.length; ++i) 689 { 690 if (isEjbCreateMethod(method[i])) 691 { 692 if (!isStatic(method[i]) && !isFinal(method[i]) 693 && ((isSession && hasVoidReturnType(method[i])) 694 || (!isSession)) 695 ) 696 { 697 return true; 698 } 699 } 700 } 701 702 return false; 703 } 704 705 709 public boolean hasDefaultCreateMethod(Class home) 710 { 711 Method [] method = home.getMethods(); 712 713 for (int i = 0; i < method.length; ++i) 714 { 715 if (isCreateMethod(method[i])) 716 { 717 Class [] params = method[i].getParameterTypes(); 718 if (params.length == 0) 719 return true; 720 } 721 } 722 723 return false; 724 } 725 726 729 public boolean hasEJBFindByPrimaryKey(Class c) 730 { 731 Method [] method = c.getMethods(); 732 for (int i = 0; i < method.length; ++i) 733 { 734 if (method[i].getName().equals(EJB_FIND_BY_PRIMARY_KEY)) 735 return true; 736 } 737 738 return false; 739 } 740 741 745 public boolean hasPrimaryKeyReturnType(EntityMetaData entity, Method m) 746 { 747 try 748 { 749 return 750 m.getReturnType().isAssignableFrom(classloader.loadClass(entity.getPrimaryKeyClass())); 751 } 752 catch (ClassNotFoundException cnfe) 753 { 754 return 756 m.getReturnType().getName().equals(entity.getPrimaryKeyClass()); 757 } 758 } 759 760 764 public Method getDefaultCreateMethod(Class c) 765 { 766 Method method = null; 767 768 try 769 { 770 method = c.getMethod(CREATE_METHOD, null); 771 } 772 catch (NoSuchMethodException ignored) 773 { 774 } 775 776 return method; 777 } 778 779 782 public Method getEJBFindByPrimaryKey(Class c) 783 { 784 Method [] method = c.getMethods(); 785 for (int i = 0; i < method.length; ++i) 786 { 787 if (method[i].getName().equals(EJB_FIND_BY_PRIMARY_KEY)) 788 return method[i]; 789 } 790 791 return null; 792 } 793 794 797 public Iterator getEJBFindMethods(Class c) 798 { 799 List finders = new LinkedList (); 800 Method [] method = c.getMethods(); 801 for (int i = 0; i < method.length; ++i) 802 { 803 if (method[i].getName().startsWith("ejbFind")) 804 finders.add(method[i]); 805 } 806 807 return finders.iterator(); 808 } 809 810 811 814 public Iterator getFinderMethods(Class home) 815 { 816 List finders = new LinkedList (); 817 Method [] method = home.getMethods(); 818 819 for (int i = 0; i < method.length; ++i) 820 { 821 if (method[i].getName().startsWith("find")) 822 finders.add(method[i]); 823 } 824 825 return finders.iterator(); 826 } 827 828 831 public Iterator getOnMessageMethods(Class c) 832 { 833 List onMessages = new LinkedList (); 834 Method [] method = c.getMethods(); 835 836 for (int i = 0; i < method.length; ++i) 837 { 838 if (isOnMessageMethod(method[i])) 839 onMessages.add(method[i]); 840 } 841 842 return onMessages.iterator(); 843 } 844 845 848 public Iterator getEJBCreateMethods(Class c) 849 { 850 List ejbCreates = new LinkedList (); 851 Method [] method = c.getMethods(); 852 853 for (int i = 0; i < method.length; ++i) 854 { 855 if (isEjbCreateMethod(method[i])) 856 ejbCreates.add(method[i]); 857 } 858 859 return ejbCreates.iterator(); 860 } 861 862 865 public Iterator getCreateMethods(Class c) 866 { 867 List creates = new LinkedList (); 868 Method [] method = c.getMethods(); 869 870 for (int i = 0; i < method.length; ++i) 871 { 872 if (isCreateMethod(method[i])) 873 creates.add(method[i]); 874 } 875 876 return creates.iterator(); 877 } 878 879 882 public boolean hasMoreThanOneCreateMethods(Class c) 883 { 884 int count = 0; 885 Method [] method = c.getMethods(); 886 for (int i = 0; i < method.length; ++i) 887 { 888 if (isCreateMethod(method[i])) 889 { 890 ++count; 891 } 892 } 893 894 return (count > 1); 895 } 896 897 900 public boolean hasMatchingExceptions(Method source, Method target) 901 { 902 Class [] a = source.getExceptionTypes(); 904 Class [] b = target.getExceptionTypes(); 905 Class rteClass = null; 906 Class errorClass = null; 907 908 try 909 { 910 rteClass = classloader.loadClass("java.lang.RuntimeException"); 911 errorClass = classloader.loadClass("java.lang.Error"); 912 } 913 catch (ClassNotFoundException cnfe) 914 { 915 } 917 918 for (int i = 0; i < a.length; ++i) 919 { 920 if (rteClass.isAssign
|