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 <rmannibu...@gmail.com>
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;
+        }
+    }
+}

Reply via email to