1 45 package org.openejb.core.entity; 46 47 import java.lang.reflect.Method ; 48 import java.rmi.RemoteException ; 49 import java.util.HashMap ; 50 import java.util.Properties ; 51 52 import javax.ejb.EJBHome ; 53 import javax.ejb.EJBLocalHome ; 54 import javax.ejb.EJBLocalObject ; 55 import javax.ejb.EJBObject ; 56 import javax.ejb.EnterpriseBean ; 57 import javax.ejb.EntityBean ; 58 import javax.transaction.Transaction ; 59 60 import org.openejb.Container; 61 import org.openejb.DeploymentInfo; 62 import org.openejb.OpenEJB; 63 import org.openejb.OpenEJBException; 64 import org.openejb.ProxyInfo; 65 import org.openejb.SystemException; 66 import org.openejb.core.EnvProps; 67 import org.openejb.core.Operations; 68 import org.openejb.core.ThreadContext; 69 import org.openejb.core.transaction.TransactionContainer; 70 import org.openejb.core.transaction.TransactionContext; 71 import org.openejb.core.transaction.TransactionPolicy; 72 import org.openejb.util.Logger; 73 import org.openejb.util.SafeProperties; 74 import org.openejb.util.SafeToolkit; 75 76 83 public class EntityContainer implements org.openejb.RpcContainer, TransactionContainer{ 84 85 88 protected EntityInstanceManager instanceManager; 89 90 93 protected HashMap deploymentRegistry; 94 95 98 protected Object containerID = null; 99 100 public Logger logger = Logger.getInstance( "OpenEJB", "org.openejb.util.resources" ); 103 104 105 120 public void init(Object id, HashMap registry, Properties properties) 121 throws org.openejb.OpenEJBException{ 122 containerID = id; 123 deploymentRegistry = registry; 124 125 if(properties == null)properties = new Properties (); 126 127 128 SafeToolkit toolkit = SafeToolkit.getToolkit("EntityContainer"); 129 SafeProperties safeProps = toolkit.getSafeProperties(properties); 130 try{ 131 String className = safeProps.getProperty(EnvProps.IM_CLASS_NAME, "org.openejb.core.entity.EntityInstanceManager"); 132 ClassLoader cl = OpenEJB.getContextClassLoader(); 133 instanceManager =(EntityInstanceManager)Class.forName(className, true, cl).newInstance(); 134 }catch(Exception e){ 135 throw new org.openejb.SystemException("Initialization of InstanceManager for the \""+containerID+"\" entity container failed",e); 136 } 137 instanceManager.init(this, registry, properties); 138 139 140 142 148 org.openejb.DeploymentInfo [] deploys = this.deployments(); 149 for(int x = 0; x < deploys.length; x++){ 150 org.openejb.core.DeploymentInfo di = (org.openejb.core.DeploymentInfo)deploys[x]; 151 di.setContainer(this); 152 } 153 154 } 155 159 166 public DeploymentInfo [] deployments(){ 167 return (DeploymentInfo [])deploymentRegistry.values().toArray(new DeploymentInfo[deploymentRegistry.size()]); 168 } 169 170 179 public DeploymentInfo getDeploymentInfo(Object deploymentID){ 180 return (DeploymentInfo)deploymentRegistry.get(deploymentID); 181 } 182 187 public int getContainerType( ){ 188 return Container.ENTITY; 189 } 190 191 196 public Object getContainerID(){ 197 return containerID; 198 } 199 200 208 public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException { 209 HashMap registry = (HashMap )deploymentRegistry.clone(); 210 registry.put(deploymentID, info); 211 deploymentRegistry = registry; 212 } 213 214 226 public Object invoke(Object deployID, Method callMethod,Object [] args,Object primKey, Object securityIdentity) throws org.openejb.OpenEJBException{ 227 try{ 228 229 org.openejb.core.DeploymentInfo deployInfo = (org.openejb.core.DeploymentInfo)this.getDeploymentInfo(deployID); 230 231 ThreadContext callContext = ThreadContext.getThreadContext(); 232 callContext.set(deployInfo, primKey, securityIdentity); 233 234 236 boolean authorized = OpenEJB.getSecurityService().isCallerAuthorized(securityIdentity, deployInfo.getAuthorizedRoles(callMethod)); 237 if(!authorized) 238 throw new org.openejb.ApplicationException(new RemoteException ("Unauthorized Access by Principal Denied")); 239 240 Class declaringClass = callMethod.getDeclaringClass(); 241 String methodName = callMethod.getName(); 242 243 if(EJBHome .class.isAssignableFrom(declaringClass) || EJBLocalHome .class.isAssignableFrom(declaringClass) ){ 245 if(declaringClass != EJBHome .class && declaringClass != EJBLocalHome .class){ 246 if(methodName.equals("create")){ 249 return createEJBObject(callMethod, args, callContext); 251 }else if(methodName.startsWith("find")){ 252 return findMethod(callMethod, args, callContext); 254 }else{ 255 return homeMethod(callMethod, args, callContext); 257 } 258 }else if(methodName.equals("remove")){ 259 removeEJBObject(callMethod, args, callContext); 260 return null; 261 } 262 } else if((EJBObject .class == declaringClass || EJBLocalObject .class == declaringClass) && methodName.equals("remove") ) { 263 removeEJBObject(callMethod, args, callContext); 264 return null; 265 } 266 267 268 callContext.setCurrentOperation(Operations.OP_BUSINESS); 270 Method runMethod = deployInfo.getMatchingBeanMethod(callMethod); 271 Object retValue = invoke(callMethod, runMethod, args, callContext) ; 272 273 return deployInfo.convertIfLocalReference(callMethod, retValue); 275 276 277 }finally{ 278 290 ThreadContext.setThreadContext(null); 291 } 292 } 293 297 298 302 public EntityInstanceManager getInstanceManager( ){ 303 return instanceManager; 304 } 305 306 protected Object invoke(Method callMethod, Method runMethod, Object [] args, ThreadContext callContext) 307 throws org.openejb.OpenEJBException{ 308 309 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 310 TransactionContext txContext = new TransactionContext(); 311 txContext.callContext = callContext; 312 313 EntityBean bean = null; 314 txPolicy.beforeInvoke( bean, txContext ); 315 316 Object returnValue = null; 317 318 try{ 319 try{ 321 bean = instanceManager.obtainInstance(callContext); 322 }catch(org.openejb.OpenEJBException e){ 323 throw e.getRootCause(); 325 } 326 327 ejbLoad_If_No_Transaction(callContext,bean); 328 returnValue = runMethod.invoke(bean, args); 329 ejbStore_If_No_Transaction(callContext, bean); 330 instanceManager.poolInstance(callContext,bean); 331 }catch(java.lang.reflect.InvocationTargetException ite){ if ( ite.getTargetException() instanceof RuntimeException ) { 333 334 txPolicy.handleSystemException( ite.getTargetException(), bean, txContext ); 336 } else { 337 338 instanceManager.poolInstance(callContext,bean); 339 txPolicy.handleApplicationException( ite.getTargetException(), txContext ); 340 } 341 }catch(org.openejb.SystemException se){ 342 txPolicy.handleSystemException( se.getRootCause(), bean, txContext ); 343 }catch(Throwable iae){ 352 txPolicy.handleSystemException( iae, bean, txContext ); 353 }finally{ 354 txPolicy.afterInvoke( bean, txContext ); 355 } 356 357 return returnValue; 358 } 359 360 371 public void ejbLoad_If_No_Transaction(ThreadContext callContext, EntityBean bean) 372 throws org.openejb.SystemException, Exception { 373 byte orginalOperation = callContext.getCurrentOperation(); 374 if(orginalOperation == Operations.OP_BUSINESS || orginalOperation == Operations.OP_REMOVE){ 375 376 Transaction currentTx = null; 377 try{ 378 currentTx = org.openejb.OpenEJB.getTransactionManager().getTransaction(); 379 }catch(javax.transaction.SystemException se){ 380 throw new org.openejb.SystemException("Transaction Manager failure",se); 381 } 382 383 if(currentTx ==null){ 384 callContext.setCurrentOperation(org.openejb.core.Operations.OP_LOAD); 385 try{ 386 ((javax.ejb.EntityBean )bean).ejbLoad(); 387 }catch(Exception e){ 388 instanceManager.discardInstance(callContext,(EntityBean )bean); 390 throw e; 391 }finally{ 392 callContext.setCurrentOperation(orginalOperation); 393 } 394 } 395 396 } 397 } 398 399 408 public void ejbStore_If_No_Transaction(ThreadContext callContext, EntityBean bean) 409 throws Exception { 410 411 byte currentOp = callContext.getCurrentOperation(); 412 if (currentOp == Operations.OP_BUSINESS){ 413 414 Transaction currentTx = null; 415 try{ 416 currentTx = org.openejb.OpenEJB.getTransactionManager().getTransaction(); 417 }catch(javax.transaction.SystemException se){ 418 throw new org.openejb.SystemException("Transaction Manager failure",se); 419 } 420 421 if (currentTx == null){ 422 callContext.setCurrentOperation(org.openejb.core.Operations.OP_STORE); 423 try{ 424 ((javax.ejb.EntityBean )bean).ejbStore(); 425 }catch(Exception e){ 426 instanceManager.discardInstance(callContext,(EntityBean )bean); 428 throw e; 429 }finally{ 430 callContext.setCurrentOperation(currentOp); 431 } 432 } 433 } 434 } 435 436 protected void didCreateBean(ThreadContext callContext, EntityBean bean) throws org.openejb.OpenEJBException{ 437 } 438 439 protected ProxyInfo createEJBObject(Method callMethod, Object [] args, ThreadContext callContext) 441 throws org.openejb.OpenEJBException { 442 443 org.openejb.core.DeploymentInfo deploymentInfo = (org.openejb.core.DeploymentInfo)callContext.getDeploymentInfo(); 444 445 callContext.setCurrentOperation(Operations.OP_CREATE); 446 EntityBean bean = null; 447 Object primaryKey = null; 448 449 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 450 TransactionContext txContext = new TransactionContext(); 451 txContext.callContext = callContext; 452 453 466 467 txPolicy.beforeInvoke( bean, txContext ); 468 469 try{ 470 471 bean = instanceManager.obtainInstance(callContext); 472 Method ejbCreateMethod = deploymentInfo.getMatchingBeanMethod(callMethod); 473 474 primaryKey = ejbCreateMethod.invoke(bean, args); 476 477 callContext.setPrimaryKey(primaryKey); 478 didCreateBean(callContext, bean); 479 callContext.setCurrentOperation(Operations.OP_POST_CREATE); 480 481 Method ejbPostCreateMethod = deploymentInfo.getMatchingPostCreateMethod(ejbCreateMethod); 483 484 ejbPostCreateMethod.invoke(bean, args); 485 primaryKey = callContext.getPrimaryKey(); 487 callContext.setPrimaryKey(null); 488 instanceManager.poolInstance(callContext,bean); 489 }catch(java.lang.reflect.InvocationTargetException ite){ if ( ite.getTargetException() instanceof RuntimeException ) { 491 492 txPolicy.handleSystemException( ite.getTargetException(), bean, txContext); 493 } else { 494 495 instanceManager.poolInstance(callContext,bean); 496 txPolicy.handleApplicationException( ite.getTargetException(), txContext); 497 } 498 }catch(OpenEJBException e){ 499 txPolicy.handleSystemException( e.getRootCause(), bean, txContext); 500 }catch(Throwable e){ 509 txPolicy.handleSystemException( e, bean, txContext); 510 }finally{ 511 txPolicy.afterInvoke( bean, txContext ); 512 } 513 514 Class callingClass = callMethod.getDeclaringClass(); 515 boolean isLocalInterface = EJBLocalHome .class.isAssignableFrom(callingClass); 516 return new ProxyInfo(deploymentInfo, primaryKey, isLocalInterface, this); 517 518 519 } 520 536 protected Object findMethod(Method callMethod, Object [] args, ThreadContext callContext) 537 throws org.openejb.OpenEJBException { 538 org.openejb.core.DeploymentInfo deploymentInfo = (org.openejb.core.DeploymentInfo)callContext.getDeploymentInfo(); 539 callContext.setCurrentOperation(Operations.OP_FIND); 540 Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod); 541 Object returnValue = invoke(callMethod,runMethod, args, callContext); 542 543 Class callingClass = callMethod.getDeclaringClass(); 544 boolean isLocalInterface = EJBLocalHome .class.isAssignableFrom(callingClass); 545 546 550 if(returnValue instanceof java.util.Collection ){ 551 java.util.Iterator keys = ((java.util.Collection )returnValue).iterator(); 552 java.util.Vector proxies = new java.util.Vector (); 553 while(keys.hasNext()){ 554 Object primaryKey = keys.next(); 555 proxies.addElement(new ProxyInfo(deploymentInfo, primaryKey, isLocalInterface, this)); 556 } 557 returnValue = proxies; 558 }else if(returnValue instanceof java.util.Enumeration ){ 559 java.util.Enumeration keys = (java.util.Enumeration )returnValue; 560 java.util.Vector proxies = new java.util.Vector (); 561 while(keys.hasMoreElements()){ 562 Object primaryKey = keys.nextElement(); 563 proxies.addElement(new ProxyInfo(deploymentInfo, primaryKey, isLocalInterface, this)); 564 } 565 returnValue = new org.openejb.util.ArrayEnumeration(proxies); 566 }else 567 returnValue = new ProxyInfo(deploymentInfo, returnValue, isLocalInterface, this); 568 569 return returnValue; 570 } 571 572 585 protected Object homeMethod(Method callMethod, Object [] args, ThreadContext callContext) 586 throws org.openejb.OpenEJBException { 587 org.openejb.core.DeploymentInfo deploymentInfo = (org.openejb.core.DeploymentInfo)callContext.getDeploymentInfo(); 588 callContext.setCurrentOperation(Operations.OP_HOME); 589 Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod); 590 return invoke(callMethod,runMethod, args, callContext); 591 } 592 593 protected void didRemove(EntityBean bean, ThreadContext callContext) throws OpenEJBException{ 594 } 595 596 protected void removeEJBObject(Method callMethod, Object [] args, ThreadContext callContext) 597 throws org.openejb.OpenEJBException { 598 callContext.setCurrentOperation(Operations.OP_REMOVE); 599 600 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 601 TransactionContext txContext = new TransactionContext(); 602 txContext.callContext = callContext; 603 604 EntityBean bean = null; 605 txPolicy.beforeInvoke( bean, txContext ); 606 607 try{ 608 bean = instanceManager.obtainInstance(callContext); 610 611 ejbLoad_If_No_Transaction(callContext,bean); 612 bean.ejbRemove(); 613 didRemove(bean, callContext); 614 instanceManager.poolInstance(callContext,bean); 615 }catch(org.openejb.SystemException se){ 616 txPolicy.handleSystemException( se.getRootCause(), bean, txContext ); 617 }catch(Exception e){ if ( e instanceof RuntimeException ) { 619 620 txPolicy.handleSystemException( e, bean, txContext ); 621 } else { 622 623 instanceManager.poolInstance(callContext,bean); 624 txPolicy.handleApplicationException( e, txContext ); 625 } 626 }finally{ 627 txPolicy.afterInvoke( bean, txContext ); 628 } 629 } 630 631 632 636 public void discardInstance(EnterpriseBean bean, ThreadContext threadContext) { 637 if ( bean != null ) { 638 try{ 639 instanceManager.discardInstance(threadContext,(EntityBean )bean); 640 } catch (SystemException e){ 641 logger.error("The instance manager encountered an unkown system exception while trying to discard the entity instance with primary key "+threadContext.getPrimaryKey()); 642 } 643 } 644 } 645 646 647 } 648 | Popular Tags |