FELIX-2175: Improve the Blueprint component to parse / introspect blueprint configuration files and generate OBR service requirements / capabilities accordingly

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@921827 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
index 8b2c70a..03300b5 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
@@ -140,7 +140,14 @@
                     sb.append(a.getName());
                     for (Map.Entry<String, String> prop : a.getProperties().entrySet())
                     {
-                        sb.append(';').append(prop.getKey()).append("=").append(prop.getValue());
+                        sb.append(';').append(prop.getKey()).append("=");
+                        if (prop.getValue().matches("[0-9a-zA-Z_-]+")) {
+                            sb.append(prop.getValue());
+                        } else {
+                            sb.append("\"");
+                            sb.append(prop.getValue().replace("\"", "\\\""));
+                            sb.append("\"");
+                        }
                     }
                 }
                 analyzer.setProperty(header, sb.toString());
diff --git a/bundleplugin/src/main/java/org/osgi/impl/bundle/obr/resource/BundleInfo.java b/bundleplugin/src/main/java/org/osgi/impl/bundle/obr/resource/BundleInfo.java
index 01ec40c..e30163c 100644
--- a/bundleplugin/src/main/java/org/osgi/impl/bundle/obr/resource/BundleInfo.java
+++ b/bundleplugin/src/main/java/org/osgi/impl/bundle/obr/resource/BundleInfo.java
@@ -340,10 +340,18 @@
 	}
 
 	String createServiceFilter(ManifestEntry pack) {
+        String f = pack.getAttribute("filter");
 		StringBuffer filter = new StringBuffer();
+        if (f != null) {
+            filter.append("(&");
+        }
 		filter.append("(service=");
 		filter.append(pack.getName());
 		filter.append(")");
+        if (f != null) {
+            filter.append(f);
+            filter.append(")");
+        }
 		return filter.toString();
 	}
 
@@ -480,6 +488,13 @@
 	CapabilityImpl createServiceCapability(ManifestEntry pack) {
 		CapabilityImpl capability = new CapabilityImpl("service");
 		capability.addProperty("service", pack.getName());
+        Map attributes = pack.getAttributes();
+        if (attributes != null)
+            for (Iterator at = attributes.keySet().iterator(); at.hasNext();) {
+                String key = (String) at.next();
+                Object value = attributes.get(key);
+                capability.addProperty(key, value);
+            }
 		return capability;
 	}
 
diff --git a/bundleplugin/src/main/resources/org/apache/felix/bundleplugin/blueprint.xsl b/bundleplugin/src/main/resources/org/apache/felix/bundleplugin/blueprint.xsl
index 4782c6c..2d16d18 100644
--- a/bundleplugin/src/main/resources/org/apache/felix/bundleplugin/blueprint.xsl
+++ b/bundleplugin/src/main/resources/org/apache/felix/bundleplugin/blueprint.xsl
@@ -33,7 +33,7 @@
                 <xsl:if test="not(namespace-uri() = 'http://www.osgi.org/xmlns/blueprint/v1.0.0'
                                         or namespace-uri() = 'http://www.w3.org/2001/XMLSchema-instance'
                                         or namespace-uri() = '')">
-                    <xsl:value-of select="concat('Import-Service:', $nsh_interface, ';', $nsh_namespace, '=&quot;', namespace-uri(), '&quot;')" />
+                    <xsl:value-of select="concat('Import-Service:', $nsh_interface, ';filter=&quot;(', $nsh_namespace, '=', namespace-uri(), ')&quot;')" />
                     <xsl:text>
                     </xsl:text>
                 </xsl:if>
@@ -89,19 +89,36 @@
         </xsl:for-each>
 
         <xsl:for-each select="//bp:reference[@interface] | //bp:reference-list[@interface]">
+            <xsl:value-of select="concat('Import-Service:', @interface)" />
             <xsl:choose>
                 <xsl:when test="@availability">
-                    <xsl:value-of select="concat('Import-Service:', @interface, ';availability:=', @availability)"/>
+                    <xsl:value-of select="concat(';availability:=', @availability)"/>
                 </xsl:when>
                 <xsl:otherwise>
                     <xsl:choose>
                         <xsl:when test="/bp:blueprint/@default-availability">
-                            <xsl:value-of select="concat('Import-Service:', @interface, ';availability:=', /bp:blueprint/@default-availability)"/>
+                            <xsl:value-of select="concat(';availability:=', /bp:blueprint/@default-availability)"/>
                         </xsl:when>
+                    </xsl:choose>
+                </xsl:otherwise>
+            </xsl:choose>
+            <xsl:choose>
+                <xsl:when test="@filter">
+                    <xsl:choose>
+                        <xsl:when test="@component-name">
+                            <xsl:value-of select="concat(';filter=&quot;(&amp;', @filter, ')(osgi.service.blueprint.compname=',  @component-name, ')&quot;')" />
+                         </xsl:when>
                         <xsl:otherwise>
-                            <xsl:value-of select="concat('Import-Service:', @interface, ';availability:=mandatory')"/>
+                            <xsl:value-of select="concat(';filter=&quot;', @filter, '&quot;')" />
                         </xsl:otherwise>
                     </xsl:choose>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:choose>
+                        <xsl:when test="@component-name">
+                            <xsl:value-of select="concat(';filter=&quot;(osgi.service.blueprint.compname=', @component-name, ')&quot;')" />
+                        </xsl:when>
+                    </xsl:choose>
                 </xsl:otherwise>
             </xsl:choose>
             <xsl:text>
diff --git a/bundleplugin/src/test/resources/OSGI-INF/blueprint/bp.xml b/bundleplugin/src/test/resources/OSGI-INF/blueprint/bp.xml
index 882f62e..170b39b 100644
--- a/bundleplugin/src/test/resources/OSGI-INF/blueprint/bp.xml
+++ b/bundleplugin/src/test/resources/OSGI-INF/blueprint/bp.xml
@@ -34,7 +34,7 @@
         </property>
     </bean>
 
-    <reference interface="p4.Foo"  availability="optional"/>
+    <reference interface="p4.Foo"  availability="optional" filter="(prop=a,b)" component-name="boo"/>
 
     <reference-list interface="p5.Foo">
     </reference-list>