1 45 package org.openejb.core; 46 47 import java.lang.reflect.Field ; 48 import java.lang.reflect.Method ; 49 import java.util.HashMap ; 50 import java.util.HashSet ; 51 52 import javax.ejb.EJBContext ; 53 import javax.ejb.EJBHome ; 54 import javax.ejb.EJBLocalHome ; 55 import javax.ejb.EJBLocalObject ; 56 import javax.ejb.SessionSynchronization ; 57 import javax.naming.Context ; 58 59 import org.openejb.Container; 60 import org.openejb.RpcContainer; 61 import org.openejb.alt.containers.castor_cmp11.CastorCMP11_EntityContainer; 62 import org.openejb.alt.containers.castor_cmp11.CastorCmpEntityTxPolicy; 63 import org.openejb.alt.containers.castor_cmp11.KeyGenerator; 64 import org.openejb.core.entity.EntityEjbHomeHandler; 65 import org.openejb.core.ivm.BaseEjbProxyHandler; 66 import org.openejb.core.ivm.EjbHomeProxyHandler; 67 import org.openejb.core.ivm.SpecialProxyInfo; 68 import org.openejb.core.stateful.SessionSynchronizationTxPolicy; 69 import org.openejb.core.stateful.StatefulBeanManagedTxPolicy; 70 import org.openejb.core.stateful.StatefulContainerManagedTxPolicy; 71 import org.openejb.core.stateful.StatefulEjbHomeHandler; 72 import org.openejb.core.stateless.StatelessBeanManagedTxPolicy; 73 import org.openejb.core.stateless.StatelessEjbHomeHandler; 74 import org.openejb.core.transaction.TransactionContainer; 75 import org.openejb.core.transaction.TransactionPolicy; 76 import org.openejb.core.transaction.TxManditory; 77 import org.openejb.core.transaction.TxNever; 78 import org.openejb.core.transaction.TxNotSupported; 79 import org.openejb.core.transaction.TxRequired; 80 import org.openejb.core.transaction.TxRequiresNew; 81 import org.openejb.core.transaction.TxSupports; 82 import org.openejb.util.proxy.ProxyManager; 83 84 97 public class DeploymentInfo implements org.openejb.DeploymentInfo{ 98 99 private Class homeInterface; 100 private Class remoteInterface; 101 private Class localHomeInterface; 102 private Class localInterface; 103 private Class beanClass; 104 private Class pkClass; 105 106 private boolean isBeanManagedTransaction; 107 private boolean isReentrant; 108 private Container container; 109 110 private EJBHome ejbHomeRef; 111 112 private final DeploymentContext context; 113 114 119 private Method createMethod = null; 120 121 125 private HashMap postCreateMethodMap = new HashMap (); 126 130 private byte componentType; 131 132 private HashMap methodPermissions = new HashMap (); 133 private HashMap methodTransactionAttributes = new HashMap (); 134 private HashMap methodTransactionPolicies = new HashMap (); 135 private HashMap methodMap = new HashMap (); 136 138 private HashMap securityRoleReferenceMap = new HashMap (); 139 private HashSet methodsWithRemoteReturnTypes = null; 140 private EJBLocalHome ejbLocalHomeRef; 141 142 161 public DeploymentInfo(DeploymentContext context, Class homeClass, Class remoteClass, Class localHomeClass, Class localClass, Class beanClass, Class pkClass, byte componentType) 162 throws org.openejb.SystemException{ 163 this.context = context; 164 this.pkClass = pkClass; 165 166 this.homeInterface = homeClass; 167 this.remoteInterface = remoteClass; 168 this.localInterface = localClass; 169 this.localHomeInterface = localHomeClass; 170 this.remoteInterface = remoteClass; 171 this.beanClass = beanClass; 172 this.pkClass = pkClass; 173 this.componentType = componentType; 174 175 createMethodMap(); 176 177 } 178 179 180 188 public void setContainer(Container cont){ 189 container = cont; 190 } 191 192 193 194 198 213 public byte getComponentType( ){ 214 return componentType; 215 } 216 217 238 public byte getTransactionAttribute(Method method){ 239 240 Byte byteWrapper = (Byte )methodTransactionAttributes.get(method); 241 if(byteWrapper==null) 242 return TX_NOT_SUPPORTED; else 244 return byteWrapper.byteValue(); 245 } 246 247 public TransactionPolicy getTransactionPolicy(Method method){ 248 249 TransactionPolicy policy = (TransactionPolicy)methodTransactionPolicies.get(method); 250 if(policy==null && !isBeanManagedTransaction) { 251 org.apache.log4j.Logger.getLogger("OpenEJB").warn("The following method doesn't have a transaction policy assigned: "+method); 252 } 253 if ( policy == null && container instanceof TransactionContainer) { 254 if ( isBeanManagedTransaction ) { 255 if ( componentType == STATEFUL ) { 256 policy = new StatefulBeanManagedTxPolicy((TransactionContainer) container ); 257 } else if (componentType == STATELESS) { 258 policy = new StatelessBeanManagedTxPolicy((TransactionContainer) container ); 259 } 260 } else if ( componentType == STATEFUL ){ 261 policy = new TxNotSupported((TransactionContainer) container ); 262 policy = new StatefulContainerManagedTxPolicy( policy ); 263 } else if ( componentType == CMP_ENTITY ){ 264 policy = new TxNotSupported((TransactionContainer) container ); 265 policy = new CastorCmpEntityTxPolicy( policy ); 266 } else { 267 policy = new TxNotSupported((TransactionContainer) container ); 268 } 269 methodTransactionPolicies.put( method, policy ); 270 } 271 return policy; 272 } 273 274 284 public String [] getAuthorizedRoles(Method method){ 285 HashSet roleSet = (HashSet )methodPermissions.get(method); 286 if(roleSet == null) return null; 287 String [] roles = new String [roleSet.size()]; 288 return (String [])roleSet.toArray(roles); 289 } 290 291 public String [] getAuthorizedRoles(String action){ 292 return null; 293 } 294 295 301 public Container getContainer( ){ 302 return container; 303 } 304 305 310 public Object getDeploymentID( ){ 311 return context.getId(); 312 } 313 314 321 public boolean isBeanManagedTransaction(){ 322 return isBeanManagedTransaction; 323 } 324 325 334 public Class getHomeInterface( ){ 335 return homeInterface; 336 } 337 338 347 public Class getRemoteInterface( ){ 348 return remoteInterface; 349 } 350 351 public Class getLocalHomeInterface() { 352 return localHomeInterface; 353 } 354 355 public Class getLocalInterface() { 356 return localInterface; 357 } 358 359 367 public Class getBeanClass( ){ 368 return beanClass; 369 } 370 371 377 public Class getPrimaryKeyClass( ){ 378 return pkClass; 379 } 380 381 385 386 390 396 public EJBHome getEJBHome() { 397 if (getHomeInterface() == null) { 398 throw new IllegalStateException ("This component has no home interface: "+getDeploymentID()); 399 } 400 if(ejbHomeRef == null){ 401 ejbHomeRef = createEJBHomeRef(); 402 } 403 return ejbHomeRef; 404 } 405 406 public EJBLocalHome getEJBLocalHome() { 407 if (getLocalHomeInterface() == null) { 408 throw new IllegalStateException ("This component has no local home interface: "+getDeploymentID()); 409 } 410 if(ejbLocalHomeRef == null) { 411 ejbLocalHomeRef = createEJBLocalHomeRef(); 412 } 413 return ejbLocalHomeRef; 414 } 415 416 422 public void setBeanManagedTransaction(boolean value){ 423 isBeanManagedTransaction = value; 424 } 425 426 434 public javax.naming.Context getJndiEnc( ){ 435 return context.getJndiContext(); 436 } 437 438 443 public boolean isReentrant(){ 444 return isReentrant; 445 } 446 447 public void setIsReentrant(boolean reentrant){ 448 isReentrant = reentrant; 449 } 450 451 476 public Object convertIfLocalReference(Method businessMethod, Object returnValue){ 477 if(returnValue == null || methodsWithRemoteReturnTypes == null) 478 return returnValue; 479 480 try{ 484 if( methodsWithRemoteReturnTypes.contains(businessMethod) 485 && ProxyManager.isProxyClass( returnValue.getClass() ) 486 && ProxyManager.getInvocationHandler( returnValue ) instanceof BaseEjbProxyHandler){ 487 488 return new SpecialProxyInfo( returnValue ); 489 } 490 } catch (ClassCastException e) { 491 } 496 return returnValue; 497 498 } 499 500 521 public Method getMatchingBeanMethod(Method interfaceMethod){ 522 Method mthd = (Method )methodMap.get(interfaceMethod); 523 return (mthd == null)? interfaceMethod : mthd; 524 } 525 526 533 public void appendMethodPermissions(Method m, String [] roleNames){ 534 HashSet hs = (HashSet )methodPermissions.get(m); 535 if(hs == null){ 536 hs = new HashSet ( ); methodPermissions.put(m,hs); 538 } 539 for(int i = 0; i < roleNames.length; i++){ 540 hs.add(roleNames[i]); 541 } 542 } 543 564 public String [] getPhysicalRole(String securityRoleReference){ 565 return (String [])securityRoleReferenceMap.get(securityRoleReference); 566 } 567 576 public void addSecurityRoleReference(String securityRoleReference, String [] physicalRoles){ 577 securityRoleReferenceMap.put(securityRoleReference, physicalRoles); 578 } 579 586 public EJBContext getEJBContext( ){ 587 if(componentType == STATEFUL) 588 return new org.openejb.core.stateful.StatefulContext(); 589 else if(componentType == STATELESS) 590 return new org.openejb.core.stateless.StatelessContext(); 591 else if(componentType == BMP_ENTITY || componentType == CMP_ENTITY ) 592 return new org.openejb.core.entity.EntityContext(); 593 else 594 return null; 595 596 } 597 598 608 public void setMethodTransactionAttribute(Method method, String transAttribute){ 609 Byte byteValue = null; 610 TransactionPolicy policy = null; 611 612 if(transAttribute.equals("Supports")){ 613 if (container instanceof TransactionContainer) { 614 policy = new TxSupports((TransactionContainer)container); 615 } 616 byteValue = new Byte (TX_SUPPORTS); 617 618 } else if(transAttribute.equals("RequiresNew")) { 619 if (container instanceof TransactionContainer) { 620 policy = new TxRequiresNew((TransactionContainer)container); 621 } 622 byteValue = new Byte (TX_REQUIRES_NEW); 623 624 } else if(transAttribute.equals("Mandatory")) { 625 if (container instanceof TransactionContainer) { 626 policy = new TxManditory((TransactionContainer)container); 627 } 628 byteValue = new Byte (TX_MANDITORY); 629 630 } else if(transAttribute.equals("NotSupported")) { 631 if (container instanceof TransactionContainer) { 632 policy = new TxNotSupported((TransactionContainer)container); 633 } 634 byteValue = new Byte (TX_NOT_SUPPORTED); 635 636 } else if(transAttribute.equals("Required")) { 637 if (container instanceof TransactionContainer) { 638 policy = new TxRequired((TransactionContainer)container); 639 } 640 byteValue = new Byte (TX_REQUIRED); 641 642 } else if(transAttribute.equals("Never")) { 643 if (container instanceof TransactionContainer) { 644 policy = new TxNever((TransactionContainer)container); 645 } 646 byteValue = new Byte (TX_NEVER); 647 } else{ 648 throw new IllegalArgumentException ("Invalid transaction attribute \""+transAttribute+"\" declared for method "+method.getName()+". Please check your configuration."); 649 } 650 651 656 if ( componentType == STATEFUL && !isBeanManagedTransaction && container instanceof TransactionContainer){ 661 662 if ( SessionSynchronization .class.isAssignableFrom(beanClass) ) { 664 if ( !transAttribute.equals("Never") && !transAttribute.equals("NotSupported") ){ 665 policy = new SessionSynchronizationTxPolicy( policy ); 667 } 668 } else { 669 policy = new StatefulContainerManagedTxPolicy( policy ); 671 } 672 673 } else if ( componentType == CMP_ENTITY ){ 674 policy = new CastorCmpEntityTxPolicy( policy ); 675 } 676 methodTransactionAttributes.put( method, byteValue ); 677 methodTransactionPolicies.put( method, policy ); 678 } 679 680 684 688 694 private javax.ejb.EJBHome createEJBHomeRef(){ 695 696 EjbHomeProxyHandler handler = null; 697 698 switch ( getComponentType() ) { 699 case STATEFUL: 700 handler = new StatefulEjbHomeHandler((RpcContainer)container, null, getDeploymentID()); 701 break; 702 703 case STATELESS: 704 handler = new StatelessEjbHomeHandler((RpcContainer)container, null, getDeploymentID()); 705 break; 706 case CMP_ENTITY: 707 case BMP_ENTITY: 708 handler = new EntityEjbHomeHandler((RpcContainer)container, null, getDeploymentID()); 709 break; 710 } 711 712 Object proxy = null; 713 try{ 714 Class [] interfaces = new Class []{ this.getHomeInterface(), org.openejb.core.ivm.IntraVmProxy.class }; 715 proxy = ProxyManager.newProxyInstance( interfaces , handler ); 716 }catch(Exception e){ 717 e.printStackTrace(); 718 throw new RuntimeException ("Can't create EJBHome stub" + e.getMessage()); 719 } 720 721 return (javax.ejb.EJBHome )proxy; 722 723 } 724 725 731 private javax.ejb.EJBLocalHome createEJBLocalHomeRef(){ 732 733 EjbHomeProxyHandler handler = null; 734 735 switch ( getComponentType() ) { 736 case STATEFUL: 737 handler = new StatefulEjbHomeHandler((RpcContainer)container, null, getDeploymentID()); 738 break; 739 740 case STATELESS: 741 handler = new StatelessEjbHomeHandler((RpcContainer)container, null, getDeploymentID()); 742 break; 743 case CMP_ENTITY: 744 case BMP_ENTITY: 745 handler = new EntityEjbHomeHandler((RpcContainer)container, null, getDeploymentID()); 746 break; 747 } 748 handler.setLocal(true); 749 Object proxy = null; 750 try{ 751 Class [] interfaces = new Class []{ this.getLocalHomeInterface(), org.openejb.core.ivm.IntraVmProxy.class }; 752 proxy = ProxyManager.newProxyInstance( interfaces , handler ); 753 }catch(Exception e){ 754 e.printStackTrace(); 755 throw new RuntimeException ("Can't create EJBLocalHome stub" + e.getMessage()); 756 } 757 758 return (javax.ejb.EJBLocalHome )proxy; 759 760 } 761 762 770 private void createMethodMap() throws org.openejb.SystemException{ 771 if (homeInterface != null){ 772 mapObjectInterface(remoteInterface, false); 773 mapHomeInterface(homeInterface); 774 } 775 if (localHomeInterface != null){ 776 mapObjectInterface(localInterface, true); 777 mapHomeInterface(localHomeInterface); 778 } 779 780 781 try{ 782 783 if(componentType == STATEFUL || componentType == STATELESS){ 784 Method beanMethod = javax.ejb.SessionBean .class.getDeclaredMethod("ejbRemove", new Class []{}); 785 Method clientMethod = EJBHome .class.getDeclaredMethod("remove", new Class [] {javax.ejb.Handle .class}); 786 methodMap.put(clientMethod, beanMethod); 787 clientMethod = EJBHome .class.getDeclaredMethod("remove", new Class [] {java.lang.Object .class}); 788 methodMap.put(clientMethod, beanMethod); 789 clientMethod = javax.ejb.EJBObject .class.getDeclaredMethod("remove", null); 790 methodMap.put(clientMethod, beanMethod); 791 }else if(componentType == BMP_ENTITY || componentType == CMP_ENTITY){ 792 Method beanMethod = javax.ejb.EntityBean .class.getDeclaredMethod("ejbRemove", new Class []{}); 793 Method clientMethod = EJBHome .class.getDeclaredMethod("remove", new Class [] {javax.ejb.Handle .class}); 794 methodMap.put(clientMethod, beanMethod); 795 clientMethod = EJBHome .class.getDeclaredMethod("remove", new Class [] {java.lang.Object .class}); 796 methodMap.put(clientMethod, beanMethod); 797 clientMethod = javax.ejb.EJBObject .class.getDeclaredMethod("remove", null); 798 methodMap.put(clientMethod, beanMethod); 799 } 800 }catch(java.lang.NoSuchMethodException nsme){ 801 throw new org.openejb.SystemException(nsme); 802 } 803 804 } 805 806 private void mapHomeInterface(Class intrface) { 807 Method [] homeMethods = intrface.getMethods(); 808 for(int i = 0; i < homeMethods.length; i++){ 809 Method method = homeMethods[i]; 810 Class owner = method.getDeclaringClass(); 811 if( owner == javax.ejb.EJBHome .class || owner == EJBLocalHome .class ) { 812 continue; 813 } 814 815 try{ 816 Method beanMethod = null; 817 if(method.getName().equals("create")){ 818 beanMethod = beanClass.getMethod("ejbCreate",method.getParameterTypes()); 819 createMethod = beanMethod; 820 824 if(this.componentType==BMP_ENTITY || this.componentType==CMP_ENTITY){ 825 Method postCreateMethod = beanClass.getMethod("ejbPostCreate",method.getParameterTypes()); 826 postCreateMethodMap.put(createMethod,postCreateMethod); 827 } 828 833 }else if(method.getName().startsWith("find")){ 834 if(this.componentType == BMP_ENTITY ){ 835 String beanMethodName = "ejbF"+method.getName().substring(1); 837 beanMethod = beanClass.getMethod(beanMethodName,method.getParameterTypes()); 838 } 839 }else { 840 String beanMethodName = "ejbHome"+method.getName().substring(0,1).toUpperCase()+method.getName().substring(1); 841 beanMethod = beanClass.getMethod(beanMethodName,method.getParameterTypes()); 842 } 843 if(beanMethod!=null){ 844 methodMap.put(homeMethods[i],beanMethod); 845 } 846 }catch(NoSuchMethodException nsme){ 847 throw new RuntimeException ("Invalid method ["+method+"] Not declared by "+beanClass.getName()+" class"); 848 } 849 } 850 } 851 852 853 private void mapObjectInterface(Class intrface, boolean isLocal) { 854 Method [] interfaceMethods = intrface.getMethods(); 855 for(int i = 0; i < interfaceMethods.length; i++){ 856 Method method = interfaceMethods[i]; 857 Class declaringClass = method.getDeclaringClass(); 858 if(declaringClass == javax.ejb.EJBObject .class || declaringClass == EJBLocalObject .class){ 859 continue; 860 } 861 try{ 862 Method beanMethod = beanClass.getMethod(method.getName(),method.getParameterTypes()); 863 methodMap.put(method,beanMethod); 864 }catch(NoSuchMethodException nsme){ 865 throw new RuntimeException ("Invalid method ["+ method +"]. Not declared by "+beanClass.getName()+" class"); 866 } 867 874 if(!isLocal && java.rmi.Remote .class.isAssignableFrom(method.getReturnType())) { 875 if( methodsWithRemoteReturnTypes == null ) { 876 methodsWithRemoteReturnTypes = new HashSet (); 877 } 878 methodsWithRemoteReturnTypes.add(method); 879 } 880 } 881 } 882 883 884 protected String extractHomeBeanMethodName(String methodName){ 885 if(methodName.equals("create")) 886 return "ejbCreate"; 887 else if(methodName.startsWith("find")) 888 return "ejbF"+methodName.substring(1); 889 else 890 return "ejbH"+methodName.substring(1); 891 } 892 897 public Method getCreateMethod( ){ 898 return createMethod; 899 } 900 906 public Method getMatchingPostCreateMethod(Method createMethod){ 907 return (Method )this.postCreateMethodMap.get(createMethod); 908 } 909 910 914 915 private KeyGenerator keyGenerator; 919 private Field primKeyField; 920 private String [] cmrFields; 921 922 923 930 private HashMap queryMethodMap = new HashMap (); 931 932 933 945 public Field getPrimaryKeyField( ){ 946 return primKeyField; 947 } 948 949 public void setPrimKeyField(String fieldName) 950 throws java.lang.NoSuchFieldException { 951 if(componentType == CMP_ENTITY){ 952 953 primKeyField = beanClass.getField(fieldName); 954 } 955 } 956 957 963 public String [] getCmrFields( ){ 964 return cmrFields; 965 } 966 967 public void setCmrFields(String [] cmrFields){ 968 this.cmrFields = cmrFields; 969 } 970 971 public KeyGenerator getKeyGenerator(){ 972 return keyGenerator; 973 } 974 975 public void setKeyGenerator(KeyGenerator keyGenerator){ 976 this.keyGenerator = keyGenerator; 977 } 978 979 992 public void addQuery(Method queryMethod, String queryString){ 993 queryMethodMap.put(queryMethod, queryString); 994 } 995 1008 public String getQuery(Method queryMethod){ 1009 return (String )queryMethodMap.get(queryMethod); 1010 } 1011 } 1015 | Popular Tags |