Author: covener
Date: Thu Jul 22 20:06:49 2010
New Revision: 966831

URL: http://svn.apache.org/viewvc?rev=966831&view=rev
Log:
OWB-406 OWB-416 OWB-417
rework the tracking of unremoved dependent stateful session beans and 
removal of un-removed SFSB during Contextual.destroy()


Modified:
    
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
    
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java

Modified: 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java?rev=966831&r1=966830&r2=966831&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
 (original)
+++ 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
 Thu Jul 22 20:06:49 2010
@@ -20,7 +20,10 @@ package org.apache.webbeans.ejb.common.c
 
 import java.lang.reflect.Method;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
+import javax.enterprise.context.Dependent;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.spi.SessionBeanType;
 
@@ -42,9 +45,9 @@ public abstract class BaseEjbBean<T> ext
     /**Injected reference local interface type*/
     protected Class<?> iface = null;
     
-    /** Has the stateful instance already been removed by a business method 
invocation */
-    protected boolean removedStatefulInstance = false;
-    
+    /** Map of proxy instances to the dependent SFSB they've acquired but not 
yet removed */
+    private Map<Object, Object> dependentSFSBToBeRemoved = new 
ConcurrentHashMap<Object, Object>();
+
     /**
      * Creates a new instance of the session bean.
      * @param ejbClassType ebj class type
@@ -72,16 +75,6 @@ public abstract class BaseEjbBean<T> ext
     }
     
     /**
-     * Sets remove flag.
-     * @param remove flag
-     */
-    public void setRemovedStatefulInstance(boolean remove)
-    {
-        this.removedStatefulInstance = remove;
-    }
-    
-        
-    /**
      * {...@inheritdoc}
      */
     @Override
@@ -90,8 +83,6 @@ public abstract class BaseEjbBean<T> ext
         //No-operations
     }
     
-    
-    
     /* (non-Javadoc)
      * @see org.apache.webbeans.component.AbstractBean#isPassivationCapable()
      */
@@ -140,17 +131,32 @@ public abstract class BaseEjbBean<T> ext
     @Override
     protected void destroyComponentInstance(T instance, CreationalContext<T> 
creational)
     {
-        if(!removedStatefulInstance && 
getEjbType().equals(SessionBeanType.STATEFUL))
+        if ((this.getScope() == Dependent.class) && 
(getEjbType().equals(SessionBeanType.STATEFUL)))
         {
-            //Call remove method
-            List<Method> methods = getRemoveMethods();
-            for(Method method : methods)
+            try
+            {
+                Object ejbInstance = getDependentSFSBForProxy(instance);
+                if (ejbInstance != null)
+                {
+                    List<Method> methods = getRemoveMethods();
+                    if (methods.size() > 0)
+                    {
+                        // FIXME: This needs to call an API from the EJB
+                        // container to remove the EJB instance directly, not
+                        // via a remove method
+                        // For now, just call 1 remove method directly on the
+                        // EJB
+                        ClassUtil.callInstanceMethod(methods.get(0), 
ejbInstance, ClassUtil.OBJECT_EMPTY);
+                    }
+                }
+            }
+            finally
             {
-                ClassUtil.callInstanceMethod(method, instance, 
ClassUtil.OBJECT_EMPTY);
+                removeDependentSFSB(instance);
             }
-        }        
+        }
     }
-    
+
     /**
      * Sets session bean type.
      * @param type session bean type
@@ -196,5 +202,36 @@ public abstract class BaseEjbBean<T> ext
     {
         return this.ejbType;
     }
+    
+    /**
+     * Keep track of which proxies have gotten EJB objects out of a context
+     * @param dependentSFSB The dependent SFSB acquired from the EJB container
+     * @param proxy The OWB proxy instance whose method handler acquired the 
dependnet SFSB
+     */
+    public void addDependentSFSB(Object dependentSFSB, Object proxy) 
+    { 
+        dependentSFSBToBeRemoved.put(proxy, dependentSFSB);
+    }
+    
+    /**
+     * Call after observing an @Remove method on an EJB instance
+     * @param proxy the proxy instance the dependent SFSB is associated with
+     */
+    public void removeDependentSFSB(Object proxy) 
+    { 
+        dependentSFSBToBeRemoved.remove(proxy);
+    }
+    
+    /**
+     * 
+     * @param proxy an instance of our own proxy
+     * @return the underlying EJB instance associated with the proxy
+     */
+    public Object getDependentSFSBForProxy(Object proxy) 
+    { 
+        return dependentSFSBToBeRemoved.get(proxy);
+    }
+    
+
 
 }
\ No newline at end of file

Modified: 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java?rev=966831&r1=966830&r2=966831&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
 (original)
+++ 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
 Thu Jul 22 20:06:49 2010
@@ -58,7 +58,7 @@ public class EjbBeanProxyHandler impleme
     /**Proxy ejb bean instance*/
     private BaseEjbBean<?> ejbBean;
     
-    private Object dependentEjb;
+    private Object dependentEJB;
     private boolean isDependent = false;
     
     /**Creational Context*/
@@ -84,7 +84,7 @@ public class EjbBeanProxyHandler impleme
         if (ejbBean.getScope().equals(Dependent.class)) 
         {
             isDependent = true;
-            dependentEjb = null;
+            dependentEJB = null;
         }
     }    
     
@@ -92,7 +92,7 @@ public class EjbBeanProxyHandler impleme
      * {...@inheritdoc}
      */
     @Override
-    public Object invoke(Object instance, Method method, Method proceed, 
Object[] arguments) throws Exception
+    public Object invoke(Object proxyInstance, Method method, Method proceed, 
Object[] arguments) throws Exception
     {
         Object result = null;
         
@@ -107,7 +107,7 @@ public class EjbBeanProxyHandler impleme
             SecurityUtil.doPrivilegedSetAccessible(method, true);
             try
             {
-                return proceed.invoke(instance, arguments);
+                return proceed.invoke(proxyInstance, arguments);
                 
             }
             finally
@@ -119,40 +119,60 @@ public class EjbBeanProxyHandler impleme
         try
         {
             Object webbeansInstance = null;
-            
-            //Check ejb remove method
-            if(this.ejbBean.getEjbType().equals(SessionBeanType.STATEFUL))
-            {
-                if(checkEjbRemoveMethod(method))
-                {
-                    this.ejbBean.setRemovedStatefulInstance(true);
-                }
-            }
-            
-            //Set Ejb bean on thread local
+
+            // Set Ejb bean on thread local
             OpenWebBeansEjbInterceptor.setThreadLocal(this.ejbBean, 
getContextualCreationalContext());
 
-            //Context of the bean
+            // Context of the bean
             Context webbeansContext = 
BeanManagerImpl.getManager().getContext(this.ejbBean.getScope());
-            
-            if (isDependent && this.dependentEjb != null) 
+
+            // Don't go into a _dependent_ context on subsequent method calls 
in
+            // this proxy!
+            if (isDependent && this.dependentEJB != null)
             {
-                webbeansInstance = this.dependentEjb;
+                webbeansInstance = this.dependentEJB;
             }
-            else 
+            else
             {
-                // try looking in the context without 
getContextualCreationalContext() first
+                // try looking in the context without
+                // getContextualCreationalContext() first
                 webbeansInstance = webbeansContext.get(this.ejbBean);
                 if (webbeansInstance == null)
                 {
-                    webbeansInstance = 
webbeansContext.get((Contextual<Object>)this.ejbBean, 
getContextualCreationalContext());
+                    webbeansInstance = 
webbeansContext.get((Contextual<Object>) this.ejbBean, 
getContextualCreationalContext());
                 }
-                if (isDependent)
+
+                // We just got a new dependent EJB, save it in this the 
+                // method handler.
+                if (isDependent && webbeansInstance != null)
                 {
-                    this.dependentEjb = webbeansInstance;
+                    this.dependentEJB = webbeansInstance;
+
+                    if 
(this.ejbBean.getEjbType().equals(SessionBeanType.STATEFUL))
+                    {
+                        // It's an SFSB, so we need to track when it's removed
+                        this.ejbBean.addDependentSFSB(webbeansInstance, 
proxyInstance);
+                    }
                 }
             }
             
+            //Check ejb remove method for dependent SFSB (
+            if (this.ejbBean.isDependent() && 
this.ejbBean.getEjbType().equals(SessionBeanType.STATEFUL))
+            {
+                if (checkEjbRemoveMethod(method))
+                {
+                    // Stop tracking the EJB associated with this proxy
+                    this.ejbBean.removeDependentSFSB(proxyInstance);
+                    
+                    /*
+                     * Keep the local reference to the dependent SFSB. If the
+                     * user calls a contextual EJB with a removed EJB 
associated
+                     * with it we should let the EJB container complain, not
+                     * give them a new EJB under the covers.
+                     */
+                }
+            }
+
             //Call actual method on proxy
             //Actually it is called from OWB Proxy --> EJB Proxy --> Actual 
Bean Instance
             boolean access = method.isAccessible();


Reply via email to