dain        2005/02/14 22:24:03

  Modified:    modules/core/src/java/org/openejb/sfsb BusinessMethod.java
                        StatefulInstanceContext.java
                        StatefulInstanceInterceptor.java
                        StatefulInterceptorBuilder.java
  Added:       modules/core/src/java/org/openejb/sfsb AfterBegin.java
                        AfterCompletion.java BeforeCompletion.java
  Log:

  o Finished GERONIMO-181 Transaction propogation accross calls to stateful 
session beans
  
  o Added code resume and suspend the BMT transaction to 
StatefulInstanceInterceptor.  This code must be here because the instance 
context holds the suspended transaction, and this context is not available in 
the transaction interceptor.  Also the code that "finds" the correct instance 
relies on the transaction context already being established
  
  o Enabled stateful tests for session synchronization callbacks
  
  o Session synchronization callbacks now go through the system interceptor 
chain
  
  o Container policies now setRollbackOnly and throw a 
TransactionRolledbac[Local]Exception when a system exception is thrown in an 
inherited transaction
  
  o Fixed GERONIMO-579 UserTransaction broken after BMT calls BMT
  
  o Added support for ejb-ql back into the openejb-jar.xml file so 1.1 beans 
can use ejb-ql for a query specification
  
  o Fixed client side handle serialization code
  
  o Fixed stateful session ejb object isIdentical code; was not comparing 
primary key
  
  o Fixed handling of remove methods
  
  Revision  Changes    Path
  1.5       +1 -2      
openejb/modules/core/src/java/org/openejb/sfsb/BusinessMethod.java
  
  Index: BusinessMethod.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/sfsb/BusinessMethod.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- BusinessMethod.java       5 Oct 2004 07:04:02 -0000       1.4
  +++ BusinessMethod.java       15 Feb 2005 03:24:03 -0000      1.5
  @@ -75,7 +75,6 @@
               if(isBMT) {
                   // we need to update the invocation cache of the transaction 
context
                   // because they may have used UserTransaction to push a new 
context
  -                //TODO MOVE THIS TO AN INTERCEPTOR that is included only if 
the bean is BMT
                   
invocation.setTransactionContext(TransactionContext.getContext());
               }
           }
  
  
  
  1.10      +48 -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.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- StatefulInstanceContext.java      14 Feb 2005 18:32:31 -0000      1.9
  +++ StatefulInstanceContext.java      15 Feb 2005 03:24:03 -0000      1.10
  @@ -48,15 +48,18 @@
   package org.openejb.sfsb;
   
   import java.util.Set;
  -
   import javax.ejb.SessionBean;
   import javax.ejb.SessionSynchronization;
   
   import org.apache.geronimo.core.service.Interceptor;
   import org.apache.geronimo.transaction.UserTransactionImpl;
  +import org.apache.geronimo.transaction.context.BeanTransactionContext;
   import org.apache.geronimo.transaction.context.TransactionContextManager;
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
   import org.openejb.AbstractInstanceContext;
   import org.openejb.EJBOperation;
  +import org.openejb.EJBInvocation;
   import org.openejb.dispatch.SystemMethodIndices;
   import org.openejb.proxy.EJBProxyFactory;
   
  @@ -66,10 +69,16 @@
    * @version $Revision$ $Date$
    */
   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 afterBeginInvocation;
  +    private final EJBInvocation beforeCompletionInvocation;
       private boolean dead = false;
  +    private BeanTransactionContext preexistingContext;
  +    private EJBOperation operation;
  +    private final SystemMethodIndices systemMethodIndices;
   
       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.
  @@ -77,16 +86,28 @@
           this.containerId = containerId;
           this.id = id;
           statefulContext = new StatefulSessionContext(this, 
transactionContextManager, userTransaction);
  +        this.systemMethodIndices = systemMethodIndices;
           setContextInvocation = 
systemMethodIndices.getSetContextInvocation(this, statefulContext);
           unsetContextInvocation = 
systemMethodIndices.getSetContextInvocation(this, null);
  +        if (instance instanceof SessionSynchronization) {
  +            afterBeginInvocation = 
systemMethodIndices.getAfterBeginInvocation(this);
  +            beforeCompletionInvocation = 
systemMethodIndices.getBeforeCompletionInvocation(this);
  +        } else {
  +            afterBeginInvocation = null;
  +            beforeCompletionInvocation = null;
  +        }
       }
   
       public Object getContainerId() {
           return containerId;
       }
   
  +    public EJBOperation getOperation() {
  +        return operation;
  +    }
       public void setOperation(EJBOperation operation) {
           statefulContext.setState(operation);
  +        this.operation = operation;
       }
   
       public boolean setTimerState(EJBOperation operation) {
  @@ -102,7 +123,23 @@
           throw new UnsupportedOperationException();
       }
   
  +    public BeanTransactionContext getPreexistingContext() {
  +        return preexistingContext;
  +    }
  +
  +    public void setPreexistingContext(BeanTransactionContext 
preexistingContext) {
  +        this.preexistingContext = preexistingContext;
  +    }
  +
       public void die() {
  +        if (preexistingContext != null) {
  +            try {
  +                preexistingContext.rollback();
  +            } catch (Exception e) {
  +                log.warn("Unable to roll back", e);
  +            }
  +            preexistingContext = null;
  +        }
           dead = true;
       }
   
  @@ -114,41 +151,28 @@
           return statefulContext;
       }
   
  -    public void afterBegin() throws Exception {
  +    public void associate() throws Throwable {
           if (getInstance() instanceof SessionSynchronization) {
  -            try {
  -                ((SessionSynchronization) getInstance()).afterBegin();
  -            } catch (Exception e) {
  -                dead = true;
  -                throw e;
  -            } catch (Error e) {
  -                dead = true;
  -                throw e;
  -            }
  +            assert(getInstance() != null);
  +            systemChain.invoke(afterBeginInvocation);
           }
       }
   
  -    public void beforeCommit() throws Exception {
  +    public void beforeCommit() throws Throwable {
           if (getInstance() instanceof SessionSynchronization) {
  -            try {
  -                ((SessionSynchronization) getInstance()).beforeCompletion();
  -            } catch (Exception e) {
  -                dead = true;
  -                throw e;
  -            } catch (Error e) {
  -                dead = true;
  -                throw e;
  -            }
  +            assert(getInstance() != null);
  +            systemChain.invoke(beforeCompletionInvocation);
           }
       }
   
  -    public void afterCommit(boolean committed) throws Exception {
  +    public void afterCommit(boolean committed) throws Throwable {
           if (!dead) {
               // @todo fix me
   //            container.getInstanceCache().putInactive(id, this);
           }
           if (getInstance() instanceof SessionSynchronization) {
  -            ((SessionSynchronization) 
getInstance()).afterCompletion(committed);
  +            assert(getInstance() != null);
  +            
systemChain.invoke(systemMethodIndices.getAfterCompletionInvocation(this, 
committed));
           }
       }
   }
  
  
  
  1.4       +81 -20    
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.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- StatefulInstanceInterceptor.java  18 Jul 2004 22:32:24 -0000      1.3
  +++ StatefulInstanceInterceptor.java  15 Feb 2005 03:24:03 -0000      1.4
  @@ -54,8 +54,14 @@
   import org.apache.geronimo.core.service.Invocation;
   import org.apache.geronimo.core.service.InvocationResult;
   import org.apache.geronimo.transaction.context.TransactionContext;
  +import org.apache.geronimo.transaction.context.BeanTransactionContext;
  +import org.apache.geronimo.transaction.context.TransactionContextManager;
  +import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
   
   import org.openejb.EJBInvocation;
  +import org.openejb.transaction.UncommittedTransactionException;
   import org.openejb.cache.InstanceCache;
   import org.openejb.cache.InstanceFactory;
   
  @@ -67,23 +73,94 @@
    * @version $Revision$ $Date$
    */
   public final class StatefulInstanceInterceptor implements Interceptor {
  +    private static final Log log = 
LogFactory.getLog(StatefulInstanceInterceptor.class);
       private final Interceptor next;
       private final Object containerId;
       private final InstanceFactory factory;
       private final InstanceCache cache;
  +    private final TransactionContextManager transactionContextManager;
   
  -    public StatefulInstanceInterceptor(Interceptor next, Object containerId, 
InstanceFactory factory, InstanceCache cache) {
  +    public StatefulInstanceInterceptor(Interceptor next, Object containerId, 
InstanceFactory factory, InstanceCache cache, TransactionContextManager 
transactionContextManager) {
           this.next = next;
           this.containerId = containerId;
           this.factory = factory;
           this.cache = cache;
  +        this.transactionContextManager = transactionContextManager;
       }
   
       public InvocationResult invoke(final Invocation invocation) throws 
Throwable {
           EJBInvocation ejbInvocation = (EJBInvocation) invocation;
   
  -        StatefulInstanceContext ctx;
  +        // initialize the context and set it into the invocation
  +        StatefulInstanceContext ctx = getInstanceContext(ejbInvocation);
  +        ejbInvocation.setEJBInstanceContext(ctx);
  +
  +        // resume the preexisting transaction context
  +        TransactionContext oldContext = 
transactionContextManager.getContext();
  +        if (ctx.getPreexistingContext() != null) {
  +            BeanTransactionContext preexistingContext = 
ctx.getPreexistingContext();
  +            ctx.setPreexistingContext(null);
  +            preexistingContext.setOldContext((UnspecifiedTransactionContext) 
oldContext);
  +
  +            ejbInvocation.setTransactionContext(preexistingContext);
  +            transactionContextManager.setContext(preexistingContext);
  +            preexistingContext.resume();
  +        }
  +
  +        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) {
  +                BeanTransactionContext preexistingContext = 
(BeanTransactionContext)currentContext;
  +                if (preexistingContext.getOldContext() != oldContext) {
  +                    throw new UncommittedTransactionException("Found an 
uncommitted bean transaction from another session bean");
  +                }
  +                // suspend and save off the BMT context
  +                preexistingContext.suspend();
  +                preexistingContext.setOldContext(null);
  +                ctx.setPreexistingContext(preexistingContext);
  +
  +                // resume the old unsupported transaction context
  +                ejbInvocation.setTransactionContext(oldContext);
  +                transactionContextManager.setContext(oldContext);
  +                oldContext.resume();
  +            }
  +
  +            return invocationResult;
  +        } catch(Throwable t) {
  +            // we must kill the instance when a system exception is thrown
  +            ctx.die();
  +
  +            // if we have tx context, other then our old tx context, 
associated with the thread roll it back
  +            if (oldContext != transactionContextManager.getContext()) {
  +                try {
  +                    transactionContextManager.getContext().rollback();
  +                } catch (Exception e) {
  +                    log.warn("Unable to roll back", e);
  +                }
  +
  +                // and resume the old transaction
  +                ejbInvocation.setTransactionContext(oldContext);
  +                transactionContextManager.setContext(oldContext);
  +                oldContext.resume();
  +            }
  +
  +            throw t;
  +        } finally {
  +            if (ctx.isDead()) {
  +                cache.remove(ctx.getId());
  +            }
   
  +            // remove the reference to the context from the invocation
  +            ejbInvocation.setEJBInstanceContext(null);
  +        }
  +    }
  +
  +    private StatefulInstanceContext getInstanceContext(EJBInvocation 
ejbInvocation) throws Throwable {
  +        StatefulInstanceContext ctx;
           Object id = ejbInvocation.getId();
           if (id == null) {
               // we don't have an id so we are a create method
  @@ -120,22 +197,6 @@
                   }
               }
           }
  -
  -        // initialize the context and set it into the invocation
  -        ejbInvocation.setEJBInstanceContext(ctx);
  -
  -        try {
  -            return next.invoke(invocation);
  -        } catch(Throwable t) {
  -            ctx.die();
  -            throw t;
  -        } finally {
  -            if (ctx.isDead()) {
  -                cache.remove(id);
  -            }
  -
  -            // remove the reference to the context from the invocation
  -            ejbInvocation.setEJBInstanceContext(null);
  -        }
  +        return ctx;
       }
   }
  
  
  
  1.7       +2 -2      
openejb/modules/core/src/java/org/openejb/sfsb/StatefulInterceptorBuilder.java
  
  Index: StatefulInterceptorBuilder.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/sfsb/StatefulInterceptorBuilder.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- StatefulInterceptorBuilder.java   27 Jul 2004 02:26:30 -0000      1.6
  +++ StatefulInterceptorBuilder.java   15 Feb 2005 03:24:03 -0000      1.7
  @@ -93,7 +93,7 @@
           if (useContextHandler) {
               firstInterceptor = new 
PolicyContextHandlerEJBInterceptor(firstInterceptor);
           }
  -        firstInterceptor = new StatefulInstanceInterceptor(firstInterceptor, 
containerId, instanceFactory, instanceCache);
  +        firstInterceptor = new StatefulInstanceInterceptor(firstInterceptor, 
containerId, instanceFactory, instanceCache, transactionContextManager);
           firstInterceptor = new 
TransactionContextInterceptor(firstInterceptor, transactionContextManager, 
transactionPolicyManager);
           firstInterceptor = new SystemExceptionInterceptor(firstInterceptor, 
ejbName);
           return new TwoChains(firstInterceptor, systemChain);
  
  
  
  1.1                  
openejb/modules/core/src/java/org/openejb/sfsb/AfterBegin.java
  
  Index: AfterBegin.java
  ===================================================================
  /* ====================================================================
   * Redistribution and use of this software and associated documentation
   * ("Software"), with or without modification, are permitted provided
   * that the following conditions are met:
   *
   * 1. Redistributions of source code must retain copyright
   *    statements and notices.  Redistributions must also contain a
   *    copy of this document.
   *
   * 2. Redistributions in binary form must reproduce this list of
   *    conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The name "OpenEJB" must not be used to endorse or promote
   *    products derived from this Software without prior written
   *    permission of The OpenEJB Group.  For written permission,
   *    please contact [EMAIL PROTECTED]
   *
   * 4. Products derived from this Software may not be called "OpenEJB"
   *    nor may "OpenEJB" appear in their names without prior written
   *    permission of The OpenEJB Group. OpenEJB is a registered
   *    trademark of The OpenEJB Group.
   *
   * 5. Due credit should be given to the OpenEJB Project
   *    (http://openejb.org/).
   *
   * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the OpenEJB Project.  For more information
   * please see <http://openejb.org/>.
   *
   * ====================================================================
   */
  package org.openejb.sfsb;
  
  import java.io.Serializable;
  import javax.ejb.SessionSynchronization;
  
  import org.apache.geronimo.core.service.InvocationResult;
  import org.apache.geronimo.core.service.SimpleInvocationResult;
  import org.openejb.EJBInvocation;
  import org.openejb.EJBOperation;
  import org.openejb.dispatch.VirtualOperation;
  
  /**
   * @version $Revision: 1.1 $ $Date: 2005/02/15 03:24:03 $
   */
  public class AfterBegin implements VirtualOperation, Serializable {
      public static final AfterBegin INSTANCE = new AfterBegin();
  
      private AfterBegin() {}
  
      public InvocationResult execute(EJBInvocation invocation) throws 
Throwable {
          StatefulInstanceContext ctx = (StatefulInstanceContext) 
invocation.getEJBInstanceContext();
          EJBOperation oldOperation = ctx.getOperation();
          try {
              ctx.setOperation(EJBOperation.BIZMETHOD);
              ((SessionSynchronization) ctx.getInstance()).afterBegin();
          } finally {
              ctx.setOperation(oldOperation);
          }
          return new SimpleInvocationResult(true, null);
      }
  }
  
  
  
  1.1                  
openejb/modules/core/src/java/org/openejb/sfsb/AfterCompletion.java
  
  Index: AfterCompletion.java
  ===================================================================
  /* ====================================================================
   * Redistribution and use of this software and associated documentation
   * ("Software"), with or without modification, are permitted provided
   * that the following conditions are met:
   *
   * 1. Redistributions of source code must retain copyright
   *    statements and notices.  Redistributions must also contain a
   *    copy of this document.
   *
   * 2. Redistributions in binary form must reproduce this list of
   *    conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The name "OpenEJB" must not be used to endorse or promote
   *    products derived from this Software without prior written
   *    permission of The OpenEJB Group.  For written permission,
   *    please contact [EMAIL PROTECTED]
   *
   * 4. Products derived from this Software may not be called "OpenEJB"
   *    nor may "OpenEJB" appear in their names without prior written
   *    permission of The OpenEJB Group. OpenEJB is a registered
   *    trademark of The OpenEJB Group.
   *
   * 5. Due credit should be given to the OpenEJB Project
   *    (http://openejb.org/).
   *
   * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the OpenEJB Project.  For more information
   * please see <http://openejb.org/>.
   *
   * ====================================================================
   */
  package org.openejb.sfsb;
  
  import java.io.Serializable;
  import javax.ejb.SessionSynchronization;
  
  import org.apache.geronimo.core.service.InvocationResult;
  import org.apache.geronimo.core.service.SimpleInvocationResult;
  import org.openejb.EJBInvocation;
  import org.openejb.EJBOperation;
  import org.openejb.dispatch.VirtualOperation;
  
  /**
   * @version $Revision: 1.1 $ $Date: 2005/02/15 03:24:03 $
   */
  public class AfterCompletion implements VirtualOperation, Serializable {
      public static final AfterCompletion INSTANCE = new AfterCompletion();
  
      private AfterCompletion() {}
  
      public InvocationResult execute(EJBInvocation invocation) throws 
Throwable {
          boolean comitted = 
((Boolean)invocation.getArguments()[0]).booleanValue();
          StatefulInstanceContext ctx = (StatefulInstanceContext) 
invocation.getEJBInstanceContext();
          EJBOperation oldOperation = ctx.getOperation();
          try {
              ctx.setOperation(EJBOperation.EJBCREATE);
              ((SessionSynchronization) 
ctx.getInstance()).afterCompletion(comitted);
          } finally {
              ctx.setOperation(oldOperation);
          }
          return new SimpleInvocationResult(true, null);
      }
  }
  
  
  
  1.1                  
openejb/modules/core/src/java/org/openejb/sfsb/BeforeCompletion.java
  
  Index: BeforeCompletion.java
  ===================================================================
  /* ====================================================================
   * Redistribution and use of this software and associated documentation
   * ("Software"), with or without modification, are permitted provided
   * that the following conditions are met:
   *
   * 1. Redistributions of source code must retain copyright
   *    statements and notices.  Redistributions must also contain a
   *    copy of this document.
   *
   * 2. Redistributions in binary form must reproduce this list of
   *    conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The name "OpenEJB" must not be used to endorse or promote
   *    products derived from this Software without prior written
   *    permission of The OpenEJB Group.  For written permission,
   *    please contact [EMAIL PROTECTED]
   *
   * 4. Products derived from this Software may not be called "OpenEJB"
   *    nor may "OpenEJB" appear in their names without prior written
   *    permission of The OpenEJB Group. OpenEJB is a registered
   *    trademark of The OpenEJB Group.
   *
   * 5. Due credit should be given to the OpenEJB Project
   *    (http://openejb.org/).
   *
   * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the OpenEJB Project.  For more information
   * please see <http://openejb.org/>.
   *
   * ====================================================================
   */
  package org.openejb.sfsb;
  
  import java.io.Serializable;
  import javax.ejb.SessionSynchronization;
  
  import org.apache.geronimo.core.service.InvocationResult;
  import org.apache.geronimo.core.service.SimpleInvocationResult;
  import org.openejb.EJBInvocation;
  import org.openejb.EJBOperation;
  import org.openejb.dispatch.VirtualOperation;
  
  /**
   * @version $Revision: 1.1 $ $Date: 2005/02/15 03:24:03 $
   */
  public class BeforeCompletion implements VirtualOperation, Serializable {
      public static final BeforeCompletion INSTANCE = new BeforeCompletion();
  
      private BeforeCompletion() {}
  
      public InvocationResult execute(EJBInvocation invocation) throws 
Throwable {
          StatefulInstanceContext ctx = (StatefulInstanceContext) 
invocation.getEJBInstanceContext();
          EJBOperation oldOperation = ctx.getOperation();
          try {
              ctx.setOperation(EJBOperation.BIZMETHOD);
              ((SessionSynchronization) ctx.getInstance()).beforeCompletion();
          } finally {
              ctx.setOperation(oldOperation);
          }
          return new SimpleInvocationResult(true, null);
      }
  }
  
  
  

Reply via email to