Repository: tomee Updated Branches: refs/heads/fb_tomee8 32c0c60d5 -> 077f828a3
TOMEE-2169 fix Interceptor Bean handling See TCK test BuiltinMetadataSessionBeanTest Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/039cc1da Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/039cc1da Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/039cc1da Branch: refs/heads/fb_tomee8 Commit: 039cc1da9858fd5cc36957e4bcb55cc7ab3005c2 Parents: 32c0c60 Author: Mark Struberg <strub...@apache.org> Authored: Thu Feb 1 23:16:16 2018 +0100 Committer: Mark Struberg <strub...@apache.org> Committed: Thu Feb 1 23:16:16 2018 +0100 ---------------------------------------------------------------------- .../java/org/apache/openejb/BeanContext.java | 51 +++++++++++++------- .../core/interceptor/InterceptorData.java | 32 ++++++++++++ 2 files changed, 65 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/039cc1da/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java b/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java index 5c72841..93a17cc 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java @@ -72,9 +72,11 @@ import javax.ejb.SessionBean; import javax.ejb.TimedObject; import javax.ejb.Timer; import javax.enterprise.context.ConversationScoped; +import javax.enterprise.context.spi.Contextual; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.AnnotatedMethod; import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.Decorator; import javax.enterprise.inject.spi.InterceptionType; import javax.enterprise.inject.spi.Interceptor; @@ -243,27 +245,13 @@ public class BeanContext extends DeploymentContext { if (CdiInterceptorBean.class.isInstance(i)) { final CdiInterceptorBean cdiInterceptorBean = CdiInterceptorBean.class.cast(i); - data = new InterceptorData(i.getBeanClass()); - data.getAroundInvoke().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.AROUND_INVOKE)); - data.getPostConstruct().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.POST_CONSTRUCT)); - data.getPreDestroy().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.PRE_DESTROY)); - data.getPostActivate().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.POST_ACTIVATE)); - data.getPrePassivate().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.PRE_PASSIVATE)); - data.getAroundTimeout().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.AROUND_TIMEOUT)); - /* - AfterBegin, BeforeCompletion and AfterCompletion are ignored since not handled by CDI - */ + data = new InterceptorData(cdiInterceptorBean); } else { // TODO: here we are not as good as in previous since we loose inheritance for instance data = InterceptorData.scan(i.getBeanClass()); } return data; } - private List<Method> getInterceptionMethodAsListOrEmpty(final CdiInterceptorBean cdiInterceptorBean, final InterceptionType aroundInvoke) { - final Method[] methods = cdiInterceptorBean.getInterceptorMethods(aroundInvoke); - return methods == null ? Collections.<Method>emptyList() : asList(methods); - } - private static void clear(final Collection<?> c) { if (c != null) { // yeah can be null with dynamically impl beans c.clear(); @@ -1679,7 +1667,22 @@ public class BeanContext extends DeploymentContext { } } } - iInstance = interceptorConstructor.create(creationalContext); + CreationalContextImpl cc = (CreationalContextImpl) creationalContext; + Object oldDelegate = cc.putDelegate(beanInstance); + Bean<?> oldBean = cc.putBean(cdiEjbBean); + Contextual<?> oldContextual = cc.putContextual(interceptorData.getCdiInterceptorBean() != null + ? interceptorData.getCdiInterceptorBean() + : interceptorConstructor); // otherwise BeanMetaData is broken + + try { + iInstance = interceptorConstructor.create(creationalContext); + } + finally { + cc.putBean(oldBean); + cc.putContextual(oldContextual); + cc.putDelegate(oldDelegate); + } + } } else { iInstance = clazz.newInstance(); @@ -1754,8 +1757,20 @@ public class BeanContext extends DeploymentContext { final Map<Decorator<?>, Object> instances = new HashMap<Decorator<?>, Object>(); for (int i = decorators.size(); i > 0; i--) { final Decorator<?> decorator = decorators.get(i - 1); - CreationalContextImpl.class.cast(creationalContext).putDelegate(beanInstance); - final Object decoratorInstance = decorator.create(CreationalContext.class.cast(creationalContext)); + CreationalContextImpl cc = (CreationalContextImpl) creationalContext; + Object oldDelegate = cc.putDelegate(beanInstance); + Bean<?> oldBean = cc.putBean(cdiEjbBean); + Contextual<?> oldContextual = cc.putContextual(decorator); // otherwise BeanMetaData is broken + + Object decoratorInstance = null; + try { + decoratorInstance = decorator.create(CreationalContext.class.cast(creationalContext)); + } + finally { + cc.putBean(oldBean); + cc.putContextual(oldContextual); + cc.putDelegate(oldDelegate); + } instances.put(decorator, decoratorInstance); beanInstance = pf.createProxyInstance(proxyClass, instance, new DecoratorHandler(interceptorInfo, decorators, instances, i - 1, instance, cdiEjbBean.getId())); http://git-wip-us.apache.org/repos/asf/tomee/blob/039cc1da/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java b/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java index 4eab48d..2af1735 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java @@ -19,6 +19,7 @@ package org.apache.openejb.core.interceptor; import org.apache.openejb.core.Operation; import org.apache.openejb.util.SetAccessible; +import org.apache.webbeans.component.CdiInterceptorBean; import org.apache.xbean.finder.ClassFinder; import javax.annotation.PostConstruct; @@ -28,6 +29,7 @@ import javax.ejb.AfterCompletion; import javax.ejb.BeforeCompletion; import javax.ejb.PostActivate; import javax.ejb.PrePassivate; +import javax.enterprise.inject.spi.InterceptionType; import javax.interceptor.AroundInvoke; import javax.interceptor.AroundTimeout; import java.lang.annotation.Annotation; @@ -40,6 +42,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import static java.util.Arrays.asList; + /** * @version $Rev$ $Date$ */ @@ -47,6 +51,7 @@ public class InterceptorData { private static final Map<Class<?>, InterceptorData> CACHE = new ConcurrentHashMap<Class<?>, InterceptorData>(); private final Class clazz; + private final CdiInterceptorBean cdiInterceptorBean; private final Set<Method> aroundInvoke = new LinkedHashSet<Method>(); @@ -66,6 +71,33 @@ public class InterceptorData { public InterceptorData(final Class clazz) { this.clazz = clazz; + this.cdiInterceptorBean = null; + } + + public InterceptorData(CdiInterceptorBean cdiInterceptorBean) { + this.cdiInterceptorBean = cdiInterceptorBean; + this.clazz = cdiInterceptorBean.getBeanClass(); + this.aroundInvoke.addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.AROUND_INVOKE)); + this.postConstruct.addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.POST_CONSTRUCT)); + this.preDestroy.addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.PRE_DESTROY)); + this.postActivate.addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.POST_ACTIVATE)); + this.prePassivate.addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.PRE_PASSIVATE)); + this.aroundTimeout.addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.AROUND_TIMEOUT)); + /* + AfterBegin, BeforeCompletion and AfterCompletion are ignored since not handled by CDI + */ + } + + private List<Method> getInterceptionMethodAsListOrEmpty(final CdiInterceptorBean cdiInterceptorBean, final InterceptionType aroundInvoke) { + final Method[] methods = cdiInterceptorBean.getInterceptorMethods(aroundInvoke); + return methods == null ? Collections.<Method>emptyList() : asList(methods); + } + + /** + * @return the CdiInterceptorBean or {@code null} if not a CDI interceptor + */ + public CdiInterceptorBean getCdiInterceptorBean() { + return cdiInterceptorBean; } public Class getInterceptorClass() {