This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 0da7a3c [OWB-1402] ensure Instance#select uses an append logic for
qualifiers
0da7a3c is described below
commit 0da7a3cfa262f7206fee11953a6d3468e493ab52
Author: Romain Manni-Bucau <[email protected]>
AuthorDate: Wed Feb 2 19:10:55 2022 +0100
[OWB-1402] ensure Instance#select uses an append logic for qualifiers
---
.../webbeans/inject/instance/InstanceImpl.java | 32 +++--
.../InstanceQualifierInjectionPointTest.java | 2 +-
.../webbeans/test/instance/InstanceSelectTest.java | 147 +++++++++++++++++++++
3 files changed, 170 insertions(+), 11 deletions(-)
diff --git
a/webbeans-impl/src/main/java/org/apache/webbeans/inject/instance/InstanceImpl.java
b/webbeans-impl/src/main/java/org/apache/webbeans/inject/instance/InstanceImpl.java
index 1219a42..c8eb746 100644
---
a/webbeans-impl/src/main/java/org/apache/webbeans/inject/instance/InstanceImpl.java
+++
b/webbeans-impl/src/main/java/org/apache/webbeans/inject/instance/InstanceImpl.java
@@ -32,9 +32,11 @@ import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Stream;
import javax.enterprise.context.spi.AlterableContext;
import javax.enterprise.context.spi.Context;
+import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.Bean;
@@ -42,6 +44,7 @@ import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.util.TypeLiteral;
import javax.inject.Provider;
+import org.apache.webbeans.annotation.DefaultLiteral;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.container.InjectionResolver;
@@ -178,14 +181,16 @@ public class InstanceImpl<T> implements Instance<T>,
Serializable
* {@inheritDoc}
*/
@Override
- public Instance<T> select(Annotation... qualifiers)
+ public Instance<T> select(final Annotation... qualifiers)
{
if (strictValidation)
{
webBeansContext.getAnnotationManager().checkQualifierConditions(qualifiers);
}
- Annotation[] newQualifiersArray = qualifiers;
+ final Annotation[] newQualifiersArray = qualifiers.length == 0?
+ qualifierAnnotations.toArray(new Annotation[0]) :
+ concatenateQualifiers(qualifiers);
return new InstanceImpl<>(
injectionClazz, injectionPoint == null ? null : new
InstanceInjectionPoint(injectionPoint, newQualifiersArray),
webBeansContext, newQualifiersArray);
@@ -203,19 +208,14 @@ public class InstanceImpl<T> implements Instance<T>,
Serializable
}
Type sub = subtype;
-
if(sub == null)
{
sub = injectionClazz;
}
- if (qualifiers== null || qualifiers.length == 0)
- {
-
- }
- Annotation[] effectiveQualifiers = qualifiers != null &&
qualifiers.length > 0
- ? qualifiers
- : qualifierAnnotations.toArray(new
Annotation[qualifierAnnotations.size()]);
+ final Annotation[] effectiveQualifiers = qualifiers != null &&
qualifiers.length > 0
+ ? concatenateQualifiers(qualifiers)
+ : qualifierAnnotations.toArray(new Annotation[0]);
return new InstanceImpl<>(sub, injectionPoint, webBeansContext,
effectiveQualifiers);
}
@@ -250,6 +250,18 @@ public class InstanceImpl<T> implements Instance<T>,
Serializable
};
}
+ private Annotation[] concatenateQualifiers(final Annotation[]
additionalQualifiers)
+ {
+ return Stream.concat(
+ qualifierAnnotations.stream()
+ .filter(it -> it.annotationType() !=
Any.class) // no more relevant if there is another one
+ // see
org.apache.webbeans.portable.InstanceProducer.produce
+ // NOT equals() to respect user request but ==
+ .filter(it -> it != DefaultLiteral.INSTANCE),
+ Stream.of(additionalQualifiers))
+ .toArray(Annotation[]::new);
+ }
+
public void destroy(T instance)
{
if (instance == null)
diff --git
a/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceQualifierInjectionPointTest.java
b/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceQualifierInjectionPointTest.java
index e82c9cb..340952a 100644
---
a/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceQualifierInjectionPointTest.java
+++
b/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceQualifierInjectionPointTest.java
@@ -64,7 +64,7 @@ public class InstanceQualifierInjectionPointTest extends
AbstractUnitTest
Factory.class), Collections.<String>emptyList(), true);
assertNotNull(instance1.select(new AnnotationLiteral<Qualifier1>()
{}).get());
- assertEquals(1, holder.getQualifiers().size());
+ assertEquals(holder.getQualifiers().toString(), 1,
holder.getQualifiers().size());
assertEquals(Qualifier1.class,
holder.getQualifiers().iterator().next().annotationType());
assertNotNull(instance2.select(AnyLiteral.INSTANCE).get());
diff --git
a/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceSelectTest.java
b/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceSelectTest.java
new file mode 100644
index 0000000..ae53f34
--- /dev/null
+++
b/webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceSelectTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.instance;
+
+import org.apache.webbeans.test.AbstractUnitTest;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Inject;
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.Collection;
+import java.util.stream.Stream;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.toList;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class InstanceSelectTest extends AbstractUnitTest {
+ @Inject
+ @Any
+ private Instance<Food> allTypesOfFood;
+
+ @Before
+ public void init() {
+ startContainer(asList(Cherry.class, Strawberry.class), emptyList(),
true);
+ }
+
+ @Test
+ public void findYummyFruit() {
+ final Instance<Food> fruits = allTypesOfFood.select(new
LiteralFoodType(FoodType.FRUIT));
+ final Instance<Food> jummyFruits = fruits.select(new
LiteralTasteType(TasteType.JUMMY));
+ assertTrue(jummyFruits.stream().findAny().isPresent());
+ }
+
+ @Test
+ public void thereIsNoJummyVegetable() {
+ final Instance<Food> vegetables = allTypesOfFood.select(new
LiteralFoodType(FoodType.VEGETABLE));
+ assertTrue(vegetables.isUnsatisfied());
+
+ final Instance<Food> jummyVegetables = vegetables.select(new
LiteralTasteType(TasteType.JUMMY));
+ final Collection<Food> selected =
jummyVegetables.stream().collect(toList());
+ assertFalse(selected.toString(),
selected.stream().findAny().isPresent());
+ }
+
+ public static class LiteralTasteType extends
AnnotationLiteral<TasteQualifier> implements TasteQualifier {
+ private final TasteType taste;
+
+ public LiteralTasteType(TasteType taste) {
+ this.taste = taste;
+ }
+
+ @Override
+ public TasteType value() {
+ return taste;
+ }
+ }
+
+ public static class LiteralFoodType extends
AnnotationLiteral<FoodQualifier> implements FoodQualifier {
+ private final FoodType food;
+
+ public LiteralFoodType(FoodType food) {
+ this.food = food;
+ }
+
+ @Override
+ public FoodType value() {
+ return food;
+ }
+ }
+
+ @Qualifier
+ @Retention(RUNTIME)
+ @Target({FIELD, TYPE, METHOD, CONSTRUCTOR, PARAMETER})
+ public @interface FoodQualifier {
+ FoodType value();
+ }
+
+ @Qualifier
+ @Retention(RUNTIME)
+ @Target({FIELD, TYPE, METHOD, CONSTRUCTOR, PARAMETER})
+ public @interface TasteQualifier {
+ TasteType value();
+ }
+
+ public enum TasteType {
+ JUMMY,
+ DISGUSTING
+ }
+
+ public enum FoodType {
+ VEGETABLE,
+ FRUIT
+ }
+
+ @FoodQualifier(FoodType.FRUIT)
+ @TasteQualifier(TasteType.DISGUSTING)
+ public static class Cherry extends Food {
+ public Cherry() {
+ super("Cherry");
+ }
+ }
+
+ @FoodQualifier(FoodType.FRUIT)
+ @TasteQualifier(TasteType.JUMMY)
+ public static class Strawberry extends Food {
+ public Strawberry() {
+ super("Strawberry");
+ }
+ }
+
+ public static abstract class Food {
+ private final String name;
+
+ protected Food(String name) {
+ this.name = name;
+ }
+ }
+}