You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2007/01/12 02:09:42 UTC

svn commit: r495458 - in /incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core: stateful/ transaction/

Author: dain
Date: Thu Jan 11 17:09:42 2007
New Revision: 495458

URL: http://svn.apache.org/viewvc?view=rev&rev=495458
Log:
Cleaned up stateful container and instance manager

Modified:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/BeanEntry.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulBeanManagedTxPolicy.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContext.java

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/BeanEntry.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/BeanEntry.java?view=diff&rev=495458&r1=495457&r2=495458
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/BeanEntry.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/BeanEntry.java Thu Jan 11 17:09:42 2007
@@ -16,29 +16,31 @@
  */
 package org.apache.openejb.core.stateful;
 
+import java.io.Serializable;
 import javax.transaction.Transaction;
 
-public class BeanEntry implements java.io.Serializable {
+public class BeanEntry implements Serializable {
+    private static final long serialVersionUID = 5940667199866151048L;
+
     protected final Object bean;
-    protected Object primaryKey;
-    protected Object ancillaryState;
-    protected transient Transaction transaction;
-    protected long timeStamp;
-    protected long timeOutInterval;
-    protected boolean inQue = false;
+    protected final Object primaryKey;
+    protected boolean inQueue = false;
+    private long timeStamp;
+    private long timeOutInterval;
+    protected transient Transaction beanTransaction;
 
-    protected BeanEntry(Object beanInstance, Object primKey, Object ancillary, long timeOut) {
+    protected BeanEntry(Object beanInstance, Object primKey, long timeOut) {
         bean = beanInstance;
         primaryKey = primKey;
-        ancillaryState = ancillary;
-        transaction = null;
+        beanTransaction = null;
         timeStamp = System.currentTimeMillis();
         timeOutInterval = timeOut;
     }
 
     protected boolean isTimedOut() {
-        if (timeOutInterval == 0)
+        if (timeOutInterval == 0) {
             return false;
+        }
         long now = System.currentTimeMillis();
         return (now - timeStamp) > timeOutInterval;
     }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulBeanManagedTxPolicy.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulBeanManagedTxPolicy.java?view=diff&rev=495458&r1=495457&r2=495458
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulBeanManagedTxPolicy.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulBeanManagedTxPolicy.java Thu Jan 11 17:09:42 2007
@@ -16,23 +16,21 @@
  */
 package org.apache.openejb.core.stateful;
 
+import javax.transaction.Status;
+import javax.transaction.Transaction;
+
 import org.apache.openejb.ApplicationException;
-import org.apache.openejb.InvalidateReferenceException;
+import org.apache.openejb.Container;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.SystemException;
 import org.apache.openejb.core.transaction.TransactionContainer;
 import org.apache.openejb.core.transaction.TransactionContext;
 import org.apache.openejb.core.transaction.TransactionPolicy;
 
-import javax.transaction.Status;
-import javax.transaction.Transaction;
-import java.rmi.RemoteException;
-
 public class StatefulBeanManagedTxPolicy extends TransactionPolicy {
-
     public StatefulBeanManagedTxPolicy(TransactionContainer container) {
-        this();
-        if (container instanceof org.apache.openejb.Container &&
-                ((org.apache.openejb.Container) container).getContainerType() != org.apache.openejb.Container.STATEFUL) {
-            throw new IllegalArgumentException();
+        if (container instanceof Container && ((Container) container).getContainerType() != Container.STATEFUL) {
+            throw new IllegalArgumentException("Container is not an StatefulContainer");
         }
         this.container = container;
     }
@@ -45,45 +43,47 @@
         return "TX_BeanManaged: ";
     }
 
-    public void beforeInvoke(Object instance, TransactionContext context) throws org.apache.openejb.SystemException, org.apache.openejb.ApplicationException {
+    public void beforeInvoke(Object instance, TransactionContext context) throws SystemException, ApplicationException {
         try {
+            StatefulInstanceManager instanceManager = ((StatefulContainer)container).getInstanceManager();
 
-            StatefulInstanceManager instanceManager = (StatefulInstanceManager) context.context.get(StatefulInstanceManager.class);
+            // suspend any transaction currently associated with this thread
             // if no transaction ---> suspend returns null
             context.clientTx = suspendTransaction(context);
 
-            // Get any previously started transaction
+            // Resume previous Bean transaction if there was one
             Object primaryKey = context.callContext.getPrimaryKey();
-            Object possibleBeanTx = instanceManager.getAncillaryState(primaryKey);
-            if (possibleBeanTx instanceof Transaction) {
-                context.currentTx = (Transaction) possibleBeanTx;
+            Transaction beanTransaction = instanceManager.getBeanTransaction(primaryKey);
+            if (beanTransaction != null) {
+                context.currentTx = beanTransaction;
                 resumeTransaction(context, context.currentTx);
             }
-        } catch (org.apache.openejb.OpenEJBException e) {
+        } catch (OpenEJBException e) {
             handleSystemException(e.getRootCause(), instance, context);
         }
     }
 
-    public void afterInvoke(Object instance, TransactionContext context) throws org.apache.openejb.ApplicationException, org.apache.openejb.SystemException {
+    public void afterInvoke(Object instance, TransactionContext context) throws ApplicationException, SystemException {
         try {
-
+            // Get the transaction after the method invocation
             context.currentTx = context.getTransactionManager().getTransaction();
 
-            /*
-
-            */
-            if (context.currentTx != null &&
-                    context.currentTx.getStatus() != Status.STATUS_COMMITTED &&
-                    context.currentTx.getStatus() != Status.STATUS_ROLLEDBACK) {
-
-                suspendTransaction(context);
+            // If it is not complete, suspend the transaction
+            if (context.currentTx != null) {
+                int status = context.currentTx.getStatus();
+                if (status != Status.STATUS_COMMITTED && status != Status.STATUS_ROLLEDBACK) {
+                    suspendTransaction(context);
+                } else {
+                    // transaction is complete, so there is no need to maintain a referecne to it
+                    context.clientTx = null;
+                }
             }
 
+            // Update the user transaction reference in the bean instance data
             Object primaryKey = context.callContext.getPrimaryKey();
-            StatefulInstanceManager instanceManager = (StatefulInstanceManager) context.context.get(StatefulInstanceManager.class);
-            instanceManager.setAncillaryState(primaryKey, context.currentTx);
-
-        } catch (org.apache.openejb.OpenEJBException e) {
+            StatefulInstanceManager instanceManager = ((StatefulContainer)container).getInstanceManager();
+            instanceManager.setBeanTransaction(primaryKey, context.currentTx);
+        } catch (OpenEJBException e) {
             handleSystemException(e.getRootCause(), instance, context);
         } catch (javax.transaction.SystemException e) {
             handleSystemException(e, instance, context);
@@ -95,12 +95,10 @@
     }
 
     public void handleApplicationException(Throwable appException, TransactionContext context) throws ApplicationException {
-
         throw new ApplicationException(appException);
     }
 
-    public void handleSystemException(Throwable sysException, Object instance, TransactionContext context) throws org.apache.openejb.ApplicationException, org.apache.openejb.SystemException {
-
+    public void handleSystemException(Throwable sysException, Object instance, TransactionContext context) throws ApplicationException, SystemException {
         logSystemException(sysException);
 
         if (context.currentTx != null) markTxRollbackOnly(context.currentTx);
@@ -108,25 +106,6 @@
         discardBeanInstance(instance, context.callContext);
 
         throwExceptionToServer(sysException);
-
-    }
-
-    protected void throwExceptionToServer(Throwable sysException) throws ApplicationException {
-
-        RemoteException re = new RemoteException("The bean encountered a non-application exception.", sysException);
-
-        throw new InvalidateReferenceException(re);
-
-    }
-
-    protected void throwTxExceptionToServer(Throwable sysException) throws ApplicationException {
-        /* Throw javax.transaction.TransactionRolledbackException to remote client */
-
-        String message = "The transaction was rolled back because the bean encountered a non-application exception :" + sysException.getClass().getName() + " : " + sysException.getMessage();
-        javax.transaction.TransactionRolledbackException txException = new javax.transaction.TransactionRolledbackException(message);
-
-        throw new InvalidateReferenceException(txException);
-
     }
 }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?view=diff&rev=495458&r1=495457&r2=495458
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java Thu Jan 11 17:09:42 2007
@@ -21,6 +21,7 @@
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.ProxyInfo;
 import org.apache.openejb.ApplicationException;
+import org.apache.openejb.RpcContainer;
 import org.apache.openejb.core.Operation;
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.CoreDeploymentInfo;
@@ -33,25 +34,30 @@
 
 import javax.ejb.SessionBean;
 import javax.transaction.TransactionManager;
+import javax.transaction.TransactionRequiredException;
 import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 import java.rmi.RemoteException;
+import java.rmi.dgc.VMID;
 import java.util.HashMap;
 import java.util.Map;
 
 /**
  * @org.apache.xbean.XBean element="statefulContainer"
  */
-public class StatefulContainer implements org.apache.openejb.RpcContainer, TransactionContainer {
+public class StatefulContainer implements RpcContainer, TransactionContainer {
+    private static final Logger logger = Logger.getInstance("OpenEJB", "org.apache.openejb.util.resources");
 
-    private StatefulInstanceManager instanceManager;
+    private final Object containerID;
+    private final TransactionManager transactionManager;
+    private final SecurityService securityService;
+    private final StatefulInstanceManager instanceManager;
+
+    /**
+     * Index used for getDeployments() and getDeploymentInfo(deploymentId).
+     */
+    protected final Map<Object, DeploymentInfo> deploymentsById = new HashMap<Object, DeploymentInfo>();
 
-    private HashMap<String,CoreDeploymentInfo> deploymentRegistry = new HashMap<String,CoreDeploymentInfo>();
-
-    private Object containerID = null;
-
-    final static protected Logger logger = Logger.getInstance("OpenEJB", "org.apache.openejb.util.resources");
-    private TransactionManager transactionManager;
-    private SecurityService securityService;
 
     public StatefulContainer(Object id, TransactionManager transactionManager, SecurityService securityService, Class passivator, int timeOut, int poolSize, int bulkPassivate) throws OpenEJBException {
         this.containerID = id;
@@ -59,11 +65,6 @@
         this.securityService = securityService;
 
         instanceManager = new StatefulInstanceManager(transactionManager, securityService, passivator, timeOut, poolSize, bulkPassivate);
-
-        for (CoreDeploymentInfo deploymentInfo : deploymentRegistry.values()) {
-            Map<Method, MethodType> methods = getLifecycelMethodsOfInterface(deploymentInfo);
-            deploymentInfo.setContainerData(new Data(new Index(methods)));
-        }
     }
 
     private class Data {
@@ -79,7 +80,7 @@
     }
 
     private Map<Method, MethodType> getLifecycelMethodsOfInterface(CoreDeploymentInfo deploymentInfo) {
-        Map<Method, MethodType> methods = new HashMap();
+        Map<Method, MethodType> methods = new HashMap<Method, MethodType>();
 
         Method preDestroy = deploymentInfo.getPreDestroy();
         if (preDestroy != null){
@@ -165,15 +166,7 @@
     }
 
     private static enum MethodType {
-        CREATE, REMOVE, BUSINESS;
-    }
-
-    public DeploymentInfo [] deployments() {
-        return (DeploymentInfo []) deploymentRegistry.values().toArray(new DeploymentInfo[deploymentRegistry.size()]);
-    }
-
-    public DeploymentInfo getDeploymentInfo(Object deploymentID) {
-        return (DeploymentInfo) deploymentRegistry.get(deploymentID);
+        CREATE, REMOVE, BUSINESS
     }
 
     public int getContainerType() {
@@ -184,72 +177,148 @@
         return containerID;
     }
 
-    public void deploy(Object deploymentID, DeploymentInfo deploymentInfo) throws OpenEJBException {
-        deploy(deploymentID, (CoreDeploymentInfo)deploymentInfo);
+    public StatefulInstanceManager getInstanceManager() {
+        return instanceManager;
+    }
+
+    public synchronized DeploymentInfo[] deployments() {
+        return deploymentsById.values().toArray(new DeploymentInfo[deploymentsById.size()]);
     }
 
-    private void deploy(Object deploymentID, CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+    public synchronized DeploymentInfo getDeploymentInfo(Object deploymentID) {
+        return deploymentsById.get(deploymentID);
+    }
+
+    public void deploy(Object deploymentId, DeploymentInfo deploymentInfo) throws OpenEJBException {
+        deploy(deploymentId, (CoreDeploymentInfo)deploymentInfo);
+    }
+
+    private synchronized void deploy(Object deploymentId, CoreDeploymentInfo deploymentInfo) {
         Map<Method, MethodType> methods = getLifecycelMethodsOfInterface(deploymentInfo);
-        deploymentInfo.setContainerData(new Data(new Index(methods)));
+        deploymentInfo.setContainerData(new Data(new Index<Method,MethodType>(methods)));
 
-        HashMap registry = (HashMap) deploymentRegistry.clone();
-        registry.put(deploymentID, deploymentInfo);
-        deploymentRegistry = registry;
-        CoreDeploymentInfo di = (CoreDeploymentInfo) deploymentInfo;
-        di.setContainer(this);
+        deploymentsById.put(deploymentId, deploymentInfo);
+        deploymentInfo.setContainer(this);
     }
 
-    public Object invoke(Object deployID, Method callMethod, Object [] args, Object primKey, Object securityIdentity) throws org.apache.openejb.OpenEJBException {
+    public Object invoke(Object deployID, Method callMethod, Object [] args, Object primKey, Object securityIdentity) throws OpenEJBException {
         CoreDeploymentInfo deployInfo = (CoreDeploymentInfo) this.getDeploymentInfo(deployID);
-        ThreadContext callContext = new ThreadContext(deployInfo, primKey, securityIdentity);
-        ThreadContext oldCallContext = ThreadContext.enter(callContext);
+
+        Data data = (Data) deployInfo.getContainerData();
+        MethodType methodType = data.getMethodIndex().get(callMethod);
+        methodType = (methodType != null) ? methodType : MethodType.BUSINESS;
+
+        switch (methodType) {
+            case CREATE:
+                ProxyInfo proxyInfo = createEJBObject(deployInfo, callMethod, args, securityIdentity);
+                return proxyInfo;
+            case REMOVE:
+                removeEJBObject(deployInfo, primKey, callMethod, args, securityIdentity);
+                return null;
+            default:
+                Object value = businessMethod(deployInfo, primKey, callMethod, args, securityIdentity);
+                return value;
+        }
+    }
+
+    protected ProxyInfo createEJBObject(CoreDeploymentInfo deploymentInfo, Method callMethod, Object [] args, Object securityIdentity) throws OpenEJBException {
+        // generate a new primary key
+        Object primaryKey = newPrimaryKey();
+
+        ThreadContext createContext = new ThreadContext(deploymentInfo, primaryKey, securityIdentity);
+        createContext.setCurrentOperation(Operation.OP_CREATE);
+        ThreadContext oldCallContext = ThreadContext.enter(createContext);
         try {
-            boolean authorized = getSecurityService().isCallerAuthorized(securityIdentity, deployInfo.getAuthorizedRoles(callMethod));
+            checkAuthorization(deploymentInfo, callMethod, securityIdentity);
+
+            // allocate a new instance
+            Object bean = instanceManager.newInstance(primaryKey, deploymentInfo.getBeanClass());
 
-            if (!authorized){
-                throw new ApplicationException(new RemoteException("Unauthorized Access by Principal Denied"));
+            // Invoke postConstructs or create(...)
+            if (bean instanceof SessionBean) {
+                Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod);
+                _invoke(callMethod, runMethod, args, bean, createContext);
+            } else {
+                Method postConstruct = deploymentInfo.getPostConstruct();
+                if (postConstruct != null){
+                    _invoke(callMethod, postConstruct, args, bean, createContext);
+                }
             }
 
-            Data data = (Data) deployInfo.getContainerData();
-            MethodType methodType = data.getMethodIndex().get(callMethod);
-            methodType = (methodType != null) ? methodType : MethodType.BUSINESS;
-
-            switch (methodType){
-                case CREATE: return createEJBObject(callContext.getDeploymentInfo(), callMethod, args, callContext.getSecurityIdentity());
-                case REMOVE: removeEJBObject(callMethod, args, callContext); return null;
+
+            instanceManager.poolInstance(primaryKey, bean);
+
+            Class callingClass = callMethod.getDeclaringClass();
+            Class objectInterface = deploymentInfo.getObjectInterface(callingClass);
+            return new ProxyInfo(deploymentInfo, primaryKey, objectInterface, this);
+        } finally {
+            ThreadContext.exit(oldCallContext);
+        }
+    }
+
+    protected Object newPrimaryKey() {
+        return new VMID();
+    }
+
+    protected void removeEJBObject(CoreDeploymentInfo deploymentInfo, Object primKey, Method callMethod, Object[] args, Object securityIdentity) throws OpenEJBException {
+        ThreadContext callContext = new ThreadContext(deploymentInfo, primKey, securityIdentity);
+        ThreadContext oldCallContext = ThreadContext.enter(callContext);
+        try {
+            checkAuthorization(deploymentInfo, callMethod, securityIdentity);
+            try {
+                Object bean = instanceManager.obtainInstance(primKey, callContext);
+                if (bean != null) {
+                    callContext.setCurrentOperation(Operation.OP_REMOVE);
+                    Method preDestroy = callContext.getDeploymentInfo().getPreDestroy();
+                    if (preDestroy != null) {
+                        _invoke(callMethod, preDestroy, null, bean, callContext);
+                    }
+                }
+            } finally {
+                instanceManager.freeInstance(callContext.getPrimaryKey());
             }
+        } finally {
+            ThreadContext.exit(oldCallContext);
+        }
+    }
+
+    private Object businessMethod(CoreDeploymentInfo deploymentInfo, Object primKey, Method callMethod, Object[] args, Object securityIdentity) throws OpenEJBException {
+        ThreadContext callContext = new ThreadContext(deploymentInfo, primKey, securityIdentity);
+        ThreadContext oldCallContext = ThreadContext.enter(callContext);
+        try {
+            checkAuthorization(deploymentInfo, callMethod, securityIdentity);
 
             Object bean = instanceManager.obtainInstance(primKey, callContext);
             callContext.setCurrentOperation(Operation.OP_BUSINESS);
             Object returnValue = null;
-            Method runMethod = deployInfo.getMatchingBeanMethod(callMethod);
+            Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod);
 
             returnValue = _invoke(callMethod, runMethod, args, bean, callContext);
 
             instanceManager.poolInstance(primKey, bean);
 
             return returnValue;
-
         } finally {
             ThreadContext.exit(oldCallContext);
         }
     }
 
-    private SecurityService getSecurityService() {
-        return securityService;
+    private void checkAuthorization(CoreDeploymentInfo deployInfo, Method callMethod, Object securityIdentity) throws ApplicationException {
+        boolean authorized = securityService.isCallerAuthorized(securityIdentity, deployInfo.getAuthorizedRoles(callMethod));
+        if (!authorized) {
+            throw new ApplicationException(new RemoteException("Unauthorized Access by Principal Denied"));
+        }
     }
 
-    protected Object _invoke(Method callMethod, Method runMethod, Object [] args, Object bean, ThreadContext callContext)
-            throws org.apache.openejb.OpenEJBException {
+    protected Object _invoke(Method callMethod, Method runMethod, Object [] args, Object bean, ThreadContext callContext) throws OpenEJBException {
 
         TransactionPolicy txPolicy = callContext.getDeploymentInfo().getTransactionPolicy(callMethod);
-        TransactionContext txContext = new TransactionContext(callContext, getTransactionManager());
-        txContext.context.put(StatefulInstanceManager.class, instanceManager);
+        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
         try {
             txPolicy.beforeInvoke(bean, txContext);
-        } catch (org.apache.openejb.ApplicationException e) {
-            if (e.getRootCause() instanceof javax.transaction.TransactionRequiredException ||
-                    e.getRootCause() instanceof java.rmi.RemoteException) {
+        } catch (ApplicationException e) {
+            if (e.getRootCause() instanceof TransactionRequiredException ||
+                    e.getRootCause() instanceof RemoteException) {
 
                 instanceManager.poolInstance(callContext.getPrimaryKey(), bean);
             }
@@ -259,7 +328,7 @@
         Object returnValue = null;
         try {
             returnValue = runMethod.invoke(bean, args);
-        } catch (java.lang.reflect.InvocationTargetException ite) {// handle enterprise bean exception
+        } catch (InvocationTargetException ite) {// handle enterprise bean exception
             if (ite.getTargetException() instanceof RuntimeException) {
                 /* System Exception ****************************/
 
@@ -288,69 +357,6 @@
         }
 
         return returnValue;
-    }
-
-    private TransactionManager getTransactionManager() {
-        return transactionManager;
-    }
-
-    public StatefulInstanceManager getInstanceManager() {
-        return instanceManager;
-    }
-
-    protected void removeEJBObject(Method callMethod, Object [] args, ThreadContext callContext)
-            throws org.apache.openejb.OpenEJBException {
-
-        try {
-            Object bean = instanceManager.obtainInstance(callContext.getPrimaryKey(), callContext);
-            if (bean != null) {
-                callContext.setCurrentOperation(Operation.OP_REMOVE);
-                Method preDestroy = callContext.getDeploymentInfo().getPreDestroy();
-                if (preDestroy != null) {
-                    _invoke(callMethod, preDestroy, null, bean, callContext);
-                }
-            }
-        } finally {
-            instanceManager.freeInstance(callContext.getPrimaryKey());
-        }
-
-    }
-
-    protected ProxyInfo createEJBObject(CoreDeploymentInfo deploymentInfo, Method callMethod, Object [] args, Object securityIdentity) throws OpenEJBException {
-        // generate a new primary key
-        Object primaryKey = newPrimaryKey();
-
-        ThreadContext createContext = new ThreadContext(deploymentInfo, primaryKey, securityIdentity);
-        createContext.setCurrentOperation(Operation.OP_CREATE);
-        ThreadContext oldContext = ThreadContext.enter(createContext);
-        try {
-            // allocate a new instance
-            Object bean = instanceManager.newInstance(primaryKey, deploymentInfo.getBeanClass());
-
-            // Invoke postConstructs or create(...)
-            if (bean instanceof SessionBean) {
-                Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod);
-                _invoke(callMethod, runMethod, args, bean, createContext);
-            } else {
-                Method postConstruct = deploymentInfo.getPostConstruct();
-                if (postConstruct != null){
-                    _invoke(callMethod, postConstruct, args, bean, createContext);
-                }
-            }
-
-
-            instanceManager.poolInstance(primaryKey, bean);
-
-            Class callingClass = callMethod.getDeclaringClass();
-            Class objectInterface = deploymentInfo.getObjectInterface(callingClass);
-            return new ProxyInfo(deploymentInfo, primaryKey, objectInterface, this);
-        } finally {
-            ThreadContext.exit(oldContext);
-        }
-    }
-
-    protected Object newPrimaryKey() {
-        return new java.rmi.dgc.VMID();
     }
 
     public void discardInstance(Object bean, ThreadContext threadContext) {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java?view=diff&rev=495458&r1=495457&r2=495458
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java Thu Jan 11 17:09:42 2007
@@ -16,58 +16,57 @@
  */
 package org.apache.openejb.core.stateful;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import javax.ejb.EJBException;
+import javax.ejb.SessionContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionRolledbackException;
+
 import org.apache.openejb.ApplicationException;
+import org.apache.openejb.Injection;
 import org.apache.openejb.InvalidateReferenceException;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.SystemException;
-import org.apache.openejb.Injection;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.Operation;
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.ivm.IntraVmCopyMonitor;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.SafeToolkit;
 import org.apache.xbean.recipe.ObjectRecipe;
-import org.apache.xbean.recipe.StaticRecipe;
 import org.apache.xbean.recipe.Option;
-
-import javax.ejb.EJBException;
-import javax.ejb.SessionContext;
-import javax.transaction.Status;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionRolledbackException;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import java.rmi.RemoteException;
-import java.rmi.NoSuchObjectException;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
+import org.apache.xbean.recipe.StaticRecipe;
 
 public class StatefulInstanceManager {
+    public static final Logger logger = Logger.getInstance("OpenEJB", "org.apache.openejb.util.resources");
 
-    private long timeOut = 0;
+    private final long timeOut;
 
-    private Hashtable beanIndex = new Hashtable();
+    private final Hashtable<Object, BeanEntry> beanIndex = new Hashtable<Object, BeanEntry>();
 
-    private BeanEntryQue lruQue;// que of beans for LRU algorithm
+    // queue of beans for LRU algorithm
+    private final BeanEntryQueue lruQueue;
 
-    private PassivationStrategy passivator;
+    private final PassivationStrategy passivator;
 
-    private int bulkPassivationSize = 100;
+    private final int bulkPassivationSize;
 
-    private SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager");
-    private TransactionManager transactionManager;
-    private SecurityService securityService;
+    private final TransactionManager transactionManager;
+    private final SecurityService securityService;
 
     public StatefulInstanceManager(TransactionManager transactionManager, SecurityService securityService, Class passivatorClass, int timeout, int poolSize, int bulkPassivate) throws OpenEJBException {
         this.transactionManager = transactionManager;
         this.securityService = securityService;
-        this.lruQue = new BeanEntryQue(poolSize);
-        if (poolSize == 0){
+        this.lruQueue = new BeanEntryQueue(poolSize);
+        if (poolSize == 0) {
             this.bulkPassivationSize = 1;
         } else {
             this.bulkPassivationSize = Math.min(bulkPassivate, poolSize);
@@ -80,30 +79,24 @@
         } catch (Exception e) {
             throw new OpenEJBException("Could not create the passivator " + passivatorClass.getName(), e);
         }
-
     }
 
-    public Object getAncillaryState(Object primaryKey) throws OpenEJBException {
-        return this.getBeanEntry(primaryKey).ancillaryState;
+    public Transaction getBeanTransaction(Object primaryKey) throws OpenEJBException {
+        BeanEntry entry = getBeanEntry(primaryKey);
+        return entry.beanTransaction;
     }
 
-    public void setAncillaryState(Object primaryKey, Object ancillaryState) throws OpenEJBException {
+    public void setBeanTransaction(Object primaryKey, Transaction beanTransaction) throws OpenEJBException {
         BeanEntry entry = getBeanEntry(primaryKey);
-        entry.ancillaryState = ancillaryState;
-        if (ancillaryState instanceof javax.transaction.Transaction){
-            entry.transaction = (javax.transaction.Transaction) ancillaryState;
-        }
-
+        entry.beanTransaction = beanTransaction;
     }
 
     public Object newInstance(Object primaryKey, Class beanClass) throws OpenEJBException {
         Object bean = null;
 
-
         ThreadContext threadContext = ThreadContext.getThreadContext();
         Operation currentOperation = threadContext.getCurrentOperation();
         threadContext.setCurrentOperation(Operation.OP_SET_CONTEXT);
-
         try {
             ObjectRecipe objectRecipe = new ObjectRecipe(beanClass);
             objectRecipe.allow(Option.FIELD_INJECTION);
@@ -119,7 +112,7 @@
                     Object object = ctx.lookup("java:comp/env/" + jndiName);
                     objectRecipe.setProperty(injection.getName(), new StaticRecipe(object));
                 } catch (NamingException e) {
-                    logger.warning("Injection data not found in enc: jndiName='"+injection.getJndiName()+"', target="+injection.getTarget()+"/"+injection.getName());
+                    logger.warning("Injection data not found in enc: jndiName='" + injection.getJndiName() + "', target=" + injection.getTarget() + "/" + injection.getName());
                 }
             }
 
@@ -140,15 +133,15 @@
             threadContext.setCurrentOperation(currentOperation);
         }
 
-        BeanEntry entry = new BeanEntry(bean, primaryKey, null, timeOut);
-
+        // add to index
+        BeanEntry entry = new BeanEntry(bean, primaryKey, timeOut);
         beanIndex.put(primaryKey, entry);
 
-        return entry.bean;
+        return bean;
     }
 
     private SessionContext createSessionContext() {
-        return (SessionContext) new StatefulContext(transactionManager, securityService);
+        return new StatefulContext(transactionManager, securityService);
     }
 
     public Object obtainInstance(Object primaryKey, ThreadContext callContext) throws OpenEJBException {
@@ -156,103 +149,95 @@
             throw new SystemException(new NullPointerException("Cannot obtain an instance of the stateful session bean with a null session id"));
         }
 
-        BeanEntry entry = (BeanEntry) beanIndex.get(primaryKey);
-        if (entry == null) {
+        // look for entry in index
+        BeanEntry entry = beanIndex.get(primaryKey);
 
-            entry = activate(primaryKey);
-            if (entry != null) {
-
-                if (entry.isTimedOut()) {
-                    /* Since the bean instance hasn't had its ejbActivate() method called yet,
-                       it is still considered to be passivated at this point. Instances that timeout
-                       while passivated must be evicted WITHOUT having their ejbRemove()
-                       method invoked. Section 6.6 of EJB 1.1 specification.
-                    */
-                    throw new InvalidateReferenceException(new NoSuchObjectException("Timed Out"));
-                }
-
-                Operation currentOperation = callContext.getCurrentOperation();
-                callContext.setCurrentOperation(Operation.OP_ACTIVATE);
+        // if we didn't find the bean in the index, try to activate it
+        if (entry == null) {
+            Object bean = activateInstance(primaryKey, callContext);
+            return bean;
+        }
 
-                try {
-                    Method postActivate = callContext.getDeploymentInfo().getPostActivate();
-                    if (postActivate != null){
-                        try {
-                            postActivate.invoke(entry.bean);
-                        } catch (InvocationTargetException e) {
-                            throw e.getTargetException();
-                        }
-                    }
-                } catch (Throwable callbackException) {
-                    /*
-                    In the event of an exception, OpenEJB is required to log the exception, evict the instance,
-                    and mark the transaction for rollback.  If there is a transaction to rollback, then the a
-                    javax.transaction.TransactionRolledbackException must be throw to the client. Otherwise a
-                    java.rmi.RemoteException is thrown to the client.
-                    See EJB 1.1 specification, section 12.3.2
-                    */
-                    handleCallbackException(callbackException, entry.bean, callContext, "ejbActivate");
-                } finally {
-                    callContext.setCurrentOperation(currentOperation);
-                }
+        // if the bean is already in a transaction, just return it
+        if (entry.beanTransaction != null) {
+            return entry.bean;
+        }
 
-                beanIndex.put(primaryKey, entry);
-                return entry.bean;
-            } else {
-                throw new InvalidateReferenceException(new NoSuchObjectException("Not Found"));
+        // remove from the queue so it is not passivated while in use
+        BeanEntry queueEntry = lruQueue.remove(entry);
+        if (queueEntry != null) {
+            // if bean is timed out, destroy it
+            if (entry.isTimedOut()) {
+                entry = beanIndex.remove(entry.primaryKey);
+                handleTimeout(entry, callContext);
+                throw new InvalidateReferenceException(new NoSuchObjectException("Stateful SessionBean has timed-out"));
+            }
+            return entry.bean;
+        } else {
+            // if it is not in the queue, the bean is already being invoked
+            // the only reentrant/concurrent operations allowed are Session synchronization callbacks
+            Operation currentOperation = callContext.getCurrentOperation();
+            if (currentOperation != Operation.OP_AFTER_COMPLETION && currentOperation != Operation.OP_BEFORE_COMPLETION) {
+                throw new ApplicationException(new RemoteException("Concurrent calls not allowed"));
             }
-        } else {// bean has been created and is pooled
-            if (entry.transaction != null) {
 
-                try {
-                    if (entry.transaction.getStatus() == Status.STATUS_ACTIVE) {
+            return entry.bean;
+        }
+    }
 
-//                        if(entry.transaction.equals(OpenEJB.getTransactionManager().getTransaction()))
-                        return entry.bean;
-//                        else
-//                            throw new ApplicationException(new javax.transaction.InvalidTransactionException());
-                    } else {
+    private Object activateInstance(Object primaryKey, ThreadContext callContext) throws SystemException, ApplicationException {
+        // attempt to active a passivated entity
+        BeanEntry entry = activate(primaryKey);
+        if (entry == null) {
+            throw new InvalidateReferenceException(new NoSuchObjectException("Not Found"));
+        }
 
-                        entry.transaction = null;
-                        return entry.bean;
-                    }
-                } catch (javax.transaction.SystemException se) {
-                    throw new SystemException(se);
-                } catch (IllegalStateException ise) {
-                    throw new SystemException(ise);
-                } catch (SecurityException lse) {
-                    throw new SystemException(lse);
-                }
-            } else {// bean is pooled in the "method ready" pool.
+        if (entry.isTimedOut()) {
+            // Since the bean instance hasn't had its ejbActivate() method called yet,
+            // it is still considered to be passivated at this point. Instances that timeout
+            // while passivated must be evicted WITHOUT having their ejbRemove()
+            // method invoked. Section 6.6 of EJB 1.1 specification.
+            throw new InvalidateReferenceException(new NoSuchObjectException("Timed Out"));
+        }
 
-                BeanEntry queEntry = lruQue.remove(entry);// remove from Que so its not passivated while in use
-                if (queEntry != null) {
-                    if (entry.isTimedOut()) {
-                        entry = (BeanEntry) beanIndex.remove(entry.primaryKey);// remove frm index
-                        handleTimeout(entry, callContext);
-                        throw new InvalidateReferenceException(new NoSuchObjectException("Stateful SessionBean has timed-out"));
-                    }
-                    return entry.bean;
-                } else {
-                    Operation currentOperation = callContext.getCurrentOperation();
-                    if (currentOperation == Operation.OP_AFTER_COMPLETION || currentOperation == Operation.OP_BEFORE_COMPLETION) {
-                        return entry.bean;
-                    } else {
-                        throw new ApplicationException(new RemoteException("Concurrent calls not allowed"));
-                    }
+        // call the activate method
+        Operation currentOperation = callContext.getCurrentOperation();
+        callContext.setCurrentOperation(Operation.OP_ACTIVATE);
+        try {
+            Method postActivate = callContext.getDeploymentInfo().getPostActivate();
+            if (postActivate != null) {
+                try {
+                    postActivate.invoke(entry.bean);
+                } catch (InvocationTargetException e) {
+                    throw e.getTargetException();
                 }
             }
+        } catch (Throwable callbackException) {
+            /*
+            In the event of an exception, OpenEJB is required to log the exception, evict the instance,
+            and mark the transaction for rollback.  If there is a transaction to rollback, then the a
+            javax.transaction.TransactionRolledbackException must be throw to the client. Otherwise a
+            java.rmi.RemoteException is thrown to the client.
+            See EJB 1.1 specification, section 12.3.2
+            */
+            handleCallbackException(callbackException, entry.bean, callContext, "ejbActivate");
+        } finally {
+            callContext.setCurrentOperation(currentOperation);
         }
+
+        // add it to the index
+        beanIndex.put(primaryKey, entry);
+
+        return entry.bean;
     }
 
     protected void handleTimeout(BeanEntry entry, ThreadContext threadContext) {
-
         Operation currentOperation = threadContext.getCurrentOperation();
         threadContext.setCurrentOperation(Operation.OP_REMOVE);
 
         try {
             Method preDestroy = threadContext.getDeploymentInfo().getPreDestroy();
-            if (preDestroy != null){
+            if (preDestroy != null) {
                 try {
                     preDestroy.invoke(entry.bean);
                 } catch (InvocationTargetException e) {
@@ -278,49 +263,45 @@
     }
 
     public void poolInstance(Object primaryKey, Object bean) throws OpenEJBException {
-        if (primaryKey == null || bean == null){
+        if (primaryKey == null || bean == null) {
             throw new SystemException("Invalid arguments");
         }
 
-        BeanEntry entry = (BeanEntry) beanIndex.get(primaryKey);
+        BeanEntry entry = beanIndex.get(primaryKey);
         if (entry == null) {
             entry = activate(primaryKey);
             if (entry == null) {
                 throw new SystemException("Invalid primaryKey:" + primaryKey);
             }
-        } else if (entry.bean != bean){
+        } else if (entry.bean != bean) {
             throw new SystemException("Invalid ID for bean");
         }
 
-        if (entry.transaction != null && entry.transaction == entry.ancillaryState) {
-            return;// don't put in LRU (method ready) pool.
-        } else {
+        if (entry.beanTransaction == null) {
             try {
-                entry.transaction = getTransactionManager().getTransaction();
+                entry.beanTransaction = transactionManager.getTransaction();
             } catch (javax.transaction.SystemException se) {
                 throw new SystemException("TransactionManager failure");
             }
 
-            if (entry.transaction == null) {// only put in LRU if no current transaction
-                lruQue.add(entry);// add it to end of Que; the most reciently used bean
+            // only put in LRU if no current transaction
+            if (entry.beanTransaction == null) {
+                // add it to end of Queue; the most reciently used bean
+                lruQueue.add(entry);
             }
         }
     }
 
-    private TransactionManager getTransactionManager() {
-        return transactionManager;
-    }
-
     public Object freeInstance(Object primaryKey) throws SystemException {
         BeanEntry entry = null;
-        entry = (BeanEntry) beanIndex.remove(primaryKey);// remove frm index
+        entry = beanIndex.remove(primaryKey);// remove frm index
         if (entry == null) {
             entry = activate(primaryKey);
         } else {
-            lruQue.remove(entry);
+            lruQueue.remove(entry);
         }
 
-        if (entry == null){
+        if (entry == null) {
             return null;
         }
 
@@ -329,15 +310,15 @@
 
     protected void passivate() throws SystemException {
         final ThreadContext threadContext = ThreadContext.getThreadContext();
-        Hashtable stateTable = new Hashtable(bulkPassivationSize);
+        Hashtable<Object, BeanEntry> stateTable = new Hashtable<Object, BeanEntry>(bulkPassivationSize);
 
         BeanEntry currentEntry;
         final Operation currentOperation = threadContext.getCurrentOperation();
         Method prePassivate = threadContext.getDeploymentInfo().getPrePassivate();
         try {
             for (int i = 0; i < bulkPassivationSize; ++i) {
-                currentEntry = lruQue.first();
-                if (currentEntry == null){
+                currentEntry = lruQueue.first();
+                if (currentEntry == null) {
                     break;
                 }
                 beanIndex.remove(currentEntry.primaryKey);
@@ -346,7 +327,7 @@
                 } else {
                     threadContext.setCurrentOperation(Operation.OP_PASSIVATE);
                     try {
-                        if (prePassivate != null){
+                        if (prePassivate != null) {
                             // TODO Are all beans in the stateTable the same type?
                             try {
                                 prePassivate.invoke(currentEntry.bean);
@@ -391,10 +372,10 @@
     protected InvalidateReferenceException destroy(BeanEntry entry, Exception t) throws SystemException {
 
         beanIndex.remove(entry.primaryKey);// remove frm index
-        lruQue.remove(entry);// remove from que
-        if (entry.transaction != null) {
+        lruQueue.remove(entry);// remove from queue
+        if (entry.beanTransaction != null) {
             try {
-                entry.transaction.setRollbackOnly();
+                entry.beanTransaction.setRollbackOnly();
             } catch (javax.transaction.SystemException se) {
                 throw new SystemException(se);
             } catch (IllegalStateException ise) {
@@ -403,9 +384,9 @@
                 throw new SystemException("Container not authorized to rollback tx", lse);
             }
             return new InvalidateReferenceException(new TransactionRolledbackException(t.getMessage()));
-        } else if (t instanceof RemoteException)
+        } else if (t instanceof RemoteException) {
             return new InvalidateReferenceException(t);
-        else {
+        } else {
             EJBException e = (EJBException) t;
             return new InvalidateReferenceException(new RemoteException(e.getMessage(), e.getCausedByException()));
         }
@@ -416,33 +397,33 @@
         if (primaryKey == null) {
             throw new SystemException(new NullPointerException("The primary key is null. Cannot get the bean entry"));
         }
-        BeanEntry entry = (BeanEntry) beanIndex.get(primaryKey);
+        BeanEntry entry = beanIndex.get(primaryKey);
         if (entry == null) {
             Object bean = this.obtainInstance(primaryKey, ThreadContext.getThreadContext());
             this.poolInstance(primaryKey, bean);
-            entry = (BeanEntry) beanIndex.get(primaryKey);
+            entry = beanIndex.get(primaryKey);
         }
         return entry;
     }
 
-    class BeanEntryQue {
-        private final LinkedList list;
+    class BeanEntryQueue {
+        private final LinkedList<BeanEntry> list;
         private final int capacity;
 
-        protected BeanEntryQue(int preferedCapacity) {
+        protected BeanEntryQueue(int preferedCapacity) {
             capacity = preferedCapacity;
-            list = new LinkedList();
+            list = new LinkedList<BeanEntry>();
         }
 
         protected synchronized BeanEntry first() {
-            return (BeanEntry) list.removeFirst();
+            return list.removeFirst();
         }
 
         protected synchronized void add(BeanEntry entry) throws SystemException {
             entry.resetTimeOut();
 
             list.addLast(entry);
-            entry.inQue = true;
+            entry.inQueue = true;
 
             if (list.size() >= capacity) {// is the LRU QUE full?
                 passivate();
@@ -450,10 +431,11 @@
         }
 
         protected synchronized BeanEntry remove(BeanEntry entry) {
-            if (!entry.inQue)
+            if (!entry.inQueue) {
                 return null;
-            if (list.remove(entry) == true) {
-                entry.inQue = false;
+            }
+            if (list.remove(entry)) {
+                entry.inQueue = false;
                 return entry;
             } else {
 
@@ -462,7 +444,6 @@
         }
     }
 
-    public Logger logger = Logger.getInstance("OpenEJB", "org.apache.openejb.util.resources");
 
     protected void handleCallbackException(Throwable e, Object instance, ThreadContext callContext, String callBack) throws ApplicationException, SystemException {
 
@@ -475,11 +456,13 @@
         /* [2] If the instance is in a transaction, mark the transaction for rollback. */
         Transaction transaction = null;
         try {
-            transaction = getTransactionManager().getTransaction();
+            transaction = transactionManager.getTransaction();
         } catch (Throwable t) {
             logger.error("Could not retreive the current transaction from the transaction manager while handling a callback exception from the " + callBack + " method of bean " + callContext.getPrimaryKey());
         }
-        if (transaction != null) markTxRollbackOnly(transaction);
+        if (transaction != null) {
+            markTxRollbackOnly(transaction);
+        }
 
         /* [3] Discard the instance */
         freeInstance(callContext.getPrimaryKey());
@@ -495,7 +478,9 @@
 
     protected void markTxRollbackOnly(Transaction tx) throws SystemException {
         try {
-            if (tx != null) tx.setRollbackOnly();
+            if (tx != null) {
+                tx.setRollbackOnly();
+            }
         } catch (javax.transaction.SystemException se) {
             throw new SystemException(se);
         }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContext.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContext.java?view=diff&rev=495458&r1=495457&r2=495458
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContext.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContext.java Thu Jan 11 17:09:42 2007
@@ -21,15 +21,10 @@
 
 import org.apache.openejb.core.ThreadContext;
 
-import java.util.Map;
-import java.util.HashMap;
-
 public class TransactionContext {
-
     public Transaction clientTx;
     public Transaction currentTx;
     public ThreadContext callContext;
-    public final Map context = new HashMap();
 
     private final TransactionManager transactionManager;