dain        2005/02/25 18:06:11

  Modified:    modules/core/src/java/org/openejb/sfsb CreateMethod.java
                        StatefulInstanceContext.java
                        StatefulInstanceInterceptor.java
  Log:

  Added support for in-tx cacheing back in
  This unturned a load of places that were not handling transaction contexts 
properly and bugs in the context itself
  Changed instance contexts so they track entrancy and can be killed as 
required by the spec
  Made all instance context fields final
  
  Revision  Changes    Path
  1.4       +1 -3      
openejb/modules/core/src/java/org/openejb/sfsb/CreateMethod.java
  
  Index: CreateMethod.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/sfsb/CreateMethod.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CreateMethod.java 18 Jul 2004 22:32:24 -0000      1.3
  +++ CreateMethod.java 25 Feb 2005 23:06:11 -0000      1.4
  @@ -117,8 +117,6 @@
                   
invocation.setTransactionContext(TransactionContext.getContext());
               }
           }
  -        // associate the new sfsb with the tx cache
  -        invocation.getTransactionContext().associate(ctx);
   
           // return a ref
           EJBInterfaceType type = invocation.getType();
  
  
  
  1.11      +45 -24    
openejb/modules/core/src/java/org/openejb/sfsb/StatefulInstanceContext.java
  
  Index: StatefulInstanceContext.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/sfsb/StatefulInstanceContext.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- StatefulInstanceContext.java      15 Feb 2005 03:24:03 -0000      1.10
  +++ StatefulInstanceContext.java      25 Feb 2005 23:06:11 -0000      1.11
  @@ -60,6 +60,7 @@
   import org.openejb.AbstractInstanceContext;
   import org.openejb.EJBOperation;
   import org.openejb.EJBInvocation;
  +import org.openejb.cache.InstanceCache;
   import org.openejb.dispatch.SystemMethodIndices;
   import org.openejb.proxy.EJBProxyFactory;
   
  @@ -70,20 +71,20 @@
    */
   public class StatefulInstanceContext extends AbstractInstanceContext {
       private static final Log log = 
LogFactory.getLog(StatefulInstanceContext.class);
  -    private final Object containerId;
       private final Object id;
       private final StatefulSessionContext statefulContext;
  +    private final EJBInvocation setContextInvocation;
  +    private final EJBInvocation unsetContextInvocation;
       private final EJBInvocation afterBeginInvocation;
       private final EJBInvocation beforeCompletionInvocation;
  -    private boolean dead = false;
  +    private final SystemMethodIndices systemMethodIndices;
       private BeanTransactionContext preexistingContext;
       private EJBOperation operation;
  -    private final SystemMethodIndices systemMethodIndices;
  +    private InstanceCache cache;
   
       public StatefulInstanceContext(Object containerId, EJBProxyFactory 
proxyFactory, SessionBean instance, Object id, TransactionContextManager 
transactionContextManager, UserTransactionImpl userTransaction, 
SystemMethodIndices systemMethodIndices, Interceptor systemChain, Set 
unshareableResources, Set applicationManagedSecurityResources) {
           //currently stateful beans have no timer service.
  -        super(systemChain, unshareableResources, 
applicationManagedSecurityResources, instance, proxyFactory, null);
  -        this.containerId = containerId;
  +        super(containerId, instance, systemChain, proxyFactory, null, 
unshareableResources, applicationManagedSecurityResources);
           this.id = id;
           statefulContext = new StatefulSessionContext(this, 
transactionContextManager, userTransaction);
           this.systemMethodIndices = systemMethodIndices;
  @@ -98,13 +99,10 @@
           }
       }
   
  -    public Object getContainerId() {
  -        return containerId;
  -    }
  -
       public EJBOperation getOperation() {
           return operation;
       }
  +
       public void setOperation(EJBOperation operation) {
           statefulContext.setState(operation);
           this.operation = operation;
  @@ -118,11 +116,6 @@
           return id;
       }
   
  -    public void setId(Object id) {
  -        // @todo remove setId from the EJBInstanceContext interface
  -        throw new UnsupportedOperationException();
  -    }
  -
       public BeanTransactionContext getPreexistingContext() {
           return preexistingContext;
       }
  @@ -131,6 +124,14 @@
           this.preexistingContext = preexistingContext;
       }
   
  +    public InstanceCache getCache() {
  +        return cache;
  +    }
  +
  +    public void setCache(InstanceCache cache) {
  +        this.cache = cache;
  +    }
  +
       public void die() {
           if (preexistingContext != null) {
               try {
  @@ -140,18 +141,33 @@
               }
               preexistingContext = null;
           }
  -        dead = true;
  -    }
  -
  -    public boolean isDead() {
  -        return dead;
  +        if (cache != null) {
  +            cache.remove(id);
  +            cache = null;
  +        }
  +        super.die();
       }
   
       public StatefulSessionContext getSessionContext() {
           return statefulContext;
       }
   
  +    public void setContext() throws Throwable {
  +        if (isDead()) {
  +            throw new IllegalStateException("Context is dead: container=" + 
getContainerId() + ", id=" + getId());
  +        }
  +        systemChain.invoke(setContextInvocation);
  +    }
  +
  +    public void unsetContext() throws Throwable {
  +        if (isDead()) {
  +            throw new IllegalStateException("Context is dead: container=" + 
getContainerId() + ", id=" + getId());
  +        }
  +        systemChain.invoke(unsetContextInvocation);
  +    }
  +
       public void associate() throws Throwable {
  +        super.associate();
           if (getInstance() instanceof SessionSynchronization) {
               assert(getInstance() != null);
               systemChain.invoke(afterBeginInvocation);
  @@ -159,6 +175,7 @@
       }
   
       public void beforeCommit() throws Throwable {
  +        super.beforeCommit();
           if (getInstance() instanceof SessionSynchronization) {
               assert(getInstance() != null);
               systemChain.invoke(beforeCompletionInvocation);
  @@ -166,13 +183,17 @@
       }
   
       public void afterCommit(boolean committed) throws Throwable {
  -        if (!dead) {
  -            // @todo fix me
  -//            container.getInstanceCache().putInactive(id, this);
  -        }
  +        super.beforeCommit();
           if (getInstance() instanceof SessionSynchronization) {
               assert(getInstance() != null);
               
systemChain.invoke(systemMethodIndices.getAfterCompletionInvocation(this, 
committed));
  +        }
  +    }
  +
  +    public void unassociate() throws Throwable {
  +        super.unassociate();
  +        if (!isDead() && cache != null) {
  +            cache.putInactive(id, this);
           }
       }
   }
  
  
  
  1.5       +27 -21    
openejb/modules/core/src/java/org/openejb/sfsb/StatefulInstanceInterceptor.java
  
  Index: StatefulInstanceInterceptor.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/sfsb/StatefulInstanceInterceptor.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StatefulInstanceInterceptor.java  15 Feb 2005 03:24:03 -0000      1.4
  +++ StatefulInstanceInterceptor.java  25 Feb 2005 23:06:11 -0000      1.5
  @@ -57,10 +57,13 @@
   import org.apache.geronimo.transaction.context.BeanTransactionContext;
   import org.apache.geronimo.transaction.context.TransactionContextManager;
   import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
  +import org.apache.geronimo.transaction.InstanceContext;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
   import org.openejb.EJBInvocation;
  +import org.openejb.NotReentrantLocalException;
  +import org.openejb.NotReentrantException;
   import org.openejb.transaction.UncommittedTransactionException;
   import org.openejb.cache.InstanceCache;
   import org.openejb.cache.InstanceFactory;
  @@ -96,26 +99,36 @@
           ejbInvocation.setEJBInstanceContext(ctx);
   
           // resume the preexisting transaction context
  -        TransactionContext oldContext = 
transactionContextManager.getContext();
  +        TransactionContext oldTransactionContext = 
transactionContextManager.getContext();
           if (ctx.getPreexistingContext() != null) {
               BeanTransactionContext preexistingContext = 
ctx.getPreexistingContext();
               ctx.setPreexistingContext(null);
  -            preexistingContext.setOldContext((UnspecifiedTransactionContext) 
oldContext);
  +            preexistingContext.setOldContext((UnspecifiedTransactionContext) 
oldTransactionContext);
   
               ejbInvocation.setTransactionContext(preexistingContext);
               transactionContextManager.setContext(preexistingContext);
               preexistingContext.resume();
           }
   
  +        // check reentrancy
  +        if (ctx.isInCall()) {
  +            if (ejbInvocation.getType().isLocal()) {
  +                throw new NotReentrantLocalException("Stateful session beans 
do not support reentrancy: " + containerId);
  +            } else {
  +                throw new NotReentrantException("Stateful session beans do 
not support reentrancy: " + containerId);
  +            }
  +        }
  +
  +        InstanceContext oldInstanceContext = 
ejbInvocation.getTransactionContext().beginInvocation(ctx);
           try {
               // invoke next
               InvocationResult invocationResult = next.invoke(invocation);
   
               // if we have a BMT still associated with the thread, suspend it 
and save it off for the next invocation
               TransactionContext currentContext = 
transactionContextManager.getContext();
  -            if (oldContext != currentContext) {
  +            if (oldTransactionContext != currentContext) {
                   BeanTransactionContext preexistingContext = 
(BeanTransactionContext)currentContext;
  -                if (preexistingContext.getOldContext() != oldContext) {
  +                if (preexistingContext.getOldContext() != 
oldTransactionContext) {
                       throw new UncommittedTransactionException("Found an 
uncommitted bean transaction from another session bean");
                   }
                   // suspend and save off the BMT context
  @@ -124,9 +137,9 @@
                   ctx.setPreexistingContext(preexistingContext);
   
                   // resume the old unsupported transaction context
  -                ejbInvocation.setTransactionContext(oldContext);
  -                transactionContextManager.setContext(oldContext);
  -                oldContext.resume();
  +                ejbInvocation.setTransactionContext(oldTransactionContext);
  +                transactionContextManager.setContext(oldTransactionContext);
  +                oldTransactionContext.resume();
               }
   
               return invocationResult;
  @@ -135,7 +148,7 @@
               ctx.die();
   
               // if we have tx context, other then our old tx context, 
associated with the thread roll it back
  -            if (oldContext != transactionContextManager.getContext()) {
  +            if (oldTransactionContext != 
transactionContextManager.getContext()) {
                   try {
                       transactionContextManager.getContext().rollback();
                   } catch (Exception e) {
  @@ -143,18 +156,14 @@
                   }
   
                   // and resume the old transaction
  -                ejbInvocation.setTransactionContext(oldContext);
  -                transactionContextManager.setContext(oldContext);
  -                oldContext.resume();
  +                ejbInvocation.setTransactionContext(oldTransactionContext);
  +                transactionContextManager.setContext(oldTransactionContext);
  +                oldTransactionContext.resume();
               }
   
               throw t;
           } finally {
  -            if (ctx.isDead()) {
  -                cache.remove(ctx.getId());
  -            }
  -
  -            // remove the reference to the context from the invocation
  +            
ejbInvocation.getTransactionContext().endInvocation(oldInstanceContext);
               ejbInvocation.setEJBInstanceContext(null);
           }
       }
  @@ -167,10 +176,8 @@
               ctx = (StatefulInstanceContext) factory.createInstance();
               assert ctx.getInstance() != null: "Got a context with no 
instance assigned";
               id = ctx.getId();
  +            ctx.setCache(cache);
               cache.putActive(id, ctx);
  -
  -            TransactionContext transactionContext = 
ejbInvocation.getTransactionContext();
  -            transactionContext.associate(ctx);
           } else {
               // first check the transaction cache
               TransactionContext transactionContext = 
ejbInvocation.getTransactionContext();
  @@ -186,7 +193,6 @@
                           throw new NoSuchObjectException(id.toString());
                       }
                   }
  -                transactionContext.associate(ctx);
               }
   
               if (ctx.isDead()) {
  
  
  

Reply via email to