You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by st...@apache.org on 2021/03/02 13:20:48 UTC

[tomee] 04/04: TOMEE-2972 move event to parent Delegation

This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee.git

commit 45f1dff753833aa57fafd046665cc1913484a06c
Author: Mark Struberg <st...@apache.org>
AuthorDate: Tue Mar 2 14:17:57 2021 +0100

    TOMEE-2972 move event to parent Delegation
    
    Introduce new WebappNotificationManager to handle ParentBm delegation
    for all events. This did not work for all cases when OWB did
    directly use NotificationManger internally.
---
 .../org/apache/openejb/cdi/WebappBeanManager.java  | 25 ----------
 .../openejb/cdi/WebappNotificationManager.java     | 58 ++++++++++++++++++++++
 .../apache/openejb/cdi/WebappWebBeansContext.java  |  8 +++
 tck/cdi-embedded/dev-tests.xml                     |  5 +-
 4 files changed, 69 insertions(+), 27 deletions(-)

diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappBeanManager.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappBeanManager.java
index 055afbc..ded4bee 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappBeanManager.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappBeanManager.java
@@ -66,17 +66,6 @@ public class WebappBeanManager extends BeanManagerImpl {
     }
 
     @Override
-    public void fireEvent(final Object event, final EventMetadataImpl metadata, final boolean isLifecycleEvent) {
-        super.fireEvent(event, metadata, isLifecycleEvent);
-        if (isEvent(event)) {
-            final BeanManagerImpl parentBm = getParentBm();
-            if (parentBm != null) {
-                parentBm.fireEvent(event, metadata, isLifecycleEvent);
-            }
-        }
-    }
-
-    @Override
     public List<Interceptor<?>> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings) {
         final List<Interceptor<?>> interceptors = super.resolveInterceptors(type, interceptorBindings);
         final List<Interceptor<?>> parentInterceptors = getParentBm().resolveInterceptors(type, interceptorBindings);
@@ -89,20 +78,6 @@ public class WebappBeanManager extends BeanManagerImpl {
     }
 
     @Override
-    public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(final T event, final EventMetadataImpl metadata) {
-        final Set<ObserverMethod<? super T>> set = new HashSet<>(super.resolveObserverMethods(event, metadata));
-
-        if (isEvent(event)) {
-            final BeanManagerImpl parentBm = getParentBm();
-            if (parentBm != null) {
-                set.addAll(parentBm.resolveObserverMethods(event, metadata));
-            }
-        } // else nothing since extensions are loaded by classloader so we already have it
-
-        return set;
-    }
-
-    @Override
     public Object getInjectableReference(final InjectionPoint injectionPoint, final CreationalContext<?> ctx) {
         Asserts.assertNotNull(injectionPoint, "injectionPoint parameter");
         if(injectionPoint == null)  {
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappNotificationManager.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappNotificationManager.java
new file mode 100644
index 0000000..9c9f89c
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappNotificationManager.java
@@ -0,0 +1,58 @@
+package org.apache.openejb.cdi;
+
+import org.apache.webbeans.event.EventMetadataImpl;
+import org.apache.webbeans.event.NotificationManager;
+
+import javax.enterprise.inject.spi.ObserverMethod;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * NotificationManager which handles delegation to the parent NotifcationManager
+ */
+public final class WebappNotificationManager extends NotificationManager {
+    private final NotificationManager parentNotificationManager;
+
+    /**
+     * We need to know when we did start.
+     * Lifecycle events will only get sent to the parent NotificationManager once the boot is finished.
+     * This is necessary to e.g. handle ProcessInjectionPoint for manual InjectionPointFactory calls.
+     */
+    private boolean hasStarted = false;
+
+    public WebappNotificationManager(WebappWebBeansContext webappWebBeansContext) {
+        super(webappWebBeansContext);
+        this.parentNotificationManager = webappWebBeansContext.getParent() != null
+                ? webappWebBeansContext.getParent().getNotificationManager()
+                : null;
+    }
+
+
+    @Override
+    public void afterStart() {
+        hasStarted = true;
+        super.afterStart();
+    }
+
+    /**
+     * Collect the observer methods of the parent BeanManager plus the own.
+     */
+    @Override
+    public <T> Collection<ObserverMethod<? super T>> resolveObservers(T event, EventMetadataImpl metadata, boolean isLifecycleEvent) {
+        if (isLifecycleEvent) {
+            // we do not send lifecycle events to the parent beanmanager
+            // because the same Extensions get loaded with different instances one per BeanManager anyway
+            return super.resolveObservers(event, metadata, isLifecycleEvent);
+        }
+
+        // for standard event and some lifecycle events at RUNTIME(!),
+        // we also have to invoke the parent NotificationManager
+        List<ObserverMethod<? super T>> observerMethods =
+                parentNotificationManager != null
+                        ? new ArrayList<>(parentNotificationManager.resolveObservers(event, metadata, isLifecycleEvent))
+                        : new ArrayList<>();
+        observerMethods.addAll(super.resolveObservers(event, metadata, isLifecycleEvent));
+        return observerMethods;
+    }
+}
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappWebBeansContext.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappWebBeansContext.java
index 6d99a1a..6effb38 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappWebBeansContext.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/WebappWebBeansContext.java
@@ -22,16 +22,19 @@ import java.util.Properties;
 
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.event.NotificationManager;
 
 import javax.enterprise.inject.spi.Bean;
 
 public class WebappWebBeansContext extends WebBeansContext {
     private final WebBeansContext parent;
     private BeanManagerImpl bm;
+    private final WebappNotificationManager webappNotificationManager;
 
     public WebappWebBeansContext(final Map<Class<?>, Object> services, final Properties properties, final WebBeansContext webBeansContext) {
         super(services, properties);
         parent = webBeansContext;
+        webappNotificationManager = new WebappNotificationManager(this);
     }
 
     @SuppressWarnings("PMD.DoubleCheckedLocking")
@@ -61,4 +64,9 @@ public class WebappWebBeansContext extends WebBeansContext {
         }
         return false;
     }
+
+    @Override
+    public NotificationManager getNotificationManager() {
+        return webappNotificationManager;
+    }
 }
diff --git a/tck/cdi-embedded/dev-tests.xml b/tck/cdi-embedded/dev-tests.xml
index 594bddc..9f4aac7 100644
--- a/tck/cdi-embedded/dev-tests.xml
+++ b/tck/cdi-embedded/dev-tests.xml
@@ -50,8 +50,9 @@
 
     <classes>
       <!-- fails due to integration issue within openejb-http, but passes on cdi-tomee -->
-      <class name="org.jboss.cdi.tck.tests.lookup.modules.specialization.alternative.Specialization06Test">
-<!--        <methods><include name="testInterceptorMetadata"/></methods>-->
+        <!--      <class name="org.jboss.cdi.tck.tests.lookup.modules.specialization.alternative.Specialization06Test">-->
+        <class name="org.jboss.cdi.tck.tests.event.observer.inheritance.enterprise.EnterpriseObserverInheritanceTest">
+<!--        <methods><include name="testNonStaticObserverMethodInherited"/></methods>-->
       </class>
 
     </classes>