User: salborini
  Date: 00/09/26 13:18:53

  Modified:    src/main/org/jboss/ejb/plugins BMPPersistenceManager.java
                        CMPPersistenceManager.java
                        EntityInstanceInterceptor.java
                        EntityInstancePool.java
                        EntitySynchronizationInterceptor.java
                        NoPassivationEntityInstanceCache.java
                        NoPassivationStatefulSessionInstanceCache.java
                        RandomEntityInstanceCache.java
                        StatefulSessionFilePersistenceManager.java
                        StatefulSessionInstanceInterceptor.java
                        TxInterceptorCMT.java
  Log:
  Removed DOS ^M at the end of each line
  
  Revision  Changes    Path
  1.9       +315 -315  jboss/src/main/org/jboss/ejb/plugins/BMPPersistenceManager.java
  
  Index: BMPPersistenceManager.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/BMPPersistenceManager.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BMPPersistenceManager.java        2000/09/26 18:39:06     1.8
  +++ BMPPersistenceManager.java        2000/09/26 20:18:50     1.9
  @@ -1,315 +1,315 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/
  -package org.jboss.ejb.plugins;
  -
  -import java.lang.reflect.Method;
  -import java.lang.reflect.InvocationTargetException;
  -import java.rmi.RemoteException;
  -import java.rmi.ServerException;
  -import java.util.Collection;
  -import java.util.ArrayList;
  -import java.util.Enumeration;
  -import java.util.Iterator;
  -
  -import javax.ejb.EntityBean;
  -import javax.ejb.CreateException;
  -import javax.ejb.FinderException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EntityContainer;
  -import org.jboss.ejb.EntityInstanceCache;
  -import org.jboss.ejb.EntityPersistenceManager;
  -import org.jboss.ejb.EntityEnterpriseContext;
  -import org.jboss.logging.Logger;
  -
  -
  -/**
  -*    <description> 
  -*      
  -*    @see <related>
  -*    @author Rickard �berg ([EMAIL PROTECTED])
  -*  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*    @version $Revision: 1.8 $
  -*/
  -public class BMPPersistenceManager
  -implements EntityPersistenceManager
  -{
  -    // Constants -----------------------------------------------------
  -    
  -    // Attributes ----------------------------------------------------
  -    EntityContainer con;
  -    
  -    Method ejbLoad;
  -    Method ejbStore;
  -    Method ejbActivate;
  -    Method ejbPassivate;
  -    Method ejbRemove;
  -    
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    public void setContainer(Container c)
  -    {
  -       con = (EntityContainer)c;
  -    }
  -    
  -    public void init()
  -    throws Exception
  -    {
  -       ejbLoad = EntityBean.class.getMethod("ejbLoad", new Class[0]);
  -       ejbStore = EntityBean.class.getMethod("ejbStore", new Class[0]);
  -       ejbActivate = EntityBean.class.getMethod("ejbActivate", new Class[0]);
  -       ejbPassivate = EntityBean.class.getMethod("ejbPassivate", new Class[0]);
  -       ejbRemove = EntityBean.class.getMethod("ejbRemove", new Class[0]);
  -    }
  -    
  -    public void start()
  -    {
  -    }
  -    
  -    public void stop()
  -    {
  -    }
  -    
  -    public void destroy()
  -    {
  -    }
  -    
  -    public void createEntity(Method m, Object[] args, EntityEnterpriseContext ctx)
  -    throws RemoteException, CreateException
  -    {
  -       // Get methods
  -       try
  -       {
  -         Method createMethod = null;
  -         Method postCreateMethod = null;
  -         
  -         // try to get the create method
  -         try {
  -          createMethod = con.getBeanClass().getMethod("ejbCreate", 
m.getParameterTypes());
  -         } catch (NoSuchMethodException nsme) {
  -          throw new CreateException("corresponding ejbCreate not found " + 
parametersToString(m.getParameterTypes()) + nsme);
  -         }
  -         
  -         // try to get the post create method
  -         try {
  -          postCreateMethod = con.getBeanClass().getMethod("ejbPostCreate", 
m.getParameterTypes());
  -         } catch (NoSuchMethodException nsme) {
  -          throw new CreateException("corresponding ejbPostCreate not found " + 
parametersToString(m.getParameterTypes()) + nsme);
  -         }
  -         
  -         Object id = null;
  -         try {
  -          // Call ejbCreate
  -          id = createMethod.invoke(ctx.getInstance(), args);
  -         } catch (InvocationTargetException ite) {
  -          throw new CreateException("Create failed(could not call ejbCreate):"+ite);
  -         }
  -         
  -         // set the id
  -         ctx.setId(id);
  -         
  -         // Create a new CacheKey
  -         Object cacheKey = ((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey( id );
  -         
  -         // Give it to the context
  -         ctx.setCacheKey(cacheKey);
  -         
  -         // We are going in cache so lock the instance (no need to synch we are 
alone on it)
  -         ctx.lock();
  -         
  -         // Insert in cache, it is now safe
  -         ((EntityInstanceCache) con.getInstanceCache()).insert(ctx);
  -         
  -         // Create EJBObject
  -         ctx.setEJBObject(con.getContainerInvoker().getEntityEJBObject(cacheKey));
  -         
  -         try {
  -          postCreateMethod.invoke(ctx.getInstance(), args);
  -         } catch (InvocationTargetException ite) {
  -          throw new CreateException("Create failed(could not call ejbPostCreate):" 
+ ite);
  -         }
  -         
  -         //      } catch (InvocationTargetException e)
  -         //      {
  -         //         throw new CreateException("Create failed:"+e);
  -         //      } catch (NoSuchMethodException e)
  -         //      {
  -         //         throw new CreateException("Create methods not found:"+e);
  -       } catch (IllegalAccessException e)
  -       {
  -         throw new CreateException("Could not create entity:"+e);
  -       }
  -    }
  -    
  -    public Object findEntity(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  -       throws RemoteException, FinderException
  -    {
  -       // call the finder method
  -       Object objectId = callFinderMethod(finderMethod, args, ctx);
  -       
  -       // get the cache, create a new key and return this new key
  -       return ((EntityInstanceCache)con.getInstanceCache()).createCacheKey( 
objectId );
  -    }
  -    
  -    public Collection findEntities(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  -    throws RemoteException, FinderException
  -    {
  -       // call the finder method
  -       Object result = callFinderMethod(finderMethod, args, ctx);
  -       
  -       if (result == null) {
  -         // for EJB 1.0 compliance
  -         // if the bean couldn't find any matching entities
  -         // it returns null, so we return an empty collection
  -         return new ArrayList();
  -       }
  -       
  -       if (result instanceof java.util.Enumeration) {
  -         // to preserve 1.0 spec compatiblity
  -         ArrayList array = new ArrayList();
  -         Enumeration enum = (Enumeration) result;
  -         while (enum.hasMoreElements() == true) {
  -          // Wrap a cache key around the given object id/primary key
  -          array.add(((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey(enum.nextElement()));
  -         }
  -         return array;
  -       } 
  -       else if (result instanceof java.util.Collection) {
  -         
  -         ArrayList array = new ArrayList(((Collection) result).size());
  -         Iterator enum =  ((Collection) result).iterator();
  -         while (enum.hasNext()) {
  -          // Wrap a cache key around the given object id/primary key
  -          array.add(((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey(enum.next()));
  -         }
  -         return array;
  -       }
  -       else {
  -         // so we received something that's not valid
  -         // throw an exception reporting it
  -         throw new RemoteException("result of finder method is not a valid return 
type: " + result.getClass());
  -       }
  -    }
  -    
  -    public void activateEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException
  -    {
  -       try
  -       {
  -         ejbActivate.invoke(ctx.getInstance(), new Object[0]);
  -       } catch (Exception e)
  -       {
  -         throw new ServerException("Activate failed", e);
  -       }
  -    }
  -    
  -    public void loadEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException
  -    {
  -       try
  -       {
  -         ejbLoad.invoke(ctx.getInstance(), new Object[0]);
  -       } catch (Exception e)
  -       {
  -         throw new ServerException("Load failed", e);
  -       }
  -    }
  -    
  -    public void storeEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException
  -    {
  -       //      Logger.log("Store entity");
  -       try
  -       {
  -         ejbStore.invoke(ctx.getInstance(), new Object[0]);
  -       } catch (Exception e)
  -       {
  -         throw new ServerException("Store failed", e);
  -       }
  -    }
  -    
  -    public void passivateEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException
  -    {
  -       try
  -       {
  -         ejbPassivate.invoke(ctx.getInstance(), new Object[0]);
  -       } catch (Exception e)
  -       {
  -         throw new ServerException("Passivate failed", e);
  -       }
  -    }
  -    
  -    public void removeEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException
  -    {
  -       try
  -       {
  -         ejbRemove.invoke(ctx.getInstance(), new Object[0]);
  -       } catch (Exception e)
  -       {
  -         throw new ServerException("Remove failed", e);
  -       }
  -    }
  -    // Z implementation ----------------------------------------------
  -    
  -    // Package protected ---------------------------------------------
  -    
  -    // Protected -----------------------------------------------------
  -    
  -    // Private -------------------------------------------------------
  -    private Object callFinderMethod(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx) 
  -      throws RemoteException, FinderException
  -   {
  -       // get the finder method
  -       Method callMethod = null;
  -       try {
  -         callMethod = getFinderMethod(con.getBeanClass(), finderMethod, args);
  -       } catch (NoSuchMethodException me) {
  -         // debug
  -         //Logger.exception(me);
  -         throw new RemoteException("couldn't find finder method in bean class. " + 
me.toString());
  -       }
  -       
  -       // invoke the finder method
  -       Object result = null;
  -       try {
  -         result = callMethod.invoke(ctx.getInstance(), args);
  -       } catch (InvocationTargetException e) {
  -        Throwable targetException = e.getTargetException();
  -        if (targetException instanceof FinderException) {
  -          throw (FinderException)targetException;
  -        }
  -        else {
  -          throw new ServerException("exception occured while invoking finder 
method", (Exception)targetException);
  -        }
  -      } catch (Exception e) {
  -         // debug
  -         // DEBUG Logger.exception(e);
  -         throw new ServerException("exception occured while invoking finder 
method",e);
  -       }
  -       
  -       return result;
  -    }
  -    
  -    private Method getFinderMethod(Class beanClass, Method finderMethod, Object[] 
args) throws NoSuchMethodException {
  -       String methodName = "ejbF" + finderMethod.getName().substring(1);
  -       return beanClass.getMethod(methodName, finderMethod.getParameterTypes());
  -    }
  -    
  -    private String parametersToString(Object []a) {
  -       String r = new String();
  -       for(int i=0;i<a.length;i++) r = r + ", " + a[i];
  -         return r;
  -    }
  -    
  -    // Inner classes -------------------------------------------------
  -}
  -
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/
  +package org.jboss.ejb.plugins;
  +
  +import java.lang.reflect.Method;
  +import java.lang.reflect.InvocationTargetException;
  +import java.rmi.RemoteException;
  +import java.rmi.ServerException;
  +import java.util.Collection;
  +import java.util.ArrayList;
  +import java.util.Enumeration;
  +import java.util.Iterator;
  +
  +import javax.ejb.EntityBean;
  +import javax.ejb.CreateException;
  +import javax.ejb.FinderException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EntityContainer;
  +import org.jboss.ejb.EntityInstanceCache;
  +import org.jboss.ejb.EntityPersistenceManager;
  +import org.jboss.ejb.EntityEnterpriseContext;
  +import org.jboss.logging.Logger;
  +
  +
  +/**
  +*    <description> 
  +*      
  +*    @see <related>
  +*    @author Rickard �berg ([EMAIL PROTECTED])
  +*  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*    @version $Revision: 1.9 $
  +*/
  +public class BMPPersistenceManager
  +implements EntityPersistenceManager
  +{
  +    // Constants -----------------------------------------------------
  +    
  +    // Attributes ----------------------------------------------------
  +    EntityContainer con;
  +    
  +    Method ejbLoad;
  +    Method ejbStore;
  +    Method ejbActivate;
  +    Method ejbPassivate;
  +    Method ejbRemove;
  +    
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    public void setContainer(Container c)
  +    {
  +       con = (EntityContainer)c;
  +    }
  +    
  +    public void init()
  +    throws Exception
  +    {
  +       ejbLoad = EntityBean.class.getMethod("ejbLoad", new Class[0]);
  +       ejbStore = EntityBean.class.getMethod("ejbStore", new Class[0]);
  +       ejbActivate = EntityBean.class.getMethod("ejbActivate", new Class[0]);
  +       ejbPassivate = EntityBean.class.getMethod("ejbPassivate", new Class[0]);
  +       ejbRemove = EntityBean.class.getMethod("ejbRemove", new Class[0]);
  +    }
  +    
  +    public void start()
  +    {
  +    }
  +    
  +    public void stop()
  +    {
  +    }
  +    
  +    public void destroy()
  +    {
  +    }
  +    
  +    public void createEntity(Method m, Object[] args, EntityEnterpriseContext ctx)
  +    throws RemoteException, CreateException
  +    {
  +       // Get methods
  +       try
  +       {
  +         Method createMethod = null;
  +         Method postCreateMethod = null;
  +         
  +         // try to get the create method
  +         try {
  +          createMethod = con.getBeanClass().getMethod("ejbCreate", 
m.getParameterTypes());
  +         } catch (NoSuchMethodException nsme) {
  +          throw new CreateException("corresponding ejbCreate not found " + 
parametersToString(m.getParameterTypes()) + nsme);
  +         }
  +         
  +         // try to get the post create method
  +         try {
  +          postCreateMethod = con.getBeanClass().getMethod("ejbPostCreate", 
m.getParameterTypes());
  +         } catch (NoSuchMethodException nsme) {
  +          throw new CreateException("corresponding ejbPostCreate not found " + 
parametersToString(m.getParameterTypes()) + nsme);
  +         }
  +         
  +         Object id = null;
  +         try {
  +          // Call ejbCreate
  +          id = createMethod.invoke(ctx.getInstance(), args);
  +         } catch (InvocationTargetException ite) {
  +          throw new CreateException("Create failed(could not call ejbCreate):"+ite);
  +         }
  +         
  +         // set the id
  +         ctx.setId(id);
  +         
  +         // Create a new CacheKey
  +         Object cacheKey = ((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey( id );
  +         
  +         // Give it to the context
  +         ctx.setCacheKey(cacheKey);
  +         
  +         // We are going in cache so lock the instance (no need to synch we are 
alone on it)
  +         ctx.lock();
  +         
  +         // Insert in cache, it is now safe
  +         ((EntityInstanceCache) con.getInstanceCache()).insert(ctx);
  +         
  +         // Create EJBObject
  +         ctx.setEJBObject(con.getContainerInvoker().getEntityEJBObject(cacheKey));
  +         
  +         try {
  +          postCreateMethod.invoke(ctx.getInstance(), args);
  +         } catch (InvocationTargetException ite) {
  +          throw new CreateException("Create failed(could not call ejbPostCreate):" 
+ ite);
  +         }
  +         
  +         //      } catch (InvocationTargetException e)
  +         //      {
  +         //         throw new CreateException("Create failed:"+e);
  +         //      } catch (NoSuchMethodException e)
  +         //      {
  +         //         throw new CreateException("Create methods not found:"+e);
  +       } catch (IllegalAccessException e)
  +       {
  +         throw new CreateException("Could not create entity:"+e);
  +       }
  +    }
  +    
  +    public Object findEntity(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  +       throws RemoteException, FinderException
  +    {
  +       // call the finder method
  +       Object objectId = callFinderMethod(finderMethod, args, ctx);
  +       
  +       // get the cache, create a new key and return this new key
  +       return ((EntityInstanceCache)con.getInstanceCache()).createCacheKey( 
objectId );
  +    }
  +    
  +    public Collection findEntities(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  +    throws RemoteException, FinderException
  +    {
  +       // call the finder method
  +       Object result = callFinderMethod(finderMethod, args, ctx);
  +       
  +       if (result == null) {
  +         // for EJB 1.0 compliance
  +         // if the bean couldn't find any matching entities
  +         // it returns null, so we return an empty collection
  +         return new ArrayList();
  +       }
  +       
  +       if (result instanceof java.util.Enumeration) {
  +         // to preserve 1.0 spec compatiblity
  +         ArrayList array = new ArrayList();
  +         Enumeration enum = (Enumeration) result;
  +         while (enum.hasMoreElements() == true) {
  +          // Wrap a cache key around the given object id/primary key
  +          array.add(((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey(enum.nextElement()));
  +         }
  +         return array;
  +       } 
  +       else if (result instanceof java.util.Collection) {
  +         
  +         ArrayList array = new ArrayList(((Collection) result).size());
  +         Iterator enum =  ((Collection) result).iterator();
  +         while (enum.hasNext()) {
  +          // Wrap a cache key around the given object id/primary key
  +          array.add(((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey(enum.next()));
  +         }
  +         return array;
  +       }
  +       else {
  +         // so we received something that's not valid
  +         // throw an exception reporting it
  +         throw new RemoteException("result of finder method is not a valid return 
type: " + result.getClass());
  +       }
  +    }
  +    
  +    public void activateEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException
  +    {
  +       try
  +       {
  +         ejbActivate.invoke(ctx.getInstance(), new Object[0]);
  +       } catch (Exception e)
  +       {
  +         throw new ServerException("Activate failed", e);
  +       }
  +    }
  +    
  +    public void loadEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException
  +    {
  +       try
  +       {
  +         ejbLoad.invoke(ctx.getInstance(), new Object[0]);
  +       } catch (Exception e)
  +       {
  +         throw new ServerException("Load failed", e);
  +       }
  +    }
  +    
  +    public void storeEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException
  +    {
  +       //      Logger.log("Store entity");
  +       try
  +       {
  +         ejbStore.invoke(ctx.getInstance(), new Object[0]);
  +       } catch (Exception e)
  +       {
  +         throw new ServerException("Store failed", e);
  +       }
  +    }
  +    
  +    public void passivateEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException
  +    {
  +       try
  +       {
  +         ejbPassivate.invoke(ctx.getInstance(), new Object[0]);
  +       } catch (Exception e)
  +       {
  +         throw new ServerException("Passivate failed", e);
  +       }
  +    }
  +    
  +    public void removeEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException
  +    {
  +       try
  +       {
  +         ejbRemove.invoke(ctx.getInstance(), new Object[0]);
  +       } catch (Exception e)
  +       {
  +         throw new ServerException("Remove failed", e);
  +       }
  +    }
  +    // Z implementation ----------------------------------------------
  +    
  +    // Package protected ---------------------------------------------
  +    
  +    // Protected -----------------------------------------------------
  +    
  +    // Private -------------------------------------------------------
  +    private Object callFinderMethod(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx) 
  +      throws RemoteException, FinderException
  +   {
  +       // get the finder method
  +       Method callMethod = null;
  +       try {
  +         callMethod = getFinderMethod(con.getBeanClass(), finderMethod, args);
  +       } catch (NoSuchMethodException me) {
  +         // debug
  +         //Logger.exception(me);
  +         throw new RemoteException("couldn't find finder method in bean class. " + 
me.toString());
  +       }
  +       
  +       // invoke the finder method
  +       Object result = null;
  +       try {
  +         result = callMethod.invoke(ctx.getInstance(), args);
  +       } catch (InvocationTargetException e) {
  +        Throwable targetException = e.getTargetException();
  +        if (targetException instanceof FinderException) {
  +          throw (FinderException)targetException;
  +        }
  +        else {
  +          throw new ServerException("exception occured while invoking finder 
method", (Exception)targetException);
  +        }
  +      } catch (Exception e) {
  +         // debug
  +         // DEBUG Logger.exception(e);
  +         throw new ServerException("exception occured while invoking finder 
method",e);
  +       }
  +       
  +       return result;
  +    }
  +    
  +    private Method getFinderMethod(Class beanClass, Method finderMethod, Object[] 
args) throws NoSuchMethodException {
  +       String methodName = "ejbF" + finderMethod.getName().substring(1);
  +       return beanClass.getMethod(methodName, finderMethod.getParameterTypes());
  +    }
  +    
  +    private String parametersToString(Object []a) {
  +       String r = new String();
  +       for(int i=0;i<a.length;i++) r = r + ", " + a[i];
  +         return r;
  +    }
  +    
  +    // Inner classes -------------------------------------------------
  +}
  +
  
  
  
  1.7       +274 -274  jboss/src/main/org/jboss/ejb/plugins/CMPPersistenceManager.java
  
  Index: CMPPersistenceManager.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/CMPPersistenceManager.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CMPPersistenceManager.java        2000/09/26 18:39:58     1.6
  +++ CMPPersistenceManager.java        2000/09/26 20:18:50     1.7
  @@ -1,274 +1,274 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/                           
  -package org.jboss.ejb.plugins;
  -
  -import java.lang.reflect.Method;
  -import java.lang.reflect.InvocationTargetException;
  -import java.rmi.RemoteException;
  -import java.rmi.ServerException;
  -import java.util.Collection;                                
  -import java.util.Iterator;
  -import java.util.ArrayList;
  -
  -import javax.ejb.EntityBean;
  -import javax.ejb.CreateException;
  -import javax.ejb.FinderException;
  -import javax.ejb.RemoveException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EntityContainer;
  -import org.jboss.ejb.EntityPersistenceManager;
  -import org.jboss.ejb.EntityEnterpriseContext;
  -import org.jboss.ejb.EntityInstanceCache;
  -import org.jboss.ejb.EntityPersistenceStore;
  -
  -/**
  -*    The CMP Persistence Manager implements the semantics of the CMP
  -*  EJB 1.1 call back specification. 
  -*
  -*  This Manager works with a "EntityPersistenceStore" that takes care of the 
  -*  physical storing of instances (JAWS, JDBC O/R, FILE, Object).
  -*      
  -*    @see <related>
  -*    @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*    @version $Revision: 1.6 $
  -*/
  -public class CMPPersistenceManager
  -implements EntityPersistenceManager {
  -    // Constants -----------------------------------------------------
  -    
  -    // Attributes ----------------------------------------------------
  -    EntityContainer con;
  -    // Physical persistence implementation
  -    EntityPersistenceStore store;
  -    
  -    // The EJB Methods, the reason for this class
  -    Method ejbLoad;
  -    Method ejbStore;
  -    Method ejbActivate;
  -    Method ejbPassivate;
  -    Method ejbRemove;
  -    
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    public void setContainer(Container c)    {
  -        con = (EntityContainer)c;
  -        if (store != null) store.setContainer(c);
  -    }
  -    
  -    
  -    public void setPersistenceStore(EntityPersistenceStore store) {
  -        this.store= store;
  -        
  -        //Give it the container
  -        if (con!= null) store.setContainer(con);
  -    }
  -    
  -    public void init()
  -    throws Exception {
  -        
  -        // The common EJB methods
  -        ejbLoad = EntityBean.class.getMethod("ejbLoad", new Class[0]);
  -        ejbStore = EntityBean.class.getMethod("ejbStore", new Class[0]);
  -        ejbActivate = EntityBean.class.getMethod("ejbActivate", new Class[0]);
  -        ejbPassivate = EntityBean.class.getMethod("ejbPassivate", new Class[0]);
  -        ejbRemove = EntityBean.class.getMethod("ejbRemove", new Class[0]);
  -        
  -        // Initialize the sto re
  -        store.init();
  -    }
  -    
  -    public void start() 
  -    throws Exception {
  -        
  -        store.start();
  -    }
  -    
  -    public void stop() {
  -        store.stop();
  -    }
  -    
  -    public void destroy() {
  -        store.destroy();
  -    }
  -    
  -    public void createEntity(Method m, Object[] args, EntityEnterpriseContext ctx)
  -    throws RemoteException, CreateException {
  -        // Get methods
  -        try {
  -            
  -            Method createMethod = con.getBeanClass().getMethod("ejbCreate", 
m.getParameterTypes());
  -            Method postCreateMethod = con.getBeanClass().getMethod("ejbPostCreate", 
m.getParameterTypes());
  -            
  -            // Call ejbCreate on the target bean
  -            createMethod.invoke(ctx.getInstance(), args);
  -            
  -            // Have the store persist the new instance, the return is the key
  -            Object id = store.createEntity(m, args, ctx);
  -            
  -            // Set the key on the target context
  -            ctx.setId(id);
  -            
  -            // Create a new CacheKey
  -               Object cacheKey = ((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey( id );
  -        
  -             // Give it to the context
  -             ctx.setCacheKey(cacheKey);
  -         
  -         
  -             // insert instance in cache, it is safe
  -             ((EntityInstanceCache) con.getInstanceCache()).insert(ctx);
  -         
  -            // Create EJBObject
  -            
ctx.setEJBObject(con.getContainerInvoker().getEntityEJBObject(cacheKey));
  -            
  -            postCreateMethod.invoke(ctx.getInstance(), args);
  -        
  -        } 
  -        catch (InvocationTargetException e) {
  -            throw new CreateException("Create failed:"+e);
  -        } 
  -        catch (NoSuchMethodException e) {
  -            throw new CreateException("Create methods not found:"+e);
  -        } 
  -        catch (IllegalAccessException e) {
  -            throw new CreateException("Could not create entity:"+e);
  -        }
  -    }
  -    
  -    public Object findEntity(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  -    throws RemoteException, FinderException {
  -      
  -       // The store will find the entity and return the primaryKey
  -       Object id = store.findEntity(finderMethod, args, ctx);
  -       
  -       // We return the cache key
  -        return ((EntityInstanceCache) con.getInstanceCache()).createCacheKey(id);
  -    }
  -    
  -    public Collection findEntities(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  -    throws RemoteException, FinderException {
  -
  -       // The store will find the id and return a collection of PrimaryKeys
  -       Collection ids = store.findEntities(finderMethod, args, ctx);
  -       
  -       // Build a collection of cacheKeys
  -       ArrayList list = new ArrayList(ids.size());
  -        Iterator idEnum = ids.iterator();
  -        while(idEnum.hasNext()) {
  -         
  -         // Get a cache key for it
  -         list.add(((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey(idEnum.next()));
  -         }
  -        
  -       return list;           
  -    }
  -    
  -    /*
  -    * activateEntity(EnterpriseContext ctx) 
  -    *
  -    * The method calls the target beans for spec compliant callbacks.
  -    * Since these are pure EJB calls it is not obvious that the store should 
  -    * expose the interfaces.  In case of jaws however we found that store specific
  -    * contexts could be set in the activateEntity calls and hence a propagation of 
  -    * the call made sense.  The persistence store is called for "extension" 
purposes.
  -    *
  -    * @see activateEntity on EntityPersistenceStore.java
  -    */
  -    public void activateEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException {
  -        
  -        // Call bean
  -        try
  -        {
  -            ejbActivate.invoke(ctx.getInstance(), new Object[0]);
  -        } catch (Exception e)
  -        {
  -            throw new ServerException("Activation failed", e);
  -        }
  -        
  -        store.activateEntity(ctx);
  -    }
  -    
  -    public void loadEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException {
  -        
  -        try {
  -            
  -            // Have the store deal with create the fields of the instance
  -            store.loadEntity(ctx);
  -            
  -            // Call ejbLoad on bean instance, wake up!
  -            ejbLoad.invoke(ctx.getInstance(), new Object[0]);
  -        }
  -        catch (Exception e) {
  -            throw new ServerException("Load failed", e);
  -        }
  -    }
  -    
  -    public void storeEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException {
  -        //      Logger.log("Store entity");
  -        try {
  -            
  -            // Prepare the instance for storage
  -            ejbStore.invoke(ctx.getInstance(), new Object[0]);
  -            
  -            // Have the store deal with storing the fields of the instance
  -            store.storeEntity(ctx);
  -        } 
  -        
  -        catch (Exception e) {
  -            throw new ServerException("Store failed", e);
  -        }
  -    }
  -    
  -    public void passivateEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException {
  -        
  -        try {
  -            
  -            // Prepare the instance for passivation 
  -            ejbPassivate.invoke(ctx.getInstance(), new Object[0]);
  -        } 
  -        catch (Exception e) {
  -            
  -            throw new ServerException("Passivation failed", e);
  -        }
  -        
  -        store.passivateEntity(ctx);
  -    }
  -    
  -    public void removeEntity(EntityEnterpriseContext ctx)
  -    throws RemoteException, RemoveException {
  -        
  -        try {
  -            
  -            // Call ejbRemove
  -            ejbRemove.invoke(ctx.getInstance(), new Object[0]);
  -        } 
  -        catch (Exception e){
  -            
  -            throw new RemoveException("Could not remove "+ctx.getId());
  -        }
  -        
  -        store.removeEntity(ctx);
  -    }
  -    // Z implementation ----------------------------------------------
  -    
  -    // Package protected ---------------------------------------------
  -    
  -    // Protected -----------------------------------------------------
  -    
  -    // Private -------------------------------------------------------
  -    
  -    // Inner classes -------------------------------------------------
  -}
  -
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/                           
  +package org.jboss.ejb.plugins;
  +
  +import java.lang.reflect.Method;
  +import java.lang.reflect.InvocationTargetException;
  +import java.rmi.RemoteException;
  +import java.rmi.ServerException;
  +import java.util.Collection;                                
  +import java.util.Iterator;
  +import java.util.ArrayList;
  +
  +import javax.ejb.EntityBean;
  +import javax.ejb.CreateException;
  +import javax.ejb.FinderException;
  +import javax.ejb.RemoveException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EntityContainer;
  +import org.jboss.ejb.EntityPersistenceManager;
  +import org.jboss.ejb.EntityEnterpriseContext;
  +import org.jboss.ejb.EntityInstanceCache;
  +import org.jboss.ejb.EntityPersistenceStore;
  +
  +/**
  +*    The CMP Persistence Manager implements the semantics of the CMP
  +*  EJB 1.1 call back specification. 
  +*
  +*  This Manager works with a "EntityPersistenceStore" that takes care of the 
  +*  physical storing of instances (JAWS, JDBC O/R, FILE, Object).
  +*      
  +*    @see <related>
  +*    @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*    @version $Revision: 1.7 $
  +*/
  +public class CMPPersistenceManager
  +implements EntityPersistenceManager {
  +    // Constants -----------------------------------------------------
  +    
  +    // Attributes ----------------------------------------------------
  +    EntityContainer con;
  +    // Physical persistence implementation
  +    EntityPersistenceStore store;
  +    
  +    // The EJB Methods, the reason for this class
  +    Method ejbLoad;
  +    Method ejbStore;
  +    Method ejbActivate;
  +    Method ejbPassivate;
  +    Method ejbRemove;
  +    
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    public void setContainer(Container c)    {
  +        con = (EntityContainer)c;
  +        if (store != null) store.setContainer(c);
  +    }
  +    
  +    
  +    public void setPersistenceStore(EntityPersistenceStore store) {
  +        this.store= store;
  +        
  +        //Give it the container
  +        if (con!= null) store.setContainer(con);
  +    }
  +    
  +    public void init()
  +    throws Exception {
  +        
  +        // The common EJB methods
  +        ejbLoad = EntityBean.class.getMethod("ejbLoad", new Class[0]);
  +        ejbStore = EntityBean.class.getMethod("ejbStore", new Class[0]);
  +        ejbActivate = EntityBean.class.getMethod("ejbActivate", new Class[0]);
  +        ejbPassivate = EntityBean.class.getMethod("ejbPassivate", new Class[0]);
  +        ejbRemove = EntityBean.class.getMethod("ejbRemove", new Class[0]);
  +        
  +        // Initialize the sto re
  +        store.init();
  +    }
  +    
  +    public void start() 
  +    throws Exception {
  +        
  +        store.start();
  +    }
  +    
  +    public void stop() {
  +        store.stop();
  +    }
  +    
  +    public void destroy() {
  +        store.destroy();
  +    }
  +    
  +    public void createEntity(Method m, Object[] args, EntityEnterpriseContext ctx)
  +    throws RemoteException, CreateException {
  +        // Get methods
  +        try {
  +            
  +            Method createMethod = con.getBeanClass().getMethod("ejbCreate", 
m.getParameterTypes());
  +            Method postCreateMethod = con.getBeanClass().getMethod("ejbPostCreate", 
m.getParameterTypes());
  +            
  +            // Call ejbCreate on the target bean
  +            createMethod.invoke(ctx.getInstance(), args);
  +            
  +            // Have the store persist the new instance, the return is the key
  +            Object id = store.createEntity(m, args, ctx);
  +            
  +            // Set the key on the target context
  +            ctx.setId(id);
  +            
  +            // Create a new CacheKey
  +               Object cacheKey = ((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey( id );
  +        
  +             // Give it to the context
  +             ctx.setCacheKey(cacheKey);
  +         
  +         
  +             // insert instance in cache, it is safe
  +             ((EntityInstanceCache) con.getInstanceCache()).insert(ctx);
  +         
  +            // Create EJBObject
  +            
ctx.setEJBObject(con.getContainerInvoker().getEntityEJBObject(cacheKey));
  +            
  +            postCreateMethod.invoke(ctx.getInstance(), args);
  +        
  +        } 
  +        catch (InvocationTargetException e) {
  +            throw new CreateException("Create failed:"+e);
  +        } 
  +        catch (NoSuchMethodException e) {
  +            throw new CreateException("Create methods not found:"+e);
  +        } 
  +        catch (IllegalAccessException e) {
  +            throw new CreateException("Could not create entity:"+e);
  +        }
  +    }
  +    
  +    public Object findEntity(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  +    throws RemoteException, FinderException {
  +      
  +       // The store will find the entity and return the primaryKey
  +       Object id = store.findEntity(finderMethod, args, ctx);
  +       
  +       // We return the cache key
  +        return ((EntityInstanceCache) con.getInstanceCache()).createCacheKey(id);
  +    }
  +    
  +    public Collection findEntities(Method finderMethod, Object[] args, 
EntityEnterpriseContext ctx)
  +    throws RemoteException, FinderException {
  +
  +       // The store will find the id and return a collection of PrimaryKeys
  +       Collection ids = store.findEntities(finderMethod, args, ctx);
  +       
  +       // Build a collection of cacheKeys
  +       ArrayList list = new ArrayList(ids.size());
  +        Iterator idEnum = ids.iterator();
  +        while(idEnum.hasNext()) {
  +         
  +         // Get a cache key for it
  +         list.add(((EntityInstanceCache) 
con.getInstanceCache()).createCacheKey(idEnum.next()));
  +         }
  +        
  +       return list;           
  +    }
  +    
  +    /*
  +    * activateEntity(EnterpriseContext ctx) 
  +    *
  +    * The method calls the target beans for spec compliant callbacks.
  +    * Since these are pure EJB calls it is not obvious that the store should 
  +    * expose the interfaces.  In case of jaws however we found that store specific
  +    * contexts could be set in the activateEntity calls and hence a propagation of 
  +    * the call made sense.  The persistence store is called for "extension" 
purposes.
  +    *
  +    * @see activateEntity on EntityPersistenceStore.java
  +    */
  +    public void activateEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException {
  +        
  +        // Call bean
  +        try
  +        {
  +            ejbActivate.invoke(ctx.getInstance(), new Object[0]);
  +        } catch (Exception e)
  +        {
  +            throw new ServerException("Activation failed", e);
  +        }
  +        
  +        store.activateEntity(ctx);
  +    }
  +    
  +    public void loadEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException {
  +        
  +        try {
  +            
  +            // Have the store deal with create the fields of the instance
  +            store.loadEntity(ctx);
  +            
  +            // Call ejbLoad on bean instance, wake up!
  +            ejbLoad.invoke(ctx.getInstance(), new Object[0]);
  +        }
  +        catch (Exception e) {
  +            throw new ServerException("Load failed", e);
  +        }
  +    }
  +    
  +    public void storeEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException {
  +        //      Logger.log("Store entity");
  +        try {
  +            
  +            // Prepare the instance for storage
  +            ejbStore.invoke(ctx.getInstance(), new Object[0]);
  +            
  +            // Have the store deal with storing the fields of the instance
  +            store.storeEntity(ctx);
  +        } 
  +        
  +        catch (Exception e) {
  +            throw new ServerException("Store failed", e);
  +        }
  +    }
  +    
  +    public void passivateEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException {
  +        
  +        try {
  +            
  +            // Prepare the instance for passivation 
  +            ejbPassivate.invoke(ctx.getInstance(), new Object[0]);
  +        } 
  +        catch (Exception e) {
  +            
  +            throw new ServerException("Passivation failed", e);
  +        }
  +        
  +        store.passivateEntity(ctx);
  +    }
  +    
  +    public void removeEntity(EntityEnterpriseContext ctx)
  +    throws RemoteException, RemoveException {
  +        
  +        try {
  +            
  +            // Call ejbRemove
  +            ejbRemove.invoke(ctx.getInstance(), new Object[0]);
  +        } 
  +        catch (Exception e){
  +            
  +            throw new RemoveException("Could not remove "+ctx.getId());
  +        }
  +        
  +        store.removeEntity(ctx);
  +    }
  +    // Z implementation ----------------------------------------------
  +    
  +    // Package protected ---------------------------------------------
  +    
  +    // Protected -----------------------------------------------------
  +    
  +    // Private -------------------------------------------------------
  +    
  +    // Inner classes -------------------------------------------------
  +}
  +
  
  
  
  1.9       +261 -261  
jboss/src/main/org/jboss/ejb/plugins/EntityInstanceInterceptor.java
  
  Index: EntityInstanceInterceptor.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/EntityInstanceInterceptor.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- EntityInstanceInterceptor.java    2000/09/26 18:41:15     1.8
  +++ EntityInstanceInterceptor.java    2000/09/26 20:18:50     1.9
  @@ -1,261 +1,261 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL 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.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.metadata.EntityMetaData;
  -
  -/**
  -*   This container acquires the given instance. 
  -*
  -*   @see <related>
  -*   @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
  -*   @version $Revision: 1.8 $
  -*/
  -public class EntityInstanceInterceptor
  -extends AbstractInterceptor
  -{
  -     // Constants -----------------------------------------------------
  -     
  -     // Attributes ----------------------------------------------------
  -     protected EntityContainer container;
  -     
  -     // Static --------------------------------------------------------
  -     
  -     // 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
  -             EnterpriseContext ctx = 
((EntityContainer)getContainer()).getInstancePool().get();
  -             mi.setEnterpriseContext(ctx);
  -             
  -             // It is a new context for sure so we can lock it (no need for sync 
(not in cache))
  -             ctx.lock();
  -             
  -             try
  -             {
  -                     // Invoke through interceptors
  -                     return getNext().invokeHome(mi);
  -             } finally
  -             {
  -                     // Still free? Not free if create() was called successfully
  -                     if (mi.getEnterpriseContext().getId() == null)
  -                     {
  -                             // Free that context
  -                             ctx.unlock();
  -                             
  -                             
container.getInstancePool().free(mi.getEnterpriseContext());
  -                     } 
  -                     else
  -                     {
  -                             // DEBUG           Logger.log("Entity was created; not 
returned to pool");
  -                             synchronized (ctx) {
  -                                     
  -                                     // Release the lock
  -                                     ctx.unlock();
  -                                     
  -                                     //Let the waiters know
  -                                     ctx.notifyAll();
  -                             }
  -                     }
  -             }
  -     }
  -     
  -     public Object invoke(MethodInvocation mi)
  -     throws Exception
  -     {
  -             // The id store is a CacheKey in the case of Entity 
  -             CacheKey key = (CacheKey) mi.getId();
  -             
  -             // Get context
  -             EnterpriseContext ctx = 
((EntityContainer)getContainer()).getInstanceCache().get(key);
  -             
  -             // Set it on the method invocation
  -             mi.setEnterpriseContext(ctx);
  -             
  -             // We synchronize the locking logic (so that the invoke is 
unsynchronized and can be reentrant)
  -             synchronized (ctx) 
  -             {
  -                     // Do we have a running transaction with the context
  -                     if (ctx.getTransaction() != null &&
  -                             // And are we trying to enter with another transaction
  -                             !ctx.getTransaction().equals(mi.getTransaction())) 
  -                     {
  -                             // Let's put the thread to sleep a lock release will 
wake the thread
  -                             try{ctx.wait();}
  -                                     catch (InterruptedException ie) {}
  -                             
  -                             // Try your luck again
  -                             return invoke(mi);
  -                     }
  -                     
  -                     if (!ctx.isLocked()){
  -                             
  -                             //take it!
  -                             ctx.lock();  
  -                     }
  -                     
  -                     else 
  -                     {
  -                             if (!isCallAllowed(mi)) {
  -                                     
  -                                     // Let's put the thread to sleep a lock 
release will wake the thread
  -                                     try{ctx.wait();}
  -                                             catch (InterruptedException ie) {}
  -                                     
  -                                     // Try your luck again
  -                                     return invoke(mi);
  -                             }
  -                             
  -                             // The call is allowed, do increment the lock though 
(ctx already locked)
  -                             ctx.lock();
  -                     }
  -             
  -             } 
  -             
  -             try {
  -                     
  -                     // Go on, you won
  -                     return getNext().invoke(mi);
  -             
  -             } 
  -             catch (RemoteException e)
  -             {
  -                     // Discard instance
  -                     // EJB 1.1 spec 12.3.1
  -                     
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  -                     
  -                     throw e;
  -             } catch (RuntimeException e)
  -             {
  -                     // Discard instance
  -                     // EJB 1.1 spec 12.3.1
  -                     
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  -                     
  -                     throw e;
  -             } catch (Error e)
  -             {
  -                     // Discard instance
  -                     // EJB 1.1 spec 12.3.1
  -                     
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  -                     
  -                     throw e;
  -             } finally
  -             {
  -                     //         Logger.log("Release instance for "+id);
  -                     if (ctx != null)
  -                     {
  -                             
  -                             synchronized (ctx) {
  -                                     
  -                                     // unlock the context
  -                                     ctx.unlock();
  -                                     
  -                                     if (ctx.getId() == null)                       
      
  -                                     {
  -                                             // Remove from cache
  -                                             
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  -                                             
  -                                             // It has been removed -> send to free 
pool
  -                                             container.getInstancePool().free(ctx);
  -                                     }
  -                                     
  -                                     // notify the thread waiting on ctx
  -                                     ctx.notifyAll();
  -                             }
  -                     }
  -             }
  -     }
  -     
  -     // Private --------------------------------------------------------
  -     
  -     private static Method getEJBHome;
  -     private static Method getHandle;
  -     private static Method getPrimaryKey;
  -     private static Method isIdentical;
  -     private static Method remove;
  -     static 
  -     {
  -             try 
  -             {
  -                     Class[] noArg = new Class[0];
  -                     getEJBHome = EJBObject.class.getMethod("getEJBHome", noArg);
  -                     getHandle = EJBObject.class.getMethod("getHandle", noArg);
  -                     getPrimaryKey = EJBObject.class.getMethod("getPrimaryKey", 
noArg);
  -                     isIdentical = EJBObject.class.getMethod("isIdentical", new 
Class[] {EJBObject.class});
  -                     remove = EJBObject.class.getMethod("remove", noArg);
  -             }
  -             catch (Exception x) {x.printStackTrace();}
  -     }
  -     
  -     private boolean isCallAllowed(MethodInvocation mi) 
  -     {
  -             boolean reentrant = 
((EntityMetaData)container.getBeanMetaData()).isReentrant();
  -             
  -             if (reentrant)
  -             {
  -                     return true;
  -             }
  -             else
  -             {
  -                     Method m = mi.getMethod();
  -                     if (m.equals(getEJBHome) ||
  -                             m.equals(getHandle) ||
  -                             m.equals(getPrimaryKey) ||
  -                             m.equals(isIdentical) ||
  -                             m.equals(remove))
  -                     {
  -                             return true;
  -                     }
  -             }
  -             
  -             return false;
  -     }
  -}
  -
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL 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.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.metadata.EntityMetaData;
  +
  +/**
  +*   This container acquires the given instance. 
  +*
  +*   @see <related>
  +*   @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
  +*   @version $Revision: 1.9 $
  +*/
  +public class EntityInstanceInterceptor
  +extends AbstractInterceptor
  +{
  +     // Constants -----------------------------------------------------
  +     
  +     // Attributes ----------------------------------------------------
  +     protected EntityContainer container;
  +     
  +     // Static --------------------------------------------------------
  +     
  +     // 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
  +             EnterpriseContext ctx = 
((EntityContainer)getContainer()).getInstancePool().get();
  +             mi.setEnterpriseContext(ctx);
  +             
  +             // It is a new context for sure so we can lock it (no need for sync 
(not in cache))
  +             ctx.lock();
  +             
  +             try
  +             {
  +                     // Invoke through interceptors
  +                     return getNext().invokeHome(mi);
  +             } finally
  +             {
  +                     // Still free? Not free if create() was called successfully
  +                     if (mi.getEnterpriseContext().getId() == null)
  +                     {
  +                             // Free that context
  +                             ctx.unlock();
  +                             
  +                             
container.getInstancePool().free(mi.getEnterpriseContext());
  +                     } 
  +                     else
  +                     {
  +                             // DEBUG           Logger.log("Entity was created; not 
returned to pool");
  +                             synchronized (ctx) {
  +                                     
  +                                     // Release the lock
  +                                     ctx.unlock();
  +                                     
  +                                     //Let the waiters know
  +                                     ctx.notifyAll();
  +                             }
  +                     }
  +             }
  +     }
  +     
  +     public Object invoke(MethodInvocation mi)
  +     throws Exception
  +     {
  +             // The id store is a CacheKey in the case of Entity 
  +             CacheKey key = (CacheKey) mi.getId();
  +             
  +             // Get context
  +             EnterpriseContext ctx = 
((EntityContainer)getContainer()).getInstanceCache().get(key);
  +             
  +             // Set it on the method invocation
  +             mi.setEnterpriseContext(ctx);
  +             
  +             // We synchronize the locking logic (so that the invoke is 
unsynchronized and can be reentrant)
  +             synchronized (ctx) 
  +             {
  +                     // Do we have a running transaction with the context
  +                     if (ctx.getTransaction() != null &&
  +                             // And are we trying to enter with another transaction
  +                             !ctx.getTransaction().equals(mi.getTransaction())) 
  +                     {
  +                             // Let's put the thread to sleep a lock release will 
wake the thread
  +                             try{ctx.wait();}
  +                                     catch (InterruptedException ie) {}
  +                             
  +                             // Try your luck again
  +                             return invoke(mi);
  +                     }
  +                     
  +                     if (!ctx.isLocked()){
  +                             
  +                             //take it!
  +                             ctx.lock();  
  +                     }
  +                     
  +                     else 
  +                     {
  +                             if (!isCallAllowed(mi)) {
  +                                     
  +                                     // Let's put the thread to sleep a lock 
release will wake the thread
  +                                     try{ctx.wait();}
  +                                             catch (InterruptedException ie) {}
  +                                     
  +                                     // Try your luck again
  +                                     return invoke(mi);
  +                             }
  +                             
  +                             // The call is allowed, do increment the lock though 
(ctx already locked)
  +                             ctx.lock();
  +                     }
  +             
  +             } 
  +             
  +             try {
  +                     
  +                     // Go on, you won
  +                     return getNext().invoke(mi);
  +             
  +             } 
  +             catch (RemoteException e)
  +             {
  +                     // Discard instance
  +                     // EJB 1.1 spec 12.3.1
  +                     
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  +                     
  +                     throw e;
  +             } catch (RuntimeException e)
  +             {
  +                     // Discard instance
  +                     // EJB 1.1 spec 12.3.1
  +                     
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  +                     
  +                     throw e;
  +             } catch (Error e)
  +             {
  +                     // Discard instance
  +                     // EJB 1.1 spec 12.3.1
  +                     
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  +                     
  +                     throw e;
  +             } finally
  +             {
  +                     //         Logger.log("Release instance for "+id);
  +                     if (ctx != null)
  +                     {
  +                             
  +                             synchronized (ctx) {
  +                                     
  +                                     // unlock the context
  +                                     ctx.unlock();
  +                                     
  +                                     if (ctx.getId() == null)                       
      
  +                                     {
  +                                             // Remove from cache
  +                                             
((EntityContainer)getContainer()).getInstanceCache().remove(key.id);
  +                                             
  +                                             // It has been removed -> send to free 
pool
  +                                             container.getInstancePool().free(ctx);
  +                                     }
  +                                     
  +                                     // notify the thread waiting on ctx
  +                                     ctx.notifyAll();
  +                             }
  +                     }
  +             }
  +     }
  +     
  +     // Private --------------------------------------------------------
  +     
  +     private static Method getEJBHome;
  +     private static Method getHandle;
  +     private static Method getPrimaryKey;
  +     private static Method isIdentical;
  +     private static Method remove;
  +     static 
  +     {
  +             try 
  +             {
  +                     Class[] noArg = new Class[0];
  +                     getEJBHome = EJBObject.class.getMethod("getEJBHome", noArg);
  +                     getHandle = EJBObject.class.getMethod("getHandle", noArg);
  +                     getPrimaryKey = EJBObject.class.getMethod("getPrimaryKey", 
noArg);
  +                     isIdentical = EJBObject.class.getMethod("isIdentical", new 
Class[] {EJBObject.class});
  +                     remove = EJBObject.class.getMethod("remove", noArg);
  +             }
  +             catch (Exception x) {x.printStackTrace();}
  +     }
  +     
  +     private boolean isCallAllowed(MethodInvocation mi) 
  +     {
  +             boolean reentrant = 
((EntityMetaData)container.getBeanMetaData()).isReentrant();
  +             
  +             if (reentrant)
  +             {
  +                     return true;
  +             }
  +             else
  +             {
  +                     Method m = mi.getMethod();
  +                     if (m.equals(getEJBHome) ||
  +                             m.equals(getHandle) ||
  +                             m.equals(getPrimaryKey) ||
  +                             m.equals(isIdentical) ||
  +                             m.equals(remove))
  +                     {
  +                             return true;
  +                     }
  +             }
  +             
  +             return false;
  +     }
  +}
  +
  
  
  
  1.6       +78 -78    jboss/src/main/org/jboss/ejb/plugins/EntityInstancePool.java
  
  Index: EntityInstancePool.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/EntityInstancePool.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- EntityInstancePool.java   2000/09/26 18:44:05     1.5
  +++ EntityInstancePool.java   2000/09/26 20:18:50     1.6
  @@ -1,78 +1,78 @@
  -/*
  - * jBoss, the OpenSource EJB server
  - *
  - * Distributable under GPL license.
  - * See terms of license at gnu.org.
  - */
  -package org.jboss.ejb.plugins;
  -
  -import java.rmi.RemoteException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.EntityEnterpriseContext;
  -
  -/**
  - *   <description> 
  - *      
  - *   @see <related>
  - *   @author Rickard �berg ([EMAIL PROTECTED])
  - *  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  - *   @version $Revision: 1.5 $
  - */
  -public class EntityInstancePool
  -   extends AbstractInstancePool
  -{
  -   // Constants -----------------------------------------------------
  -    
  -   // Attributes ----------------------------------------------------
  -   
  -   // Static --------------------------------------------------------
  -   
  -   // Constructors --------------------------------------------------
  -   
  -   // Public --------------------------------------------------------
  -   /**
  -    *   Return an instance to the free pool. Reset state
  -    *
  -    *   Called in 3 cases:
  -    *   a) Done with finder method
  -    *   b) Removed
  -    *   c) Passivated
  -    *
  -    * @param   ctx  
  -    */
  -   public synchronized void free(EnterpriseContext ctx)
  -   {
  -       // If transaction still present don't do anything (let the instance be GC)
  -       if (ctx.getTransaction() != null) return ;
  -           
  -      // Reset instance
  -      ((EntityEnterpriseContext)ctx).setValid(false);
  -      ((EntityEnterpriseContext)ctx).setInvoked(false);
  -      
  -      super.free(ctx);
  -   }
  -   
  -   // Z implementation ----------------------------------------------
  -   public void start()
  -      throws Exception
  -   {
  -   }
  -    
  -   // Package protected ---------------------------------------------
  -    
  -   // Protected -----------------------------------------------------
  -   protected EnterpriseContext create(Object instance, Container con)
  -      throws RemoteException
  -   {
  -       // MF FIXME why pass con and then use getContainer()
  -      return new EntityEnterpriseContext(instance, getContainer());
  -   }
  -    
  -   // Private -------------------------------------------------------
  -
  -   // Inner classes -------------------------------------------------
  -
  -}
  -
  +/*
  + * jBoss, the OpenSource EJB server
  + *
  + * Distributable under GPL license.
  + * See terms of license at gnu.org.
  + */
  +package org.jboss.ejb.plugins;
  +
  +import java.rmi.RemoteException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.EntityEnterpriseContext;
  +
  +/**
  + *   <description> 
  + *      
  + *   @see <related>
  + *   @author Rickard �berg ([EMAIL PROTECTED])
  + *  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  + *   @version $Revision: 1.6 $
  + */
  +public class EntityInstancePool
  +   extends AbstractInstancePool
  +{
  +   // Constants -----------------------------------------------------
  +    
  +   // Attributes ----------------------------------------------------
  +   
  +   // Static --------------------------------------------------------
  +   
  +   // Constructors --------------------------------------------------
  +   
  +   // Public --------------------------------------------------------
  +   /**
  +    *   Return an instance to the free pool. Reset state
  +    *
  +    *   Called in 3 cases:
  +    *   a) Done with finder method
  +    *   b) Removed
  +    *   c) Passivated
  +    *
  +    * @param   ctx  
  +    */
  +   public synchronized void free(EnterpriseContext ctx)
  +   {
  +       // If transaction still present don't do anything (let the instance be GC)
  +       if (ctx.getTransaction() != null) return ;
  +           
  +      // Reset instance
  +      ((EntityEnterpriseContext)ctx).setValid(false);
  +      ((EntityEnterpriseContext)ctx).setInvoked(false);
  +      
  +      super.free(ctx);
  +   }
  +   
  +   // Z implementation ----------------------------------------------
  +   public void start()
  +      throws Exception
  +   {
  +   }
  +    
  +   // Package protected ---------------------------------------------
  +    
  +   // Protected -----------------------------------------------------
  +   protected EnterpriseContext create(Object instance, Container con)
  +      throws RemoteException
  +   {
  +       // MF FIXME why pass con and then use getContainer()
  +      return new EntityEnterpriseContext(instance, getContainer());
  +   }
  +    
  +   // Private -------------------------------------------------------
  +
  +   // Inner classes -------------------------------------------------
  +
  +}
  +
  
  
  
  1.16      +423 -423  
jboss/src/main/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java
  
  Index: EntitySynchronizationInterceptor.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- EntitySynchronizationInterceptor.java     2000/09/26 18:47:13     1.15
  +++ EntitySynchronizationInterceptor.java     2000/09/26 20:18:50     1.16
  @@ -1,423 +1,423 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL 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 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.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.logging.Logger;
  -
  -/**
  -*   This container filter takes care of EntityBean persistance.
  -*   Specifically, it calls ejbStore at appropriate times
  -*
  -*   Possible options:
  -*   After each call
  -*   On tx commit
  -*      
  -*   @see <related>
  -*   @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*   @version $Revision: 1.15 $
  -*/
  -public class EntitySynchronizationInterceptor
  -extends AbstractInterceptor
  -{
  -     // Constants -----------------------------------------------------
  -     
  -     /**
  -     *  Cache a "ready" instance between transactions.
  -     *  Data will <em>not</em> be reloaded from persistent storage when
  -     *  a new transaction is started.
  -     *  This option should only be used if the instance has exclusive
  -     *  access to its persistent storage.
  -     */
  -     public static final int A = 0; // Keep instance cached
  -     
  -     /**
  -     *  Cache a "ready" instance between transactions and reload data
  -     *  from persistent storage on transaction start.
  -     */
  -     public static final int B = 1; // Invalidate state
  -     
  -     /**
  -     *  Passivate instance after each transaction.
  -     */
  -     public static final int C = 2; // Passivate
  -     
  -     // Attributes ----------------------------------------------------
  -     
  -     /**
  -     *  The current commit option.
  -     */
  -     protected int commitOption = A;
  -     
  -     /**
  -     *  The container of this interceptor.
  -     */
  -     protected EntityContainer container;
  -     
  -     // Static --------------------------------------------------------
  -     
  -     // Constructors --------------------------------------------------
  -     
  -     // Public --------------------------------------------------------
  -     public void setContainer(Container container) 
  -     { 
  -             this.container = (EntityContainer)container; 
  -     }
  -     
  -     public Container getContainer()
  -     {
  -             return container;
  -     }
  -     
  -     /**
  -     *  Setter for property commitOption.
  -     */
  -     public void setCommitOption(int commitOption)
  -     {
  -             this.commitOption = commitOption;
  -     }
  -     
  -     /**
  -     *  Getter for property commitOption.
  -     */
  -     public int getCommitOption()
  -     {
  -             return commitOption;
  -     }
  -     
  -     /**
  -     *  Register a transaction synchronization callback with a context.
  -     */
  -     private void register(EntityEnterpriseContext ctx, Transaction tx)
  -     {
  -             // Create a new synchronization
  -             InstanceSynchronization synch = new InstanceSynchronization(tx, ctx);
  -             
  -             try {
  -                     // OSH: An extra check to avoid warning.
  -                     // Can go when we are sure that we no longer get
  -                     // the JTA violation warning.
  -                     if (tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
  -                             
  -                             ctx.setValid(false);
  -                             
  -                             return;
  -                     }
  -                     
  -                     // We want to be notified when the transaction commits
  -                     tx.registerSynchronization(synch);
  -             
  -             } catch (RollbackException e) {
  -                     
  -                     // The state in the instance is to be discarded, we force a 
reload of state
  -                     ctx.setValid(false);
  -             
  -             } catch (Exception e) {
  -                     
  -                     throw new EJBException(e);
  -             
  -             }
  -     }
  -     
  -     private void deregister(EntityEnterpriseContext ctx)
  -     {
  -             // MF FIXME: I suspect this is redundant now
  -             // (won't the pool clean it up?)
  -             
  -             // Deassociate ctx with tx
  -             // OSH: TxInterceptor seems to do this: ctx.setTransaction(null);
  -             // OSH: Pool seems to do this: ctx.setInvoked(false);
  -     }
  -     
  -     // Interceptor implementation --------------------------------------
  -     
  -     public Object invokeHome(MethodInvocation mi)
  -     throws Exception
  -     {
  -             try {
  -                     return getNext().invokeHome(mi);
  -             } finally {
  -                     // Anonymous was sent in, so if it has an id it was created
  -                     EntityEnterpriseContext ctx = 
(EntityEnterpriseContext)mi.getEnterpriseContext();
  -                     if (ctx.getId() != null) {
  -                             Transaction tx = mi.getTransaction();
  -                             
  -                             if (tx != null && tx.getStatus() == 
Status.STATUS_ACTIVE)
  -                                     register(ctx, tx); // Set tx
  -                             
  -                             // Currently synched with underlying storage
  -                             ctx.setValid(true);
  -                     }
  -             }
  -     }
  -     
  -     public Object invoke(MethodInvocation mi)
  -     throws Exception
  -     {
  -             // We are going to work with the context a lot
  -             EntityEnterpriseContext ctx = 
(EntityEnterpriseContext)mi.getEnterpriseContext();
  -             
  -             // The Tx coming as part of the Method Invocation 
  -             Transaction tx = mi.getTransaction();
  -             
  -             //Logger.debug("CTX in: isValid():"+ctx.isValid()+" 
isInvoked():"+ctx.isInvoked());
  -             //Logger.debug("newTx: "+ tx);
  -             
  -             // Is my state valid?
  -             if (!ctx.isValid()) {
  -                     
  -                     // If not tell the persistence manager to load the state
  -                     
((EntityContainer)getContainer()).getPersistenceManager().loadEntity(ctx);
  -                     
  -                     // Now the state is valid
  -                     ctx.setValid(true);
  -             }
  -             
  -             // So we can go on with the invocation
  -             Logger.log("Tx is "+ ((tx == null)? "null" : tx.toString()));
  -             
  -             // Invocation with a running Transaction
  -             
  -             if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE) {
  -                     
  -                     try {
  -                             
  -                             //Invoke down the chain
  -                             return getNext().invoke(mi);
  -                     
  -                     } 
  -                     
  -                     finally {
  -                             
  -                             // Do we have a valid bean (not removed)
  -                             if (ctx.getId() != null) {
  -                                     
  -                                     // If the context was not invoked previously...
  -                                     if (!ctx.isInvoked()) {
  -                                             
  -                                             // It is now and this will cause 
ejbStore to be called...
  -                                             ctx.setInvoked(true);
  -                                             
  -                                             // ... on a transaction callback that 
we register here.
  -                                             register(ctx, tx);
  -                                     }
  -                             }
  -                             
  -                             // Entity was removed
  -                             else {
  -                                     
  -                                     if (ctx.getTransaction() != null) {
  -                                             
  -                                             //DEBUG Logger.debug("CTX out: 
isValid():"+ctx.isValid()+" isInvoked():"+ctx.isInvoked());
  -                                             //DEBUG Logger.debug("PresentTx:"+tx);
  -                                             
  -                                             // If a ctx still has a transaction we 
would need to deresgister the sync
  -                                             // The simplest is to tell the pool to 
kill the instance if tx is present
  -                                     
  -                                     }
  -                             }
  -                     }
  -             }
  -             
  -             //    
  -             else { // No tx
  -                     try {
  -                             Object result = getNext().invoke(mi);
  -                             
  -                             // Store after each invocation -- not on exception 
though, or removal
  -                             // And skip reads too ("get" methods)
  -                             // OSH FIXME: Isn't this startsWith("get") 
optimization a violation of
  -                             // the EJB specification? Think of 
SequenceBean.getNext().
  -                             if (ctx.getId() != null && 
!mi.getMethod().getName().startsWith("get"))
  -                                     
((EntityContainer)getContainer()).getPersistenceManager().storeEntity(ctx);
  -                             
  -                             return result;
  -                     } catch (Exception e) {
  -                             // Exception - force reload on next call
  -                             ctx.setValid(false);
  -                             throw e;
  -                     }
  -             }
  -     }
  -     
  -     
  -     // Protected  ----------------------------------------------------
  -     
  -     // Inner classes -------------------------------------------------
  -     
  -     private class InstanceSynchronization
  -     implements Synchronization
  -     {
  -             /**
  -             *  The transaction we follow.
  -             */
  -             private Transaction tx;
  -             
  -             /**
  -             *  The context we manage.
  -             */
  -             private EntityEnterpriseContext ctx;
  -             
  -             /**
  -             *  Create a new instance synchronization instance.
  -             */
  -             InstanceSynchronization(Transaction tx, EntityEnterpriseContext ctx)
  -             {
  -                     this.tx = tx;
  -                     this.ctx = ctx;
  -             }
  -             
  -             // Synchronization implementation -----------------------------
  -             
  -             public void beforeCompletion()
  -             {
  -                     Logger.log("beforeCompletion called for ctx "+ctx.hashCode());
  -                     
  -                     if (ctx.getId() != null) {
  -                             try {
  -                                     try {
  -                                             
  -                                             // MF FIXME: should we throw an 
exception if lock is present (app error)
  -                                             // it would mean that someone is 
commiting when all the work is not done
  -                                             
  -                                             // Store instance if business method 
was invoked
  -                                             if (ctx.isInvoked())  {
  -                                                     
  -                                                     //DEBUG 
Logger.log("EntitySynchronization sync calling store on ctx "+ctx.hashCode());
  -                                                     
  -                                                     
Logger.log("EntitySynchronization sync calling store on ctx "+ctx.hashCode());
  -                                                     
  -                                                     
container.getPersistenceManager().storeEntity(ctx);
  -                                             }
  -                                     } catch (NoSuchEntityException e) {
  -                                             // Object has been removed -- ignore
  -                                     }
  -                             } catch (RemoteException e) {
  -                                     Logger.exception(e);
  -                                     
  -                                     // Store failed -> rollback!
  -                                     try {
  -                                             tx.setRollbackOnly();
  -                                     } catch (SystemException ex) {
  -                                             // DEBUG ex.printStackTrace();
  -                                     }
  -                             }
  -                     }
  -             }
  -             
  -             public void afterCompletion(int status)
  -             {
  -                     if (ctx.getId() != null) {
  -                             Logger.log("afterCompletion called for ctx 
"+ctx.hashCode());
  -                             // If rolled back -> invalidate instance
  -                             if (status == Status.STATUS_ROLLEDBACK) {
  -                                     try {
  -                                             
  -                                             // finish the transaction association
  -                                             ctx.setTransaction(null);
  -                                             
  -                                             ctx.setValid(false); 
  -                                                     
  -                                             // remove from the cache
  -                                             
container.getInstanceCache().remove(ctx.getId());
  -                                             
  -                                             // return to pool
  -                                             container.getInstancePool().free(ctx); 
  -                                             
  -                                             // wake threads waiting
  -                                             synchronized(ctx) { ctx.notifyAll();}
  -                                     
  -                                     } catch (Exception e) {
  -                                             // Ignore
  -                                     }
  -                             
  -                             
  -                             
  -                             } else {
  -                                     // The transaction is done
  -                                     ctx.setTransaction(null);
  -                                     
  -                                     // We are afterCompletion so the invoked can 
be set to false (db sync is done)
  -                                     ctx.setInvoked(false);
  -                                     
  -                                     switch (commitOption) {
  -                                             // Keep instance cached after tx commit
  -                                             case A:
  -                                                     try {
  -                                                             // The state is still 
valid (only point of access is us)
  -                                                             ctx.setValid(true); 
  -                                             
  -                                                     } catch (Exception e) {
  -                                                             Logger.debug(e);
  -                                                     }
  -                                             break;
  -                                             
  -                                             // Keep instance active, but 
invalidate state
  -                                             case B:
  -                                                     try {
  -                                                             // Invalidate state 
(there might be other points of entry)
  -                                                             ctx.setValid(false); 
  -                                                             
  -                                                     } catch (Exception e) {
  -                                                             Logger.debug(e);
  -                                                     }
  -                                             break;
  -                                             
  -                                             // Invalidate everything AND Passivate 
instance
  -                                             case C:
  -                                                     try {
  -                                                             
  -                                                             // Passivate instance
  -                                                             
container.getPersistenceManager().passivateEntity(ctx); 
  -                                                             
  -                                                             // Remove from the 
cache, it is not active anymore
  -                                                             
container.getInstanceCache().remove(ctx.getId()); 
  -                                                             
  -                                                             // Back to the pool
  -                                                             
container.getInstancePool().free(ctx); 
  -                                                     } catch (Exception e) {
  -                                                             Logger.debug(e);
  -                                                     }
  -                                             break;
  -                                     }
  -                             }
  -                     }
  -                     // Notify all who are waiting for this tx to end, they are 
waiting since the locking logic
  -                     synchronized (ctx) {ctx.notifyAll();}
  -             }
  -     }
  -}
  -
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL 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 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.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.logging.Logger;
  +
  +/**
  +*   This container filter takes care of EntityBean persistance.
  +*   Specifically, it calls ejbStore at appropriate times
  +*
  +*   Possible options:
  +*   After each call
  +*   On tx commit
  +*      
  +*   @see <related>
  +*   @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*   @version $Revision: 1.16 $
  +*/
  +public class EntitySynchronizationInterceptor
  +extends AbstractInterceptor
  +{
  +     // Constants -----------------------------------------------------
  +     
  +     /**
  +     *  Cache a "ready" instance between transactions.
  +     *  Data will <em>not</em> be reloaded from persistent storage when
  +     *  a new transaction is started.
  +     *  This option should only be used if the instance has exclusive
  +     *  access to its persistent storage.
  +     */
  +     public static final int A = 0; // Keep instance cached
  +     
  +     /**
  +     *  Cache a "ready" instance between transactions and reload data
  +     *  from persistent storage on transaction start.
  +     */
  +     public static final int B = 1; // Invalidate state
  +     
  +     /**
  +     *  Passivate instance after each transaction.
  +     */
  +     public static final int C = 2; // Passivate
  +     
  +     // Attributes ----------------------------------------------------
  +     
  +     /**
  +     *  The current commit option.
  +     */
  +     protected int commitOption = A;
  +     
  +     /**
  +     *  The container of this interceptor.
  +     */
  +     protected EntityContainer container;
  +     
  +     // Static --------------------------------------------------------
  +     
  +     // Constructors --------------------------------------------------
  +     
  +     // Public --------------------------------------------------------
  +     public void setContainer(Container container) 
  +     { 
  +             this.container = (EntityContainer)container; 
  +     }
  +     
  +     public Container getContainer()
  +     {
  +             return container;
  +     }
  +     
  +     /**
  +     *  Setter for property commitOption.
  +     */
  +     public void setCommitOption(int commitOption)
  +     {
  +             this.commitOption = commitOption;
  +     }
  +     
  +     /**
  +     *  Getter for property commitOption.
  +     */
  +     public int getCommitOption()
  +     {
  +             return commitOption;
  +     }
  +     
  +     /**
  +     *  Register a transaction synchronization callback with a context.
  +     */
  +     private void register(EntityEnterpriseContext ctx, Transaction tx)
  +     {
  +             // Create a new synchronization
  +             InstanceSynchronization synch = new InstanceSynchronization(tx, ctx);
  +             
  +             try {
  +                     // OSH: An extra check to avoid warning.
  +                     // Can go when we are sure that we no longer get
  +                     // the JTA violation warning.
  +                     if (tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
  +                             
  +                             ctx.setValid(false);
  +                             
  +                             return;
  +                     }
  +                     
  +                     // We want to be notified when the transaction commits
  +                     tx.registerSynchronization(synch);
  +             
  +             } catch (RollbackException e) {
  +                     
  +                     // The state in the instance is to be discarded, we force a 
reload of state
  +                     ctx.setValid(false);
  +             
  +             } catch (Exception e) {
  +                     
  +                     throw new EJBException(e);
  +             
  +             }
  +     }
  +     
  +     private void deregister(EntityEnterpriseContext ctx)
  +     {
  +             // MF FIXME: I suspect this is redundant now
  +             // (won't the pool clean it up?)
  +             
  +             // Deassociate ctx with tx
  +             // OSH: TxInterceptor seems to do this: ctx.setTransaction(null);
  +             // OSH: Pool seems to do this: ctx.setInvoked(false);
  +     }
  +     
  +     // Interceptor implementation --------------------------------------
  +     
  +     public Object invokeHome(MethodInvocation mi)
  +     throws Exception
  +     {
  +             try {
  +                     return getNext().invokeHome(mi);
  +             } finally {
  +                     // Anonymous was sent in, so if it has an id it was created
  +                     EntityEnterpriseContext ctx = 
(EntityEnterpriseContext)mi.getEnterpriseContext();
  +                     if (ctx.getId() != null) {
  +                             Transaction tx = mi.getTransaction();
  +                             
  +                             if (tx != null && tx.getStatus() == 
Status.STATUS_ACTIVE)
  +                                     register(ctx, tx); // Set tx
  +                             
  +                             // Currently synched with underlying storage
  +                             ctx.setValid(true);
  +                     }
  +             }
  +     }
  +     
  +     public Object invoke(MethodInvocation mi)
  +     throws Exception
  +     {
  +             // We are going to work with the context a lot
  +             EntityEnterpriseContext ctx = 
(EntityEnterpriseContext)mi.getEnterpriseContext();
  +             
  +             // The Tx coming as part of the Method Invocation 
  +             Transaction tx = mi.getTransaction();
  +             
  +             //Logger.debug("CTX in: isValid():"+ctx.isValid()+" 
isInvoked():"+ctx.isInvoked());
  +             //Logger.debug("newTx: "+ tx);
  +             
  +             // Is my state valid?
  +             if (!ctx.isValid()) {
  +                     
  +                     // If not tell the persistence manager to load the state
  +                     
((EntityContainer)getContainer()).getPersistenceManager().loadEntity(ctx);
  +                     
  +                     // Now the state is valid
  +                     ctx.setValid(true);
  +             }
  +             
  +             // So we can go on with the invocation
  +             Logger.log("Tx is "+ ((tx == null)? "null" : tx.toString()));
  +             
  +             // Invocation with a running Transaction
  +             
  +             if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE) {
  +                     
  +                     try {
  +                             
  +                             //Invoke down the chain
  +                             return getNext().invoke(mi);
  +                     
  +                     } 
  +                     
  +                     finally {
  +                             
  +                             // Do we have a valid bean (not removed)
  +                             if (ctx.getId() != null) {
  +                                     
  +                                     // If the context was not invoked previously...
  +                                     if (!ctx.isInvoked()) {
  +                                             
  +                                             // It is now and this will cause 
ejbStore to be called...
  +                                             ctx.setInvoked(true);
  +                                             
  +                                             // ... on a transaction callback that 
we register here.
  +                                             register(ctx, tx);
  +                                     }
  +                             }
  +                             
  +                             // Entity was removed
  +                             else {
  +                                     
  +                                     if (ctx.getTransaction() != null) {
  +                                             
  +                                             //DEBUG Logger.debug("CTX out: 
isValid():"+ctx.isValid()+" isInvoked():"+ctx.isInvoked());
  +                                             //DEBUG Logger.debug("PresentTx:"+tx);
  +                                             
  +                                             // If a ctx still has a transaction we 
would need to deresgister the sync
  +                                             // The simplest is to tell the pool to 
kill the instance if tx is present
  +                                     
  +                                     }
  +                             }
  +                     }
  +             }
  +             
  +             //    
  +             else { // No tx
  +                     try {
  +                             Object result = getNext().invoke(mi);
  +                             
  +                             // Store after each invocation -- not on exception 
though, or removal
  +                             // And skip reads too ("get" methods)
  +                             // OSH FIXME: Isn't this startsWith("get") 
optimization a violation of
  +                             // the EJB specification? Think of 
SequenceBean.getNext().
  +                             if (ctx.getId() != null && 
!mi.getMethod().getName().startsWith("get"))
  +                                     
((EntityContainer)getContainer()).getPersistenceManager().storeEntity(ctx);
  +                             
  +                             return result;
  +                     } catch (Exception e) {
  +                             // Exception - force reload on next call
  +                             ctx.setValid(false);
  +                             throw e;
  +                     }
  +             }
  +     }
  +     
  +     
  +     // Protected  ----------------------------------------------------
  +     
  +     // Inner classes -------------------------------------------------
  +     
  +     private class InstanceSynchronization
  +     implements Synchronization
  +     {
  +             /**
  +             *  The transaction we follow.
  +             */
  +             private Transaction tx;
  +             
  +             /**
  +             *  The context we manage.
  +             */
  +             private EntityEnterpriseContext ctx;
  +             
  +             /**
  +             *  Create a new instance synchronization instance.
  +             */
  +             InstanceSynchronization(Transaction tx, EntityEnterpriseContext ctx)
  +             {
  +                     this.tx = tx;
  +                     this.ctx = ctx;
  +             }
  +             
  +             // Synchronization implementation -----------------------------
  +             
  +             public void beforeCompletion()
  +             {
  +                     Logger.log("beforeCompletion called for ctx "+ctx.hashCode());
  +                     
  +                     if (ctx.getId() != null) {
  +                             try {
  +                                     try {
  +                                             
  +                                             // MF FIXME: should we throw an 
exception if lock is present (app error)
  +                                             // it would mean that someone is 
commiting when all the work is not done
  +                                             
  +                                             // Store instance if business method 
was invoked
  +                                             if (ctx.isInvoked())  {
  +                                                     
  +                                                     //DEBUG 
Logger.log("EntitySynchronization sync calling store on ctx "+ctx.hashCode());
  +                                                     
  +                                                     
Logger.log("EntitySynchronization sync calling store on ctx "+ctx.hashCode());
  +                                                     
  +                                                     
container.getPersistenceManager().storeEntity(ctx);
  +                                             }
  +                                     } catch (NoSuchEntityException e) {
  +                                             // Object has been removed -- ignore
  +                                     }
  +                             } catch (RemoteException e) {
  +                                     Logger.exception(e);
  +                                     
  +                                     // Store failed -> rollback!
  +                                     try {
  +                                             tx.setRollbackOnly();
  +                                     } catch (SystemException ex) {
  +                                             // DEBUG ex.printStackTrace();
  +                                     }
  +                             }
  +                     }
  +             }
  +             
  +             public void afterCompletion(int status)
  +             {
  +                     if (ctx.getId() != null) {
  +                             Logger.log("afterCompletion called for ctx 
"+ctx.hashCode());
  +                             // If rolled back -> invalidate instance
  +                             if (status == Status.STATUS_ROLLEDBACK) {
  +                                     try {
  +                                             
  +                                             // finish the transaction association
  +                                             ctx.setTransaction(null);
  +                                             
  +                                             ctx.setValid(false); 
  +                                                     
  +                                             // remove from the cache
  +                                             
container.getInstanceCache().remove(ctx.getId());
  +                                             
  +                                             // return to pool
  +                                             container.getInstancePool().free(ctx); 
  +                                             
  +                                             // wake threads waiting
  +                                             synchronized(ctx) { ctx.notifyAll();}
  +                                     
  +                                     } catch (Exception e) {
  +                                             // Ignore
  +                                     }
  +                             
  +                             
  +                             
  +                             } else {
  +                                     // The transaction is done
  +                                     ctx.setTransaction(null);
  +                                     
  +                                     // We are afterCompletion so the invoked can 
be set to false (db sync is done)
  +                                     ctx.setInvoked(false);
  +                                     
  +                                     switch (commitOption) {
  +                                             // Keep instance cached after tx commit
  +                                             case A:
  +                                                     try {
  +                                                             // The state is still 
valid (only point of access is us)
  +                                                             ctx.setValid(true); 
  +                                             
  +                                                     } catch (Exception e) {
  +                                                             Logger.debug(e);
  +                                                     }
  +                                             break;
  +                                             
  +                                             // Keep instance active, but 
invalidate state
  +                                             case B:
  +                                                     try {
  +                                                             // Invalidate state 
(there might be other points of entry)
  +                                                             ctx.setValid(false); 
  +                                                             
  +                                                     } catch (Exception e) {
  +                                                             Logger.debug(e);
  +                                                     }
  +                                             break;
  +                                             
  +                                             // Invalidate everything AND Passivate 
instance
  +                                             case C:
  +                                                     try {
  +                                                             
  +                                                             // Passivate instance
  +                                                             
container.getPersistenceManager().passivateEntity(ctx); 
  +                                                             
  +                                                             // Remove from the 
cache, it is not active anymore
  +                                                             
container.getInstanceCache().remove(ctx.getId()); 
  +                                                             
  +                                                             // Back to the pool
  +                                                             
container.getInstancePool().free(ctx); 
  +                                                     } catch (Exception e) {
  +                                                             Logger.debug(e);
  +                                                     }
  +                                             break;
  +                                     }
  +                             }
  +                     }
  +                     // Notify all who are waiting for this tx to end, they are 
waiting since the locking logic
  +                     synchronized (ctx) {ctx.notifyAll();}
  +             }
  +     }
  +}
  +
  
  
  
  1.11      +166 -166  
jboss/src/main/org/jboss/ejb/plugins/NoPassivationEntityInstanceCache.java
  
  Index: NoPassivationEntityInstanceCache.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/NoPassivationEntityInstanceCache.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- NoPassivationEntityInstanceCache.java     2000/09/26 18:53:55     1.10
  +++ NoPassivationEntityInstanceCache.java     2000/09/26 20:18:51     1.11
  @@ -1,166 +1,166 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/
  -package org.jboss.ejb.plugins;
  -
  -import java.rmi.RemoteException;
  -import java.rmi.ServerException;
  -import java.util.Map;
  -import java.util.HashMap;
  -import java.util.Stack;    
  -import java.util.LinkedList;
  -import java.util.Collections;
  -import java.util.Iterator;
  -
  -import javax.transaction.SystemException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EntityContainer;
  -import org.jboss.ejb.EntityInstanceCache;
  -import org.jboss.ejb.InstanceCache;
  -import org.jboss.ejb.InstancePool;
  -import org.jboss.ejb.InstancePoolContainer;
  -import org.jboss.ejb.EntityPersistenceManager;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.EntityEnterpriseContext;
  -import org.jboss.ejb.CacheKey;
  -
  -import org.jboss.metadata.EntityMetaData;
  -
  -/**
  -*    <description> 
  -*      
  -*    @see <related>
  -*    @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Andy Schaefer</a>
  -*    @version $Revision: 1.10 $
  -*/
  -public class NoPassivationEntityInstanceCache
  -implements EntityInstanceCache
  -{
  -    // Constants -----------------------------------------------------
  -    
  -    // Attributes ----------------------------------------------------
  -    Container con;
  -    
  -    Map cache = Collections.synchronizedMap(new HashMap());
  -    
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    
  -    /**
  -    *   Set the callback to the container. This is for initialization.
  -    *   The IM may extract the configuration from the container.
  -    *
  -    * @param   c  
  -    */
  -    public void setContainer(Container c)
  -    {
  -        this.con = c;
  -    }
  -    
  -    public void init()
  -    throws Exception
  -    {
  -    }
  -    
  -    public void start()
  -    throws Exception
  -    {
  -    }
  -    
  -    public void stop()
  -    {
  -    }
  -    
  -    public void destroy()
  -    {
  -    }
  -    
  -    public Object createCacheKey( Object id ) {
  -       
  -       return new CacheKey( id );
  -    }
  -    
  -    /**
  -    *  get(Object CacheKey)
  -    * 
  -    * We base our lookups on the CacheKey. 
  -    */
  -    
  -    public synchronized EnterpriseContext get(Object id)
  -    throws RemoteException
  -    {
  -        
  -        // Use the CacheKey for the rest of the method
  -        CacheKey cacheKey = (CacheKey) id;
  -        
  -        EntityEnterpriseContext ctx;
  -      
  -       // Lookup the instance 
  -       ctx = (EntityEnterpriseContext)cache.get(cacheKey);
  -       
  -        if (ctx == null) // Not in fast cache under that cacheKey
  -        {
  -            
  -            // Get new instance from pool
  -            ctx = 
(EntityEnterpriseContext)((InstancePoolContainer)con).getInstancePool().get();
  -            
  -            // The context only knows about the Database id
  -            ctx.setId(cacheKey.id);
  -            
  -            // Activate it
  -            ((EntityContainer)con).getPersistenceManager().activateEntity(ctx);
  -              
  -            // insert
  -            cache.put(cacheKey, ctx);
  -        }
  -        
  -       
  -        // At this point we own the instance with the given identity
  -        
  -       // Tell the context the key 
  -       ctx.setCacheKey(cacheKey);
  -       
  -        // DEBUG Logger.log("Got entity:"+ctx.getId());
  -       
  -        return ctx;
  -    }
  -    
  -    public synchronized void insert (EnterpriseContext ctx) {
  -    
  -        // Cache can know about the instance now
  -        cache.put(((EntityEnterpriseContext) ctx).getCacheKey(), ctx);
  -    }
  -    
  -    /*
  -    * Remove works with the cachekey that the cache constructs.  Leakage will 
happen if the cache key 
  -    * doesn't consistently see 
  -    * m1 = new CacheKey(id); and 
  -    * m2 = new CacheKey(id);
  -    * as hashCode equals and equals.  The implementation of org.jboss.CacheKey 
behaves correctly
  -    *
  -    */
  -    public synchronized void remove(Object id)
  -    {
  -        // remove usually comes with the id of the db instance
  -        cache.remove(createCacheKey(id));                         
  -    }
  -    
  -    // Z implementation ----------------------------------------------
  -    
  -    // Package protected ---------------------------------------------
  -    
  -    // Protected -----------------------------------------------------
  -    
  -    // Private -------------------------------------------------------
  -    
  -    // Inner classes -------------------------------------------------
  -}
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/
  +package org.jboss.ejb.plugins;
  +
  +import java.rmi.RemoteException;
  +import java.rmi.ServerException;
  +import java.util.Map;
  +import java.util.HashMap;
  +import java.util.Stack;    
  +import java.util.LinkedList;
  +import java.util.Collections;
  +import java.util.Iterator;
  +
  +import javax.transaction.SystemException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EntityContainer;
  +import org.jboss.ejb.EntityInstanceCache;
  +import org.jboss.ejb.InstanceCache;
  +import org.jboss.ejb.InstancePool;
  +import org.jboss.ejb.InstancePoolContainer;
  +import org.jboss.ejb.EntityPersistenceManager;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.EntityEnterpriseContext;
  +import org.jboss.ejb.CacheKey;
  +
  +import org.jboss.metadata.EntityMetaData;
  +
  +/**
  +*    <description> 
  +*      
  +*    @see <related>
  +*    @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Andy Schaefer</a>
  +*    @version $Revision: 1.11 $
  +*/
  +public class NoPassivationEntityInstanceCache
  +implements EntityInstanceCache
  +{
  +    // Constants -----------------------------------------------------
  +    
  +    // Attributes ----------------------------------------------------
  +    Container con;
  +    
  +    Map cache = Collections.synchronizedMap(new HashMap());
  +    
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    
  +    /**
  +    *   Set the callback to the container. This is for initialization.
  +    *   The IM may extract the configuration from the container.
  +    *
  +    * @param   c  
  +    */
  +    public void setContainer(Container c)
  +    {
  +        this.con = c;
  +    }
  +    
  +    public void init()
  +    throws Exception
  +    {
  +    }
  +    
  +    public void start()
  +    throws Exception
  +    {
  +    }
  +    
  +    public void stop()
  +    {
  +    }
  +    
  +    public void destroy()
  +    {
  +    }
  +    
  +    public Object createCacheKey( Object id ) {
  +       
  +       return new CacheKey( id );
  +    }
  +    
  +    /**
  +    *  get(Object CacheKey)
  +    * 
  +    * We base our lookups on the CacheKey. 
  +    */
  +    
  +    public synchronized EnterpriseContext get(Object id)
  +    throws RemoteException
  +    {
  +        
  +        // Use the CacheKey for the rest of the method
  +        CacheKey cacheKey = (CacheKey) id;
  +        
  +        EntityEnterpriseContext ctx;
  +      
  +       // Lookup the instance 
  +       ctx = (EntityEnterpriseContext)cache.get(cacheKey);
  +       
  +        if (ctx == null) // Not in fast cache under that cacheKey
  +        {
  +            
  +            // Get new instance from pool
  +            ctx = 
(EntityEnterpriseContext)((InstancePoolContainer)con).getInstancePool().get();
  +            
  +            // The context only knows about the Database id
  +            ctx.setId(cacheKey.id);
  +            
  +            // Activate it
  +            ((EntityContainer)con).getPersistenceManager().activateEntity(ctx);
  +              
  +            // insert
  +            cache.put(cacheKey, ctx);
  +        }
  +        
  +       
  +        // At this point we own the instance with the given identity
  +        
  +       // Tell the context the key 
  +       ctx.setCacheKey(cacheKey);
  +       
  +        // DEBUG Logger.log("Got entity:"+ctx.getId());
  +       
  +        return ctx;
  +    }
  +    
  +    public synchronized void insert (EnterpriseContext ctx) {
  +    
  +        // Cache can know about the instance now
  +        cache.put(((EntityEnterpriseContext) ctx).getCacheKey(), ctx);
  +    }
  +    
  +    /*
  +    * Remove works with the cachekey that the cache constructs.  Leakage will 
happen if the cache key 
  +    * doesn't consistently see 
  +    * m1 = new CacheKey(id); and 
  +    * m2 = new CacheKey(id);
  +    * as hashCode equals and equals.  The implementation of org.jboss.CacheKey 
behaves correctly
  +    *
  +    */
  +    public synchronized void remove(Object id)
  +    {
  +        // remove usually comes with the id of the db instance
  +        cache.remove(createCacheKey(id));                         
  +    }
  +    
  +    // Z implementation ----------------------------------------------
  +    
  +    // Package protected ---------------------------------------------
  +    
  +    // Protected -----------------------------------------------------
  +    
  +    // Private -------------------------------------------------------
  +    
  +    // Inner classes -------------------------------------------------
  +}
  
  
  
  1.10      +138 -138  
jboss/src/main/org/jboss/ejb/plugins/NoPassivationStatefulSessionInstanceCache.java
  
  Index: NoPassivationStatefulSessionInstanceCache.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/NoPassivationStatefulSessionInstanceCache.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- NoPassivationStatefulSessionInstanceCache.java    2000/09/26 18:55:50     1.9
  +++ NoPassivationStatefulSessionInstanceCache.java    2000/09/26 20:18:51     1.10
  @@ -1,138 +1,138 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/
  -package org.jboss.ejb.plugins;
  -
  -import java.rmi.RemoteException;
  -import java.rmi.ServerException;
  -import java.util.Map;
  -import java.util.HashMap;
  -import java.util.Stack;
  -import java.util.Collections;
  -
  -import javax.transaction.SystemException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.StatefulSessionContainer;
  -import org.jboss.ejb.InstanceCache;
  -import org.jboss.ejb.InstancePool;
  -import org.jboss.ejb.InstancePoolContainer;
  -import org.jboss.ejb.StatefulSessionPersistenceManager;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.StatefulSessionEnterpriseContext;
  -import org.jboss.logging.Logger;
  -
  -
  -/**
  -*    <description> 
  -*      
  -*    @see <related>
  -*    @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
  -*    @version $Revision: 1.9 $
  -*/
  -public class NoPassivationStatefulSessionInstanceCache
  -implements InstanceCache
  -{
  -    // Constants -----------------------------------------------------
  -    
  -    // Attributes ----------------------------------------------------
  -    Container con;
  -    
  -    Map active = new HashMap();
  -    
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    
  -    /**
  -    *   Set the callback to the container. This is for initialization.
  -    *   The IM may extract the configuration from the container.
  -    *
  -    * @param   c  
  -    */
  -    public void setContainer(Container c)
  -    {
  -       this.con = c;
  -    }
  -    
  -    public void init()
  -    throws Exception
  -    {
  -    }
  -    
  -    public void start()
  -    throws Exception
  -    {
  -    }
  -    
  -    public void stop()
  -    {
  -    }
  -    
  -    public void destroy()
  -    {
  -    }
  -    
  -    public synchronized EnterpriseContext get(Object id)
  -    throws RemoteException
  -    {
  -       
  -        //DEBUG Logger.log("Stateful cache looking for ID "+id);
  -        Logger.log("Stateful cache looking for ID "+id);
  -     
  -       // Do we have the context in cache?
  -       StatefulSessionEnterpriseContext ctx = 
  -         (StatefulSessionEnterpriseContext)active.get(id);
  -         
  -        // We don't have it in cache
  -        if (ctx == null) {
  -            
  -            // Get new instance from pool (bogus in our case)
  -            ctx = 
(StatefulSessionEnterpriseContext)((InstancePoolContainer)con).getInstancePool().get();
  -            
  -            // Activate
  -            ctx.setId(id);
  -            
  -            try {
  -                
  -                
((StatefulSessionContainer)con).getPersistenceManager().activateSession(ctx);
  -            }
  -            catch (Exception e) {
  -                
  -                throw new RemoteException("Object was not found");
  -            }
  -            
  -            insert(ctx);
  -        }
  -       // The context has the instance as well and the right id
  -       return ctx;
  -    }
  -    
  -    public synchronized void insert(EnterpriseContext ctx)
  -    {
  -       active.put(ctx.getId(), ctx) ;
  -    }
  -    
  -    
  -    
  -    public synchronized void remove(Object id)
  -    {
  -       Object ctx = active.remove(id);
  -    }
  -    
  -    // Z implementation ----------------------------------------------
  -    
  -    // Package protected ---------------------------------------------
  -    
  -    // Protected -----------------------------------------------------
  -    
  -    // Private -------------------------------------------------------
  -    
  -    // Inner classes -------------------------------------------------
  -}
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/
  +package org.jboss.ejb.plugins;
  +
  +import java.rmi.RemoteException;
  +import java.rmi.ServerException;
  +import java.util.Map;
  +import java.util.HashMap;
  +import java.util.Stack;
  +import java.util.Collections;
  +
  +import javax.transaction.SystemException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.StatefulSessionContainer;
  +import org.jboss.ejb.InstanceCache;
  +import org.jboss.ejb.InstancePool;
  +import org.jboss.ejb.InstancePoolContainer;
  +import org.jboss.ejb.StatefulSessionPersistenceManager;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.StatefulSessionEnterpriseContext;
  +import org.jboss.logging.Logger;
  +
  +
  +/**
  +*    <description> 
  +*      
  +*    @see <related>
  +*    @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
  +*    @version $Revision: 1.10 $
  +*/
  +public class NoPassivationStatefulSessionInstanceCache
  +implements InstanceCache
  +{
  +    // Constants -----------------------------------------------------
  +    
  +    // Attributes ----------------------------------------------------
  +    Container con;
  +    
  +    Map active = new HashMap();
  +    
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    
  +    /**
  +    *   Set the callback to the container. This is for initialization.
  +    *   The IM may extract the configuration from the container.
  +    *
  +    * @param   c  
  +    */
  +    public void setContainer(Container c)
  +    {
  +       this.con = c;
  +    }
  +    
  +    public void init()
  +    throws Exception
  +    {
  +    }
  +    
  +    public void start()
  +    throws Exception
  +    {
  +    }
  +    
  +    public void stop()
  +    {
  +    }
  +    
  +    public void destroy()
  +    {
  +    }
  +    
  +    public synchronized EnterpriseContext get(Object id)
  +    throws RemoteException
  +    {
  +       
  +        //DEBUG Logger.log("Stateful cache looking for ID "+id);
  +        Logger.log("Stateful cache looking for ID "+id);
  +     
  +       // Do we have the context in cache?
  +       StatefulSessionEnterpriseContext ctx = 
  +         (StatefulSessionEnterpriseContext)active.get(id);
  +         
  +        // We don't have it in cache
  +        if (ctx == null) {
  +            
  +            // Get new instance from pool (bogus in our case)
  +            ctx = 
(StatefulSessionEnterpriseContext)((InstancePoolContainer)con).getInstancePool().get();
  +            
  +            // Activate
  +            ctx.setId(id);
  +            
  +            try {
  +                
  +                
((StatefulSessionContainer)con).getPersistenceManager().activateSession(ctx);
  +            }
  +            catch (Exception e) {
  +                
  +                throw new RemoteException("Object was not found");
  +            }
  +            
  +            insert(ctx);
  +        }
  +       // The context has the instance as well and the right id
  +       return ctx;
  +    }
  +    
  +    public synchronized void insert(EnterpriseContext ctx)
  +    {
  +       active.put(ctx.getId(), ctx) ;
  +    }
  +    
  +    
  +    
  +    public synchronized void remove(Object id)
  +    {
  +       Object ctx = active.remove(id);
  +    }
  +    
  +    // Z implementation ----------------------------------------------
  +    
  +    // Package protected ---------------------------------------------
  +    
  +    // Protected -----------------------------------------------------
  +    
  +    // Private -------------------------------------------------------
  +    
  +    // Inner classes -------------------------------------------------
  +}
  
  
  
  1.9       +153 -153  
jboss/src/main/org/jboss/ejb/plugins/RandomEntityInstanceCache.java
  
  Index: RandomEntityInstanceCache.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/RandomEntityInstanceCache.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- RandomEntityInstanceCache.java    2000/09/26 18:57:16     1.8
  +++ RandomEntityInstanceCache.java    2000/09/26 20:18:51     1.9
  @@ -1,153 +1,153 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/
  -package org.jboss.ejb.plugins;
  -
  -import java.rmi.RemoteException;
  -import java.rmi.ServerException;
  -import java.util.Collection;
  -import java.util.Iterator;
  -import java.util.HashMap;
  -import java.util.LinkedList;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EntityContainer;
  -import org.jboss.ejb.InstanceCache;
  -import org.jboss.ejb.InstancePool;
  -import org.jboss.ejb.EntityPersistenceManager;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.EntityEnterpriseContext;
  -
  -import org.jboss.logging.Logger;
  -
  -/**
  -*    <description> 
  -*      
  -*    @see <related>
  -*    @author Rickard �berg ([EMAIL PROTECTED])
  -*  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*    @version $Revision: 1.8 $
  -*/
  -public class RandomEntityInstanceCache
  -extends NoPassivationEntityInstanceCache
  -{
  -
  -    // Constants -----------------------------------------------------
  -    
  -    // Attributes ----------------------------------------------------
  -    boolean running = false; // Passivator thread running?
  -    
  -    int minActive = 100; // Always try to passivate if more than this nr are active
  -    
  -    long timeout = 60*1000L; // Passivation sweep sleep time
  -    
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    public void start()
  -    throws Exception
  -    {
  -       running = true;
  -       new Thread(new Passivator()).start();
  -    }
  -    
  -    public void stop()
  -    {
  -       running = false;
  -    }
  -    
  -    // Z implementation ----------------------------------------------
  -    
  -    // Package protected ---------------------------------------------
  -    
  -    // Protected -----------------------------------------------------
  -    
  -    // Private -------------------------------------------------------
  -    
  -    // Inner classes -------------------------------------------------
  -    class Passivator
  -    implements Runnable
  -    {
  -       //RandomEntityInstanceCache cache;
  -       
  -       public void run()
  -       {
  -         Logger.debug("Passivator started");
  -         // Passivation loop
  -         while(running)
  -         {
  -          //            Logger.log("Clearing cache");
  -          // Passivate old. Lock cache first
  -          //synchronized(RandomEntityInstanceCache.this)
  -          synchronized(cache)
  -          {
  -              // Do not use cache (many to one entries)
  -              int currentActive = cache.size();
  -              if (currentActive > minActive)
  -              {
  -                 InstancePool pool = ((EntityContainer)con).getInstancePool();
  -                 
  -                 Logger.debug("Too many active instances:"+currentActive);
  -                 
  -                 // Passivate some instance; they need to be unlocked though
  -                 
  -                 //KeySet has cacheKeys (currentActive>0)    
  -                 Iterator keys = cache.keySet().iterator();
  -                 
  -                 while(keys.hasNext())
  -                 {
  -                   
  -                   Object key = keys.next();
  -                   
  -                   //Get the context
  -                   EntityEnterpriseContext ctx =  
  -                    (EntityEnterpriseContext) cache.get(key);
  -                   
  -                   
  -                   // Make sure we can work on it
  -                   Logger.debug("Checking:"+ctx.getId());
  -                            
  -                   //TODO do the Locking logic
  -                            try
  -                   {
  -                    Logger.debug("Passivating:"+ctx.getId());
  -                    
  -                                // Passivate the entry
  -                                
((EntityContainer)con).getPersistenceManager().passivateEntity(ctx);
  -                        
  -                    // Remove the entry      
  -                    cache.remove(key);
  -                    
  -                                //keep the count
  -                                currentActive--;
  -                   }
  -                    
  -                   catch (Exception e) { Logger.log("Could not passivate 
instance");}
  -                 
  -                   // Are we done?
  -                   if (currentActive == minActive) break;
  -                 }
  -              
  -              }    
  -          }  
  -          // DEBUG Logger.log("Passivation done");
  -                Logger.log("Passivation done");
  -          
  -          // Sleep
  -          try
  -          {
  -              Thread.sleep(timeout);
  -          } catch (InterruptedException e)
  -          {
  -              // Ignore
  -          }
  -         
  -         }
  -       }
  -    }
  -}
  \ No newline at end of file
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/
  +package org.jboss.ejb.plugins;
  +
  +import java.rmi.RemoteException;
  +import java.rmi.ServerException;
  +import java.util.Collection;
  +import java.util.Iterator;
  +import java.util.HashMap;
  +import java.util.LinkedList;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EntityContainer;
  +import org.jboss.ejb.InstanceCache;
  +import org.jboss.ejb.InstancePool;
  +import org.jboss.ejb.EntityPersistenceManager;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.EntityEnterpriseContext;
  +
  +import org.jboss.logging.Logger;
  +
  +/**
  +*    <description> 
  +*      
  +*    @see <related>
  +*    @author Rickard �berg ([EMAIL PROTECTED])
  +*  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*    @version $Revision: 1.9 $
  +*/
  +public class RandomEntityInstanceCache
  +extends NoPassivationEntityInstanceCache
  +{
  +
  +    // Constants -----------------------------------------------------
  +    
  +    // Attributes ----------------------------------------------------
  +    boolean running = false; // Passivator thread running?
  +    
  +    int minActive = 100; // Always try to passivate if more than this nr are active
  +    
  +    long timeout = 60*1000L; // Passivation sweep sleep time
  +    
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    public void start()
  +    throws Exception
  +    {
  +       running = true;
  +       new Thread(new Passivator()).start();
  +    }
  +    
  +    public void stop()
  +    {
  +       running = false;
  +    }
  +    
  +    // Z implementation ----------------------------------------------
  +    
  +    // Package protected ---------------------------------------------
  +    
  +    // Protected -----------------------------------------------------
  +    
  +    // Private -------------------------------------------------------
  +    
  +    // Inner classes -------------------------------------------------
  +    class Passivator
  +    implements Runnable
  +    {
  +       //RandomEntityInstanceCache cache;
  +       
  +       public void run()
  +       {
  +         Logger.debug("Passivator started");
  +         // Passivation loop
  +         while(running)
  +         {
  +          //            Logger.log("Clearing cache");
  +          // Passivate old. Lock cache first
  +          //synchronized(RandomEntityInstanceCache.this)
  +          synchronized(cache)
  +          {
  +              // Do not use cache (many to one entries)
  +              int currentActive = cache.size();
  +              if (currentActive > minActive)
  +              {
  +                 InstancePool pool = ((EntityContainer)con).getInstancePool();
  +                 
  +                 Logger.debug("Too many active instances:"+currentActive);
  +                 
  +                 // Passivate some instance; they need to be unlocked though
  +                 
  +                 //KeySet has cacheKeys (currentActive>0)    
  +                 Iterator keys = cache.keySet().iterator();
  +                 
  +                 while(keys.hasNext())
  +                 {
  +                   
  +                   Object key = keys.next();
  +                   
  +                   //Get the context
  +                   EntityEnterpriseContext ctx =  
  +                    (EntityEnterpriseContext) cache.get(key);
  +                   
  +                   
  +                   // Make sure we can work on it
  +                   Logger.debug("Checking:"+ctx.getId());
  +                            
  +                   //TODO do the Locking logic
  +                            try
  +                   {
  +                    Logger.debug("Passivating:"+ctx.getId());
  +                    
  +                                // Passivate the entry
  +                                
((EntityContainer)con).getPersistenceManager().passivateEntity(ctx);
  +                        
  +                    // Remove the entry      
  +                    cache.remove(key);
  +                    
  +                                //keep the count
  +                                currentActive--;
  +                   }
  +                    
  +                   catch (Exception e) { Logger.log("Could not passivate 
instance");}
  +                 
  +                   // Are we done?
  +                   if (currentActive == minActive) break;
  +                 }
  +              
  +              }    
  +          }  
  +          // DEBUG Logger.log("Passivation done");
  +                Logger.log("Passivation done");
  +          
  +          // Sleep
  +          try
  +          {
  +              Thread.sleep(timeout);
  +          } catch (InterruptedException e)
  +          {
  +              // Ignore
  +          }
  +         
  +         }
  +       }
  +    }
  +}
  
  
  
  1.8       +240 -240  
jboss/src/main/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
  
  Index: StatefulSessionFilePersistenceManager.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- StatefulSessionFilePersistenceManager.java        2000/09/26 18:58:32     1.7
  +++ StatefulSessionFilePersistenceManager.java        2000/09/26 20:18:51     1.8
  @@ -1,240 +1,240 @@
  -/*
  - * jBoss, the OpenSource EJB server
  - *
  - * Distributable under GPL license.
  - * See terms of license at gnu.org.
  - */
  -package org.jboss.ejb.plugins;
  -
  -import java.beans.Beans;
  -import java.beans.beancontext.BeanContextServicesSupport;
  -import java.io.File;
  -import java.io.InputStream;
  -import java.io.OutputStream;
  -import java.io.ObjectInputStream;
  -import java.io.ObjectOutputStream;
  -import java.io.FileOutputStream;
  -import java.io.FileInputStream;
  -import java.io.IOException;
  -import java.lang.reflect.Method;
  -import java.lang.reflect.Field;
  -import java.lang.reflect.Modifier;
  -import java.lang.reflect.InvocationTargetException;
  -import java.rmi.RemoteException;
  -import java.rmi.NoSuchObjectException;
  -import java.rmi.ServerException;
  -import java.util.Collection;
  -import java.util.ArrayList;
  -import java.util.Iterator;
  -import java.sql.SQLException;
  -import java.sql.ResultSet;
  -import java.sql.ResultSetMetaData;
  -import java.sql.DriverManager;
  -import java.sql.Statement;
  -import java.sql.PreparedStatement;
  -import java.sql.Connection;
  -
  -import javax.ejb.EJBObject;
  -import javax.ejb.Handle;
  -import javax.ejb.SessionBean;
  -import javax.ejb.CreateException;
  -import javax.ejb.DuplicateKeyException;
  -import javax.ejb.FinderException;
  -import javax.ejb.RemoveException;
  -import javax.naming.Context;
  -import javax.naming.InitialContext;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.StatefulSessionContainer;
  -import org.jboss.ejb.StatefulSessionPersistenceManager;
  -import org.jboss.ejb.StatefulSessionEnterpriseContext;
  -import org.jboss.logging.Logger;
  -
  -
  -/**
  - *   StatefulSessionFilePersistenceManager
  - *
  - *  This class is one of the passivating plugins for jBoss.  
  - *  It is fairly simple and can work from the file system from wich jBoss is 
operating
  - *      
  - *   @see <related>
  - *   @author Rickard �berg ([EMAIL PROTECTED])
  - *  @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
  - *   @version $Revision: 1.7 $
  - */
  -public class StatefulSessionFilePersistenceManager
  -   implements StatefulSessionPersistenceManager
  -{
  -   // Constants -----------------------------------------------------
  -    
  -   // Attributes ----------------------------------------------------
  -   StatefulSessionContainer con;
  -   
  -   Method ejbActivate;
  -   Method ejbPassivate;
  -   Method ejbRemove;
  -   
  -   File dir;
  -   
  -   // Static --------------------------------------------------------
  -   private static long id = System.currentTimeMillis();
  -   
  -   // Constructors --------------------------------------------------
  -   
  -   // Public --------------------------------------------------------
  -   public void setContainer(Container c)
  -   {
  -      con = (StatefulSessionContainer)c;
  -   }
  -   
  -    public void init()
  -        throws Exception {
  -         
  -        // Find methods
  -        ejbActivate = SessionBean.class.getMethod("ejbActivate", new Class[0]);
  -        
  -       ejbPassivate = SessionBean.class.getMethod("ejbPassivate", new Class[0]);
  -        
  -       ejbRemove = SessionBean.class.getMethod("ejbRemove", new Class[0]);
  -      
  -        // Initialize the dataStore
  -       String ejbName = con.getBeanMetaData().getEjbName();
  -      
  -       File database = new File("database");
  -      
  -       dir = new File(database, ejbName);
  -         
  -       dir.mkdirs();
  -       
  -       Logger.log("Storing sessions for "+ejbName+" in:"+dir);
  -      
  -       // Clear dir of old files
  -       File[] sessions = dir.listFiles();
  -       for (int i = 0; i < sessions.length; i++)
  -       {
  -         sessions[i].delete();
  -       }
  -       Logger.log(sessions.length + " old sessions removed");
  -   }
  -   
  -   public void start()
  -      throws Exception
  -   {
  -   }
  -
  -   public void stop()
  -   {
  -   }
  -   
  -   public void destroy()
  -   {
  -   }
  -   
  -   public void createSession(Method m, Object[] args, 
StatefulSessionEnterpriseContext ctx)
  -      throws RemoteException, CreateException
  -   {
  -      // Get methods
  -      try
  -      {
  -         Method createMethod = con.getBeanClass().getMethod("ejbCreate", 
m.getParameterTypes());
  -      
  -         // Call ejbCreate
  -         createMethod.invoke(ctx.getInstance(), args);
  -         
  -         // Set id
  -         ctx.setId(nextId());
  -       
  -         // Insert in cache
  -         ((StatefulSessionContainer)con).getInstanceCache().insert(ctx);
  -        
  -         // Create EJBObject
  -         
ctx.setEJBObject(con.getContainerInvoker().getStatefulSessionEJBObject(ctx.getId()));
  -
  -      } catch (InvocationTargetException e)
  -      {
  -         throw new CreateException("Create failed:"+e);
  -      } catch (NoSuchMethodException e)
  -      {
  -         throw new CreateException("Create methods not found:"+e);
  -      } catch (IllegalAccessException e)
  -      {
  -         throw new CreateException("Could not create entity:"+e);
  -      } 
  -   }
  -
  -   public void activateSession(StatefulSessionEnterpriseContext ctx)
  -      throws RemoteException
  -   {
  -       try
  -       {
  -         
  -            ObjectInputStream in;
  -            
  -            
  -            // Load state
  -            in = new SessionObjectInputStream(ctx, new FileInputStream(new 
File(dir, ctx.getId()+".ser")));
  -         Field[] fields = ctx.getInstance().getClass().getFields();
  -         
  -         for (int i = 0; i < fields.length; i++)
  -          if (!Modifier.isTransient(fields[i].getModifiers()))
  -              fields[i].set(ctx.getInstance(), in.readObject());
  -         
  -          // Call bean
  -         ejbActivate.invoke(ctx.getInstance(), new Object[0]);
  -      } catch (Exception e)
  -      {
  -         throw new ServerException("Activation failed", e);
  -      }
  -   }
  -   
  -   public void passivateSession(StatefulSessionEnterpriseContext ctx)
  -      throws RemoteException
  -   {
  -      try
  -      {
  -          // Call bean
  -         ejbPassivate.invoke(ctx.getInstance(), new Object[0]);
  -       
  -          // Store state
  -          ObjectOutputStream out = new SessionObjectOutputStream(new 
FileOutputStream(new File(dir, ctx.getId()+".ser")));
  -         
  -         Field[] fields = ctx.getInstance().getClass().getFields();
  -         
  -         for (int i = 0; i < fields.length; i++)
  -          if (!Modifier.isTransient(fields[i].getModifiers()))
  -              out.writeObject(fields[i].get(ctx.getInstance()));
  -         
  -         out.close();        
  -       } catch (Exception e)
  -       {
  -          throw new ServerException("Passivation failed", e);
  -       }
  -   }
  -      
  -   public void removeSession(StatefulSessionEnterpriseContext ctx)
  -      throws RemoteException, RemoveException
  -   {
  -      // Call bean
  -      try
  -      {
  -         ejbRemove.invoke(ctx.getInstance(), new Object[0]);
  -      } catch (Exception e)
  -      {
  -         throw new ServerException("Remove failed", e);
  -      }
  -   }
  -   
  -   // Z implementation ----------------------------------------------
  -    
  -   // Package protected ---------------------------------------------
  -    
  -   // Protected -----------------------------------------------------
  -   protected Long nextId()
  -   {
  -      return new Long(id++);
  -   }
  -   
  -   // Private -------------------------------------------------------
  -   
  -   // Inner classes -------------------------------------------------
  -}
  +/*
  + * jBoss, the OpenSource EJB server
  + *
  + * Distributable under GPL license.
  + * See terms of license at gnu.org.
  + */
  +package org.jboss.ejb.plugins;
  +
  +import java.beans.Beans;
  +import java.beans.beancontext.BeanContextServicesSupport;
  +import java.io.File;
  +import java.io.InputStream;
  +import java.io.OutputStream;
  +import java.io.ObjectInputStream;
  +import java.io.ObjectOutputStream;
  +import java.io.FileOutputStream;
  +import java.io.FileInputStream;
  +import java.io.IOException;
  +import java.lang.reflect.Method;
  +import java.lang.reflect.Field;
  +import java.lang.reflect.Modifier;
  +import java.lang.reflect.InvocationTargetException;
  +import java.rmi.RemoteException;
  +import java.rmi.NoSuchObjectException;
  +import java.rmi.ServerException;
  +import java.util.Collection;
  +import java.util.ArrayList;
  +import java.util.Iterator;
  +import java.sql.SQLException;
  +import java.sql.ResultSet;
  +import java.sql.ResultSetMetaData;
  +import java.sql.DriverManager;
  +import java.sql.Statement;
  +import java.sql.PreparedStatement;
  +import java.sql.Connection;
  +
  +import javax.ejb.EJBObject;
  +import javax.ejb.Handle;
  +import javax.ejb.SessionBean;
  +import javax.ejb.CreateException;
  +import javax.ejb.DuplicateKeyException;
  +import javax.ejb.FinderException;
  +import javax.ejb.RemoveException;
  +import javax.naming.Context;
  +import javax.naming.InitialContext;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.StatefulSessionContainer;
  +import org.jboss.ejb.StatefulSessionPersistenceManager;
  +import org.jboss.ejb.StatefulSessionEnterpriseContext;
  +import org.jboss.logging.Logger;
  +
  +
  +/**
  + *   StatefulSessionFilePersistenceManager
  + *
  + *  This class is one of the passivating plugins for jBoss.  
  + *  It is fairly simple and can work from the file system from wich jBoss is 
operating
  + *      
  + *   @see <related>
  + *   @author Rickard �berg ([EMAIL PROTECTED])
  + *  @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
  + *   @version $Revision: 1.8 $
  + */
  +public class StatefulSessionFilePersistenceManager
  +   implements StatefulSessionPersistenceManager
  +{
  +   // Constants -----------------------------------------------------
  +    
  +   // Attributes ----------------------------------------------------
  +   StatefulSessionContainer con;
  +   
  +   Method ejbActivate;
  +   Method ejbPassivate;
  +   Method ejbRemove;
  +   
  +   File dir;
  +   
  +   // Static --------------------------------------------------------
  +   private static long id = System.currentTimeMillis();
  +   
  +   // Constructors --------------------------------------------------
  +   
  +   // Public --------------------------------------------------------
  +   public void setContainer(Container c)
  +   {
  +      con = (StatefulSessionContainer)c;
  +   }
  +   
  +    public void init()
  +        throws Exception {
  +         
  +        // Find methods
  +        ejbActivate = SessionBean.class.getMethod("ejbActivate", new Class[0]);
  +        
  +       ejbPassivate = SessionBean.class.getMethod("ejbPassivate", new Class[0]);
  +        
  +       ejbRemove = SessionBean.class.getMethod("ejbRemove", new Class[0]);
  +      
  +        // Initialize the dataStore
  +       String ejbName = con.getBeanMetaData().getEjbName();
  +      
  +       File database = new File("database");
  +      
  +       dir = new File(database, ejbName);
  +         
  +       dir.mkdirs();
  +       
  +       Logger.log("Storing sessions for "+ejbName+" in:"+dir);
  +      
  +       // Clear dir of old files
  +       File[] sessions = dir.listFiles();
  +       for (int i = 0; i < sessions.length; i++)
  +       {
  +         sessions[i].delete();
  +       }
  +       Logger.log(sessions.length + " old sessions removed");
  +   }
  +   
  +   public void start()
  +      throws Exception
  +   {
  +   }
  +
  +   public void stop()
  +   {
  +   }
  +   
  +   public void destroy()
  +   {
  +   }
  +   
  +   public void createSession(Method m, Object[] args, 
StatefulSessionEnterpriseContext ctx)
  +      throws RemoteException, CreateException
  +   {
  +      // Get methods
  +      try
  +      {
  +         Method createMethod = con.getBeanClass().getMethod("ejbCreate", 
m.getParameterTypes());
  +      
  +         // Call ejbCreate
  +         createMethod.invoke(ctx.getInstance(), args);
  +         
  +         // Set id
  +         ctx.setId(nextId());
  +       
  +         // Insert in cache
  +         ((StatefulSessionContainer)con).getInstanceCache().insert(ctx);
  +        
  +         // Create EJBObject
  +         
ctx.setEJBObject(con.getContainerInvoker().getStatefulSessionEJBObject(ctx.getId()));
  +
  +      } catch (InvocationTargetException e)
  +      {
  +         throw new CreateException("Create failed:"+e);
  +      } catch (NoSuchMethodException e)
  +      {
  +         throw new CreateException("Create methods not found:"+e);
  +      } catch (IllegalAccessException e)
  +      {
  +         throw new CreateException("Could not create entity:"+e);
  +      } 
  +   }
  +
  +   public void activateSession(StatefulSessionEnterpriseContext ctx)
  +      throws RemoteException
  +   {
  +       try
  +       {
  +         
  +            ObjectInputStream in;
  +            
  +            
  +            // Load state
  +            in = new SessionObjectInputStream(ctx, new FileInputStream(new 
File(dir, ctx.getId()+".ser")));
  +         Field[] fields = ctx.getInstance().getClass().getFields();
  +         
  +         for (int i = 0; i < fields.length; i++)
  +          if (!Modifier.isTransient(fields[i].getModifiers()))
  +              fields[i].set(ctx.getInstance(), in.readObject());
  +         
  +          // Call bean
  +         ejbActivate.invoke(ctx.getInstance(), new Object[0]);
  +      } catch (Exception e)
  +      {
  +         throw new ServerException("Activation failed", e);
  +      }
  +   }
  +   
  +   public void passivateSession(StatefulSessionEnterpriseContext ctx)
  +      throws RemoteException
  +   {
  +      try
  +      {
  +          // Call bean
  +         ejbPassivate.invoke(ctx.getInstance(), new Object[0]);
  +       
  +          // Store state
  +          ObjectOutputStream out = new SessionObjectOutputStream(new 
FileOutputStream(new File(dir, ctx.getId()+".ser")));
  +         
  +         Field[] fields = ctx.getInstance().getClass().getFields();
  +         
  +         for (int i = 0; i < fields.length; i++)
  +          if (!Modifier.isTransient(fields[i].getModifiers()))
  +              out.writeObject(fields[i].get(ctx.getInstance()));
  +         
  +         out.close();        
  +       } catch (Exception e)
  +       {
  +          throw new ServerException("Passivation failed", e);
  +       }
  +   }
  +      
  +   public void removeSession(StatefulSessionEnterpriseContext ctx)
  +      throws RemoteException, RemoveException
  +   {
  +      // Call bean
  +      try
  +      {
  +         ejbRemove.invoke(ctx.getInstance(), new Object[0]);
  +      } catch (Exception e)
  +      {
  +         throw new ServerException("Remove failed", e);
  +      }
  +   }
  +   
  +   // Z implementation ----------------------------------------------
  +    
  +   // Package protected ---------------------------------------------
  +    
  +   // Protected -----------------------------------------------------
  +   protected Long nextId()
  +   {
  +      return new Long(id++);
  +   }
  +   
  +   // Private -------------------------------------------------------
  +   
  +   // Inner classes -------------------------------------------------
  +}
  
  
  
  1.5       +313 -313  
jboss/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java
  
  Index: StatefulSessionInstanceInterceptor.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StatefulSessionInstanceInterceptor.java   2000/09/26 18:58:32     1.4
  +++ StatefulSessionInstanceInterceptor.java   2000/09/26 20:18:51     1.5
  @@ -1,313 +1,313 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/
  -package org.jboss.ejb.plugins;
  -
  -import java.lang.reflect.Method;
  -import java.rmi.RemoteException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.InstanceCache;
  -import org.jboss.ejb.InstancePool;
  -import org.jboss.ejb.StatefulSessionContainer;
  -import org.jboss.ejb.StatefulSessionEnterpriseContext;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.MethodInvocation;
  -import org.jboss.logging.Logger;
  -import org.jboss.metadata.SessionMetaData;
  -import javax.transaction.Transaction;
  -import javax.transaction.RollbackException;
  -import javax.transaction.Status;
  -import javax.transaction.Synchronization;
  -
  -import javax.ejb.EJBException;
  -
  -
  -/**
  -*   This container acquires the given instance. 
  -*
  -*   @see <related>
  -*   @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*   @version $Revision: 1.4 $
  -*/
  -public class StatefulSessionInstanceInterceptor
  -extends AbstractInterceptor
  -{
  -     // Constants ----------------------------------------------------
  -     
  -     // Attributes ---------------------------------------------------
  -     protected StatefulSessionContainer container;
  -     
  -     // Static -------------------------------------------------------
  -     
  -     // Constructors -------------------------------------------------
  -     
  -     // Public -------------------------------------------------------
  -     
  -     public void setContainer(Container container) 
  -     { 
  -             this.container = (StatefulSessionContainer)container; 
  -     }
  -     
  -     public  Container getContainer()
  -     {
  -             return container;
  -     }
  -     // Interceptor implementation -----------------------------------
  -     public Object invokeHome(MethodInvocation mi)
  -     throws Exception
  -     {
  -             // Get context
  -             
  -             // get a new context from the pool (this is a home method call)
  -             EnterpriseContext ctx = container.getInstancePool().get();
  -             
  -             
  -             // set the context on the methodInvocation
  -             mi.setEnterpriseContext(ctx);
  -             
  -             // It is a new context for sure so we can lock it
  -             ctx.lock();
  -             
  -             
  -             try
  -             {
  -                     // Invoke through interceptors
  -                     return getNext().invokeHome(mi);
  -             } finally
  -             {
  -                     // Still free? Not free if create() was called successfully
  -                     if (ctx.getId() == null)
  -                     {
  -                             
  -                             
container.getInstancePool().free(mi.getEnterpriseContext()); 
  -                     } else
  -                     {
  -                             // DEBUG  Logger.log("Session was created; not 
returned to pool");
  -                             
  -                             // Create was called succesfully we go to the cache
  -                             synchronized (ctx) {
  -                                     
  -                                     // Release the lock
  -                                     ctx.unlock();
  -                                     
  -                                     //Let the waiters know
  -                                     //ctx.notifyAll();
  -                             }
  -                     }
  -             }
  -     }
  -     
  -     
  -     private void register(EnterpriseContext ctx, Transaction tx)
  -     {
  -             // Create a new synchronization
  -             InstanceSynchronization synch = new InstanceSynchronization(tx, ctx);
  -             
  -             try {
  -                     // OSH: An extra check to avoid warning.
  -                     // Can go when we are sure that we no longer get
  -                     // the JTA violation warning.
  -                     if (tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
  -                             
  -                             return;
  -                     }
  -                     
  -                     // We want to be notified when the transaction commits
  -                     tx.registerSynchronization(synch);
  -             
  -             } catch (RollbackException e) {
  -             
  -             } catch (Exception e) {
  -                     
  -                     throw new EJBException(e);
  -             
  -             }
  -     }
  -     
  -     public Object invoke(MethodInvocation mi)
  -     throws Exception
  -     {
  -             // Get context
  -             EnterpriseContext ctx = container.getInstanceCache().get(mi.getId());
  -             
  -             // Associate it with the method invocation
  -             mi.setEnterpriseContext(ctx);
  -             
  -             
  -             // We synchronize the locking logic (so we can be reentrant)
  -             synchronized (ctx) 
  -             {
  -                     
  -                     // BMT beans will lock and replace tx no matter what, CMT do 
work on transaction
  -                     if 
(!((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx()) {
  -                             
  -                             // Do we have a running transaction with the context
  -                             if (ctx.getTransaction() != null &&
  -                                     // And are we trying to enter with another 
transaction
  -                                     
!ctx.getTransaction().equals(mi.getTransaction()))
  -                             {
  -                                     // Calls must be in the same transaction
  -                                     throw new RemoteException("Application Error: 
tried to enter Stateful bean with different transaction context");
  -                             }
  -                             
  -                             //If the instance will participate in a new 
transaction we register a sync for it
  -                             if (ctx.getTransaction() == null && 
mi.getTransaction() != null) {
  -                                     
  -                                     register(ctx, mi.getTransaction());
  -                             
  -                             }
  -                     }
  -                     
  -                     if (!ctx.isLocked()){
  -                             
  -                             //take it!
  -                             ctx.lock();  
  -                     }
  -                     
  -                     else 
  -                     {
  -                             
  -                             // Calls must be in the same transaction
  -                             throw new RemoteException("Application Error: no 
concurrent calls on stateful beans");
  -                     }
  -             } 
  -             
  -             try
  -             {
  -                     // Invoke through interceptors
  -                     return getNext().invoke(mi);
  -             } catch (RemoteException e)
  -             {
  -                     // Discard instance
  -                     container.getInstanceCache().remove(mi.getId());
  -                     ctx = null;
  -                     
  -                     throw e;
  -             } catch (RuntimeException e)
  -             {
  -                     // Discard instance
  -                     container.getInstanceCache().remove(mi.getId());
  -                     ctx = null;
  -                     
  -                     throw e;
  -             } catch (Error e)
  -             {
  -                     // Discard instance
  -                     container.getInstanceCache().remove(mi.getId());
  -                     ctx = null;
  -                     
  -                     throw e;
  -             } finally 
  -             {
  -                     if (ctx != null)
  -                     {
  -                             // Still a valid instance
  -                             
  -                             // release it
  -                             ctx.unlock();
  -                             
  -                             // if removed, remove from cache
  -                             if (ctx.getId() == null)
  -                             {
  -                                     // Remove from cache
  -                                     
container.getInstanceCache().remove(mi.getId());
  -                             }
  -                     }
  -             }
  -     }
  -     
  -     // Inner classes -------------------------------------------------
  -     
  -     private class InstanceSynchronization
  -     implements Synchronization
  -     {
  -             /**
  -             *  The transaction we follow.
  -             */
  -             private Transaction tx;
  -             
  -             /**
  -             *  The context we manage.
  -             */
  -             private EnterpriseContext ctx;
  -             
  -             // a utility boolean for session sync
  -             boolean notifySession = false;
  -             
  -             // Utility methods for the notifications
  -             Method beforeCompletion, afterCompletion;
  -             
  -             
  -             /**
  -             *  Create a new instance synchronization instance.
  -             */
  -             InstanceSynchronization(Transaction tx, EnterpriseContext ctx)
  -             {
  -                     this.tx = tx;
  -                     this.ctx = ctx;
  -                     
  -                     // Let's compute it now
  -                     notifySession = (ctx.getInstance() instanceof 
javax.ejb.SessionSynchronization);
  -                     
  -                     if (notifySession) {
  -                             try {
  -                                     
  -                                     // Get the class we are working on
  -                                     Class sync = 
Class.forName("javax.ejb.SessionSynchronization");
  -                                     
  -                                     // Lookup the methods on it
  -                                     beforeCompletion = 
sync.getMethod("beforeCompletion", new Class[0]);
  -                                     
  -                                     afterCompletion =  
sync.getMethod("afterCompletion", new Class[] {Integer.TYPE});
  -                             }
  -                             catch (Exception e) { Logger.exception(e);}
  -                     }
  -             }
  -             
  -             // Synchronization implementation -----------------------------
  -             
  -             public void beforeCompletion()
  -             {
  -                     Logger.log("beforeCompletion called");
  -                     
  -                     // lock the context the transaction is being commited (no need 
for sync)
  -                     ctx.lock();
  -                     
  -                     if (notifySession) {
  -                             try {
  -                                     
  -                                     beforeCompletion.invoke(ctx.getInstance(), new 
Object[0]);
  -                             }
  -                             catch (Exception e) { Logger.exception(e);}
  -                     }
  -             }
  -             
  -             public void afterCompletion(int status)
  -             {
  -                     Logger.log("afterCompletion called");
  -                     
  -                     // finish the transaction association
  -                     ctx.setTransaction(null);
  -                     
  -                     // unlock this context
  -                     ctx.unlock();
  -                     
  -                     if (notifySession) {
  -                             
  -                             try {
  -                                     
  -                                     afterCompletion.invoke(ctx.getInstance(), new 
Object[] {new Integer(status)});
  -                             }
  -                             catch (Exception e) {Logger.exception(e);}
  -                     }
  -             
  -             
  -             }
  -     }
  -}
  -
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/
  +package org.jboss.ejb.plugins;
  +
  +import java.lang.reflect.Method;
  +import java.rmi.RemoteException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.InstanceCache;
  +import org.jboss.ejb.InstancePool;
  +import org.jboss.ejb.StatefulSessionContainer;
  +import org.jboss.ejb.StatefulSessionEnterpriseContext;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.MethodInvocation;
  +import org.jboss.logging.Logger;
  +import org.jboss.metadata.SessionMetaData;
  +import javax.transaction.Transaction;
  +import javax.transaction.RollbackException;
  +import javax.transaction.Status;
  +import javax.transaction.Synchronization;
  +
  +import javax.ejb.EJBException;
  +
  +
  +/**
  +*   This container acquires the given instance. 
  +*
  +*   @see <related>
  +*   @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*   @version $Revision: 1.5 $
  +*/
  +public class StatefulSessionInstanceInterceptor
  +extends AbstractInterceptor
  +{
  +     // Constants ----------------------------------------------------
  +     
  +     // Attributes ---------------------------------------------------
  +     protected StatefulSessionContainer container;
  +     
  +     // Static -------------------------------------------------------
  +     
  +     // Constructors -------------------------------------------------
  +     
  +     // Public -------------------------------------------------------
  +     
  +     public void setContainer(Container container) 
  +     { 
  +             this.container = (StatefulSessionContainer)container; 
  +     }
  +     
  +     public  Container getContainer()
  +     {
  +             return container;
  +     }
  +     // Interceptor implementation -----------------------------------
  +     public Object invokeHome(MethodInvocation mi)
  +     throws Exception
  +     {
  +             // Get context
  +             
  +             // get a new context from the pool (this is a home method call)
  +             EnterpriseContext ctx = container.getInstancePool().get();
  +             
  +             
  +             // set the context on the methodInvocation
  +             mi.setEnterpriseContext(ctx);
  +             
  +             // It is a new context for sure so we can lock it
  +             ctx.lock();
  +             
  +             
  +             try
  +             {
  +                     // Invoke through interceptors
  +                     return getNext().invokeHome(mi);
  +             } finally
  +             {
  +                     // Still free? Not free if create() was called successfully
  +                     if (ctx.getId() == null)
  +                     {
  +                             
  +                             
container.getInstancePool().free(mi.getEnterpriseContext()); 
  +                     } else
  +                     {
  +                             // DEBUG  Logger.log("Session was created; not 
returned to pool");
  +                             
  +                             // Create was called succesfully we go to the cache
  +                             synchronized (ctx) {
  +                                     
  +                                     // Release the lock
  +                                     ctx.unlock();
  +                                     
  +                                     //Let the waiters know
  +                                     //ctx.notifyAll();
  +                             }
  +                     }
  +             }
  +     }
  +     
  +     
  +     private void register(EnterpriseContext ctx, Transaction tx)
  +     {
  +             // Create a new synchronization
  +             InstanceSynchronization synch = new InstanceSynchronization(tx, ctx);
  +             
  +             try {
  +                     // OSH: An extra check to avoid warning.
  +                     // Can go when we are sure that we no longer get
  +                     // the JTA violation warning.
  +                     if (tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
  +                             
  +                             return;
  +                     }
  +                     
  +                     // We want to be notified when the transaction commits
  +                     tx.registerSynchronization(synch);
  +             
  +             } catch (RollbackException e) {
  +             
  +             } catch (Exception e) {
  +                     
  +                     throw new EJBException(e);
  +             
  +             }
  +     }
  +     
  +     public Object invoke(MethodInvocation mi)
  +     throws Exception
  +     {
  +             // Get context
  +             EnterpriseContext ctx = container.getInstanceCache().get(mi.getId());
  +             
  +             // Associate it with the method invocation
  +             mi.setEnterpriseContext(ctx);
  +             
  +             
  +             // We synchronize the locking logic (so we can be reentrant)
  +             synchronized (ctx) 
  +             {
  +                     
  +                     // BMT beans will lock and replace tx no matter what, CMT do 
work on transaction
  +                     if 
(!((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx()) {
  +                             
  +                             // Do we have a running transaction with the context
  +                             if (ctx.getTransaction() != null &&
  +                                     // And are we trying to enter with another 
transaction
  +                                     
!ctx.getTransaction().equals(mi.getTransaction()))
  +                             {
  +                                     // Calls must be in the same transaction
  +                                     throw new RemoteException("Application Error: 
tried to enter Stateful bean with different transaction context");
  +                             }
  +                             
  +                             //If the instance will participate in a new 
transaction we register a sync for it
  +                             if (ctx.getTransaction() == null && 
mi.getTransaction() != null) {
  +                                     
  +                                     register(ctx, mi.getTransaction());
  +                             
  +                             }
  +                     }
  +                     
  +                     if (!ctx.isLocked()){
  +                             
  +                             //take it!
  +                             ctx.lock();  
  +                     }
  +                     
  +                     else 
  +                     {
  +                             
  +                             // Calls must be in the same transaction
  +                             throw new RemoteException("Application Error: no 
concurrent calls on stateful beans");
  +                     }
  +             } 
  +             
  +             try
  +             {
  +                     // Invoke through interceptors
  +                     return getNext().invoke(mi);
  +             } catch (RemoteException e)
  +             {
  +                     // Discard instance
  +                     container.getInstanceCache().remove(mi.getId());
  +                     ctx = null;
  +                     
  +                     throw e;
  +             } catch (RuntimeException e)
  +             {
  +                     // Discard instance
  +                     container.getInstanceCache().remove(mi.getId());
  +                     ctx = null;
  +                     
  +                     throw e;
  +             } catch (Error e)
  +             {
  +                     // Discard instance
  +                     container.getInstanceCache().remove(mi.getId());
  +                     ctx = null;
  +                     
  +                     throw e;
  +             } finally 
  +             {
  +                     if (ctx != null)
  +                     {
  +                             // Still a valid instance
  +                             
  +                             // release it
  +                             ctx.unlock();
  +                             
  +                             // if removed, remove from cache
  +                             if (ctx.getId() == null)
  +                             {
  +                                     // Remove from cache
  +                                     
container.getInstanceCache().remove(mi.getId());
  +                             }
  +                     }
  +             }
  +     }
  +     
  +     // Inner classes -------------------------------------------------
  +     
  +     private class InstanceSynchronization
  +     implements Synchronization
  +     {
  +             /**
  +             *  The transaction we follow.
  +             */
  +             private Transaction tx;
  +             
  +             /**
  +             *  The context we manage.
  +             */
  +             private EnterpriseContext ctx;
  +             
  +             // a utility boolean for session sync
  +             boolean notifySession = false;
  +             
  +             // Utility methods for the notifications
  +             Method beforeCompletion, afterCompletion;
  +             
  +             
  +             /**
  +             *  Create a new instance synchronization instance.
  +             */
  +             InstanceSynchronization(Transaction tx, EnterpriseContext ctx)
  +             {
  +                     this.tx = tx;
  +                     this.ctx = ctx;
  +                     
  +                     // Let's compute it now
  +                     notifySession = (ctx.getInstance() instanceof 
javax.ejb.SessionSynchronization);
  +                     
  +                     if (notifySession) {
  +                             try {
  +                                     
  +                                     // Get the class we are working on
  +                                     Class sync = 
Class.forName("javax.ejb.SessionSynchronization");
  +                                     
  +                                     // Lookup the methods on it
  +                                     beforeCompletion = 
sync.getMethod("beforeCompletion", new Class[0]);
  +                                     
  +                                     afterCompletion =  
sync.getMethod("afterCompletion", new Class[] {Integer.TYPE});
  +                             }
  +                             catch (Exception e) { Logger.exception(e);}
  +                     }
  +             }
  +             
  +             // Synchronization implementation -----------------------------
  +             
  +             public void beforeCompletion()
  +             {
  +                     Logger.log("beforeCompletion called");
  +                     
  +                     // lock the context the transaction is being commited (no need 
for sync)
  +                     ctx.lock();
  +                     
  +                     if (notifySession) {
  +                             try {
  +                                     
  +                                     beforeCompletion.invoke(ctx.getInstance(), new 
Object[0]);
  +                             }
  +                             catch (Exception e) { Logger.exception(e);}
  +                     }
  +             }
  +             
  +             public void afterCompletion(int status)
  +             {
  +                     Logger.log("afterCompletion called");
  +                     
  +                     // finish the transaction association
  +                     ctx.setTransaction(null);
  +                     
  +                     // unlock this context
  +                     ctx.unlock();
  +                     
  +                     if (notifySession) {
  +                             
  +                             try {
  +                                     
  +                                     afterCompletion.invoke(ctx.getInstance(), new 
Object[] {new Integer(status)});
  +                             }
  +                             catch (Exception e) {Logger.exception(e);}
  +                     }
  +             
  +             
  +             }
  +     }
  +}
  +
  
  
  
  1.2       +428 -428  jboss/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java
  
  Index: TxInterceptorCMT.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TxInterceptorCMT.java     2000/09/26 18:58:32     1.1
  +++ TxInterceptorCMT.java     2000/09/26 20:18:51     1.2
  @@ -1,428 +1,428 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL 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.*;
  -
  -import javax.swing.tree.*;
  -
  -import javax.transaction.Status;
  -import javax.transaction.Transaction;
  -import javax.transaction.TransactionManager;
  -import javax.transaction.RollbackException;
  -import javax.transaction.TransactionRequiredException;
  -import javax.transaction.SystemException;
  -
  -import javax.ejb.EJBException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.MethodInvocation;
  -import org.jboss.tm.TxManager;
  -import org.jboss.logging.Logger;
  -
  -import org.jboss.metadata.MetaData;
  -import org.jboss.metadata.BeanMetaData;
  -import org.jboss.metadata.MethodMetaData;
  -
  -/**
  -*   <description>
  -*
  -*   @see <related>
  -*   @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Sebastien Alborini</a>
  -*   @version $Revision: 1.1 $
  -*/
  -public class TxInterceptorCMT
  -extends AbstractInterceptor
  -{
  -    
  -    // Attributes ----------------------------------------------------
  -    private TxManager tm;
  -    private HashMap methodTx = new HashMap();
  -    
  -    protected Container container;
  -
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    public void setContainer(Container container)
  -    {
  -        this.container = container;
  -    }
  -    
  -    public  Container getContainer()
  -    {
  -        return container;
  -    }
  -    
  -    // Interceptor implementation --------------------------------------
  -    public void init()
  -    throws Exception
  -    {
  -        // Store TM reference locally
  -        tm = (TxManager) getContainer().getTransactionManager();
  -        
  -        // Find out method->tx-type mappings from meta-info
  -        //           EnterpriseBean eb = getContainer.getMetaData();
  -        //           eb.getBeanContext()
  -
  -    }
  -    
  -    public Object invokeHome(MethodInvocation mi)
  -    throws Exception
  -    {
  -        return runWithTransactions(false, mi);
  -    }
  -    
  -    /**
  -    *   This method does invocation interpositioning of tx management
  -    *
  -    * @param   id
  -    * @param   m
  -    * @param   args
  -    * @return
  -    * @exception   Exception
  -    */
  -    public Object invoke(MethodInvocation mi) throws Exception {
  -        return runWithTransactions(true, mi);
  -    }
  -    
  -    private void printMethod(Method m, byte type) {
  -        String name;
  -        switch(type) {
  -            case MetaData.TX_MANDATORY:
  -                name = "TX_MANDATORY";
  -            break;
  -            case MetaData.TX_NEVER:
  -                name = "TX_NEVER";
  -            break;
  -            case MetaData.TX_NOT_SUPPORTED:
  -                name = "TX_NOT_SUPPORTED";
  -            break;
  -            case MetaData.TX_REQUIRED:
  -                name = "TX_REQUIRED";
  -            break;
  -            case MetaData.TX_REQUIRES_NEW:
  -                name = "TX_REQUIRES_NEW";
  -            break;
  -            case MetaData.TX_SUPPORTS:
  -                name = "TX_SUPPORTS";
  -            break;
  -            default:
  -                name = "TX_UNKNOWN";
  -        }
  -        Logger.debug(name+" for "+m.getName());
  -    }
  -    
  -    private Object invokeNext(boolean remoteInvocation, MethodInvocation mi) throws 
Exception {
  -        if (remoteInvocation) {
  -            return getNext().invoke(mi);
  -        } else {
  -            return getNext().invokeHome(mi);
  -        }
  -    }
  -    
  -    /*
  -    * runWithTransactions
  -    *
  -    * This is where the meat is.  We define what to do with the Tx based on the 
declaration.
  -    * The MethodInvocation is always the final authority on what the Tx looks like 
leaving this 
  -    * interceptor.  In other words, interceptors down the chain should not rely on 
the thread
  -    * association with Tx but on the Tx present in the MethodInvocation
  -    */
  -    
  -    private Object runWithTransactions(boolean remoteInvocation, MethodInvocation 
mi) throws Exception {
  -        
  -        // Old transaction is the transaction that comes with the MI
  -        Transaction oldTransaction = mi.getTransaction();
  -        // New transaction is the new transaction this might start
  -        Transaction newTransaction = null;
  -        
  -        //DEBUG       Logger.log("Current transaction in MI is 
"+mi.getTransaction()); 
  -        //DEBUG       Logger.log("Current method "+mi.getMethod().getName());       
    
  -        byte transType = getTransactionMethod(mi.getMethod(), remoteInvocation);
  -        
  -        printMethod(mi.getMethod(), transType);
  -        
  -        switch (transType) {
  -            
  -            case MetaData.TX_NOT_SUPPORTED: 
  -                {
  -                    
  -                    
  -                    // Thread arriving must be clean (jboss doesn't set the thread 
previously)
  -                    // However optimized calls come with associated thread for 
example
  -                    Transaction threadTx = tm.disassociateThread();
  -                    
  -                    try {
  -                        
  -                        // Do not set a transaction on the thread even if in MI, 
just run
  -                        return invokeNext(remoteInvocation,mi );
  -                    }
  -                    finally {
  -                        
  -                        // IN case we had a Tx associated with the thread 
reassociate
  -                        if (threadTx != null) {
  -                            
  -                            tm.associateThread(threadTx);
  -                        }
  -                    }
  -                }
  -                
  -                
  -            case MetaData.TX_REQUIRED:      
  -                {
  -                    
  -                    if (oldTransaction == null) { // No tx running
  -                        
  -                        // Create tx 
  -                        tm.begin();
  -                        
  -                        // get the tx
  -                        newTransaction = tm.getTransaction();
  -                        
  -                        // Let the method invocation know
  -                        mi.setTransaction(newTransaction);            
  -                    }
  -                    
  -                    else { // We have a tx propagated
  -                        
  -                        // Associate it with the thread
  -                        tm.associateThread(oldTransaction);
  -                    }
  -                    
  -                    // Continue invocation
  -                    try      {
  -                        
  -                        return invokeNext(remoteInvocation,mi );
  -                    } 
  -                    catch (RemoteException e) {
  -                        
  -                        if (newTransaction != null) {
  -                            
  -                            //We started it, 
  -                            newTransaction.rollback();
  -                        }
  -                        
  -                        throw e;
  -                    } 
  -                    catch (RuntimeException e) {
  -                        
  -                        if (newTransaction != null) {
  -                            
  -                            // We started it
  -                            newTransaction.rollback();
  -                        }
  -                        
  -                        throw new ServerException("Exception occurred", e);
  -                    } 
  -                    catch (Error e) {
  -                        
  -                        if (newTransaction != null) {
  -                            
  -                            // we started it
  -                            newTransaction.rollback();
  -                        }
  -                        throw new ServerException("Exception 
occurred:"+e.getMessage());
  -                    } 
  -                    
  -                    finally {
  -                        
  -                        //DEBUG Logger.log("TxInterceptorCMT: in finally");
  -                        Logger.log("TxInterceptorCMT: In finally");
  -                        
  -                        // Only do something if we started the transaction
  -                        if (newTransaction != null) {
  -                            
  -                            // Marked rollback
  -                            if (newTransaction.getStatus() == 
Status.STATUS_MARKED_ROLLBACK) {
  -                                
  -                                // actually roll it back 
  -                                newTransaction.rollback();
  -                            }
  -                            
  -                            //Still running
  -                            else if(newTransaction.getStatus() == 
Status.STATUS_ACTIVE) {
  -                                
  -                                // Commit tx
  -                                // This will happen if
  -                                // a) everything goes well
  -                                // b) app. exception was thrown
  -                                Logger.log("TxInterceptorCMT:before commit");
  -                                newTransaction.commit();
  -                                Logger.log("TxInterceptorCMT:after commit");
  -                            
  -                            }
  -                            
  -                            // reassociate the oldTransaction with the 
methodInvocation (even null)
  -                            mi.setTransaction(oldTransaction);
  -                        }
  -                    }
  -                }
  -                
  -            case MetaData.TX_SUPPORTS: 
  -                {
  -                    
  -                    if (oldTransaction != null) { // We have a tx propagated
  -                        
  -                        // Associate it with the thread
  -                        tm.associateThread(oldTransaction);
  -                    }
  -                    
  -                    // If we don't have a tx propagated we don't do anything
  -                    
  -                    // Continue invocation
  -                    try      {
  -                        
  -                        return invokeNext(remoteInvocation,mi );
  -                    } 
  -                    catch (RuntimeException e) {
  -                        
  -                        throw new ServerException("Exception occurred", e);
  -                    } 
  -                    catch (Error e) {
  -                        
  -                        throw new ServerException("Exception 
occurred:"+e.getMessage());
  -                    }                                
  -                    
  -                    // Even on error we don't do anything with the tx, we didn't 
start it
  -                
  -                }
  -                
  -            case MetaData.TX_REQUIRES_NEW: 
  -                {
  -                    
  -                    // Thread arriving must be clean (jboss doesn't set the thread 
previously)
  -                    // However optimized calls come with associated thread for 
example
  -                    Transaction threadTx = tm.disassociateThread();
  -                    
  -                    
  -                    // Always begin a transaction 
  -                    tm.begin();
  -                    
  -                    // get it
  -                    newTransaction = tm.getTransaction();
  -                    
  -                    // Set it on the method invocation
  -                    mi.setTransaction(newTransaction);
  -                    
  -                    // Continue invocation
  -                    try {
  -                        
  -                        return invokeNext(remoteInvocation,mi );
  -                    } 
  -                    catch (RemoteException e) {
  -                        
  -                        // We started it for sure
  -                        newTransaction.rollback();
  -                        
  -                        throw e;
  -                    } 
  -                    catch (RuntimeException e) {
  -                        
  -                        // We started it for sure
  -                        newTransaction.rollback();
  -                        
  -                        throw new ServerException("Exception occurred", e);
  -                    } 
  -                    catch (Error e) {
  -                        
  -                        // We started it for sure
  -                        newTransaction.rollback();
  -                        
  -                        throw new ServerException("Exception 
occurred:"+e.getMessage());
  -                    } 
  -                    finally {
  -                        
  -                        // We started the transaction for sure so we commit or roll 
back
  -                        
  -                        if (newTransaction.getStatus() == 
Status.STATUS_MARKED_ROLLBACK) {
  -                            
  -                            newTransaction.rollback();
  -                        }
  -                        else {
  -                            
  -                            // Commit tx
  -                            // This will happen if
  -                            // a) everything goes well
  -                            // b) app. exception was thrown
  -                            newTransaction.commit();
  -                        }
  -                        
  -                        // set the old transaction back on the method invocation
  -                        mi.setTransaction(oldTransaction);
  -                        
  -                        // IN case we had a Tx associated with the thread 
reassociate
  -                        if (threadTx != null) {
  -                            
  -                            tm.associateThread(threadTx);
  -                        }
  -                    }        
  -                }
  -                
  -            case MetaData.TX_MANDATORY: 
  -                {
  -                    
  -                    if (oldTransaction == null) { // no transaction = bad! 
  -                        
  -                        throw new TransactionRequiredException("Transaction 
Required, read the spec!");
  -                    } 
  -                    else {
  -                        
  -                        // Associate it with the thread
  -                        tm.associateThread(oldTransaction);
  -                        
  -                        // That's it
  -                        return invokeNext(remoteInvocation,mi );
  -                    }
  -                }
  -                
  -            case MetaData.TX_NEVER: 
  -                {
  -                    
  -                    if (oldTransaction != null) { // Transaction = bad!
  -                        
  -                        throw new RemoteException("Transaction not allowed");
  -                    } 
  -                    else {
  -                        
  -                        return invokeNext(remoteInvocation,mi );
  -                    }
  -                }
  -        }
  -        
  -        return null;
  -    }
  -    
  -    // Protected  ----------------------------------------------------
  -    
  -    // This should be cached, since this method is called very often
  -    protected byte getTransactionMethod(Method m, boolean remoteInvocation) {
  -        Byte b = (Byte)methodTx.get(m);
  -        if(b != null) return b.byteValue();
  -            
  -        BeanMetaData bmd = container.getBeanMetaData();
  -        //DEBUG Logger.log("Found metadata for bean '"+bmd.getEjbName()+"'"+" 
method is "+m.getName());
  -        byte result = bmd.getMethodTransactionType(m.getName(), 
m.getParameterTypes(), remoteInvocation);
  -        
  -        // provide default if method is not found in descriptor 
  -        if (result == MetaData.TX_UNKNOWN) result = MetaData.TX_REQUIRED;
  -            
  -        methodTx.put(m, new Byte(result));
  -        return result;
  -    }
  -    
  -    // Inner classes -------------------------------------------------
  -    
  -}
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL 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.*;
  +
  +import javax.swing.tree.*;
  +
  +import javax.transaction.Status;
  +import javax.transaction.Transaction;
  +import javax.transaction.TransactionManager;
  +import javax.transaction.RollbackException;
  +import javax.transaction.TransactionRequiredException;
  +import javax.transaction.SystemException;
  +
  +import javax.ejb.EJBException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.MethodInvocation;
  +import org.jboss.tm.TxManager;
  +import org.jboss.logging.Logger;
  +
  +import org.jboss.metadata.MetaData;
  +import org.jboss.metadata.BeanMetaData;
  +import org.jboss.metadata.MethodMetaData;
  +
  +/**
  +*   <description>
  +*
  +*   @see <related>
  +*   @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Sebastien Alborini</a>
  +*   @version $Revision: 1.2 $
  +*/
  +public class TxInterceptorCMT
  +extends AbstractInterceptor
  +{
  +    
  +    // Attributes ----------------------------------------------------
  +    private TxManager tm;
  +    private HashMap methodTx = new HashMap();
  +    
  +    protected Container container;
  +
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    public void setContainer(Container container)
  +    {
  +        this.container = container;
  +    }
  +    
  +    public  Container getContainer()
  +    {
  +        return container;
  +    }
  +    
  +    // Interceptor implementation --------------------------------------
  +    public void init()
  +    throws Exception
  +    {
  +        // Store TM reference locally
  +        tm = (TxManager) getContainer().getTransactionManager();
  +        
  +        // Find out method->tx-type mappings from meta-info
  +        //           EnterpriseBean eb = getContainer.getMetaData();
  +        //           eb.getBeanContext()
  +
  +    }
  +    
  +    public Object invokeHome(MethodInvocation mi)
  +    throws Exception
  +    {
  +        return runWithTransactions(false, mi);
  +    }
  +    
  +    /**
  +    *   This method does invocation interpositioning of tx management
  +    *
  +    * @param   id
  +    * @param   m
  +    * @param   args
  +    * @return
  +    * @exception   Exception
  +    */
  +    public Object invoke(MethodInvocation mi) throws Exception {
  +        return runWithTransactions(true, mi);
  +    }
  +    
  +    private void printMethod(Method m, byte type) {
  +        String name;
  +        switch(type) {
  +            case MetaData.TX_MANDATORY:
  +                name = "TX_MANDATORY";
  +            break;
  +            case MetaData.TX_NEVER:
  +                name = "TX_NEVER";
  +            break;
  +            case MetaData.TX_NOT_SUPPORTED:
  +                name = "TX_NOT_SUPPORTED";
  +            break;
  +            case MetaData.TX_REQUIRED:
  +                name = "TX_REQUIRED";
  +            break;
  +            case MetaData.TX_REQUIRES_NEW:
  +                name = "TX_REQUIRES_NEW";
  +            break;
  +            case MetaData.TX_SUPPORTS:
  +                name = "TX_SUPPORTS";
  +            break;
  +            default:
  +                name = "TX_UNKNOWN";
  +        }
  +        Logger.debug(name+" for "+m.getName());
  +    }
  +    
  +    private Object invokeNext(boolean remoteInvocation, MethodInvocation mi) throws 
Exception {
  +        if (remoteInvocation) {
  +            return getNext().invoke(mi);
  +        } else {
  +            return getNext().invokeHome(mi);
  +        }
  +    }
  +    
  +    /*
  +    * runWithTransactions
  +    *
  +    * This is where the meat is.  We define what to do with the Tx based on the 
declaration.
  +    * The MethodInvocation is always the final authority on what the Tx looks like 
leaving this 
  +    * interceptor.  In other words, interceptors down the chain should not rely on 
the thread
  +    * association with Tx but on the Tx present in the MethodInvocation
  +    */
  +    
  +    private Object runWithTransactions(boolean remoteInvocation, MethodInvocation 
mi) throws Exception {
  +        
  +        // Old transaction is the transaction that comes with the MI
  +        Transaction oldTransaction = mi.getTransaction();
  +        // New transaction is the new transaction this might start
  +        Transaction newTransaction = null;
  +        
  +        //DEBUG       Logger.log("Current transaction in MI is 
"+mi.getTransaction()); 
  +        //DEBUG       Logger.log("Current method "+mi.getMethod().getName());       
    
  +        byte transType = getTransactionMethod(mi.getMethod(), remoteInvocation);
  +        
  +        printMethod(mi.getMethod(), transType);
  +        
  +        switch (transType) {
  +            
  +            case MetaData.TX_NOT_SUPPORTED: 
  +                {
  +                    
  +                    
  +                    // Thread arriving must be clean (jboss doesn't set the thread 
previously)
  +                    // However optimized calls come with associated thread for 
example
  +                    Transaction threadTx = tm.disassociateThread();
  +                    
  +                    try {
  +                        
  +                        // Do not set a transaction on the thread even if in MI, 
just run
  +                        return invokeNext(remoteInvocation,mi );
  +                    }
  +                    finally {
  +                        
  +                        // IN case we had a Tx associated with the thread 
reassociate
  +                        if (threadTx != null) {
  +                            
  +                            tm.associateThread(threadTx);
  +                        }
  +                    }
  +                }
  +                
  +                
  +            case MetaData.TX_REQUIRED:      
  +                {
  +                    
  +                    if (oldTransaction == null) { // No tx running
  +                        
  +                        // Create tx 
  +                        tm.begin();
  +                        
  +                        // get the tx
  +                        newTransaction = tm.getTransaction();
  +                        
  +                        // Let the method invocation know
  +                        mi.setTransaction(newTransaction);            
  +                    }
  +                    
  +                    else { // We have a tx propagated
  +                        
  +                        // Associate it with the thread
  +                        tm.associateThread(oldTransaction);
  +                    }
  +                    
  +                    // Continue invocation
  +                    try      {
  +                        
  +                        return invokeNext(remoteInvocation,mi );
  +                    } 
  +                    catch (RemoteException e) {
  +                        
  +                        if (newTransaction != null) {
  +                            
  +                            //We started it, 
  +                            newTransaction.rollback();
  +                        }
  +                        
  +                        throw e;
  +                    } 
  +                    catch (RuntimeException e) {
  +                        
  +                        if (newTransaction != null) {
  +                            
  +                            // We started it
  +                            newTransaction.rollback();
  +                        }
  +                        
  +                        throw new ServerException("Exception occurred", e);
  +                    } 
  +                    catch (Error e) {
  +                        
  +                        if (newTransaction != null) {
  +                            
  +                            // we started it
  +                            newTransaction.rollback();
  +                        }
  +                        throw new ServerException("Exception 
occurred:"+e.getMessage());
  +                    } 
  +                    
  +                    finally {
  +                        
  +                        //DEBUG Logger.log("TxInterceptorCMT: in finally");
  +                        Logger.log("TxInterceptorCMT: In finally");
  +                        
  +                        // Only do something if we started the transaction
  +                        if (newTransaction != null) {
  +                            
  +                            // Marked rollback
  +                            if (newTransaction.getStatus() == 
Status.STATUS_MARKED_ROLLBACK) {
  +                                
  +                                // actually roll it back 
  +                                newTransaction.rollback();
  +                            }
  +                            
  +                            //Still running
  +                            else if(newTransaction.getStatus() == 
Status.STATUS_ACTIVE) {
  +                                
  +                                // Commit tx
  +                                // This will happen if
  +                                // a) everything goes well
  +                                // b) app. exception was thrown
  +                                Logger.log("TxInterceptorCMT:before commit");
  +                                newTransaction.commit();
  +                                Logger.log("TxInterceptorCMT:after commit");
  +                            
  +                            }
  +                            
  +                            // reassociate the oldTransaction with the 
methodInvocation (even null)
  +                            mi.setTransaction(oldTransaction);
  +                        }
  +                    }
  +                }
  +                
  +            case MetaData.TX_SUPPORTS: 
  +                {
  +                    
  +                    if (oldTransaction != null) { // We have a tx propagated
  +                        
  +                        // Associate it with the thread
  +                        tm.associateThread(oldTransaction);
  +                    }
  +                    
  +                    // If we don't have a tx propagated we don't do anything
  +                    
  +                    // Continue invocation
  +                    try      {
  +                        
  +                        return invokeNext(remoteInvocation,mi );
  +                    } 
  +                    catch (RuntimeException e) {
  +                        
  +                        throw new ServerException("Exception occurred", e);
  +                    } 
  +                    catch (Error e) {
  +                        
  +                        throw new ServerException("Exception 
occurred:"+e.getMessage());
  +                    }                                
  +                    
  +                    // Even on error we don't do anything with the tx, we didn't 
start it
  +                
  +                }
  +                
  +            case MetaData.TX_REQUIRES_NEW: 
  +                {
  +                    
  +                    // Thread arriving must be clean (jboss doesn't set the thread 
previously)
  +                    // However optimized calls come with associated thread for 
example
  +                    Transaction threadTx = tm.disassociateThread();
  +                    
  +                    
  +                    // Always begin a transaction 
  +                    tm.begin();
  +                    
  +                    // get it
  +                    newTransaction = tm.getTransaction();
  +                    
  +                    // Set it on the method invocation
  +                    mi.setTransaction(newTransaction);
  +                    
  +                    // Continue invocation
  +                    try {
  +                        
  +                        return invokeNext(remoteInvocation,mi );
  +                    } 
  +                    catch (RemoteException e) {
  +                        
  +                        // We started it for sure
  +                        newTransaction.rollback();
  +                        
  +                        throw e;
  +                    } 
  +                    catch (RuntimeException e) {
  +                        
  +                        // We started it for sure
  +                        newTransaction.rollback();
  +                        
  +                        throw new ServerException("Exception occurred", e);
  +                    } 
  +                    catch (Error e) {
  +                        
  +                        // We started it for sure
  +                        newTransaction.rollback();
  +                        
  +                        throw new ServerException("Exception 
occurred:"+e.getMessage());
  +                    } 
  +                    finally {
  +                        
  +                        // We started the transaction for sure so we commit or roll 
back
  +                        
  +                        if (newTransaction.getStatus() == 
Status.STATUS_MARKED_ROLLBACK) {
  +                            
  +                            newTransaction.rollback();
  +                        }
  +                        else {
  +                            
  +                            // Commit tx
  +                            // This will happen if
  +                            // a) everything goes well
  +                            // b) app. exception was thrown
  +                            newTransaction.commit();
  +                        }
  +                        
  +                        // set the old transaction back on the method invocation
  +                        mi.setTransaction(oldTransaction);
  +                        
  +                        // IN case we had a Tx associated with the thread 
reassociate
  +                        if (threadTx != null) {
  +                            
  +                            tm.associateThread(threadTx);
  +                        }
  +                    }        
  +                }
  +                
  +            case MetaData.TX_MANDATORY: 
  +                {
  +                    
  +                    if (oldTransaction == null) { // no transaction = bad! 
  +                        
  +                        throw new TransactionRequiredException("Transaction 
Required, read the spec!");
  +                    } 
  +                    else {
  +                        
  +                        // Associate it with the thread
  +                        tm.associateThread(oldTransaction);
  +                        
  +                        // That's it
  +                        return invokeNext(remoteInvocation,mi );
  +                    }
  +                }
  +                
  +            case MetaData.TX_NEVER: 
  +                {
  +                    
  +                    if (oldTransaction != null) { // Transaction = bad!
  +                        
  +                        throw new RemoteException("Transaction not allowed");
  +                    } 
  +                    else {
  +                        
  +                        return invokeNext(remoteInvocation,mi );
  +                    }
  +                }
  +        }
  +        
  +        return null;
  +    }
  +    
  +    // Protected  ----------------------------------------------------
  +    
  +    // This should be cached, since this method is called very often
  +    protected byte getTransactionMethod(Method m, boolean remoteInvocation) {
  +        Byte b = (Byte)methodTx.get(m);
  +        if(b != null) return b.byteValue();
  +            
  +        BeanMetaData bmd = container.getBeanMetaData();
  +        //DEBUG Logger.log("Found metadata for bean '"+bmd.getEjbName()+"'"+" 
method is "+m.getName());
  +        byte result = bmd.getMethodTransactionType(m.getName(), 
m.getParameterTypes(), remoteInvocation);
  +        
  +        // provide default if method is not found in descriptor 
  +        if (result == MetaData.TX_UNKNOWN) result = MetaData.TX_REQUIRED;
  +            
  +        methodTx.put(m, new Byte(result));
  +        return result;
  +    }
  +    
  +    // Inner classes -------------------------------------------------
  +    
  +}
  
  
  

Reply via email to