User: patriot1burke
  Date: 01/08/09 13:28:56

  Added:       src/main/org/jboss/ejb/plugins
                        EntityMultiInstanceSynchronizationInterceptor.java
                        EntityMultiInstanceInterceptor.java
  Log:
  Entity instance per transaction
  
  Revision  Changes    Path
  1.1                  
jboss/src/main/org/jboss/ejb/plugins/EntityMultiInstanceSynchronizationInterceptor.java
  
  Index: EntityMultiInstanceSynchronizationInterceptor.java
  ===================================================================
  /**
  * JBoss, the OpenSource J2EE webOS
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package org.jboss.ejb.plugins;
  
  import java.lang.reflect.Method;
  import java.rmi.RemoteException;
  import java.rmi.ServerException;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.ArrayList;
  import java.util.HashSet;
  
  import javax.ejb.EJBObject;
  import javax.ejb.CreateException;
  import javax.ejb.EJBException;
  import javax.ejb.NoSuchEntityException;
  import javax.ejb.RemoveException;
  import javax.ejb.EntityBean;
  import javax.transaction.Status;
  import javax.transaction.Synchronization;
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  import javax.transaction.RollbackException;
  import javax.transaction.SystemException;
  
  import org.jboss.ejb.BeanLock;
  import org.jboss.ejb.BeanLockManager;
  import org.jboss.ejb.Container;
  import org.jboss.ejb.EntityContainer;
  import org.jboss.ejb.EntityPersistenceManager;
  import org.jboss.ejb.EntityEnterpriseContext;
  import org.jboss.ejb.EnterpriseContext;
  import org.jboss.ejb.InstanceCache;
  import org.jboss.ejb.InstancePool;
  import org.jboss.ejb.MethodInvocation;
  import org.jboss.metadata.ConfigurationMetaData;
  import org.jboss.logging.log4j.JBossCategory;
  import org.jboss.util.Sync;
  
  /**
   * The role of this interceptor is to synchronize the state of the cache with
   * the underlying storage.  It does this with the ejbLoad and ejbStore
   * semantics of the EJB specification.  In the presence of a transaction this
   * is triggered by transaction demarcation. It registers a callback with the
   * underlying transaction monitor through the JTA interfaces.  If there is no
   * transaction the policy is to store state upon returning from invocation.
   * The synchronization polices A,B,C of the specification are taken care of
   * here.
   *
   * <p><b>WARNING: critical code</b>, get approval from senior developers
   *    before changing.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Bill Burke</a>
   * @version $Revision: 1.1 $
   *
   * <p><b>Revisions:</b><br>
   * <p><b>2001/08/08: billb</b>
   * <ol>
   *   <li>Initial revision
   * </ol>
   */
  public class EntityMultiInstanceSynchronizationInterceptor
     extends EntitySynchronizationInterceptor
  {
     public void init()
        throws Exception
     {
        super.init();
        if (container.getInstancePool() instanceof EntityInstancePool)
        {
           ((EntityInstancePool)container.getInstancePool()).setReclaim(true);
        }
     }
  
     protected Synchronization createSynchronization(Transaction tx, 
EntityEnterpriseContext ctx)
     {
        return new MultiInstanceSynchronization(tx, ctx);
     } 
     // Protected  ----------------------------------------------------
   
     // Inner classes -------------------------------------------------
   
     protected class MultiInstanceSynchronization extends 
EntitySynchronizationInterceptor.InstanceSynchronization
     {
        /**
         *  The transaction we follow.
         */
        private Transaction tx;
    
        /**
         *  The context we manage.
         */
        private EntityEnterpriseContext ctx;
    
        /**
         * The context lock
         */
        private BeanLock lock;
    
        /**
         *  Create a new instance synchronization instance.
         */
        MultiInstanceSynchronization(Transaction tx, EntityEnterpriseContext ctx)
        {
           super(tx, ctx);
        }
    
        // Synchronization implementation -----------------------------
    
        public void afterCompletion(int status)
        {
           boolean trace = log.isTraceEnabled();
     
           // This is an independent point of entry. We need to make sure the
           // thread is associated with the right context class loader
           ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
           Thread.currentThread().setContextClassLoader(container.getClassLoader());
     
           lock.sync();
           try
           {
              try
              {
                 // If rolled back -> invalidate instance
                 if (status != Status.STATUS_ROLLEDBACK)
                 {
                    switch (commitOption)
                    {
                       // Keep instance cached after tx commit
                    case ConfigurationMetaData.A_COMMIT_OPTION:
                       throw new IllegalStateException("Commit option A not allowed 
with this Interceptor");
                       // Keep instance active, but invalidate state
                    case ConfigurationMetaData.B_COMMIT_OPTION:
                       break;
                       // Invalidate everything AND Passivate instance
                    case ConfigurationMetaData.C_COMMIT_OPTION:
                       break;
                    case ConfigurationMetaData.D_COMMIT_OPTION:
                       throw new IllegalStateException("Commit option A not allowed 
with this Interceptor");
                    }
                 }
                 try
                 {
                    container.getPersistenceManager().passivateEntity(ctx);
                 }
                 catch (Exception ignored) {}
  
                 container.getInstancePool().free(ctx);
              }
              finally
              {
                 if( trace )
                    log.trace("afterCompletion, clear tx for ctx="+ctx+", tx="+tx);
  
                 lock.endTransaction(tx);
       
                 if( trace )
                    log.trace("afterCompletion, sent notify on TxLock for ctx="+ctx);
              }
           } // synchronized(lock)
           finally
           {
              lock.releaseSync();
              container.getLockManager().removeLockRef(lock.getId());
              Thread.currentThread().setContextClassLoader(oldCl);               
           }
        }
   
     }
   
  }
  
  
  
  1.1                  
jboss/src/main/org/jboss/ejb/plugins/EntityMultiInstanceInterceptor.java
  
  Index: EntityMultiInstanceInterceptor.java
  ===================================================================
  /*
  * JBoss, the OpenSource J2EE webOS
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package org.jboss.ejb.plugins;
  
  import java.lang.reflect.Method;
  import java.rmi.RemoteException;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.ArrayList;
  
  import javax.ejb.EJBObject;
  import javax.ejb.CreateException;
  import javax.ejb.EJBException;
  import javax.ejb.NoSuchEntityException;
  import javax.ejb.RemoveException;
  import javax.ejb.EntityBean;
  import javax.transaction.Status;
  import javax.transaction.Synchronization;
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  import javax.transaction.RollbackException;
  import javax.transaction.SystemException;
  
  import org.jboss.ejb.Container;
  import org.jboss.ejb.BeanLock;
  import org.jboss.ejb.BeanLockManager;
  import org.jboss.ejb.EntityContainer;
  import org.jboss.ejb.EntityPersistenceManager;
  import org.jboss.ejb.EntityEnterpriseContext;
  import org.jboss.ejb.EnterpriseContext;
  import org.jboss.ejb.InstanceCache;
  import org.jboss.ejb.InstancePool;
  import org.jboss.ejb.MethodInvocation;
  import org.jboss.ejb.CacheKey;
  import org.jboss.logging.log4j.JBossCategory;
  import org.jboss.metadata.EntityMetaData;
  import org.jboss.tm.TxManager;
  
  /**
   * The instance interceptors role is to acquire a context representing
   * the target object from the cache.
   *
   *    
   * @author <a href="mailto:[EMAIL PROTECTED]";>Bill Burke</a>
   * @version $Revision: 1.1 $
   *
   * <p><b>Revisions:</b><br>
   * <p><b>2001/08/08: billb</b>
   * <ol>
   *   <li>Initial Revision
   * </ol>
   */
  public class EntityMultiInstanceInterceptor
     extends AbstractInterceptor
  {
     // Constants -----------------------------------------------------
        
     // Attributes ----------------------------------------------------
        
     protected EntityContainer container;
        
     // Static --------------------------------------------------------
        
        /** Use a JBoss custom log4j category for trace level logging */
     static JBossCategory log = (JBossCategory) 
JBossCategory.getInstance(EntityMultiInstanceInterceptor.class);
        
     // Constructors --------------------------------------------------
        
        // Public --------------------------------------------------------
        
     public void setContainer(Container container)
     {
        this.container = (EntityContainer)container;
     }
        
     public Container getContainer()
     {
        return container;
     }
        
     // Interceptor implementation --------------------------------------
        
     public Object invokeHome(MethodInvocation mi)
        throws Exception
     {
        // Get context
        EntityEnterpriseContext ctx = 
(EntityEnterpriseContext)((EntityContainer)getContainer()).getInstancePool().get();
                
                // Pass it to the method invocation
        mi.setEnterpriseContext(ctx);
                
        // Give it the transaction
        ctx.setTransaction(mi.getTransaction());
                
        // Invoke through interceptors
        return getNext().invokeHome(mi);
     }
        
     public Object invoke(MethodInvocation mi)
        throws Exception
     {
                
        // The key
        CacheKey key = (CacheKey) mi.getId();
  
        EntityEnterpriseContext ctx = null;
        if (mi.getTransaction() != null)
        {
           ctx = container.getTxEntityMap().getCtx(mi.getTransaction(), key);
        }
        if (ctx == null)
        {
           ctx = (EntityEnterpriseContext)container.getInstancePool().get();
           ctx.setCacheKey(key);
           ctx.setId(key.getId());
           container.getPersistenceManager().activateEntity(ctx);
        }
                
        boolean trace = log.isTraceEnabled();
        if( trace ) log.trace("Begin invoke, key="+key);
                        
        // Associate transaction, in the new design the lock already has the 
transaction from the 
        // previous interceptor
        ctx.setTransaction(mi.getTransaction());
                
        // Set context on the method invocation
        mi.setEnterpriseContext(ctx);
                
        return getNext().invoke(mi);
     }
        
  }
  
  
  
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to