Properly attach BSN/BV to extension bundle exports when attached to system
bundle. (FELIX-1123)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@774519 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index caedc7d..1631ecc 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -206,14 +206,14 @@
             {
                 // If there is a bundle symbolic name attribute, add the
                 // standard alias as a value.
-                if (attrs[i].getName().equalsIgnoreCase(FelixConstants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+                if (attrs[i].getName().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
                 {
                     // Make a copy of the attribute array.
                     R4Attribute[] aliasAttrs = new R4Attribute[attrs.length];
                     System.arraycopy(attrs, 0, aliasAttrs, 0, attrs.length);
                     // Add the aliased value.
                     aliasAttrs[i] = new R4Attribute(
-                        FelixConstants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
+                        Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
                         new String[] { (String) attrs[i].getValue(), Constants.SYSTEM_BUNDLE_SYMBOLICNAME }, false);
                     // Create the aliased capability to replace the old capability.
                     aliasCaps[capIdx] = new Capability(
@@ -274,10 +274,10 @@
         }
 
         R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
-            bundle.getCurrentModule().getHeaders().get(FelixConstants.FRAGMENT_HOST));
+            bundle.getCurrentModule().getHeaders().get(Constants.FRAGMENT_HOST));
 
         // We only support classpath extensions (not bootclasspath).
-        if (!FelixConstants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
+        if (!Constants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
         {
             throw new BundleException("Unsupported Extension Bundle type: " +
                 dir.getValue(), new UnsupportedOperationException(
@@ -297,14 +297,16 @@
             try
             {
                 exports = ManifestParser.parseExportHeader((String)
-                    bundle.getCurrentModule().getHeaders().get(FelixConstants.EXPORT_PACKAGE));
+                    bundle.getCurrentModule().getHeaders().get(Constants.EXPORT_PACKAGE),
+                    m_module.getSymbolicName(), m_module.getVersion());
+                exports = aliasSymbolicName(exports);
             }
             catch (Exception ex)
             {
                 m_logger.log(
                     Logger.LOG_ERROR,
                     "Error parsing extension bundle export statement: "
-                    + bundle.getCurrentModule().getHeaders().get(FelixConstants.EXPORT_PACKAGE), ex);
+                    + bundle.getCurrentModule().getHeaders().get(Constants.EXPORT_PACKAGE), ex);
                 return;
             }
 
@@ -401,7 +403,7 @@
     void setCapabilities(ICapability[] capabilities)
     {
         m_capabilities = capabilities;
-        m_headerMap.put(FelixConstants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(m_headerMap));
+        m_headerMap.put(Constants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(m_headerMap));
     }
 
     private String convertCapabilitiesToHeaders(Map headers)
@@ -592,7 +594,7 @@
                     Util.substVars(props.getProperty(name), name, null, props));
             }
             // Return system packages property.
-            return props.getProperty(FelixConstants.FRAMEWORK_SYSTEMPACKAGES);
+            return props.getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES);
         }
         catch (Exception ex)
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index 94146c8..64b1a29 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -747,44 +747,13 @@
     private void checkAndNormalizeR4() throws BundleException
     {
         // Verify that bundle symbolic name is specified.
-        String symName = (String) m_headerMap.get(Constants.BUNDLE_SYMBOLICNAME);
-        if (symName == null)
+        if (m_bundleSymbolicName == null)
         {
             throw new BundleException("R4 bundle manifests must include bundle symbolic name.");
         }
 
-        // Verify that the exports do not specify bundle symbolic name
-        // or bundle version.
-        for (int i = 0; (m_capabilities != null) && (i < m_capabilities.length); i++)
-        {
-            if (m_capabilities[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                R4Attribute[] attrs = ((Capability) m_capabilities[i]).getAttributes();
-                for (int attrIdx = 0; attrIdx < attrs.length; attrIdx++)
-                {
-                    // Find symbolic name and version attribute, if present.
-                    if (attrs[attrIdx].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE) ||
-                        attrs[attrIdx].getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
-                    {
-                        throw new BundleException(
-                            "Exports must not specify bundle symbolic name or bundle version.");
-                    }
-                }
-
-                // Now that we know that there are no bundle symbolic name and version
-                // attributes, add them since the spec says they are there implicitly.
-                R4Attribute[] newAttrs = new R4Attribute[attrs.length + 2];
-                System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
-                newAttrs[attrs.length] = new R4Attribute(
-                    Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false);
-                newAttrs[attrs.length + 1] = new R4Attribute(
-                    Constants.BUNDLE_VERSION_ATTRIBUTE, getBundleVersion(), false);
-                m_capabilities[i] = new Capability(
-                    ICapability.PACKAGE_NAMESPACE,
-                    ((Capability) m_capabilities[i]).getDirectives(),
-                    newAttrs);
-            }
-        }
+        m_capabilities = checkAndNormalizeR4Exports(
+            m_capabilities, m_bundleSymbolicName, m_bundleVersion);
 
         R4Directive extension = parseExtensionBundleHeader((String)
             m_headerMap.get(Constants.FRAGMENT_HOST));
@@ -802,6 +771,46 @@
         }
     }
 
+    private static ICapability[] checkAndNormalizeR4Exports(
+        ICapability[] caps, String bsn, Version bv)
+        throws BundleException
+    {
+        // Verify that the exports do not specify bundle symbolic name
+        // or bundle version.
+        for (int i = 0; (caps != null) && (i < caps.length); i++)
+        {
+            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+            {
+                R4Attribute[] attrs = ((Capability) caps[i]).getAttributes();
+                for (int attrIdx = 0; attrIdx < attrs.length; attrIdx++)
+                {
+                    // Find symbolic name and version attribute, if present.
+                    if (attrs[attrIdx].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE) ||
+                        attrs[attrIdx].getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+                    {
+                        throw new BundleException(
+                            "Exports must not specify bundle symbolic name or bundle version.");
+                    }
+                }
+
+                // Now that we know that there are no bundle symbolic name and version
+                // attributes, add them since the spec says they are there implicitly.
+                R4Attribute[] newAttrs = new R4Attribute[attrs.length + 2];
+                System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
+                newAttrs[attrs.length] = new R4Attribute(
+                    Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn, false);
+                newAttrs[attrs.length + 1] = new R4Attribute(
+                    Constants.BUNDLE_VERSION_ATTRIBUTE, bv, false);
+                caps[i] = new Capability(
+                    ICapability.PACKAGE_NAMESPACE,
+                    ((Capability) caps[i]).getDirectives(),
+                    newAttrs);
+            }
+        }
+
+        return caps;
+    }
+
     private void checkExtensionBundle() throws BundleException
     {
         if (m_headerMap.containsKey(Constants.IMPORT_PACKAGE) ||
@@ -814,7 +823,7 @@
         }
     }
 
-    public static ICapability parseBundleSymbolicName(Map headerMap)
+    private static ICapability parseBundleSymbolicName(Map headerMap)
         throws BundleException
     {
         Object[][][] clauses = parseStandardHeader(
@@ -866,7 +875,22 @@
         return null;
     }
 
-    public static ICapability[] parseExportHeader(String header)
+    public static ICapability[] parseExportHeader(String header, String bsn, Version bv)
+        throws BundleException
+    {
+        ICapability[] caps = parseExportHeader(header);
+        try
+        {
+            caps = checkAndNormalizeR4Exports(caps, bsn, bv);
+        }
+        catch (BundleException ex)
+        {
+            caps = null;
+        }
+        return caps;
+    }
+
+    private static ICapability[] parseExportHeader(String header)
     {
         Object[][][] clauses = parseStandardHeader(header);
 
@@ -962,7 +986,7 @@
         return (ICapability[]) capList.toArray(new ICapability[capList.size()]);
     }
 
-    public static IRequirement[] parseImportHeader(String header)
+    private static IRequirement[] parseImportHeader(String header)
     {
         Object[][][] clauses = parseStandardHeader(header);
 
@@ -1061,7 +1085,7 @@
         return (IRequirement[]) reqList.toArray(new IRequirement[reqList.size()]);
     }
 
-    public static IRequirement[] parseRequireBundleHeader(String header)
+    private static IRequirement[] parseRequireBundleHeader(String header)
     {
         Object[][][] clauses = parseStandardHeader(header);
 
@@ -1157,7 +1181,7 @@
 
     // Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2,
     //            path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2
-    public static Object[][][] parseStandardHeader(String header)
+    private static Object[][][] parseStandardHeader(String header)
     {
         Object[][][] clauses = null;
 
@@ -1184,7 +1208,7 @@
     }
 
     // Like this: path; path; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2
-    public static Object[][] parseStandardHeaderClause(String clauseString)
+    private static Object[][] parseStandardHeaderClause(String clauseString)
         throws IllegalArgumentException
     {
         // Break string into semi-colon delimited pieces.
@@ -1363,7 +1387,7 @@
      * @return an array of <tt>LibraryInfo</tt> objects for the
      *         passed in strings.
     **/
-    public static R4LibraryClause[] parseLibraryStrings(Logger logger, String[] libStrs)
+    private static R4LibraryClause[] parseLibraryStrings(Logger logger, String[] libStrs)
         throws IllegalArgumentException
     {
         if (libStrs == null)