This is an automated email from the ASF dual-hosted git repository.

tjwatson pushed a commit to branch scrR8
in repository https://gitbox.apache.org/repos/asf/felix-dev.git

commit 6701c6cc5ed2d8eea91217ac31c487bf9a57bb43
Author: Thomas Watson <[email protected]>
AuthorDate: Wed Feb 17 09:55:27 2021 -0600

    Add Optional service injection tests
    
    If a reference uses an interface of java.lang.Optional
    then the injected object should be an Optional obtained
    as a service object
---
 .../scr/integration/ComponentOptionalTest.java     | 76 +++++++++++++++++-----
 .../components/InjectOptionalComponent.java        | 59 ++++++++++++++---
 .../resources/integration_test_inject_optional.xml | 25 +++++++
 3 files changed, 136 insertions(+), 24 deletions(-)

diff --git 
a/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java 
b/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java
index efd13e7..0613c47 100644
--- 
a/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java
+++ 
b/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java
@@ -21,12 +21,15 @@ package org.apache.felix.scr.integration;
 
 import static org.junit.Assert.assertEquals;
 
+import java.util.Optional;
+
 import org.apache.felix.scr.integration.components.ConstructorSingleReference;
 import org.apache.felix.scr.integration.components.InjectOptionalComponent;
 import 
org.apache.felix.scr.integration.components.InjectOptionalComponent.Mode;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.PaxExam;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
 
 
@@ -60,14 +63,26 @@ public class ComponentOptionalTest extends ComponentTestBase
             cmp1.checkMode(mode, null);
         }
 
-        ComponentConfigurationDTO ref1DTO = getDisabledConfigurationAndEnable(
-            SINGLE_REFERENCE1,
-            mode.isDynamic() && !mode.isMandatory()//
-                ? ComponentConfigurationDTO.ACTIVE
-                : ComponentConfigurationDTO.SATISFIED);
-        ConstructorSingleReference ref1Service = 
getServiceFromConfiguration(ref1DTO,
-            ConstructorSingleReference.class);
-
+        Object ref1Service;
+        ComponentConfigurationDTO ref1DTO;
+        ServiceRegistration<?> ref1Reg;
+        if (mode.isOptionalService())
+        {
+            ref1Service = Optional.of("Test1");
+            ref1DTO = null;
+            ref1Reg = bundleContext.registerService(Optional.class,
+                (Optional<?>) ref1Service, null);
+        }
+        else
+        {
+            ref1DTO = getDisabledConfigurationAndEnable(
+                SINGLE_REFERENCE1, mode.isDynamic() && !mode.isMandatory()//
+                    ? ComponentConfigurationDTO.ACTIVE
+                    : ComponentConfigurationDTO.SATISFIED);
+            ref1Service = getServiceFromConfiguration(ref1DTO,
+                ConstructorSingleReference.class);
+            ref1Reg = null;
+        }
         cc = findComponentConfigurationByName(componentname, 
mode.getSecondState());
         InjectOptionalComponent cmp2 = this.getServiceFromConfiguration(cc,
             InjectOptionalComponent.class);
@@ -86,12 +101,24 @@ public class ComponentOptionalTest extends 
ComponentTestBase
             cmp2.checkMode(mode, null);
         }
 
-        ComponentConfigurationDTO ref2DTO = getDisabledConfigurationAndEnable(
-            SINGLE_REFERENCE2, ComponentConfigurationDTO.SATISFIED);
-
-        ConstructorSingleReference ref2Service = 
getServiceFromConfiguration(ref2DTO,
-            ConstructorSingleReference.class);
-
+        Object ref2Service;
+        ComponentConfigurationDTO ref2DTO;
+        ServiceRegistration<?> ref2Reg;
+        if (mode.isOptionalService())
+        {
+            ref2Service = Optional.of("Test2");
+            ref2DTO = null;
+            ref2Reg = bundleContext.registerService(Optional.class,
+                (Optional<?>) ref2Service, null);
+        }
+        else
+        {
+            ref2DTO = getDisabledConfigurationAndEnable(
+                SINGLE_REFERENCE2, ComponentConfigurationDTO.SATISFIED);
+            ref2Service = getServiceFromConfiguration(ref2DTO,
+                ConstructorSingleReference.class);
+            ref2Reg = null;
+        }
         if (mode.isMandatory() || mode.isDynamic())
         {
             cmp2.checkMode(mode, ref1Service);
@@ -101,7 +128,14 @@ public class ComponentOptionalTest extends 
ComponentTestBase
             cmp2.checkMode(mode, null);
         }
 
-        disableAndCheck(ref1DTO);
+        if (ref1Reg != null)
+        {
+            ref1Reg.unregister();
+        }
+        if (ref1DTO != null)
+        {
+            disableAndCheck(ref1DTO);
+        }
 
         if (mode.isDynamic())
         {
@@ -167,4 +201,16 @@ public class ComponentOptionalTest extends 
ComponentTestBase
     {
         doTest(Mode.CONSTRUCTOR_OPTIONAL);
     }
+
+    @Test
+    public void test_field_static_mandatory_service_optional() throws Exception
+    {
+        doTest(Mode.FIELD_SERVICE_STATIC_MANDATORY);
+    }
+
+    @Test
+    public void test_constructor_static_mandatory_service_optional() throws 
Exception
+    {
+        doTest(Mode.CONSTRUCTOR_SERVICE_STATIC_MANDATORY);
+    }
 }
diff --git 
a/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java
 
b/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java
index 90cbd1d..86a15c8 100644
--- 
a/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java
+++ 
b/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java
@@ -22,7 +22,9 @@ package org.apache.felix.scr.integration.components;
 import java.util.Map;
 import java.util.Optional;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
 
 public class InjectOptionalComponent
@@ -33,17 +35,25 @@ public class InjectOptionalComponent
         FIELD_DYNAMIC_MANDATORY(1, true, true), //
         FIELD_STATIC_OPTIONAL(1, false, false), //
         FIELD_DYNAMIC_OPTIONAL(1, true, false), //
+        FIELD_SERVICE_STATIC_MANDATORY(3, false, true, true), //
         CONSTRUCTOR_MANDATORY(2, false, true), //
-        CONSTRUCTOR_OPTIONAL(2, false, false);
+        CONSTRUCTOR_OPTIONAL(2, false, false), //
+        CONSTRUCTOR_SERVICE_STATIC_MANDATORY(4, false, true, true);
 
         final int initCount;
         final int initialState;
         final int secondState;
         final boolean isMandatory;
         final boolean isDynamic;
+        final boolean isOptionalService;
 
         Mode(int initCount, boolean isDynamic, boolean isMandatory)
         {
+            this(initCount, isDynamic, isMandatory, false);
+        }
+
+        Mode(int initCount, boolean isDynamic, boolean isMandatory, boolean 
isOptionalService)
+        {
             this.initCount = initCount;
             this.initialState = isMandatory
                 ? ComponentConfigurationDTO.UNSATISFIED_REFERENCE
@@ -52,6 +62,7 @@ public class InjectOptionalComponent
                 : ComponentConfigurationDTO.ACTIVE;
             this.isMandatory = isMandatory;
             this.isDynamic = isDynamic;
+            this.isOptionalService = isOptionalService;
         }
 
         public int getInitCount()
@@ -79,6 +90,10 @@ public class InjectOptionalComponent
             return isDynamic;
         }
 
+        public final boolean isOptionalService()
+        {
+            return isOptionalService;
+        }
     }
 
     private final Mode mode;
@@ -87,10 +102,30 @@ public class InjectOptionalComponent
     private Optional<ConstructorSingleReference> refFieldStatic = null;
     private volatile Optional<ConstructorSingleReference> refFieldDynamic = 
null;
 
-    public InjectOptionalComponent(Map<String, Object> props, 
Optional<ConstructorSingleReference> single)
+    private Optional<?> refServiceFieldStatic = Optional.empty();
+    private final Optional<?> refServiceConstructor;
+
+    private InjectOptionalComponent(Map<String, Object> props, 
ComponentContext cc, BundleContext bc, Optional<ConstructorSingleReference> 
single, Optional<?> optionalSerice)
     {
         this.mode = getMode(props);
         this.refConstructor = single;
+        this.refServiceConstructor = optionalSerice == null ? Optional.empty()
+            : optionalSerice;
+    }
+
+    public InjectOptionalComponent(Map<String, Object> props, ComponentContext 
cc, BundleContext bc, Optional<?> optionalService)
+    {
+        this(props, cc, bc, null, optionalService);
+    }
+
+    public InjectOptionalComponent(Map<String, Object> props, ComponentContext 
cc, BundleContext bc)
+    {
+        this(props, cc, bc, null, null);
+    }
+
+    public InjectOptionalComponent(Map<String, Object> props, 
Optional<ConstructorSingleReference> single)
+    {
+        this(props, null, null, single, null);
     }
 
     public InjectOptionalComponent(Map<String, Object> props)
@@ -103,17 +138,20 @@ public class InjectOptionalComponent
         return Mode.valueOf((String) 
props.get(ComponentConstants.COMPONENT_NAME));
     }
 
-    public boolean checkMode(Mode mode, ConstructorSingleReference expected)
+    public boolean checkMode(Mode mode, Object expected)
     {
         if (this.mode != mode)
         {
             throw new AssertionError(
                 "Wrong mode, expected \"" + mode + "\" but was\"" + this.mode);
         }
-        Optional<ConstructorSingleReference> optional = getOptional();
+
+        final Object fExpected = expected == null || !mode.isOptionalService ? 
expected
+            : ((Optional<?>) expected).orElseGet(null);
+        Optional<?> optional = getOptional();
         if (expected != null)
         {
-            return optional.map((c) -> checkExpected(expected, c)).orElseGet(
+            return optional.map((c) -> checkExpected(fExpected, c)).orElseGet(
                 () -> throwAssertionError(
                     "FAILED - expected: " + expected + " but got empty 
optional."));
         }
@@ -130,30 +168,33 @@ public class InjectOptionalComponent
         throw new AssertionError(message);
     }
 
-    private boolean checkExpected(ConstructorSingleReference expected,
-        ConstructorSingleReference actual)
+    private boolean checkExpected(Object expected, Object actual)
     {
         if (expected == actual)
         {
             return true;
         }
         throw new AssertionError(
-            "FAILED - expected: " + expected + " bug got: " + actual);
+            "FAILED - expected: " + expected + " but got: " + actual);
     }
 
-    private Optional<ConstructorSingleReference> getOptional()
+    private Optional<?> getOptional()
     {
         switch (mode)
         {
             case CONSTRUCTOR_MANDATORY:
             case CONSTRUCTOR_OPTIONAL:
                 return refConstructor;
+            case CONSTRUCTOR_SERVICE_STATIC_MANDATORY:
+                return refServiceConstructor;
             case FIELD_DYNAMIC_MANDATORY:
             case FIELD_DYNAMIC_OPTIONAL:
                 return refFieldDynamic;
             case FIELD_STATIC_MANDATORY:
             case FIELD_STATIC_OPTIONAL:
                 return refFieldStatic;
+            case FIELD_SERVICE_STATIC_MANDATORY:
+                return refServiceFieldStatic;
             default:
                 throw new UnsupportedOperationException(String.valueOf(mode));
         }
diff --git a/scr/src/test/resources/integration_test_inject_optional.xml 
b/scr/src/test/resources/integration_test_inject_optional.xml
index a40be9d..93f9b54 100644
--- a/scr/src/test/resources/integration_test_inject_optional.xml
+++ b/scr/src/test/resources/integration_test_inject_optional.xml
@@ -48,6 +48,20 @@
         />
     </scr:component>
 
+    <scr:component name="FIELD_SERVICE_STATIC_MANDATORY" enabled="false"
+                   init="3">
+        <implementation 
class="org.apache.felix.scr.integration.components.InjectOptionalComponent" />
+        <service factory="false">
+            <provide 
interface="org.apache.felix.scr.integration.components.InjectOptionalComponent"/>
+        </service>
+        <reference
+            name="refServiceFieldStatic"
+            interface="java.util.Optional"
+            field="refServiceFieldStatic"
+            cardinality="1..1"
+        />
+    </scr:component>
+
     <!-- Dynamic Field -->
     <scr:component name="FIELD_DYNAMIC_MANDATORY" enabled="false"
                    init="1">
@@ -103,6 +117,17 @@
                    parameter="1"/>
     </scr:component>
 
+    <scr:component name="CONSTRUCTOR_SERVICE_STATIC_MANDATORY" enabled="false"
+                   init="4">
+        <implementation 
class="org.apache.felix.scr.integration.components.InjectOptionalComponent" />
+        <service factory="false">
+            <provide 
interface="org.apache.felix.scr.integration.components.InjectOptionalComponent"/>
+        </service>
+        <reference interface="java.util.Optional"
+                   cardinality="1..1"
+                   parameter="3"/>
+    </scr:component>
+
     <scr:component name="SingleReference1" enabled="false" 
activate="activator">
         <implementation 
class="org.apache.felix.scr.integration.components.ConstructorSingleReference" 
/>
         <service factory="false">

Reply via email to