FELIX-4949 : [DS][RFC-190] Implement prototype_required

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1689301 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 07a5a8a..0a0105f 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -1873,11 +1873,40 @@
             }
         }
         m_target = target;
-        String filterString = "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")";
-        if (m_target != null)
+        final boolean multipleExpr = m_target != null || m_dependencyMetadata.getScope() == ReferenceScope.prototype_required;
+        final StringBuilder filterSB = new StringBuilder();
+        if (multipleExpr )
         {
-            filterString = "(&" + filterString + m_target + ")";
+            filterSB.append("(&");
         }
+        // "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")"
+        filterSB.append('(');
+        filterSB.append(Constants.OBJECTCLASS);
+        filterSB.append('=');
+        filterSB.append(m_dependencyMetadata.getInterface());
+        filterSB.append(')');
+
+        // if reference scope is prototype_required, we simply add
+        // service.scope=prototype to the filter
+        if ( m_dependencyMetadata.getScope() == ReferenceScope.prototype_required )
+        {
+            filterSB.append('(');
+            filterSB.append(Constants.SERVICE_SCOPE);
+            filterSB.append('=');
+            filterSB.append(Constants.SCOPE_PROTOTYPE);
+            filterSB.append(')');
+        }
+
+        // append target
+        if ( m_target != null )
+        {
+            filterSB.append(m_target);
+        }
+        if (multipleExpr )
+        {
+            filterSB.append(')');
+        }
+        String filterString = filterSB.toString();
 
         final ServiceTracker<T, RefPair<S, T>> oldTracker = m_tracker;
         AtomicInteger trackingCount = new AtomicInteger();
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 789885b..bac95ea 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
@@ -659,7 +659,7 @@
         	{
         		m_scope = ReferenceScope.valueOf(m_scopeName);
         	}
-        	catch (IllegalArgumentException e)
+        	catch (final IllegalArgumentException e)
         	{
         		throw componentMetadata.validationFailure( "reference scope must be 'bundle' or 'prototype' not " + m_scopeName);