1 45 46 47 package org.openejb.core.stateful; 48 49 import java.lang.reflect.Method ; 50 import java.rmi.RemoteException ; 51 import java.util.HashMap ; 52 import java.util.Properties ; 53 54 import javax.ejb.EJBHome ; 55 import javax.ejb.EJBLocalHome ; 56 import javax.ejb.EJBLocalObject ; 57 import javax.ejb.EJBObject ; 58 import javax.ejb.EnterpriseBean ; 59 import javax.ejb.SessionBean ; 60 61 import org.openejb.Container; 62 import org.openejb.DeploymentInfo; 63 import org.openejb.OpenEJB; 64 import org.openejb.OpenEJBException; 65 import org.openejb.ProxyInfo; 66 import org.openejb.SystemException; 67 import org.openejb.core.EnvProps; 68 import org.openejb.core.Operations; 69 import org.openejb.core.ThreadContext; 70 import org.openejb.core.transaction.TransactionContainer; 71 import org.openejb.core.transaction.TransactionContext; 72 import org.openejb.core.transaction.TransactionPolicy; 73 import org.openejb.util.Logger; 74 import org.openejb.util.SafeProperties; 75 import org.openejb.util.SafeToolkit; 76 77 84 public class StatefulContainer implements org.openejb.RpcContainer, TransactionContainer { 85 86 StatefulInstanceManager instanceManager; 88 HashMap deploymentRegistry; 90 Object containerID = null; 92 93 Method EJB_REMOVE_METHOD = null; 95 96 final static protected Logger logger = Logger.getInstance("OpenEJB", "org.openejb.util.resources"); 97 98 101 113 public void init(Object id, HashMap registry, Properties properties) 114 throws org.openejb.OpenEJBException{ 115 containerID = id; 116 deploymentRegistry = registry; 117 118 if ( properties == null )properties = new Properties (); 119 120 SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulContainer"); 121 SafeProperties safeProps = toolkit.getSafeProperties(properties); 122 try { 123 String className = safeProps.getProperty(EnvProps.IM_CLASS_NAME, "org.openejb.core.stateful.StatefulInstanceManager"); 124 ClassLoader cl = OpenEJB.getContextClassLoader(); 125 instanceManager =(StatefulInstanceManager)Class.forName(className, true, cl).newInstance(); 126 } catch ( Exception e ) { 127 throw new org.openejb.SystemException("Initialization of InstanceManager for the \""+containerID+"\" stateful container failed",e); 128 } 129 instanceManager.init(properties); 130 131 133 139 org.openejb.DeploymentInfo [] deploys = this.deployments(); 140 for ( int x = 0; x < deploys.length; x++ ) { 141 org.openejb.core.DeploymentInfo di = (org.openejb.core.DeploymentInfo)deploys[x]; 142 di.setContainer(this); 143 } 144 145 try { 146 EJB_REMOVE_METHOD = javax.ejb.SessionBean .class.getMethod("ejbRemove", new Class [0]); 147 } catch ( NoSuchMethodException nse ) { 148 throw new SystemException("Fixed remove method can not be initated", nse); 149 } 150 151 } 152 153 157 163 public DeploymentInfo [] deployments() { 164 return(DeploymentInfo [])deploymentRegistry.values().toArray(new DeploymentInfo[deploymentRegistry.size()]); 165 } 166 167 175 public DeploymentInfo getDeploymentInfo(Object deploymentID) { 176 return(DeploymentInfo)deploymentRegistry.get(deploymentID); 177 } 178 183 public int getContainerType( ) { 184 return Container.STATEFUL; 185 } 186 191 public Object getContainerID() { 192 return containerID; 193 } 194 195 203 public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException { 204 HashMap registry = (HashMap )deploymentRegistry.clone(); 205 registry.put(deploymentID, info); 206 deploymentRegistry = registry; 207 } 208 209 222 public Object invoke(Object deployID, Method callMethod,Object [] args,Object primKey, Object securityIdentity) throws org.openejb.OpenEJBException{ 223 try { 224 225 org.openejb.core.DeploymentInfo deployInfo = (org.openejb.core.DeploymentInfo)this.getDeploymentInfo(deployID); 226 227 ThreadContext callContext = ThreadContext.getThreadContext(); 228 callContext.set(deployInfo, primKey, securityIdentity); 229 230 boolean authorized = OpenEJB.getSecurityService().isCallerAuthorized(securityIdentity, deployInfo.getAuthorizedRoles(callMethod)); 232 if ( !authorized ) 233 throw new org.openejb.ApplicationException(new RemoteException ("Unauthorized Access by Principal Denied")); 234 235 Class declaringClass = callMethod.getDeclaringClass(); 237 String methodName = callMethod.getName(); 238 239 if(EJBHome .class.isAssignableFrom(declaringClass) || EJBLocalHome .class.isAssignableFrom(declaringClass) ){ 240 if ( methodName.equals("create") ) { 241 return createEJBObject(callMethod, args, callContext); 242 } else if ( methodName.equals("remove") ) { 243 removeEJBObject(callMethod,args,callContext); 244 return null; 245 } 246 } else if((EJBObject .class == declaringClass || EJBLocalObject .class == declaringClass) && methodName.equals("remove") ) { 247 removeEJBObject(callMethod,args,callContext); 248 return null; 249 } 250 251 252 SessionBean bean = null; 253 254 bean = instanceManager.obtainInstance(primKey, callContext); 256 callContext.setCurrentOperation(Operations.OP_BUSINESS); 257 Object returnValue = null; 258 Method runMethod = deployInfo.getMatchingBeanMethod(callMethod); 259 260 returnValue = this.invoke(callMethod,runMethod, args, bean, callContext); 261 262 instanceManager.poolInstance(primKey, bean); 265 266 return deployInfo.convertIfLocalReference(callMethod, returnValue); 268 269 } finally { 270 282 ThreadContext.setThreadContext(null); 283 } 284 285 } 286 287 291 292 296 protected Object invoke(Method callMethod, Method runMethod, Object [] args, EnterpriseBean bean, ThreadContext callContext) 297 throws org.openejb.OpenEJBException{ 298 299 TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy( callMethod ); 302 TransactionContext txContext = new TransactionContext( callContext ); 303 txContext.context.put(StatefulInstanceManager.class, instanceManager); 304 try { 305 txPolicy.beforeInvoke( bean, txContext ); 306 } catch ( org.openejb.ApplicationException e ) { 307 if ( e.getRootCause() instanceof javax.transaction.TransactionRequiredException || 308 e.getRootCause() instanceof java.rmi.RemoteException ) { 309 instanceManager.poolInstance(callContext.getPrimaryKey(), bean); 313 } 314 throw e; 315 } 316 317 Object returnValue = null; 318 try { 319 returnValue = runMethod.invoke(bean, args); 320 } catch ( java.lang.reflect.InvocationTargetException ite ) { if ( ite.getTargetException() instanceof RuntimeException ) { 322 323 txPolicy.handleSystemException( ite.getTargetException(), bean, txContext ); 325 } else { 326 327 instanceManager.poolInstance(callContext.getPrimaryKey(), bean); 328 txPolicy.handleApplicationException( ite.getTargetException(), txContext ); 330 } 331 } catch ( Throwable re ) { 340 txPolicy.handleSystemException( re, bean, txContext ); 342 343 } finally { 344 txPolicy.afterInvoke( bean, txContext ); 346 } 347 348 return returnValue; 349 } 350 351 public StatefulInstanceManager getInstanceManager( ) { 352 return instanceManager; 353 } 354 355 protected void removeEJBObject(Method callMethod, Object [] args, ThreadContext callContext) 358 throws org.openejb.OpenEJBException{ 359 360 try { 362 EnterpriseBean bean = instanceManager.obtainInstance(callContext.getPrimaryKey(), callContext); 363 if ( bean!=null ) { 364 callContext.setCurrentOperation(Operations.OP_REMOVE); 366 invoke(callMethod,this.EJB_REMOVE_METHOD,null,bean,callContext); 367 } 368 } finally { 369 instanceManager.freeInstance(callContext.getPrimaryKey()); 370 } 371 372 } 373 374 protected ProxyInfo createEJBObject(Method callMethod, Object [] args, ThreadContext callContext) 376 throws org.openejb.OpenEJBException { 377 org.openejb.core.DeploymentInfo deploymentInfo = (org.openejb.core.DeploymentInfo)callContext.getDeploymentInfo(); 378 Class beanType = deploymentInfo.getBeanClass(); 379 Object primaryKey = this.newPrimaryKey(); 380 callContext.setPrimaryKey(primaryKey); 381 382 EnterpriseBean bean = instanceManager.newInstance(primaryKey,beanType); 383 384 Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod); 385 386 callContext.setCurrentOperation(Operations.OP_CREATE); 387 invoke(callMethod, runMethod, args, bean,callContext); 388 389 instanceManager.poolInstance(primaryKey, bean); 390 391 Class callingClass = callMethod.getDeclaringClass(); 392 boolean isLocalInterface = EJBLocalHome .class.isAssignableFrom(callingClass); 393 return new ProxyInfo(deploymentInfo, primaryKey, isLocalInterface, this); 394 } 395 396 397 protected Object newPrimaryKey() { 399 return new java.rmi.dgc.VMID (); 400 } 401 402 406 public void discardInstance(EnterpriseBean bean, ThreadContext threadContext) { 407 try { 408 Object primaryKey = threadContext.getPrimaryKey(); 409 instanceManager.freeInstance(primaryKey); 410 } catch ( Throwable t ) { 411 logger.error("", t); 412 } 413 } 414 } 415 | Popular Tags |