You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by tj...@apache.org on 2021/06/17 15:16:37 UTC

[felix-dev] branch scrR8 updated (bd2823a -> a86ef80)

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

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


    from bd2823a  Use the correct target when missing any service target
     new 4bdb29f  Fix for field-collection-type attribute for injection to Optional
     new a86ef80  Add implicit target property as first in the list of properties

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/felix/scr/impl/inject/ValueUtils.java   | 130 +++++++++++----------
 .../felix/scr/impl/inject/field/FieldHandler.java  |   8 +-
 .../inject/internal/ComponentConstructorImpl.java  |   9 +-
 .../felix/scr/impl/inject/methods/BindMethod.java  |   3 +-
 .../felix/scr/impl/metadata/ComponentMetadata.java |  20 +++-
 .../felix/scr/impl/metadata/ReferenceMetadata.java |  61 +++-------
 .../impl/runtime/ServiceComponentRuntimeImpl.java  |   2 +-
 .../org/apache/felix/scr/impl/xml/XmlHandler.java  |  10 +-
 .../impl/metadata/ComponentMetaDataCacheTest.java  |   6 +-
 .../scr/integration/SatisfyingConditionTest.java   |  44 +++++--
 .../integration_test_satisfying_condition.xml      |  43 +++++++
 11 files changed, 202 insertions(+), 134 deletions(-)

[felix-dev] 02/02: Add implicit target property as first in the list of properties

Posted by tj...@apache.org.
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 a86ef80595ca82b8ec61d5a4422447779f37499e
Author: Thomas Watson <tj...@us.ibm.com>
AuthorDate: Thu Jun 17 08:41:14 2021 -0500

    Add implicit target property as first in the list of properties
    
    For the implicit satisfying condition reference add the target property
    as the first in the list of properties.  This allows any explicitly
    specified properties in the component descriptor to override the
    implicit target property for this reference.
---
 .../felix/scr/impl/metadata/ComponentMetadata.java | 20 +++++++++-
 .../org/apache/felix/scr/impl/xml/XmlHandler.java  |  8 ++++
 .../scr/integration/SatisfyingConditionTest.java   | 44 ++++++++++++++++------
 .../integration_test_satisfying_condition.xml      | 43 +++++++++++++++++++++
 4 files changed, 102 insertions(+), 13 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 a250880..0892720 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,6 +327,16 @@ 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;
@@ -335,10 +345,16 @@ public class ComponentMetadata
         {
             throw new IllegalArgumentException( "Cannot add a null property" );
         }
-        m_propertyMetaData.add( newProperty );
+        if (first)
+        {
+            m_propertyMetaData.add(0, newProperty);
+        }
+        else
+        {
+            m_propertyMetaData.add(newProperty);
+        }
     }
 
-
     /**
      * Used to add a factory property to the instance
      *
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 10f2153..755f02a 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
@@ -504,6 +504,14 @@ public class XmlHandler extends DefaultHandler
                 trueReference.setInterface(ReferenceMetadata.CONDITION_SERVICE_CLASS);
                 trueReference.setPolicy(ReferenceMetadata.POLICY_DYNAMIC);
                 m_currentComponent.addDependency(trueReference);
+                // 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();
+                prop.setName(
+                    ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION + ".target");
+                prop.setValue(ReferenceMetadata.CONDITION_TRUE_FILTER);
+                m_currentComponent.addFirstProperty(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 58c589c..1533507 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
@@ -86,21 +86,30 @@ public class SatisfyingConditionTest extends ComponentTestBase
     @Test
     public void test_default_satisfying_condition() throws Exception
     {
-        final String componentname = "satisfying.condition.default";
+        doTargetTrueCondition("satisfying.condition.default");
+    }
 
+    @Test
+    public void test_specified_satisfying_condition() throws Exception
+    {
+        doTargetTrueCondition("satisfying.condition.reference.specified");
+    }
+
+    void doTargetTrueCondition(final String componentname) throws Exception
+    {
         ComponentConfigurationDTO configDTO = getDisabledConfigurationAndEnable(
             componentname,
             ComponentConfigurationDTO.ACTIVE);
 
-        assertEquals("Wrong number of references.", 1,
+        assertEquals("Wrong number of references.", 2,
             configDTO.satisfiedReferences.length);
-        SatisfiedReferenceDTO satisfiedDTO = configDTO.satisfiedReferences[0];
+        SatisfiedReferenceDTO satisfiedDTO = configDTO.satisfiedReferences[1];
         assertEquals("Wrong target.", "(osgi.condition.id=true)", satisfiedDTO.target);
 
         ComponentDescriptionDTO descriptionDTO = configDTO.description;
-        assertEquals("Wrong number of references.", 1, descriptionDTO.references.length);
+        assertEquals("Wrong number of references.", 2, descriptionDTO.references.length);
 
-        ReferenceDTO trueReference = descriptionDTO.references[0];
+        ReferenceDTO trueReference = descriptionDTO.references[1];
         assertEquals("Wrong name.", "osgi.ds.satisfying.condition", trueReference.name);
         assertEquals("Wrong interface.", "org.osgi.service.condition.Condition",
             trueReference.interfaceName);
@@ -115,26 +124,39 @@ public class SatisfyingConditionTest extends ComponentTestBase
         configDTO = findComponentConfigurationByName(componentname,
             ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
 
+        assertEquals("Wrong number of unsatisfied references.", 1,
+            configDTO.unsatisfiedReferences.length);
         UnsatisfiedReferenceDTO unsatisfiedDTO = configDTO.unsatisfiedReferences[0];
         assertEquals("Wrong target.", "(foo=baz)", unsatisfiedDTO.target);
     }
 
     @Test
-    public void test_specified_satisfying_condition() throws Exception
+    public void test_default_satisfying_condition_target() throws Exception
     {
-        final String componentname = "satisfying.condition.target.specified";
+        doTestTargetCustomCondition("satisfying.condition.target.specified");
+    }
 
+    @Test
+    public void test_specified_satisfying_condition_target() throws Exception
+    {
+        doTestTargetCustomCondition("satisfying.condition.reference.target.specified");
+    }
+
+    void doTestTargetCustomCondition(final String componentname) throws Exception
+    {
         ComponentConfigurationDTO configDTO = getDisabledConfigurationAndEnable(
             componentname, ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
         ComponentDescriptionDTO descriptionDTO = configDTO.description;
 
+        assertEquals("Wrong number of unsatisfied references.", 1,
+            configDTO.unsatisfiedReferences.length);
         UnsatisfiedReferenceDTO unsatisfiedDTO = configDTO.unsatisfiedReferences[0];
         assertEquals("Wrong target.", "(foo=bar)", unsatisfiedDTO.target);
 
         assertNotNull("No component DTO found.", descriptionDTO);
-        assertEquals("Wrong number of references.", 1, descriptionDTO.references.length);
+        assertEquals("Wrong number of references.", 2, descriptionDTO.references.length);
 
-        ReferenceDTO trueReference = descriptionDTO.references[0];
+        ReferenceDTO trueReference = descriptionDTO.references[1];
         assertEquals("Wrong name.", "osgi.ds.satisfying.condition", trueReference.name);
         assertEquals("Wrong interface.", "org.osgi.service.condition.Condition",
             trueReference.interfaceName);
@@ -151,9 +173,9 @@ public class SatisfyingConditionTest extends ComponentTestBase
 
         configDTO = findComponentConfigurationByName(componentname,
             ComponentConfigurationDTO.ACTIVE);
-        assertEquals("Wrong number of references.", 1,
+        assertEquals("Wrong number of references.", 2,
             configDTO.satisfiedReferences.length);
-        SatisfiedReferenceDTO satisfiedDTO = configDTO.satisfiedReferences[0];
+        SatisfiedReferenceDTO satisfiedDTO = configDTO.satisfiedReferences[1];
         assertEquals("Wrong target.", "(foo=bar)", satisfiedDTO.target);
     }
 
diff --git a/scr/src/test/resources/integration_test_satisfying_condition.xml b/scr/src/test/resources/integration_test_satisfying_condition.xml
index addeaca..445dce1 100644
--- a/scr/src/test/resources/integration_test_satisfying_condition.xml
+++ b/scr/src/test/resources/integration_test_satisfying_condition.xml
@@ -29,6 +29,11 @@
         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)"
+          policy="dynamic"
+          cardinality="0..1"/>
     </scr:component>
 
     <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0"
@@ -37,5 +42,43 @@
         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)"
+          policy="dynamic"
+          cardinality="0..1"/>
+    </scr:component>
+
+    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.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)"
+          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"
+        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)"
+          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>
 </components>

[felix-dev] 01/02: Fix for field-collection-type attribute for injection to Optional

Posted by tj...@apache.org.
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 4bdb29fbd520f040b1952754aa8d8cc5e86f14da
Author: Thomas Watson <tj...@us.ibm.com>
AuthorDate: Wed Jun 16 16:00:32 2021 -0500

    Fix for field-collection-type attribute for injection to Optional
---
 .../apache/felix/scr/impl/inject/ValueUtils.java   | 130 +++++++++++----------
 .../felix/scr/impl/inject/field/FieldHandler.java  |   8 +-
 .../inject/internal/ComponentConstructorImpl.java  |   9 +-
 .../felix/scr/impl/inject/methods/BindMethod.java  |   3 +-
 .../felix/scr/impl/metadata/ReferenceMetadata.java |  61 +++-------
 .../impl/runtime/ServiceComponentRuntimeImpl.java  |   2 +-
 .../org/apache/felix/scr/impl/xml/XmlHandler.java  |   2 +-
 .../impl/metadata/ComponentMetaDataCacheTest.java  |   6 +-
 8 files changed, 100 insertions(+), 121 deletions(-)

diff --git a/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java b/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java
index 4f2af5c..fc8c242 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java
@@ -196,27 +196,8 @@ public class ValueUtils {
         }
         else
         {
-            String colType = field != null ? metadata.getFieldCollectionType() : metadata.getParameterCollectionType();
-            if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE.equals(colType) )
-            {
-                valueType = ValueType.ref_serviceType;
-            }
-            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_REFERENCE.equals(colType) )
-            {
-                valueType = ValueType.ref_serviceReference;
-            }
-            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICEOBJECTS.equals(colType) )
-            {
-                valueType = ValueType.ref_serviceObjects;
-            }
-            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_PROPERTIES.equals(colType) )
-            {
-                valueType = ValueType.ref_map;
-            }
-            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_TUPLE.equals(colType) )
-            {
-                valueType = ValueType.ref_tuple;
-            }
+            String colType = metadata.getCollectionType();
+            valueType = getCollectionValueType(colType);
 
             // multiple cardinality, field type must be collection or subtype
             if ( !ClassUtils.COLLECTION_CLASS.isAssignableFrom(typeClass) )
@@ -282,6 +263,29 @@ public class ValueUtils {
         return valueType;
     }
 
+    public static ValueType getCollectionValueType(String colType)
+    {
+        if (colType == null)
+        {
+            return ValueType.ref_serviceType;
+        }
+        switch (colType)
+        {
+            case ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE:
+                return ValueType.ref_serviceType;
+            case ReferenceMetadata.FIELD_VALUE_TYPE_REFERENCE:
+                return ValueType.ref_serviceReference;
+            case ReferenceMetadata.FIELD_VALUE_TYPE_SERVICEOBJECTS:
+                return ValueType.ref_serviceObjects;
+            case ReferenceMetadata.FIELD_VALUE_TYPE_PROPERTIES:
+                return ValueType.ref_map;
+            case ReferenceMetadata.FIELD_VALUE_TYPE_TUPLE:
+                return ValueType.ref_tuple;
+            default:
+                return ValueType.ignore;
+        }
+    }
+
     /**
      * Get the value for the value type
      * @param componentType The class of the component
@@ -293,48 +297,56 @@ public class ValueUtils {
      */
     @SuppressWarnings("unchecked")
     public static Object getValue(
-            final String componentType,
-            final ValueType type,
-            final Class<?> targetType,
-            final ScrComponentContext componentContext,
-            final RefPair<?, ?> refPair)
+        final String componentType,
+        final ValueType type,
+        final Class<?> targetType,
+        final ScrComponentContext componentContext,
+        final RefPair<?, ?> refPair,
+        final ReferenceMetadata referenceMetaData)
     {
-        final Object value;
         switch ( type )
         {
-            case ignore                 : value = null;
-                                          break;
-            case componentContext       : value = componentContext;
-                                          break;
-            case bundleContext          : value = componentContext.getBundleContext();
-                                          break;
-            case config_map             : // note: getProperties() returns a ReadOnlyDictionary which is a Map
-                                          value = componentContext.getProperties();
-                                          break;
-            case config_annotation      : value = Annotations.toObject(targetType,
-                                                (Map<String, Object>) componentContext.getProperties(),
-                                          componentContext.getBundleContext().getBundle(), componentContext.getComponentMetadata().isConfigureWithInterfaces());
-                                          break;
-            case ref_serviceType        : value = refPair.getServiceObject(componentContext);
-                                          break;
-            case ref_serviceReference   : value = refPair.getRef();
-                                          break;
-            case ref_serviceObjects     : value = componentContext.getComponentServiceObjectsHelper().getServiceObjects(refPair.getRef());
-                                          break;
-            case ref_map                : value = new ReadOnlyDictionary( refPair.getRef() );
-                                          break;
-            case ref_tuple              : final Object tupleKey = new ReadOnlyDictionary( refPair.getRef() );
-                                          final Object tupleValue = refPair.getServiceObject(componentContext);
-                                          value = new MapEntryImpl(tupleKey, tupleValue, refPair.getRef());
-                                          break;
-            case ref_logger             :
-            case ref_formatterLogger    : value = getLogger(componentType, targetType, componentContext, refPair);
-                                          break;
-            case ref_optional           : value = Optional.ofNullable(refPair.getServiceObject(componentContext));
-                                          break;
-            default: value = null;
+            case ignore:
+                return null;
+            case componentContext:
+                return componentContext;
+            case bundleContext:
+                return componentContext.getBundleContext();
+            case config_map:
+                // note: getProperties() returns a ReadOnlyDictionary which is a Map
+                return componentContext.getProperties();
+            case config_annotation:
+                return Annotations.toObject(targetType,
+                    (Map<String, Object>) componentContext.getProperties(),
+                    componentContext.getBundleContext().getBundle(),
+                    componentContext.getComponentMetadata().isConfigureWithInterfaces());
+            case ref_serviceType:
+                return refPair.getServiceObject(componentContext);
+            case ref_serviceReference:
+                return refPair.getRef();
+            case ref_serviceObjects:
+                return componentContext.getComponentServiceObjectsHelper().getServiceObjects(
+                    refPair.getRef());
+            case ref_map:
+                return new ReadOnlyDictionary(refPair.getRef());
+            case ref_tuple:
+                final Object tupleKey = new ReadOnlyDictionary(refPair.getRef());
+                final Object tupleValue = refPair.getServiceObject(componentContext);
+                return new MapEntryImpl(tupleKey, tupleValue, refPair.getRef());
+            case ref_logger:
+            case ref_formatterLogger:
+                return getLogger(componentType, targetType, componentContext, refPair);
+            case ref_optional:
+                final String stringType = referenceMetaData == null
+                    ? ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE
+                    : referenceMetaData.getCollectionType();
+                final ValueType optionalValueType = getCollectionValueType(stringType);
+                Object value = getValue(componentType, optionalValueType, targetType,
+                    componentContext, refPair, referenceMetaData);
+                return Optional.ofNullable(value);
+            default:
+                return null;
         }
-        return value;
     }
 
     private static Object getLogger(String componentType,
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java
index a5d25bd..22d10b2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java
@@ -225,7 +225,7 @@ public class FieldHandler
             			return MethodResult.REACTIVATE;
             		}
                     final Object obj = ValueUtils.getValue(componentInstance.getClass().getName(),
-                            valueType, field.getType(), key, refPair);
+                        valueType, field.getType(), key, refPair, this.metadata);
                     this.setFieldValue(componentInstance, obj);
                     bp.getComponentContext().getBoundValues(metadata.getName()).put(refPair, obj);
             	}
@@ -234,7 +234,7 @@ public class FieldHandler
             else
             {
                 final Object obj = ValueUtils.getValue(componentInstance.getClass().getName(),
-                        valueType, field.getType(), key, refPair);
+                    valueType, field.getType(), key, refPair, this.metadata);
                 this.setFieldValue(componentInstance, obj);
                 bp.getComponentContext().getBoundValues(metadata.getName()).put(refPair, obj);
             }
@@ -247,7 +247,7 @@ public class FieldHandler
             if ( mType == METHOD_TYPE.BIND )
             {
                 final Object obj = ValueUtils.getValue(componentInstance.getClass().getName(),
-                        valueType, field.getType(), key, refPair);
+                    valueType, field.getType(), key, refPair, this.metadata);
                 bp.getComponentContext().getBoundValues(metadata.getName()).put(refPair, obj);
                 if ( metadata.isReplace() )
                 {
@@ -286,7 +286,7 @@ public class FieldHandler
                     if ( !this.metadata.isStatic() )
                     {
 	                    final Object obj = ValueUtils.getValue(componentInstance.getClass().getName(),
-	                            valueType, field.getType(), key, refPair);
+                            valueType, field.getType(), key, refPair, this.metadata);
 	                    final Object oldObj = bp.getComponentContext().getBoundValues(metadata.getName()).put(refPair, obj);
 
 	                    if ( metadata.isReplace() )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentConstructorImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentConstructorImpl.java
index 5d9fc5a..2b4d13c 100755
--- a/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentConstructorImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentConstructorImpl.java
@@ -266,7 +266,8 @@ public class ComponentConstructorImpl<S> implements ComponentConstructor<S>
                             constructorArgTypes[i],
                             constructor.getParameterTypes()[i],
                             componentContext,
-                            null);
+                            null,
+                            refMetadata);
                 }
                 else
                 {
@@ -289,7 +290,8 @@ public class ComponentConstructorImpl<S> implements ComponentConstructor<S>
                                     constructorArgTypes[i],
                                     constructor.getParameterTypes()[i],
                                     componentContext,
-                                    refPair);
+                                    refPair,
+                                    refMetadata);
                             if ( refMetadata.isMultiple() && ref != null )
                             {
                                 refs.add(ref);
@@ -332,7 +334,8 @@ public class ComponentConstructorImpl<S> implements ComponentConstructor<S>
                         activationFieldTypes[i],
                         activationFields[i].getType(),
                         componentContext,
-                        null); // null is ok as activation fields are not references
+                        null, // null is ok as activation fields are not references
+                        null);
                 FieldUtils.setField(activationFields[i], component, value, componentContext.getLogger());
             }
         }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
index 38ef0c8..9886894 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
@@ -687,7 +687,8 @@ implements org.apache.felix.scr.impl.inject.ReferenceMethod
         int i = 0;
         for ( ValueUtils.ValueType pt: m_paramTypes )
         {
-            result[i] = ValueUtils.getValue(getComponentClass().getName(), pt, method.getParameterTypes()[i], key, refPair);
+            result[i] = ValueUtils.getValue(getComponentClass().getName(), pt,
+                method.getParameterTypes()[i], key, refPair, null);
             i++;
         }
         return result;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
index 1406291..dfaf73d 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
@@ -384,7 +384,7 @@ public class ReferenceMetadata
      *
      * @param valuetype the field value type
      */
-    public void setFieldCollectionType( final String valuetype )
+    public void setCollectionType(final String valuetype)
     {
         if ( m_validated )
         {
@@ -548,7 +548,7 @@ public class ReferenceMetadata
      *
      * @return a String with the value type for the field
      */
-    public String getFieldCollectionType()
+    public String getCollectionType()
     {
         return m_collection_type;
     }
@@ -566,17 +566,6 @@ public class ReferenceMetadata
     	return m_parameterIndex;
     }
 
-    /**
-     * Get the value type of a parameter in the component implementation class that is used to hold
-     * the reference
-     * DS 1.4
-     * @return a String with the value type for the parameter
-     */
-    public String getParameterCollectionType()
-    {
-        return m_collection_type;
-    }
-
     // Getters for boolean values that determine both policy and cardinality
 
     /**
@@ -759,25 +748,11 @@ public class ReferenceMetadata
             }
 
             // field value type
-            if ( !m_isMultiple )
-            {
-                // value type must not be specified for unary references
-                if ( m_collection_type != null )
-                {
-                    // spec says to ignore this
-                    this.m_collection_type = null;
-                }
-            }
-            else
+            if (m_collection_type != null
+                && !FIELD_VALUE_TYPE_VALID.contains(m_collection_type))
             {
-                if ( m_collection_type == null )
-                {
-                    setFieldCollectionType( FIELD_VALUE_TYPE_SERVICE );
-                }
-                else if ( !FIELD_VALUE_TYPE_VALID.contains( m_collection_type ) )
-                {
-                    throw componentMetadata.validationFailure( "Field value type must be one of " + FIELD_VALUE_TYPE_VALID );
-                }
+                throw componentMetadata.validationFailure(
+                    "Field value type must be one of " + FIELD_VALUE_TYPE_VALID);
             }
         }
 
@@ -801,25 +776,14 @@ public class ReferenceMetadata
                 throw componentMetadata.validationFailure( "Reference parameter value must be zero or higher: " + m_parameter );
             }
             // parameter value type
-            if ( !m_isMultiple )
+            if (m_collection_type == null)
             {
-                // value type must not be specified for unary references
-                if ( m_collection_type != null )
-                {
-                    // spec says to ignore this
-                    this.m_collection_type = null;
-                }
+                setCollectionType(FIELD_VALUE_TYPE_SERVICE);
             }
-            else
+            else if (!FIELD_VALUE_TYPE_VALID.contains(m_collection_type))
             {
-                if ( m_collection_type == null )
-                {
-                    setFieldCollectionType( FIELD_VALUE_TYPE_SERVICE );
-                }
-                else if ( !FIELD_VALUE_TYPE_VALID.contains( m_collection_type ) )
-                {
-                    throw componentMetadata.validationFailure( "Collection value type must be one of " + FIELD_VALUE_TYPE_VALID );
-                }
+                throw componentMetadata.validationFailure(
+                    "Collection value type must be one of " + FIELD_VALUE_TYPE_VALID);
             }
         }
         m_validated = true;
@@ -837,7 +801,8 @@ public class ReferenceMetadata
                 ", updated=" + this.getUpdated() +
                 ", field=" + this.getField() +
                 ", field-option=" + this.getFieldOption() +
-                ", collection-type=" + this.getFieldCollectionType() +
+                ", collection-type=" + this.getCollectionType()
+            +
                 ", parameter=" + this.getParameterIndex();
     }
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
index 328fd0a..7df365e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
@@ -444,7 +444,7 @@ public class ServiceComponentRuntimeImpl implements ServiceComponentRuntime, Ser
             dto.updated = r.getUpdated();
             // DS 1.4
             dto.parameter = r.getParameterIndex();
-            dto.collectionType = r.getFieldCollectionType();
+            dto.collectionType = r.getCollectionType();
             dtos[i++] = dto;
         }
         return dtos;
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 e40954c..10f2153 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
@@ -407,7 +407,7 @@ public class XmlHandler extends DefaultHandler
                     // field reference
                     ref.setField( attributes.getValue( XmlConstants.NAMESPACE_URI_EMPTY, "field" ) );
                     ref.setFieldOption( attributes.getValue( XmlConstants.NAMESPACE_URI_EMPTY, "field-option" ) );
-                    ref.setFieldCollectionType( attributes.getValue( XmlConstants.NAMESPACE_URI_EMPTY, "field-collection-type" ) );
+                    ref.setCollectionType( attributes.getValue( XmlConstants.NAMESPACE_URI_EMPTY, "field-collection-type" ) );
 
                     // DS 1.4 : references as parameter of the activator (method or constructor)
                     if ( attributes.getValue( XmlConstants.NAMESPACE_URI_EMPTY, "parameter" ) != null)
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetaDataCacheTest.java b/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetaDataCacheTest.java
index fe2546a..35e3ce2 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetaDataCacheTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetaDataCacheTest.java
@@ -175,13 +175,11 @@ public class ComponentMetaDataCacheTest extends ComponentBase
             assertEquals("Reference field not equal", r1.getField(), r2.getField());
             assertEquals("Reference field option not equal", r1.getFieldOption(),
                 r2.getFieldOption());
-            assertEquals("Reference field collection type not equal",
-                r1.getFieldCollectionType(), r2.getFieldCollectionType());
+            assertEquals("Reference collection type not equal", r1.getCollectionType(),
+                r2.getCollectionType());
             assertEquals("Reference scope not equal", r1.getScope(), r2.getScope());
             assertEquals("Reference parameter index not equal", r1.getParameterIndex(),
                 r2.getParameterIndex());
-            assertEquals("Reference parameter collection type not equal",
-                r1.getParameterCollectionType(), r2.getParameterCollectionType());
         }
     }