1 45 package org.openejb.alt.containers.castor_cmp11; 46 47 import java.io.File ; 48 import java.lang.reflect.Field ; 49 import java.lang.reflect.InvocationTargetException ; 50 import java.lang.reflect.Method ; 51 import java.rmi.RemoteException ; 52 import java.util.HashMap ; 53 import java.util.Hashtable ; 54 import java.util.Properties ; 55 56 import javax.ejb.EJBHome ; 57 import javax.ejb.EJBLocalHome ; 58 import javax.ejb.EJBLocalObject ; 59 import javax.ejb.EJBObject ; 60 import javax.ejb.EnterpriseBean ; 61 import javax.ejb.EntityBean ; 62 import javax.transaction.Status ; 63 import javax.transaction.Transaction ; 64 65 import org.exolab.castor.jdo.Database; 66 import org.exolab.castor.jdo.JDO; 67 import org.exolab.castor.jdo.OQLQuery; 68 import org.exolab.castor.jdo.QueryResults; 69 import org.exolab.castor.mapping.AccessMode; 70 import org.exolab.castor.persist.spi.CallbackInterceptor; 71 import org.exolab.castor.persist.spi.Complex; 72 import org.exolab.castor.persist.spi.InstanceFactory; 73 import org.openejb.Container; 74 import org.openejb.DeploymentInfo; 75 import org.openejb.OpenEJB; 76 import org.openejb.OpenEJBException; 77 import org.openejb.ProxyInfo; 78 import org.openejb.RpcContainer; 79 import org.openejb.core.EnvProps; 80 import org.openejb.core.Operations; 81 import org.openejb.core.ThreadContext; 82 import org.openejb.core.transaction.TransactionContainer; 83 import org.openejb.core.transaction.TransactionContext; 84 import org.openejb.core.transaction.TransactionPolicy; 85 import org.openejb.loader.SystemInstance; 86 import org.openejb.util.LinkedListStack; 87 import org.openejb.util.Logger; 88 import org.openejb.util.SafeProperties; 89 import org.openejb.util.SafeToolkit; 90 import org.openejb.util.Stack; 91 92 99 public class CastorCMP11_EntityContainer 100 implements RpcContainer, TransactionContainer, CallbackInterceptor, InstanceFactory { 101 102 103 116 protected Hashtable txReadyPoolMap = new Hashtable (); 117 118 protected Hashtable pooledInstancesMap = new Hashtable (); 120 protected Hashtable readyInstancesMap = new Hashtable (); 121 122 129 131 135 protected HashMap methodReadyPoolMap = new HashMap (); 136 137 138 protected int poolsize = 0; 139 140 146 protected static Method SET_ENTITY_CONTEXT_METHOD; 147 148 155 protected static Method UNSET_ENTITY_CONTEXT_METHOD; 156 157 163 protected static Method EJB_REMOVE_METHOD; 164 165 169 static { 170 try { 171 SET_ENTITY_CONTEXT_METHOD = javax.ejb.EntityBean .class.getMethod( "setEntityContext", new Class []{javax.ejb.EntityContext .class} ); 172 UNSET_ENTITY_CONTEXT_METHOD = javax.ejb.EntityBean .class.getMethod( "unsetEntityContext", null ); 173 EJB_REMOVE_METHOD = javax.ejb.EntityBean .class.getMethod( "ejbRemove", null ); 174 } catch ( NoSuchMethodException nse ) { 175 } 176 } 177 178 179 public Logger logger = Logger.getInstance( "OpenEJB", "org.openejb.alt.util.resources" ); 180 181 HashMap deploymentRegistry; 183 Object containerID = null; 185 186 193 protected String Global_TX_Database = null; 194 195 202 protected String Local_TX_Database = null; 203 204 208 protected JDO jdo_ForGlobalTransaction; 209 210 214 protected JDO jdo_ForLocalTransaction; 215 216 219 java.util.Hashtable syncWrappers = new java.util.Hashtable (); 221 222 protected HashMap resetMap; 224 225 private Properties props; 226 227 229 244 public void init( Object id, HashMap registry, Properties properties ) throws org.openejb.OpenEJBException { 245 containerID = id; 246 deploymentRegistry = registry; 247 248 this.props = properties; 249 250 SafeToolkit toolkit = SafeToolkit.getToolkit( "CastorCMP11_EntityContainer" ); 251 SafeProperties safeProps = toolkit.getSafeProperties( properties ); 252 253 poolsize = safeProps.getPropertyAsInt(EnvProps.IM_POOL_SIZE, 100 ); 254 Global_TX_Database = safeProps.getProperty(EnvProps.GLOBAL_TX_DATABASE); 255 Local_TX_Database = safeProps.getProperty(EnvProps.LOCAL_TX_DATABASE); 256 257 File gTxDb = null; 258 File lTxDb = null; 259 try { 260 gTxDb = SystemInstance.get().getBase().getFile( Global_TX_Database ); 261 } catch ( Exception e ) { 262 throw new OpenEJBException("Cannot locate the " + EnvProps.GLOBAL_TX_DATABASE + " file. " + e.getMessage()); 263 } 264 265 try { 266 lTxDb = SystemInstance.get().getBase().getFile( Local_TX_Database ); 267 } catch ( Exception e ) { 268 throw new OpenEJBException("Cannot locate the " + EnvProps.LOCAL_TX_DATABASE + " file. " + e.getMessage()); 269 } 270 271 if (!gTxDb.exists()) { 272 throw new OpenEJBException(id+": The "+EnvProps.GLOBAL_TX_DATABASE+" file does not exit: "+gTxDb.getAbsolutePath()); 273 } 274 if (!lTxDb.exists()) { 275 throw new OpenEJBException(id+": The "+EnvProps.LOCAL_TX_DATABASE+" file does not exit: "+lTxDb.getAbsolutePath()); 276 } 277 if (gTxDb.equals(lTxDb)) { 278 throw new OpenEJBException(id+": The "+EnvProps.LOCAL_TX_DATABASE+" and "+EnvProps.GLOBAL_TX_DATABASE+" files cannot be the same: "+lTxDb.getAbsolutePath()); 279 } 280 281 290 291 String transactionManagerJndiName = "java:openejb/TransactionManager"; 292 293 297 jdo_ForGlobalTransaction = new JDO(); 298 299 jdo_ForGlobalTransaction.setDatabasePooling( true ); 300 jdo_ForGlobalTransaction.setConfiguration( gTxDb.getAbsolutePath() ); 301 jdo_ForGlobalTransaction.setDatabaseName(EnvProps.GLOBAL_TX_DATABASE); 302 jdo_ForGlobalTransaction.setCallbackInterceptor( this ); 303 jdo_ForGlobalTransaction.setInstanceFactory( this ); 304 jdo_ForGlobalTransaction.setLogInterceptor( new CMPLogger(EnvProps.GLOBAL_TX_DATABASE) ); 305 306 jdo_ForLocalTransaction = new JDO(); 308 309 310 jdo_ForLocalTransaction.setConfiguration( lTxDb.getAbsolutePath() ); 311 jdo_ForLocalTransaction.setDatabaseName(EnvProps.LOCAL_TX_DATABASE); 312 jdo_ForLocalTransaction.setCallbackInterceptor( this ); 313 jdo_ForLocalTransaction.setInstanceFactory( this ); 314 jdo_ForLocalTransaction.setLogInterceptor( new CMPLogger(EnvProps.LOCAL_TX_DATABASE) ); 315 316 317 327 org.openejb.DeploymentInfo[] deploys = this.deployments(); 328 329 333 JndiTxReference txReference = new JndiTxReference(); 334 for ( int x = 0; x < deploys.length; x++ ) { 335 org.openejb.core.DeploymentInfo di = ( org.openejb.core.DeploymentInfo ) deploys[x]; 336 di.setContainer( this ); 337 338 methodReadyPoolMap.put( di.getDeploymentID(), new LinkedListStack( poolsize / 2 ) ); 340 KeyGenerator kg = null; 341 try { 342 kg = KeyGeneratorFactory.createKeyGenerator( di ); 343 di.setKeyGenerator( kg ); 344 } catch ( Exception e ) { 345 logger.error( "Unable to create KeyGenerator for deployment id = " + di.getDeploymentID(), e ); 346 throw new org.openejb.SystemException( "Unable to create KeyGenerator for deployment id = " + di.getDeploymentID(), e ); 347 } 348 349 try { 351 di.getJndiEnc().bind( transactionManagerJndiName, txReference ); 352 } catch ( Exception e ) { 353 logger.error( "Unable to bind TransactionManager to deployment id = " + di.getDeploymentID() + " using JNDI name = \"" + transactionManagerJndiName + "\"", e ); 354 throw new org.openejb.SystemException( "Unable to bind TransactionManager to deployment id = " + di.getDeploymentID() + " using JNDI name = \"" + transactionManagerJndiName + "\"", e ); 355 } 356 357 try { 358 363 StringBuffer findByPrimarKeyQuery = new StringBuffer ("SELECT e FROM " + di.getBeanClass().getName() + " e WHERE "); 364 365 if ( kg.isKeyComplex() ) { 366 367 Field [] pkFields = di.getPrimaryKeyClass().getFields(); 368 for ( int i = 1; i <= pkFields.length; i++ ) { 369 findByPrimarKeyQuery.append("e." + pkFields[i - 1].getName() + " = $" + i); 370 if ( ( i + 1 ) <= pkFields.length ) 371 findByPrimarKeyQuery.append(" AND "); 372 } 373 374 } else { 375 findByPrimarKeyQuery.append("e." + di.getPrimaryKeyField().getName() + " = $1"); 376 } 377 378 if (di.getHomeInterface() != null) { 379 Method findByPrimaryKeyMethod = di.getHomeInterface().getMethod( "findByPrimaryKey", new Class []{di.getPrimaryKeyClass()} ); 380 di.addQuery( findByPrimaryKeyMethod, findByPrimarKeyQuery.toString() ); 381 } 382 if (di.getLocalHomeInterface() != null) { 383 Method findByPrimaryKeyMethod = di.getLocalHomeInterface().getMethod( "findByPrimaryKey", new Class []{di.getPrimaryKeyClass()} ); 384 di.addQuery( findByPrimaryKeyMethod, findByPrimarKeyQuery.toString() ); 385 } 386 } catch ( Exception e ) { 387 throw new org.openejb.SystemException( "Could not generate a query statement for the findByPrimaryKey method of the deployment = " + di.getDeploymentID(), e ); 388 } 389 } 390 resetMap = new HashMap (); 391 resetMap.put( byte.class, new Byte ( ( byte ) 0 ) ); 392 resetMap.put( boolean.class, new Boolean ( false ) ); 393 resetMap.put( char.class, new Character ( ( char ) 0 ) ); 394 resetMap.put( short.class, new Short ( ( short ) 0 ) ); 395 resetMap.put( int.class, new Integer ( 0 ) ); 396 resetMap.put( long.class, new Long ( 0 ) ); 397 resetMap.put( float.class, new Float ( 0 ) ); 398 resetMap.put( double.class, new Double ( 0.0 ) ); 399 } 400 401 boolean initialized; 402 403 415 protected void postInit() { 416 if (initialized) return; 417 418 Properties systemProperties = System.getProperties(); 419 synchronized(systemProperties) { 420 String userDir = systemProperties.getProperty("user.dir"); 421 try{ 422 File base = SystemInstance.get().getBase().getDirectory(); 423 systemProperties.setProperty("user.dir", base.getAbsolutePath()); 424 ClassLoader classLoader = deployments()[0].getBeanClass().getClassLoader(); 425 jdo_ForLocalTransaction.setClassLoader(classLoader); 426 jdo_ForLocalTransaction.getDatabase(); 427 jdo_ForGlobalTransaction.setClassLoader(classLoader); 428 jdo_ForGlobalTransaction.getDatabase(); 429 } catch (Throwable e){ 430 logger.fatal("Castor JDO initialization failed: "+e.getMessage(), e); 431 throw (IllegalStateException ) new IllegalStateException ("Castor JDO initialization failed").initCause(e); 432 } finally { 433 systemProperties.setProperty("user.dir",userDir); 434 } 435 initialized = true; 436 } 437 } 438 442 450 public DeploymentInfo[] deployments() { 451 return( DeploymentInfo[] ) deploymentRegistry.values().toArray( new DeploymentInfo[deploymentRegistry.size()] ); 452 } 453 454 464 public DeploymentInfo getDeploymentInfo( Object deploymentID ) { 465 return( DeploymentInfo ) deploymentRegistry.get( deploymentID ); 466 } 467 468 473 public int getContainerType() { 474 return Container.ENTITY; 475 } 476 477 483 public Object getContainerID() { 484 return containerID; 485 } 486 487 495 public void deploy( Object deploymentID, DeploymentInfo info ) throws OpenEJBException { 496 HashMap registry = ( HashMap ) deploymentRegistry.clone(); 497 registry.put( deploymentID, info ); 498 deploymentRegistry = registry; 499 } 500 501 514 public Object invoke( Object deployID, Method callMethod, Object [] args, Object primKey, Object securityIdentity ) 515 throws org.openejb.OpenEJBException { 516 postInit(); 517 try { 518 org.openejb.core.DeploymentInfo deployInfo = ( org.openejb.core.DeploymentInfo ) this.getDeploymentInfo( deployID ); 519 520 ThreadContext callContext = ThreadContext.getThreadContext(); 521 callContext.set( deployInfo, primKey, securityIdentity ); 522 523 525 boolean authorized = OpenEJB.getSecurityService().isCallerAuthorized( securityIdentity, deployInfo.getAuthorizedRoles( callMethod ) ); 526 if ( !authorized ) 527 throw new org.openejb.ApplicationException( new RemoteException ( "Unauthorized Access by Principal Denied" ) ); 528 529 Class declaringClass = callMethod.getDeclaringClass(); 531 String methodName = callMethod.getName(); 532 533 if (EJBHome .class.isAssignableFrom(declaringClass) || EJBLocalHome .class.isAssignableFrom(declaringClass) ){ 534 if ( declaringClass != EJBHome .class && declaringClass != EJBLocalHome .class) { 535 if ( methodName.equals( "create" ) ) { 538 return createEJBObject( callMethod, args, callContext ); 540 } else if ( methodName.startsWith( "find" ) ) { 541 return findEJBObject( callMethod, args, callContext ); 543 } else { 544 throw new org.openejb.InvalidateReferenceException( new java.rmi.RemoteException ( "Invalid method " + methodName + " only find<METHOD>( ) and create( ) method are allowed in EJB 1.1 container-managed persistence" ) ); 546 } 547 } else if ( methodName.equals( "remove" ) ) { 548 removeEJBObject( callMethod, args, callContext ); 549 return null; 550 } 551 } else if((EJBObject .class == declaringClass || EJBLocalObject .class == declaringClass) && methodName.equals("remove") ) { 552 removeEJBObject( callMethod, args, callContext ); 553 return null; 554 } 555 556 557 558 callContext.setCurrentOperation( Operations.OP_BUSINESS ); 560 Method runMethod = deployInfo.getMatchingBeanMethod( callMethod ); 561 562 Object retValue = businessMethod( callMethod, runMethod, args, callContext ); 563 564 return deployInfo.convertIfLocalReference( callMethod, retValue ); 566 567 568 } finally { 569 581 ThreadContext.setThreadContext( null ); 582 } 583 } 584 588 589 593 599 public void discardInstance( EnterpriseBean bean, ThreadContext threadContext ) { 600 if ( bean != null ) txReadyPoolMap.remove( bean ); 601 } 602 603 618 public EntityBean fetchFreeInstance( ThreadContext callContext ) throws IllegalAccessException , InvocationTargetException , InstantiationException { 619 620 org.openejb.core.DeploymentInfo deploymentInfo = callContext.getDeploymentInfo(); 621 622 625 Stack methodReadyPool = ( Stack ) methodReadyPoolMap.get( deploymentInfo.getDeploymentID() ); 626 627 if ( methodReadyPool == null ) { 628 throw new java.lang.RuntimeException ( "Invalid deployment id " + deploymentInfo.getDeploymentID() + " for this container" ); 630 } 631 632 635 EntityBean bean = ( EntityBean ) methodReadyPool.pop(); 638 639 if ( bean == null ) { 640 byte currentOperation = callContext.getCurrentOperation(); 641 try { 642 bean = ( EntityBean ) deploymentInfo.getBeanClass().newInstance(); 643 648 callContext.setCurrentOperation( Operations.OP_SET_CONTEXT ); 649 Object [] params = new javax.ejb.EntityContext []{( javax.ejb.EntityContext ) deploymentInfo.getEJBContext()}; 650 SET_ENTITY_CONTEXT_METHOD.invoke( bean, params ); 652 } finally { 653 callContext.setCurrentOperation( currentOperation ); 654 } 655 } else { 656 resetBeanFields( bean, deploymentInfo ); 658 } 659 txReadyPoolMap.put( bean, methodReadyPool ); 661 return bean; 662 } 663 664 665 675 protected Object businessMethod( Method callMethod, Method runMethod, Object [] args, ThreadContext callContext ) 676 throws org.openejb.OpenEJBException { 677 678 EntityBean bean = null; 679 680 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 681 TransactionContext txContext = new TransactionContext( callContext ); 682 683 txPolicy.beforeInvoke( bean, txContext ); 684 685 Object returnValue = null; 686 try { 687 688 Database db = getDatabase( callContext ); 689 690 bean = fetchAndLoadBean( callContext, db ); 691 if ( OpenEJB.getTransactionManager().getTransaction() != null ) { 693 try { 694 Key key = new Key( OpenEJB.getTransactionManager().getTransaction(), 695 callContext.getDeploymentInfo().getDeploymentID(), 696 callContext.getPrimaryKey() ); 697 SynchronizationWrapper sync = new SynchronizationWrapper( ( ( javax.ejb.EntityBean ) bean ), key ); 698 699 OpenEJB.getTransactionManager().getTransaction().registerSynchronization( sync ); 700 701 syncWrappers.put( key, sync ); 702 } catch ( Exception ex ) { 703 ex.printStackTrace(); 704 } 705 } 706 707 returnValue = runMethod.invoke( bean, args ); 708 709 } catch ( java.lang.reflect.InvocationTargetException ite ) { 710 if ( ite.getTargetException() instanceof RuntimeException ) { 712 713 txPolicy.handleSystemException( ite.getTargetException(), bean, txContext ); 714 715 } else { 716 717 txPolicy.handleApplicationException( ite.getTargetException(), txContext ); 718 } 719 } catch ( org.exolab.castor.jdo.DuplicateIdentityException e ) { 720 721 Exception re = new javax.ejb.DuplicateKeyException ( "Attempt to update an entity bean (DeploymentID=\"" + callContext.getDeploymentInfo().getDeploymentID() + "\") with an primary key that already exsists. Castor nested exception message = " + e.getMessage() ); 723 txPolicy.handleSystemException( re, bean, txContext ); 724 725 } catch ( org.exolab.castor.jdo.ClassNotPersistenceCapableException e ) { 726 727 RemoteException re = new RemoteException ( "Attempt to update an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") that can not be persisted.", e ); 729 txPolicy.handleSystemException( re, bean, txContext ); 730 731 } catch ( org.exolab.castor.jdo.TransactionAbortedException e ) { 732 733 RemoteException re = new RemoteException ( "Attempt to update an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") failed because transaction was aborted.", e ); 735 txPolicy.handleSystemException( re, bean, txContext ); 736 737 } catch ( org.exolab.castor.jdo.TransactionNotInProgressException e ) { 738 739 RemoteException re = new RemoteException ( "Attempt to update an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") failed because a transaction didn't exist.", e ); 741 txPolicy.handleSystemException( re, bean, txContext ); 742 743 } catch ( org.exolab.castor.jdo.DatabaseNotFoundException e ) { 744 745 txPolicy.handleSystemException( e, bean, txContext ); 746 747 } catch ( org.exolab.castor.jdo.PersistenceException e ) { 748 749 txPolicy.handleSystemException( e, bean, txContext ); 750 751 } catch ( Throwable e ) { 761 762 txPolicy.handleSystemException( e, bean, txContext ); 763 764 } finally { 765 txPolicy.afterInvoke( bean, txContext ); 766 } 767 768 return returnValue; 769 770 771 } 772 773 786 protected ProxyInfo createEJBObject( Method callMethod, Object [] args, ThreadContext callContext ) 787 throws org.openejb.OpenEJBException { 788 org.openejb.core.DeploymentInfo deploymentInfo = callContext.getDeploymentInfo(); 789 790 EntityBean bean = null; 791 Object primaryKey = null; 792 793 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 794 TransactionContext txContext = new TransactionContext( callContext ); 795 796 txPolicy.beforeInvoke( bean, txContext ); 797 798 799 try { 800 801 804 bean = fetchFreeInstance( callContext ); 805 806 809 Method ejbCreateMethod = deploymentInfo.getMatchingBeanMethod( callMethod ); 810 811 814 callContext.setCurrentOperation( Operations.OP_CREATE ); 815 816 819 ejbCreateMethod.invoke( bean, args ); 820 821 int txStatus = OpenEJB.getTransactionManager().getStatus(); 822 if ( txStatus == Status.STATUS_ACTIVE || txStatus == Status.STATUS_NO_TRANSACTION ) { 823 824 827 Database db = getDatabase( callContext ); 828 829 832 if ( !db.isActive() ) db.begin(); 833 834 837 db.create( bean ); 838 839 } 840 841 848 KeyGenerator kg = deploymentInfo.getKeyGenerator(); 849 850 854 primaryKey = kg.getPrimaryKey( bean ); 855 856 860 callContext.setPrimaryKey( primaryKey ); 861 862 865 callContext.setCurrentOperation( Operations.OP_POST_CREATE ); 866 867 870 Method ejbPostCreateMethod = deploymentInfo.getMatchingPostCreateMethod( ejbCreateMethod ); 871 872 875 ejbPostCreateMethod.invoke( bean, args ); 876 877 885 888 891 callContext.setPrimaryKey( null ); 892 893 } catch ( java.lang.reflect.InvocationTargetException ite ) { if ( ite.getTargetException() instanceof RuntimeException ) { 895 896 txPolicy.handleSystemException( ite.getTargetException(), bean, txContext ); 897 } else { 898 899 txPolicy.handleApplicationException( ite.getTargetException(), txContext ); 900 } 901 } catch ( org.exolab.castor.jdo.DuplicateIdentityException e ) { 902 903 Exception re = new javax.ejb.DuplicateKeyException ( "Attempt to create an entity bean (DeploymentID=\"" + callContext.getDeploymentInfo().getDeploymentID() + "\") with an primary key that already exsists. Castor nested exception message = " + e.getMessage() ); 904 txPolicy.handleSystemException( re, bean, txContext ); 905 906 } catch ( org.exolab.castor.jdo.ClassNotPersistenceCapableException e ) { 907 908 RemoteException re = new RemoteException ( "Attempt to create an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") that can not be persisted.", e ); 909 txPolicy.handleSystemException( re, bean, txContext ); 910 911 } catch ( org.exolab.castor.jdo.TransactionAbortedException e ) { 912 913 RemoteException re = new RemoteException ( "Attempt to create an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") failed because transaction was aborted.", e ); 915 txPolicy.handleSystemException( re, bean, txContext ); 916 917 } catch ( org.exolab.castor.jdo.TransactionNotInProgressException e ) { 918 919 RemoteException re = new RemoteException ( "Attempt to create an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") failed because a transaction didn't exist.", e ); 920 txPolicy.handleSystemException( re, bean, txContext ); 921 922 } catch ( org.exolab.castor.jdo.DatabaseNotFoundException e ) { 923 924 txPolicy.handleSystemException( e, bean, txContext ); 925 926 } catch ( org.exolab.castor.jdo.PersistenceException e ) { 927 928 txPolicy.handleSystemException( e, bean, txContext ); 929 930 } catch ( Throwable e ) { 940 941 txPolicy.handleSystemException( e, bean, txContext ); 942 } finally { 943 txPolicy.afterInvoke( bean, txContext ); 944 } 945 Class callingClass = callMethod.getDeclaringClass(); 946 boolean isLocalInterface = EJBLocalHome .class.isAssignableFrom(callingClass); 947 948 return new ProxyInfo( deploymentInfo, primaryKey, isLocalInterface, this ); 949 } 950 951 protected static final Object [] noArgs = new Object [0]; 952 953 967 protected Object findEJBObject( Method callMethod, Object [] args, ThreadContext callContext ) throws org.openejb.OpenEJBException { 968 969 org.openejb.core.DeploymentInfo deploymentInfo = callContext.getDeploymentInfo(); 970 971 QueryResults results = null; 972 Object returnValue = null; 973 EntityBean bean = null; 974 975 976 String queryString = deploymentInfo.getQuery( callMethod ); 977 978 979 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 980 TransactionContext txContext = new TransactionContext( callContext ); 981 982 txPolicy.beforeInvoke( bean, txContext ); 983 984 985 try { 986 987 990 Database db = getDatabase( callContext ); 991 992 995 if ( !db.isActive() ) db.begin(); 996 997 1000 OQLQuery query = db.getOQLQuery( queryString ); 1001 1002 1003 if ( callMethod.getName().equals( "findByPrimaryKey" ) ) { 1004 KeyGenerator kg = deploymentInfo.getKeyGenerator(); 1006 1007 if ( kg.isKeyComplex() ) { 1008 1012 org.exolab.castor.persist.spi.Complex c = kg.getJdoComplex( args[0] ); 1013 args = new Object [c.size()]; 1014 for ( int i = 0; i < args.length; i++ ) 1015 args[i] = c.get( i ); 1016 } 1017 } 1018 1019 1020 if ( args == null ) args = noArgs; 1021 1022 for ( int i = 0; i < args.length; i++ ) { 1023 if ( args[i] instanceof javax.ejb.EJBObject ) { 1024 1038 try { 1039 args[i] = ( ( javax.ejb.EJBObject ) args[i] ).getPrimaryKey(); 1040 } catch ( java.rmi.RemoteException re ) { 1041 throw new javax.ejb.FinderException ( "Could not extract primary key from EJBObject reference; argument number " + i ); 1043 } 1044 } 1045 1046 1060 1061 query.bind( args[i] ); 1062 } 1063 1064 1065 1066 results = query.execute(); 1067 1068 1073 KeyGenerator kg = deploymentInfo.getKeyGenerator(); 1074 1075 Object primaryKey = null; 1076 Class callingClass = callMethod.getDeclaringClass(); 1077 boolean isLocalInterface = EJBLocalHome .class.isAssignableFrom(callingClass); 1078 1079 1085 if ( callMethod.getReturnType() == java.util.Collection .class || callMethod.getReturnType() == java.util.Enumeration .class ) { 1086 java.util.Vector proxies = new java.util.Vector (); 1087 while ( results.hasMore() ) { 1088 1089 bean = ( EntityBean ) results.next(); 1090 1091 1095 primaryKey = kg.getPrimaryKey( bean ); 1096 1097 proxies.addElement( new ProxyInfo( deploymentInfo, primaryKey, isLocalInterface, this ) ); 1098 } 1099 if ( callMethod.getReturnType() == java.util.Enumeration .class ) 1100 returnValue = new org.openejb.util.Enumerator( proxies ); 1101 else 1102 returnValue = proxies; 1103 } else { 1104 1105 if ( !results.hasMore() ) 1106 throw new javax.ejb.ObjectNotFoundException ( "A Enteprise bean with deployment_id = " + deploymentInfo.getDeploymentID() + " and primarykey = " + args[0] + " Does not exist" ); 1107 1108 bean = ( EntityBean ) results.next(); 1109 1113 primaryKey = kg.getPrimaryKey( bean ); 1114 1115 returnValue = new ProxyInfo( deploymentInfo, primaryKey, isLocalInterface, this ); 1116 } 1117 1118 } catch ( javax.ejb.FinderException fe ) { 1119 1120 txPolicy.handleApplicationException( fe, txContext ); 1121 1122 } catch ( org.exolab.castor.jdo.QueryException qe ) { 1123 1124 javax.ejb.FinderException fe = new javax.ejb.FinderException ( "Castor JDO could not execute query for this finder method. QueryException: " + qe.getMessage() ); 1125 txPolicy.handleApplicationException( fe, txContext ); 1127 1128 } catch ( org.exolab.castor.jdo.TransactionNotInProgressException e ) { 1129 1130 RemoteException re = new RemoteException ( "Attempt to create an entity bean (DeploymentID=\"" + callContext.getDeploymentInfo().getDeploymentID() + "\") failed because a transaction didn't exist.", e ); 1132 txPolicy.handleSystemException( re, bean, txContext ); 1133 1134 } catch ( org.exolab.castor.jdo.DatabaseNotFoundException e ) { 1135 1136 txPolicy.handleSystemException( e, bean, txContext ); 1137 1138 } catch ( org.exolab.castor.jdo.PersistenceException e ) { 1139 1140 txPolicy.handleSystemException( e, bean, txContext ); 1141 1142 } catch ( Throwable e ) { 1152 1153 txPolicy.handleSystemException( e, bean, txContext ); 1154 } finally { 1155 if ( results != null ) results.close(); 1156 txPolicy.afterInvoke( bean, txContext ); 1157 } 1158 return returnValue; 1159 } 1160 1161 1162 1170 protected void removeEJBObject( Method callMethod, Object [] args, ThreadContext callContext ) 1171 throws org.openejb.OpenEJBException { 1172 EntityBean bean = null; 1173 TransactionContext txContext = new TransactionContext( callContext ); 1174 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 1175 1176 txPolicy.beforeInvoke( bean, txContext ); 1177 1178 try { 1179 int status = OpenEJB.getTransactionManager().getStatus(); 1180 if ( status == Status.STATUS_ACTIVE || status == Status.STATUS_NO_TRANSACTION ) { 1182 1183 1186 Database db = getDatabase( callContext ); 1187 1188 1191 if ( !db.isActive() ) db.begin(); 1192 1193 bean = fetchAndLoadBean( callContext, db ); 1194 1195 callContext.setCurrentOperation( Operations.OP_REMOVE ); 1196 EJB_REMOVE_METHOD.invoke( bean, null ); 1197 1198 db.remove( bean ); 1199 } 1200 } catch ( java.lang.reflect.InvocationTargetException ite ) { 1201 if ( ite.getTargetException() instanceof RuntimeException ) { 1203 1204 txPolicy.handleSystemException( ite.getTargetException(), bean, txContext ); 1205 } else { 1206 1207 txPolicy.handleApplicationException( ite.getTargetException(), txContext ); 1208 } 1209 } catch ( org.exolab.castor.jdo.DuplicateIdentityException e ) { 1210 1211 Exception re = new javax.ejb.DuplicateKeyException ( "Attempt to remove an entity bean (DeploymentID=\"" + callContext.getDeploymentInfo().getDeploymentID() + "\") with an primary key that already exsists. Castor nested exception message = " + e.getMessage() ); 1213 txPolicy.handleSystemException( re, bean, txContext ); 1214 1215 } catch ( org.exolab.castor.jdo.ClassNotPersistenceCapableException e ) { 1216 1217 RemoteException re = new RemoteException ( "Attempt to remove an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") that can not be persisted.", e ); 1219 txPolicy.handleSystemException( re, bean, txContext ); 1220 1221 } catch ( org.exolab.castor.jdo.TransactionAbortedException e ) { 1222 1223 RemoteException re = new RemoteException ( "Attempt to remove an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") failed because transaction was aborted.", e ); 1226 txPolicy.handleSystemException( re, bean, txContext ); 1227 1228 } catch ( org.exolab.castor.jdo.TransactionNotInProgressException e ) { 1229 1230 RemoteException re = new RemoteException ( "Attempt to remove an entity bean (DeploymentID=\"" + txContext.callContext.getDeploymentInfo().getDeploymentID() + "\") failed because a transaction didn't exist.", e ); 1232 txPolicy.handleSystemException( re, bean, txContext ); 1233 1234 } catch ( org.exolab.castor.jdo.DatabaseNotFoundException e ) { 1235 1236 txPolicy.handleSystemException( e, bean, txContext ); 1237 1238 } catch ( org.exolab.castor.jdo.PersistenceException e ) { 1239 1240 txPolicy.handleSystemException( e, bean, txContext ); 1241 1242 } catch ( Throwable e ) { 1266 1267 txPolicy.handleSystemException( e, bean, txContext ); 1268 } finally { 1269 txPolicy.afterInvoke( bean, txContext ); 1270 } 1271 } 1272 1273 1294 protected EntityBean fetchAndLoadBean( ThreadContext callContext, Database db ) 1295 throws org.exolab.castor.jdo.PersistenceException, org.exolab.castor.jdo.ObjectNotFoundException, 1296 org.exolab.castor.jdo.TransactionNotInProgressException, org.exolab.castor.jdo.LockNotGrantedException, 1297 java.lang.InstantiationException , java.lang.reflect.InvocationTargetException , 1298 java.lang.IllegalAccessException { 1299 1308 KeyGenerator kg = callContext.getDeploymentInfo().getKeyGenerator(); 1309 1310 1315 EntityBean bean = null; 1316 1317 1322 if ( kg.isKeyComplex() ) { 1323 Complex complexIdentity = kg.getJdoComplex( callContext.getPrimaryKey() ); 1324 1332 bean = ( EntityBean ) db.load( callContext.getDeploymentInfo().getBeanClass(), 1333 complexIdentity ); 1335 1336 } else { 1337 bean = ( EntityBean ) db.load( callContext.getDeploymentInfo().getBeanClass(), 1338 callContext.getPrimaryKey() ); 1340 } 1341 1342 return bean; 1343 } 1344 1345 1363 protected Database getDatabase( ThreadContext callContext ) 1364 throws org.exolab.castor.jdo.DatabaseNotFoundException, 1365 org.exolab.castor.jdo.PersistenceException, 1366 javax.transaction.SystemException { 1367 1379 Database db = ( Database ) callContext.getUnspecified(); 1380 1381 if ( db != null ) { 1382 return db; 1383 } else { 1384 1403 return jdo_ForGlobalTransaction.getDatabase(); 1404 } 1405 } 1406 1407 1413 protected void resetBeanFields( java.lang.Object bean, org.openejb.core.DeploymentInfo info ) { 1414 final String [] cmFields = info.getCmrFields(); 1415 final Class beanClass = bean.getClass(); 1416 1417 try { 1418 for ( int i = 0; i < cmFields.length; i++ ) { 1419 Field field = beanClass.getDeclaredField( cmFields[i] ); 1420 Object value = resetMap.get( field.getType() ); 1421 field.set( bean, value ); 1423 } 1424 } catch ( Exception e ) { 1425 logger.error( "Internal inconsistency accessing the fields of a CMP entity bean" + bean + ":" + e ); 1428 } 1429 } 1430 1431 1436 1437 1447 public Object newInstance( String className, ClassLoader loader ) { 1448 1449 Object obj = null; 1450 1451 try { 1452 obj = fetchFreeInstance( ThreadContext.getThreadContext() ); 1453 } catch ( IllegalAccessException iae ) { 1454 throw new RuntimeException ( iae.getLocalizedMessage() ); 1455 } catch ( InvocationTargetException ite ) { 1456 throw new RuntimeException ( ite.getLocalizedMessage() ); 1457 } catch ( InstantiationException ie ) { 1458 throw new RuntimeException ( ie.getLocalizedMessage() ); 1459 } 1460 1461 return obj; 1462 } 1463 1464 1472 public Class loaded( Object object, short accessMode ) { 1473 return null; 1474 } 1475 1476 1477 1484 public void storing( Object object, boolean modified ) { 1485 } 1486 1487 1494 public void creating( Object object, Database db ) { 1495 } 1496 1497 1498 1503 public void created( Object object ) { 1504 } 1505 1506 1507 1515 public void removing( Object object ) { 1516 } 1517 1518 1519 1526 public void removed( Object object ) { 1527 } 1528 1529 1530 1540 public void releasing( Object object, boolean committed ) { 1541 1550 1551 LinkedListStack stack = ( LinkedListStack ) txReadyPoolMap.remove( object ); 1552 if ( stack != null ) stack.push( object ); 1553 } 1554 1555 1556 1562 public void using( Object object, Database db ) { 1563 } 1564 1565 1566 1572 public void updated( Object object ) { 1573 } 1574 1575 public static class Key { 1576 Object deploymentID, primaryKey; 1577 Transaction transaction; 1578 1579 public Key( Transaction tx, Object depID, Object prKey ) { 1580 transaction = tx; 1581 deploymentID = depID; 1582 primaryKey = prKey; 1583 } 1584 1585 public int hashCode() { 1586 return transaction.hashCode() ^ deploymentID.hashCode() ^ primaryKey.hashCode(); 1587 } 1588 1589 public boolean equals( Object other ) { 1590 if ( other != null && other.getClass() == CastorCMP11_EntityContainer.Key.class ) { 1591 Key otherKey = ( Key ) other; 1592 if ( otherKey.transaction.equals( transaction ) && otherKey.deploymentID.equals( deploymentID ) && otherKey.primaryKey.equals( 1593 primaryKey ) ) 1594 return true; 1595 } 1596 return false; 1597 } 1598 } 1599 1600 public class SynchronizationWrapper 1601 implements javax.transaction.Synchronization { 1602 EntityBean bean; 1603 Key myIndex; 1604 1605 public SynchronizationWrapper( EntityBean ebean, Key key ) { 1606 bean = ebean; 1607 myIndex = key; 1608 } 1609 1610 public void beforeCompletion() { 1611 try { 1612 bean.ejbStore(); 1613 } catch ( Exception re ) { 1614 javax.transaction.TransactionManager txmgr = OpenEJB.getTransactionManager(); 1615 try { 1616 txmgr.setRollbackOnly(); 1617 } catch ( javax.transaction.SystemException se ) { 1618 } 1620 1621 } 1622 } 1623 1624 public void afterCompletion( int status ) { 1625 syncWrappers.remove( myIndex ); 1626 } 1627 1628 } 1629 1630 1634 public Class loaded(Object loaded, AccessMode mode) throws Exception { 1635 return loaded(loaded, mode.getId()); 1636 } 1637 1638} | Popular Tags |