diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java b/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java index 6cce9156f..548a85070 100644 --- a/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java +++ b/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java @@ -25,7 +25,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -747,19 +746,10 @@ private boolean checkEventTypeParameterForExtensions(Type beanClass, Type observ { if(ClassUtil.isTypeVariable(observerTypeActualArg)) { - TypeVariable tv = (TypeVariable)observerTypeActualArg; - Type tvBound = tv.getBounds()[0]; - - if(tvBound instanceof Class) + if (Class.class.isInstance(beanClass) && GenericsUtil.isAssignableFrom(false, true, observerTypeActualArg, beanClass, new HashMap<>())) { - Class clazzTvBound = (Class)tvBound; - - if(Class.class.isInstance(beanClass) && clazzTvBound.isAssignableFrom(Class.class.cast(beanClass))) - { - return true; - } - } - + return true; + } } else if(ClassUtil.isWildCardType(observerTypeActualArg)) { @@ -773,9 +763,9 @@ else if(observerTypeActualArg instanceof Class) return true; } } - else if (observerTypeActualArg instanceof ParameterizedType) + else if(observerTypeActualArg instanceof ParameterizedType) { - return GenericsUtil.isAssignableFrom(false, true, observerTypeActualArg, beanClass, new HashMap<>()); + return GenericsUtil.isAssignableFrom(true, true, observerTypeActualArg, beanClass, new HashMap<>()); } return false; diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/WithAnnotationTest.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/WithAnnotationTest.java index 257c6ce94..a5f840dca 100644 --- a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/WithAnnotationTest.java +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/WithAnnotationTest.java @@ -51,6 +51,7 @@ public void testWithAnnotation() Assert.assertEquals(4, WithAnnotationExtension.scannedClasses); Assert.assertEquals(1, WithAnnotationExtension.one); + Assert.assertEquals(1, WithAnnotationExtension.extend); } @@ -58,6 +59,7 @@ public static class WithAnnotationExtension implements Extension { public static int scannedClasses = 0; public static int one = 0; + public static int extend = 0; public void processClassess(@Observes @WithAnnotations(MyAnnoation.class) ProcessAnnotatedType pat) { @@ -73,6 +75,12 @@ public void noIssueWithGenericsOWB997(@Observes @WithAnnotations(MyAnnoation.cla { one++; } + + void noIssueWithExtendGenericsOWB997(@Observes @WithAnnotations(MyAnnoation.class) ProcessAnnotatedType pat) + { + extend++; + } + } @Retention(RetentionPolicy.RUNTIME) diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/PortableEventTest.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/PortableEventTest.java index b2103d83c..4a5c73a98 100644 --- a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/PortableEventTest.java +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/PortableEventTest.java @@ -21,25 +21,28 @@ import java.util.ArrayList; import java.util.Collection; -import org.junit.Assert; - -import org.apache.webbeans.test.AbstractUnitTest; -import org.apache.webbeans.test.portable.events.beans.Apple; -import org.apache.webbeans.test.portable.events.beans.AppleTree; -import org.apache.webbeans.test.portable.events.beans.Cherry; -import org.apache.webbeans.test.portable.events.beans.CherryTree; -import org.apache.webbeans.test.portable.events.beans.Tree; import org.apache.webbeans.test.portable.events.extensions.AppleExtension; import org.apache.webbeans.test.portable.events.extensions.AppleExtension1; import org.apache.webbeans.test.portable.events.extensions.MessageReceiverExtension; import org.apache.webbeans.test.portable.events.extensions.MessageSenderExtension; import org.apache.webbeans.test.portable.events.extensions.NotAppleExtnsion; +import org.apache.webbeans.test.portable.events.extensions.ParameterizedTypeWithTypeVariableExtension; import org.apache.webbeans.test.portable.events.extensions.RawTypeExtension; +import org.apache.webbeans.test.portable.events.extensions.ThreeParameterMixedVarianceExtension; import org.apache.webbeans.test.portable.events.extensions.TreeExtension; +import org.apache.webbeans.test.portable.events.extensions.TwoParameterTypeWithTypeVariableExtension; import org.apache.webbeans.test.portable.events.extensions.TypeVariableExtension; import org.apache.webbeans.test.portable.events.extensions.WildcardExtension; import org.apache.webbeans.test.portable.events.extensions.WrongTypeVariableExtension; import org.apache.webbeans.test.portable.events.extensions.WrongWildcardExtension; +import org.junit.Assert; + +import org.apache.webbeans.test.AbstractUnitTest; +import org.apache.webbeans.test.portable.events.beans.Apple; +import org.apache.webbeans.test.portable.events.beans.AppleTree; +import org.apache.webbeans.test.portable.events.beans.Cherry; +import org.apache.webbeans.test.portable.events.beans.CherryTree; +import org.apache.webbeans.test.portable.events.beans.Tree; import org.junit.Test; public class PortableEventTest extends AbstractUnitTest @@ -260,4 +263,68 @@ public void testNumberCallsGenerics() shutDownContainer(); } + + @Test + public void testParameterizedTypeWithTypeVariableExtension() + { + Collection beanXmls = new ArrayList(); + + Collection> beanClasses = new ArrayList>(); + beanClasses.add(ParameterizedTypeWithTypeVariableExtension.PaintToolFactoryImpl.class); + addExtension(new ParameterizedTypeWithTypeVariableExtension()); + startContainer(beanClasses, beanXmls); + + Assert.assertTrue(ParameterizedTypeWithTypeVariableExtension.CALLED); + + shutDownContainer(); + } + + @Test + public void testTwoParameterTypeWithTypeVariableExtension() + { + Collection beanXmls = new ArrayList(); + + Collection> beanClasses = new ArrayList>(); + beanClasses.add(TwoParameterTypeWithTypeVariableExtension.KeyValueStoreImpl.class); + addExtension(new TwoParameterTypeWithTypeVariableExtension()); + startContainer(beanClasses, beanXmls); + + Assert.assertTrue(TwoParameterTypeWithTypeVariableExtension.CALLED); + + shutDownContainer(); + } + + @Test + public void testThreeParameterMixedVarianceExtension_positive() + { + ThreeParameterMixedVarianceExtension.CALLED = false; + + Collection beanXmls = new ArrayList(); + + Collection> beanClasses = new ArrayList>(); + beanClasses.add(ThreeParameterMixedVarianceExtension.TripleStoreImpl.class); + addExtension(new ThreeParameterMixedVarianceExtension()); + startContainer(beanClasses, beanXmls); + + Assert.assertTrue(ThreeParameterMixedVarianceExtension.CALLED); + + shutDownContainer(); + } + + @Test + public void testThreeParameterMixedVarianceExtension_negative() + { + ThreeParameterMixedVarianceExtension.CALLED = false; + + Collection beanXmls = new ArrayList(); + + Collection> beanClasses = new ArrayList>(); + beanClasses.add(ThreeParameterMixedVarianceExtension.TripleStoreWrongImpl.class); + addExtension(new ThreeParameterMixedVarianceExtension()); + startContainer(beanClasses, beanXmls); + + Assert.assertFalse(ThreeParameterMixedVarianceExtension.CALLED); + + shutDownContainer(); + } } diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/ParameterizedTypeWithTypeVariableExtension.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/ParameterizedTypeWithTypeVariableExtension.java new file mode 100644 index 000000000..4923d9d50 --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/ParameterizedTypeWithTypeVariableExtension.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.webbeans.test.portable.events.extensions; + +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.Extension; +import jakarta.enterprise.inject.spi.ProcessAnnotatedType; + +public class ParameterizedTypeWithTypeVariableExtension implements Extension +{ + + public static boolean CALLED = false; + + > void processClasses(@Observes ProcessAnnotatedType event) + { + CALLED = true; + } + + public static class PaintToolFactoryImpl implements PaintToolFactory> + { + @Override + public PaintBrush createPaintTool() + { + return new PaintBrush(); + } + } + + public static class PaintBrush implements PaintTool + { + @Override + public void paint(T color) + { + // no-op + } + } + + public interface PaintTool + { + void paint(T color); + } + + public interface PaintToolFactory> + { + T createPaintTool(); + } + + public interface Color + { + void getColor(); + } + + public static class Red implements Color { + + @Override + public void getColor() { + + } + } + + public static class Green implements Color { + + @Override + public void getColor() { + + } + } +} diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/ThreeParameterMixedVarianceExtension.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/ThreeParameterMixedVarianceExtension.java new file mode 100644 index 000000000..d1f94431e --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/ThreeParameterMixedVarianceExtension.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.webbeans.test.portable.events.extensions; + +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.Extension; +import jakarta.enterprise.inject.spi.ProcessAnnotatedType; + +/** + * Three-parameter generic with mixed variance: + * {@code TripleStore}. + */ +public class ThreeParameterMixedVarianceExtension implements Extension +{ + public static boolean CALLED = false; + + void processClasses(@Observes ProcessAnnotatedType> event) + { + CALLED = true; + } + + public interface Baz3 + { + } + + public static class BazImpl3 implements Baz3 + { + } + + public static class OtherBazImpl3 implements Baz3 + { + } + + public interface Bar3 + { + } + + public static class HeadlineBar implements Bar3 + { + } + + public static class OtherBar implements Bar3 + { + } + + public interface Foo3 + { + } + + public static class HeadlineFoo implements Foo3 + { + } + + public static class OtherFoo implements Foo3 + { + } + + public interface TripleStore> + { + void store(A a, B b, C c); + } + + /** + * Matches the observer: uses HeadlineFoo and HeadlineBar. + */ + public static class TripleStoreImpl implements TripleStore + { + @Override + public void store(HeadlineFoo a, String b, HeadlineBar c) + { + // no-op + } + } + + /** + * Does not match the observer: uses OtherBar instead of HeadlineBar. + */ + public static class TripleStoreWrongImpl implements TripleStore + { + @Override + public void store(HeadlineFoo a, String b, OtherBar c) + { + // no-op + } + } +} + diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/TwoParameterTypeWithTypeVariableExtension.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/TwoParameterTypeWithTypeVariableExtension.java new file mode 100644 index 000000000..8e8c89a8b --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/portable/events/extensions/TwoParameterTypeWithTypeVariableExtension.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.webbeans.test.portable.events.extensions; + +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.Extension; +import jakarta.enterprise.inject.spi.ProcessAnnotatedType; + +/** + * Extension that observes a {@link ProcessAnnotatedType} with a type that has + * two bounded type parameters: {@code }. + */ +public class TwoParameterTypeWithTypeVariableExtension implements Extension +{ + public static boolean CALLED = false; + + void processClasses(@Observes ProcessAnnotatedType> event) + { + CALLED = true; + } + + public interface Foo + { + } + + public interface Bar + { + } + + public interface KeyValueStore + { + void put(K key, V value); + + V get(K key); + } + + public static class FooImpl implements Foo + { + } + + public static class BarImpl implements Bar + { + } + + public static class KeyValueStoreImpl implements KeyValueStore + { + @Override + public void put(FooImpl key, BarImpl value) + { + // no-op + } + + @Override + public BarImpl get(FooImpl key) + { + return null; + } + } +} +