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


The following commit(s) were added to refs/heads/scrR8 by this push:
     new b503f5d  Reference target attributes must not override component 
properties
b503f5d is described below

commit b503f5d018b1749d9e226de378ddb423d894198f
Author: Thomas Watson <[email protected]>
AuthorDate: Tue Jun 22 15:25:04 2021 -0500

    Reference target attributes must not override component properties
    
    For DS 15 components the reference target attributes must not
    override the component properties specified by the property or
    properties elements, regardless of the order the reference
    element occurs in the component XML.
    
    For DS components <1.5 the order the reference occurs
    must still work such that the last one specified
    wins
---
 .../felix/scr/impl/metadata/ComponentMetadata.java | 30 ++++-----
 .../felix/scr/impl/metadata/PropertyMetadata.java  | 16 +++++
 .../org/apache/felix/scr/impl/xml/XmlHandler.java  |  6 +-
 .../scr/integration/SatisfyingConditionTest.java   | 26 ++++++++
 .../integration_test_satisfying_condition.xml      | 73 ++++++++++++++++++++--
 5 files changed, 124 insertions(+), 27 deletions(-)

diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java 
b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
index 0892720..92da7a7 100644
--- 
a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
+++ 
b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
@@ -327,16 +327,6 @@ public class ComponentMetadata
      */
     public void addProperty( PropertyMetadata newProperty )
     {
-        addProperty(newProperty, false);
-    }
-
-    public void addFirstProperty(PropertyMetadata newProperty)
-    {
-        addProperty(newProperty, true);
-    }
-
-    private void addProperty(PropertyMetadata newProperty, boolean first)
-    {
         if ( m_validated )
         {
             return;
@@ -345,14 +335,7 @@ public class ComponentMetadata
         {
             throw new IllegalArgumentException( "Cannot add a null property" );
         }
-        if (first)
-        {
-            m_propertyMetaData.add(0, newProperty);
-        }
-        else
-        {
-            m_propertyMetaData.add(newProperty);
-        }
+        m_propertyMetaData.add(newProperty);
     }
 
     /**
@@ -965,7 +948,16 @@ public class ComponentMetadata
         for ( PropertyMetadata propMeta: m_propertyMetaData )
         {
             propMeta.validate( this );
-            m_properties.put( propMeta.getName(), propMeta.getValue() );
+            if (m_dsVersion.isDS15() && propMeta.isReferenceTarget())
+            {
+                // for DS 15 the reference target property must not override,
+                // only add if the key does not exist yet
+                m_properties.putIfAbsent(propMeta.getName(), 
propMeta.getValue());
+            }
+            else
+            {
+                m_properties.put(propMeta.getName(), propMeta.getValue());
+            }
         }
         m_propertyMetaData.clear();
 
diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/metadata/PropertyMetadata.java 
b/scr/src/main/java/org/apache/felix/scr/impl/metadata/PropertyMetadata.java
index 5dd37dd..10ed223 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/PropertyMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/PropertyMetadata.java
@@ -28,7 +28,9 @@ import java.util.StringTokenizer;
  *
  */
 public class PropertyMetadata {
+    // true if property is from a reference target attribute
 
+    private final boolean m_referenceTarget;
        // Name of the property (required)
        private String m_name;
 
@@ -43,6 +45,16 @@ public class PropertyMetadata {
        // Flag that indicates if this PropertyMetadata has been validated and 
thus has become immutable
        private boolean m_validated = false;
 
+    public PropertyMetadata()
+    {
+        this(false);
+    }
+
+    public PropertyMetadata(boolean referenceTarget)
+    {
+        m_referenceTarget = referenceTarget;
+    }
+
        /**
         * Set the name
         *
@@ -130,6 +142,10 @@ public class PropertyMetadata {
         return m_value;
     }
 
+    public boolean isReferenceTarget()
+    {
+        return m_referenceTarget;
+    }
     /**
      * Method used to verify if the semantics of this metadata are correct
      */
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java 
b/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
index 755f02a..00a0546 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
@@ -392,7 +392,7 @@ public class XmlHandler extends DefaultHandler
                     if ( attributes.getValue( 
XmlConstants.NAMESPACE_URI_EMPTY, "target" ) != null)
                     {
                         ref.setTarget( attributes.getValue( 
XmlConstants.NAMESPACE_URI_EMPTY, "target" ) );
-                        PropertyMetadata prop = new PropertyMetadata();
+                        PropertyMetadata prop = new PropertyMetadata(true);
                         prop.setName( (ref.getName() == null? 
ref.getInterface(): ref.getName()) + ".target");
                         prop.setValue( attributes.getValue( 
XmlConstants.NAMESPACE_URI_EMPTY, "target" ) );
                         m_currentComponent.addProperty( prop );
@@ -507,11 +507,11 @@ public class XmlHandler extends DefaultHandler
                 // Here we add the target property for the implicit satisfying 
condition
                 // first such that any properties that are specified 
explicitly can
                 // be used to override this implicit property
-                PropertyMetadata prop = new PropertyMetadata();
+                PropertyMetadata prop = new PropertyMetadata(true);
                 prop.setName(
                     ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION + 
".target");
                 prop.setValue(ReferenceMetadata.CONDITION_TRUE_FILTER);
-                m_currentComponent.addFirstProperty(prop);
+                m_currentComponent.addProperty(prop);
             }
         }
     }
diff --git 
a/scr/src/test/java/org/apache/felix/scr/integration/SatisfyingConditionTest.java
 
b/scr/src/test/java/org/apache/felix/scr/integration/SatisfyingConditionTest.java
index 1533507..c8b306c 100644
--- 
a/scr/src/test/java/org/apache/felix/scr/integration/SatisfyingConditionTest.java
+++ 
b/scr/src/test/java/org/apache/felix/scr/integration/SatisfyingConditionTest.java
@@ -95,6 +95,12 @@ public class SatisfyingConditionTest extends 
ComponentTestBase
         doTargetTrueCondition("satisfying.condition.reference.specified");
     }
 
+    @Test
+    public void test_specified_satisfying_condition_14() throws Exception
+    {
+        
doTargetTrueCondition("satisfying.condition.reference.specified.1.4.0");
+    }
+
     void doTargetTrueCondition(final String componentname) throws Exception
     {
         ComponentConfigurationDTO configDTO = 
getDisabledConfigurationAndEnable(
@@ -137,11 +143,31 @@ public class SatisfyingConditionTest extends 
ComponentTestBase
     }
 
     @Test
+    public void test_default_satisfying_condition_target_14() throws Exception
+    {
+        doTargetTrueCondition("satisfying.condition.target.specified.1.4.0");
+    }
+
+    @Test
     public void test_specified_satisfying_condition_target() throws Exception
     {
         
doTestTargetCustomCondition("satisfying.condition.reference.target.specified");
     }
 
+    @Test
+    public void test_specified_satisfying_condition_target_14_postfix() throws 
Exception
+    {
+        doTestTargetCustomCondition(
+            "satisfying.condition.reference.target.specified.1.4.0.postfix");
+    }
+
+    @Test
+    public void test_specified_satisfying_condition_target_14_prefic() throws 
Exception
+    {
+        doTargetTrueCondition(
+            "satisfying.condition.reference.target.specified.1.4.0.prefix");
+    }
+
     void doTestTargetCustomCondition(final String componentname) throws 
Exception
     {
         ComponentConfigurationDTO configDTO = 
getDisabledConfigurationAndEnable(
diff --git a/scr/src/test/resources/integration_test_satisfying_condition.xml 
b/scr/src/test/resources/integration_test_satisfying_condition.xml
index 445dce1..f5e2a22 100644
--- a/scr/src/test/resources/integration_test_satisfying_condition.xml
+++ b/scr/src/test/resources/integration_test_satisfying_condition.xml
@@ -31,12 +31,12 @@
         <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
         <reference name="optional.condition"
           interface="org.osgi.service.condition.Condition"
-          target="(optional.condition)"
+          target="(optional.condition=true)"
           policy="dynamic"
           cardinality="0..1"/>
     </scr:component>
 
-    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0";
+    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.5.0";
         name="satisfying.condition.target.specified"
         immediate="true"
         enabled="false">
@@ -44,19 +44,32 @@
         <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
         <reference name="optional.condition"
           interface="org.osgi.service.condition.Condition"
-          target="(optional.condition)"
+          target="(optional.condition=true)"
           policy="dynamic"
           cardinality="0..1"/>
     </scr:component>
 
     <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0";
+        name="satisfying.condition.target.specified.1.4.0"
+        immediate="true"
+        enabled="false">
+        <property name="osgi.ds.satisfying.condition.target" 
value="(foo=bar)"/>
+        <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
+        <reference name="optional.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(optional.condition=true)"
+          policy="dynamic"
+          cardinality="0..1"/>
+    </scr:component>
+
+    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.5.0";
         name="satisfying.condition.reference.specified"
         immediate="true"
         enabled="false">
         <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
         <reference name="optional.condition"
           interface="org.osgi.service.condition.Condition"
-          target="(optional.condition)"
+          target="(optional.condition=true)"
           policy="dynamic"
           cardinality="0..1"/>
         <reference name="osgi.ds.satisfying.condition"
@@ -66,19 +79,69 @@
     </scr:component>
 
     <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0";
+        name="satisfying.condition.reference.specified.1.4.0"
+        immediate="true"
+        enabled="false">
+        <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
+        <reference name="optional.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(optional.condition=true)"
+          policy="dynamic"
+          cardinality="0..1"/>
+        <reference name="osgi.ds.satisfying.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(osgi.condition.id=true)"
+          policy="dynamic"/>
+    </scr:component>
+
+    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.5.0";
         name="satisfying.condition.reference.target.specified"
         immediate="true"
         enabled="false">
         <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
+        <property name="osgi.ds.satisfying.condition.target" 
value="(foo=bar)"/>
         <reference name="optional.condition"
           interface="org.osgi.service.condition.Condition"
-          target="(optional.condition)"
+          target="(optional.condition=true)"
           policy="dynamic"
           cardinality="0..1"/>
         <reference name="osgi.ds.satisfying.condition"
           interface="org.osgi.service.condition.Condition"
           target="(osgi.condition.id=true)"
           policy="dynamic"/>
+    </scr:component>
+
+    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0";
+        name="satisfying.condition.reference.target.specified.1.4.0.postfix"
+        immediate="true"
+        enabled="false">
+        <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
+        <reference name="optional.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(optional.condition=true)"
+          policy="dynamic"
+          cardinality="0..1"/>
+        <reference name="osgi.ds.satisfying.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(osgi.condition.id=true)"
+          policy="dynamic"/>
+        <property name="osgi.ds.satisfying.condition.target" 
value="(foo=bar)"/>
+    </scr:component>
+
+    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0";
+        name="satisfying.condition.reference.target.specified.1.4.0.prefix"
+        immediate="true"
+        enabled="false">
         <property name="osgi.ds.satisfying.condition.target" 
value="(foo=bar)"/>
+        <implementation 
class="org.apache.felix.scr.integration.components.SatisfyingConditionComponentClass"/>
+        <reference name="optional.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(optional.condition=true)"
+          policy="dynamic"
+          cardinality="0..1"/>
+        <reference name="osgi.ds.satisfying.condition"
+          interface="org.osgi.service.condition.Condition"
+          target="(osgi.condition.id=true)"
+          policy="dynamic"/>
     </scr:component>
 </components>

Reply via email to