1 22 package org.jboss.ejb3.stateful; 23 24 import org.jboss.aop.metadata.SimpleMetaData; 25 import org.jboss.ejb3.BaseContext; 26 import org.jboss.ejb3.Container; 27 import org.jboss.ejb3.Ejb3Registry; 28 import org.jboss.ejb3.ThreadLocalStack; 29 import org.jboss.ejb3.interceptor.InterceptorInfo; 30 import org.jboss.ejb3.tx.TxUtil; 31 import org.jboss.serial.io.MarshalledObject; 32 import org.jboss.tm.TxUtils; 33 34 import javax.persistence.EntityManager; 35 import javax.transaction.Synchronization ; 36 import javax.transaction.Transaction ; 37 import java.io.Externalizable ; 38 import java.io.IOException ; 39 import java.io.ObjectInput ; 40 import java.io.ObjectOutput ; 41 import java.util.ArrayList ; 42 import java.util.HashMap ; 43 import java.util.List ; 44 import java.util.Map ; 45 import java.util.concurrent.locks.ReentrantLock ; 46 47 53 public class StatefulBeanContext extends BaseContext implements Externalizable 54 { 55 protected Object id; 56 57 protected boolean txSynchronized = false; 58 59 protected boolean inInvocation = false; 60 61 protected MarshalledObject beanMO; 62 63 protected ReentrantLock lock = new ReentrantLock (); 64 65 protected boolean discarded; 66 67 public static ThreadLocalStack<StatefulBeanContext> propagatedContainedIn = new ThreadLocalStack<StatefulBeanContext>(); 70 71 public static ThreadLocalStack<StatefulBeanContext> currentBean = new ThreadLocalStack<StatefulBeanContext>(); 72 73 protected StatefulBeanContext containedIn; 74 75 protected List <StatefulBeanContext> contains; 76 77 protected HashMap <String , EntityManager> persistenceContexts; 78 79 protected boolean removed; 80 81 protected String containerName; 82 83 public StatefulBeanContext() 84 85 { 86 87 } 88 89 public List <StatefulBeanContext> getContains() 90 { 91 if (bean == null) 92 extractBeanAndInterceptors(); 93 return contains; 94 } 95 96 public EntityManager getExtendedPersistenceContext(String id) 97 { 98 EntityManager found = null; 99 Map <String , EntityManager> extendedPCS = getExtendedPersistenceContexts(); 100 if (extendedPCS != null) 101 { 102 found = extendedPCS.get(id); 103 } 104 if (found != null) 105 return found; 106 if (containedIn != null) 107 { 108 found = containedIn.getExtendedPersistenceContext(id); 109 } 110 return found; 111 } 112 113 public void addExtendedPersistenceContext(String id, EntityManager pc) 114 { 115 Map <String , EntityManager> extendedPCS = getExtendedPersistenceContexts(); 116 if (extendedPCS == null) 117 { 118 extendedPCS = persistenceContexts = new HashMap <String , EntityManager>(); 119 } 120 extendedPCS.put(id, pc); 121 } 122 123 public Map <String , EntityManager> getExtendedPersistenceContexts() 124 { 125 if (persistenceContexts == null) 126 { 127 if (bean == null) 128 getInstance(); } 130 return persistenceContexts; 131 } 132 133 public StatefulBeanContext getContainedIn() 134 { 135 return containedIn; 136 } 137 138 public void addContains(StatefulBeanContext ctx) 139 { 140 if (contains == null) 141 contains = new ArrayList <StatefulBeanContext>(); 142 contains.add(ctx); 143 ctx.containedIn = this; 144 } 145 146 public StatefulBeanContext pushContainedIn() 147 { 148 StatefulBeanContext thisPtr = this; 149 if (propagatedContainedIn.getList() != null) 150 { 151 containedIn = propagatedContainedIn.get(); 164 NestedStatefulBeanContext nested = new NestedStatefulBeanContext(); 165 nested.id = id; 166 nested.container = getContainer(); 167 nested.containerName = containerName; 168 nested.bean = bean; 169 containedIn.addContains(nested); 170 thisPtr = new ProxiedStatefulBeanContext(nested); 171 } 172 propagatedContainedIn.push(thisPtr); 173 return thisPtr; 174 } 175 176 public void prePassivate() 177 { 178 getContainer().invokePrePassivate(this); 179 } 180 181 public void postActivate() 182 { 183 getContainer().invokePostActivate(this); } 185 186 public void popContainedIn() 187 { 188 propagatedContainedIn.pop(); 189 } 190 191 public boolean isDiscarded() 192 { 193 return discarded; 194 } 195 196 public void setDiscarded(boolean discarded) 197 { 198 this.discarded = discarded; 199 } 200 201 public ReentrantLock getLock() 202 { 203 return lock; 204 } 205 206 public boolean isInInvocation() 207 { 208 return inInvocation; 209 } 210 211 public void setInInvocation(boolean inInvocation) 212 { 213 this.inInvocation = inInvocation; 214 } 215 216 public Object getId() 217 { 218 return id; 219 } 220 221 public void setId(Object id) 222 { 223 this.id = id; 224 } 225 226 public boolean isTxSynchronized() 227 { 228 return txSynchronized; 229 } 230 231 public void setTxSynchronized(boolean txSynchronized) 232 { 233 this.txSynchronized = txSynchronized; 234 } 235 236 public boolean isRemoved() 237 { 238 return removed; 239 } 240 241 public void remove() 242 { 243 if (removed) 244 return; 245 removed = true; 246 RuntimeException exceptionThrown = null; 247 if (contains != null) 248 { 249 for (StatefulBeanContext contained : contains) 250 { 251 try 252 { 253 ((StatefulContainer) contained.getContainer()).getCache().remove( 254 contained.getId()); 255 } 256 catch (RuntimeException e) 257 { 258 exceptionThrown = e; 261 } 262 } 263 } 264 try 265 { 266 Transaction tx = TxUtil.getTransactionManager().getTransaction(); 267 if (tx != null && TxUtils.isActive(tx)) 268 { 269 tx.registerSynchronization(new Synchronization () 270 { 271 public void beforeCompletion() 272 { 273 } 274 275 public void afterCompletion(int status) 276 { 277 closeExtendedPCs(); 278 } 279 }); 280 } 281 else 282 { 283 closeExtendedPCs(); 284 } 285 } 286 catch (Exception e) 287 { 288 throw new RuntimeException ("Exception thrown while removing SFSB", e); 289 } 290 if (exceptionThrown != null) throw new RuntimeException ("exception thrown while removing SFSB", exceptionThrown); 291 } 292 293 private void closeExtendedPCs() 294 { 295 Map <String , EntityManager> extendedPCS = getExtendedPersistenceContexts(); 296 if (extendedPCS != null) 297 { 298 RuntimeException exceptionThrown = null; 299 for (EntityManager pc : extendedPCS.values()) 300 { 301 try 302 { 303 pc.close(); 304 } 305 catch (RuntimeException e) 306 { 307 exceptionThrown = e; 308 } 309 } 310 if (exceptionThrown != null) throw new RuntimeException ("Error cleaning up PersistenceContexts in SFSB removal", exceptionThrown); 311 } 312 } 313 314 public void setContainer(Container container) 315 { 316 super.setContainer(container); 317 containerName = container.getObjectName().getCanonicalName(); 318 } 319 320 public Container getContainer() 321 { 322 if (container == null) 323 { 324 container = Ejb3Registry.getContainer(containerName); 325 } 326 return container; 327 } 328 329 @Override 330 public Object getInstance() 331 { 332 if (bean == null) 333 { 334 extractBeanAndInterceptors(); 335 } 337 return bean; 338 } 339 340 @Override 341 public SimpleMetaData getMetaData() 342 { 343 return super.getMetaData(); 344 } 345 346 public volatile boolean markedForPassivation = false; 348 349 public volatile boolean inUse = false; 350 351 public volatile long lastUsed = System.currentTimeMillis(); 352 353 @Override 354 public Object [] getInterceptorInstances(InterceptorInfo[] interceptorInfos) 355 { 356 if (bean == null) 357 { 358 extractBeanAndInterceptors(); 359 } 360 return super.getInterceptorInstances(interceptorInfos); 361 } 362 363 protected void extractBeanAndInterceptors() 364 { 365 try 366 { 367 Object [] beanAndInterceptors = (Object []) beanMO.get(); 368 bean = beanAndInterceptors[0]; 369 persistenceContexts = (HashMap <String , EntityManager>) beanAndInterceptors[1]; 370 ArrayList list = (ArrayList ) beanAndInterceptors[2]; 371 interceptorInstances = new HashMap <Class , Object >(); 372 if (list != null) 373 { 374 for (Object o : list) 375 { 376 interceptorInstances.put(o.getClass(), o); 377 } 378 } 379 contains = (List <StatefulBeanContext>) beanAndInterceptors[3]; 380 389 } 390 catch (IOException e) 391 { 392 throw new RuntimeException (e); 393 } 394 catch (ClassNotFoundException e) 395 { 396 throw new RuntimeException (e); 397 } 398 } 399 400 public void writeExternal(ObjectOutput out) throws IOException 401 { 402 out.writeUTF(containerName); 403 out.writeObject(id); 404 out.writeObject(metadata); 405 if (bean == null) 406 { 407 out.writeObject(beanMO); 408 } 409 else 410 { 411 Object [] beanAndInterceptors = new Object [4]; 412 beanAndInterceptors[0] = bean; 413 beanAndInterceptors[1] = persistenceContexts; 414 if (interceptorInstances != null && interceptorInstances.size() > 0) 415 { 416 ArrayList list = new ArrayList (); 417 list.addAll(interceptorInstances.values()); 418 beanAndInterceptors[2] = list; 419 } 420 beanAndInterceptors[3] = contains; 421 430 beanMO = new MarshalledObject(beanAndInterceptors); 431 out.writeObject(beanMO); 432 } 433 } 434 435 public void readExternal(ObjectInput in) throws IOException , 436 ClassNotFoundException 437 { 438 containerName = in.readUTF(); 439 id = in.readObject(); 440 metadata = (SimpleMetaData) in.readObject(); 441 beanMO = (MarshalledObject) in.readObject(); 442 } 443 444 public Object getInvokedMethodKey() 445 { 446 return this.getId(); 447 } 448 } 449 | Popular Tags |