[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)
{