diff --git a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/StateBuilder.java b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/StateBuilder.java index 1735efa76c9..f3d812aa135 100644 --- a/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/StateBuilder.java +++ b/bundles/org.eclipse.osgi.compatibility.state/src/org/eclipse/osgi/internal/resolver/StateBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2020 IBM Corporation and others. + * Copyright (c) 2003, 2024 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -25,7 +25,9 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.stream.Stream; import org.eclipse.osgi.internal.framework.EquinoxContainer; import org.eclipse.osgi.internal.framework.FilterImpl; import org.eclipse.osgi.internal.messages.Msg; @@ -47,6 +49,7 @@ import org.osgi.framework.InvalidSyntaxException; 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.resource.Namespace; @@ -128,7 +131,7 @@ static BundleDescription createBundleDescription(StateImpl state, Dictionary manifest) throws BundleException { + @SuppressWarnings("deprecation") + String requiredEE = manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT); + if (requiredEE != null) { + return ManifestElement.getArrayFromList(requiredEE); + } + String requiredCapability = manifest.get(Constants.REQUIRE_CAPABILITY); + ManifestElement[] headers = ManifestElement.parseHeader(Constants.REQUIRE_CAPABILITY, requiredCapability); + if (headers != null) { + return Stream.of(headers) // + .map(header -> header.getDirective(Constants.FILTER_DIRECTIVE)) // + .map(StateBuilder::getEEFromFilter) // + .filter(Objects::nonNull) // + .toArray(String[]::new); + } + return null; + } + + /** + * Extracts the execution environment of the given filter specification + * using the environment namespace (e.g. JavaSE) and version attribute + * (e.g. 17). Both values are joined with a '-'. If the filter doesn't + * contain either value or if the filter is otherwise invalid, {@code null} + * is returned. + * + * @see ExecutionEnvironmentNamespace#EXECUTION_ENVIRONMENT_NAMESPACE + * @see ExecutionEnvironmentNamespace#CAPABILITY_VERSION_ATTRIBUTE + */ + private static String getEEFromFilter(String filterSpec) { + if (filterSpec == null) { + return null; + } + try { + FilterImpl filter = FilterImpl.newInstance(filterSpec); + String ee = filter.getPrimaryKeyValue(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE); + String version = filter.getPrimaryKeyValue(ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE); + if (ee != null && version != null) { + return ee + '-' + version; + } + } catch (InvalidSyntaxException e) { + // TODO Special handling needed? + } + return null; + } }