From aecedf707ca9ac02784883bc162226068269a506 Mon Sep 17 00:00:00 2001 From: Jozef Hartinger Date: Sun, 10 Mar 2013 10:48:03 +0100 Subject: [PATCH] WELD-1355 Interceptor and decorators are applied globally (not only within accessible closure) --- .../jboss/weld/manager/BeanManagerImpl.java | 37 +++++++++++--- .../global/accessibility/Foo.java | 25 ++++++++++ .../global/accessibility/FooBinding.java | 36 ++++++++++++++ .../global/accessibility/FooInterceptor.java | 34 +++++++++++++ .../GlobalInterceptorAccessibilityTest.java | 48 +++++++++++++++++++ .../accessibility/VerifyingListener.java | 40 ++++++++++++++++ 6 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/Foo.java create mode 100644 tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooBinding.java create mode 100644 tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooInterceptor.java create mode 100644 tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/GlobalInterceptorAccessibilityTest.java create mode 100644 tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/VerifyingListener.java diff --git a/impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java b/impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java index 0b0bfbb36ef..fdc8282fff1 100644 --- a/impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java +++ b/impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java @@ -256,6 +256,12 @@ public class BeanManagerImpl implements WeldManager, Serializable { */ private final transient Set> beanSet = Collections.synchronizedSet(new HashSet>()); + /* + * Data structure representing all managers *accessible* from this bean + * deployment archive activity + */ + private final transient Set managers; + /* * These data structures represent the managers *accessible* from this bean * deployment archive activity @@ -302,7 +308,8 @@ public static BeanManagerImpl newRootManager(String id, ServiceRegistry serviceR new CopyOnWriteArraySet(), ModuleEnablement.EMPTY_ENABLEMENT, id, - new AtomicInteger()); + new AtomicInteger(), + new HashSet()); } public static BeanManagerImpl newManager(BeanManagerImpl rootManager, String id, ServiceRegistry services) { @@ -320,7 +327,8 @@ public static BeanManagerImpl newManager(BeanManagerImpl rootManager, String id, new CopyOnWriteArraySet(), ModuleEnablement.EMPTY_ENABLEMENT, id, - new AtomicInteger()); + new AtomicInteger(), + rootManager.managers); } /** @@ -354,7 +362,8 @@ public static BeanManagerImpl newChildActivityManager(BeanManagerImpl parentMana parentManager.getCurrentActivities(), parentManager.getEnabled(), new StringBuilder().append(parentManager.getChildIds().incrementAndGet()).toString(), - parentManager.getChildIds()); + parentManager.getChildIds(), + parentManager.managers); } private BeanManagerImpl( @@ -371,7 +380,8 @@ private BeanManagerImpl( Set currentActivities, ModuleEnablement enabled, String id, - AtomicInteger childIds) { + AtomicInteger childIds, + Set managers) { this.services = serviceRegistry; this.beans = beans; this.transitiveBeans = transitiveBeans; @@ -386,6 +396,9 @@ private BeanManagerImpl( this.namespaces = namespaces; this.id = id; this.childIds = new AtomicInteger(); + this.managers = managers; + + managers.add(this); // Set up the structure to store accessible managers in this.accessibleManagers = new HashSet(); @@ -393,8 +406,8 @@ private BeanManagerImpl( // TODO Currently we build the accessible bean list on the fly, we need to set it in stone once bootstrap is finished... Transform> beanTransform = new BeanTransform(this); this.beanResolver = new TypeSafeBeanResolver(this, createDynamicAccessibleIterable(beanTransform)); - this.decoratorResolver = new TypeSafeDecoratorResolver(this, createDynamicAccessibleIterable(DecoratorTransform.INSTANCE)); - this.interceptorResolver = new TypeSafeInterceptorResolver(this, createDynamicAccessibleIterable(InterceptorTransform.INSTANCE)); + this.decoratorResolver = new TypeSafeDecoratorResolver(this, createDynamicGlobalIterable(DecoratorTransform.INSTANCE)); + this.interceptorResolver = new TypeSafeInterceptorResolver(this, createDynamicGlobalIterable(InterceptorTransform.INSTANCE)); this.nameBasedResolver = new NameBasedResolver(this, createDynamicAccessibleIterable(beanTransform)); this.weldELResolver = new WeldELResolver(this); this.childActivities = new CopyOnWriteArraySet(); @@ -408,6 +421,17 @@ private BeanManagerImpl( this.containerLifecycleEvents = serviceRegistry.get(ContainerLifecycleEvents.class); } + private Iterable createDynamicGlobalIterable(final Transform transform) { + return new Iterable() { + public Iterator iterator() { + Set> result = new HashSet>(); + for (BeanManagerImpl manager : managers) { + result.add(transform.transform(manager)); + } + return Iterators.concat(Iterators.transform(result.iterator(), IterableToIteratorFunction.instance())); + } + }; + } private Iterable createDynamicAccessibleIterable(final Transform transform) { return new Iterable() { @@ -1142,6 +1166,7 @@ public SessionBean getBean(EjbDescriptor descriptor) { public void cleanup() { services.cleanup(); this.accessibleManagers.clear(); + this.managers.clear(); this.beanResolver.clear(); this.beans.clear(); this.childActivities.clear(); diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/Foo.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/Foo.java new file mode 100644 index 00000000000..8c76c2c6904 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/Foo.java @@ -0,0 +1,25 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.weld.tests.interceptors.global.accessibility; + +@FooBinding +public class Foo { + + public String ping() { + return "pong"; + } +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooBinding.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooBinding.java new file mode 100644 index 00000000000..4d237103191 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooBinding.java @@ -0,0 +1,36 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.weld.tests.interceptors.global.accessibility; + +import java.lang.annotation.Documented; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.interceptor.InterceptorBinding; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@InterceptorBinding +@Inherited +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +public @interface FooBinding { + +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooInterceptor.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooInterceptor.java new file mode 100644 index 00000000000..6a0c1c98dca --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/FooInterceptor.java @@ -0,0 +1,34 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.weld.tests.interceptors.global.accessibility; + +import javax.annotation.Priority; +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; + +@Interceptor +@FooBinding +@Priority(Interceptor.Priority.APPLICATION + 100) +public class FooInterceptor { + + @AroundInvoke + Object intercept(InvocationContext ctx) throws Exception { + ctx.proceed(); + return "intercepted"; + } +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/GlobalInterceptorAccessibilityTest.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/GlobalInterceptorAccessibilityTest.java new file mode 100644 index 00000000000..d89ac76c105 --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/GlobalInterceptorAccessibilityTest.java @@ -0,0 +1,48 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.weld.tests.interceptors.global.accessibility; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.BeanArchive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.weld.tests.category.Integration; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +@RunWith(Arquillian.class) +@Category(Integration.class) +public class GlobalInterceptorAccessibilityTest { + + @Deployment(testable = false) + public static Archive getDeployment() { + WebArchive war = ShrinkWrap.create(WebArchive.class).addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml").addClasses(FooInterceptor.class, VerifyingListener.class); + JavaArchive jar = ShrinkWrap.create(BeanArchive.class).addClasses(Foo.class, FooBinding.class); + return ShrinkWrap.create(EnterpriseArchive.class).addAsModule(war).addAsLibrary(jar); + } + + @Test + public void test() { + // noop, the deployment is verified within VerifyingListener + } +} diff --git a/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/VerifyingListener.java b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/VerifyingListener.java new file mode 100644 index 00000000000..6411121ff6e --- /dev/null +++ b/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/global/accessibility/VerifyingListener.java @@ -0,0 +1,40 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.weld.tests.interceptors.global.accessibility; + +import javax.inject.Inject; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +@WebListener +public class VerifyingListener implements ServletContextListener { + + @Inject + private Foo foo; + + @Override + public void contextInitialized(ServletContextEvent sce) { + if (!"intercepted".equals(foo.ping())) { + throw new IllegalStateException(); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + } +}