[FELIX-4353] Fix for BundleWiringTests.testRequiredExecutionEnvironment()



git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1560317 13f79535-47bb-0310-9956-ffa450edef68
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 a067dbb..672fd2f 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
@@ -18,8 +18,15 @@
  */
 package org.apache.felix.framework.util.manifestparser;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import org.apache.felix.framework.BundleRevisionImpl;
 import org.apache.felix.framework.Logger;
@@ -32,6 +39,7 @@
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
@@ -192,6 +200,12 @@
         List<BundleRequirement> requireReqs = convertRequireCapabilities(importClauses, owner);
 
         //
+        // Parse Bundle-RequiredExecutionEnvironment.
+        //
+        List<BundleRequirement> breeReqs =
+            parseBreeHeader((String) headerMap.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT), owner);
+
+        //
         // Parse Export-Package.
         //
 
@@ -239,12 +253,13 @@
         // Combine all requirements.
         m_requirements = new ArrayList(
             hostReqs.size() + importReqs.size() + rbReqs.size()
-            + requireReqs.size() + dynamicReqs.size());
+            + requireReqs.size() + dynamicReqs.size() + breeReqs.size());
         m_requirements.addAll(hostReqs);
         m_requirements.addAll(importReqs);
         m_requirements.addAll(rbReqs);
         m_requirements.addAll(requireReqs);
         m_requirements.addAll(dynamicReqs);
+        m_requirements.addAll(breeReqs);
 
         //
         // Parse Bundle-NativeCode.
@@ -1461,6 +1476,126 @@
         return caps;
     }
 
+    private static List<BundleRequirement> parseBreeHeader(String header, BundleRevision owner)
+    {
+        List<String> filters = new ArrayList<String>();
+        for (String entry : parseDelimitedString(header, ","))
+        {
+            List<String> names = parseDelimitedString(entry, "/");
+            List<String> left = parseDelimitedString(names.get(0), "-");
+
+            String lName = left.get(0);
+            Version lVer;
+            try
+            {
+                lVer = Version.parseVersion(left.get(1));
+            }
+            catch (Exception ex)
+            {
+                // Version doesn't parse. Make it part of the name.
+                lName = names.get(0);
+                lVer = null;
+            }
+
+            String rName = null;
+            Version rVer = null;
+            if (names.size() > 1)
+            {
+                List<String> right = parseDelimitedString(names.get(1), "-");
+                rName = right.get(0);
+                try
+                {
+                    rVer = Version.parseVersion(right.get(1));
+                }
+                catch (Exception ex)
+                {
+                    rName = names.get(1);
+                    rVer = null;
+                }
+            }
+
+            String versionClause;
+            if (lVer != null)
+            {
+                if ((rVer != null) && (!rVer.equals(lVer)))
+                {
+                    // Both versions are defined, but different. Make each of them part of the name
+                    lName = names.get(0);
+                    rName = names.get(1);
+                    versionClause = null;
+                }
+                else
+                {
+                    versionClause = getBreeVersionClause(lVer);
+                }
+            }
+            else
+            {
+                versionClause = getBreeVersionClause(rVer);
+            }
+
+            if ("J2SE".equals(lName))
+            {
+                // J2SE is not used in the Capability variant of BREE, use JavaSE here
+                // This can only happen with the lName part...
+                lName = "JavaSE";
+            }
+
+            String nameClause;
+            if (rName != null)
+                nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + "/" + rName + ")";
+            else
+                nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + ")";
+
+            String filter;
+            if (versionClause != null)
+                filter = "(&" + nameClause + versionClause + ")";
+            else
+                filter = nameClause;
+
+            filters.add(filter);
+        }
+
+        if (filters.size() == 0)
+        {
+            return Collections.emptyList();
+        }
+        else
+        {
+            String reqFilter;
+            if (filters.size() == 1)
+            {
+                reqFilter = filters.get(0);
+            }
+            else
+            {
+                // If there are more BREE filters, we need to or them together
+                StringBuilder sb = new StringBuilder("(|");
+                for (String f : filters)
+                {
+                    sb.append(f);
+                }
+                sb.append(")");
+                reqFilter = sb.toString();
+            }
+
+            SimpleFilter sf = SimpleFilter.parse(reqFilter);
+            return Collections.<BundleRequirement>singletonList(new BundleRequirementImpl(
+                owner,
+                ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE,
+                Collections.singletonMap(ExecutionEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, reqFilter),
+                Collections.<String, Object>emptyMap(),
+                sf));
+        }
+    }
+
+    private static String getBreeVersionClause(Version ver) {
+        if (ver == null)
+            return null;
+
+        return "(" + ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE + "=" + ver + ")";
+    }
+
     private static List<ParsedHeaderClause> normalizeRequireClauses(
         Logger logger, List<ParsedHeaderClause> clauses, String mv)
     {