From 5597825438bbdef935047f860781e0c4d62eb93e Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Wed, 14 Feb 2024 00:14:28 +0100 Subject: [PATCH] Provide utility to obtain the BREE from a EE requirement --- .../pde/internal/core/util/ManifestUtils.java | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/ManifestUtils.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/ManifestUtils.java index f2b7db192e..b806a9c385 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/ManifestUtils.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/ManifestUtils.java @@ -13,11 +13,16 @@ *******************************************************************************/ package org.eclipse.pde.internal.core.util; +import static org.osgi.framework.namespace.ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE; +import static org.osgi.framework.namespace.ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; import java.util.LinkedList; @@ -25,6 +30,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -38,6 +45,8 @@ import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.jdt.launching.environments.IExecutionEnvironment; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.build.IBuild; @@ -50,6 +59,9 @@ import org.eclipse.pde.internal.core.project.PDEProject; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; public class ManifestUtils { @@ -77,7 +89,7 @@ public class ManifestUtils { *

* If this method is being called from a dev mode workspace, the returned map * should be passed to {@link TargetWeaver#weaveManifest(Map, File)} so that the - * bundle classpath can be corrected. + * bundle classpath can be corrected. *

*

* This method is called by @@ -285,4 +297,61 @@ private static String splitOnComma(String value) { sb.append(values[values.length - 1]); return sb.toString(); } + + + // Simple filters are for example (&(version=17)(osgi.ee=JavaSE)) + private static final Pattern SIMPLE_EE_FILTER; + private static final int NAME_GROUP = 2; + private static final int VERSION_GROUP = 3; + static { + String nameSegment = "\\(" + EXECUTION_ENVIRONMENT_NAMESPACE + "=([\\w/]+)\\)"; //$NON-NLS-1$//$NON-NLS-2$ + String versionSegment = "\\(" + CAPABILITY_VERSION_ATTRIBUTE + "=([\\d\\.]+)\\)"; //$NON-NLS-1$ //$NON-NLS-2$ + SIMPLE_EE_FILTER = Pattern.compile("\\(&(" + nameSegment + ")|(" + versionSegment + ")\\)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + private static final List> AVAILABLE_EE_PROPERTIES = createEEProperties(); + + private static List> createEEProperties() { + IExecutionEnvironment[] availableEEs = JavaRuntime.getExecutionEnvironmentsManager().getExecutionEnvironments(); + List> eeProperties = Arrays.stream(availableEEs).map(ee -> { + String id = ee.getId(); + int versionSeparator = id.lastIndexOf('-'); + if (versionSeparator < 0) { + throw new IllegalArgumentException("Missing version-separator in EE Id"); //$NON-NLS-1$ + } + String name = id.substring(0, versionSeparator); + String version = id.substring(versionSeparator + 1); + return Map.of(EXECUTION_ENVIRONMENT_NAMESPACE, name, CAPABILITY_VERSION_ATTRIBUTE, version); + }).toList(); + return eeProperties; + } + + public static List parseRequiredEEsFromFilter(String eeFilter) { + if (eeFilter.chars().anyMatch(Character::isWhitespace)) { + eeFilter = eeFilter.replaceAll("\\s*", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + Matcher matcher = SIMPLE_EE_FILTER.matcher(eeFilter); + if (matcher.matches()) { // fast track + String name = matcher.group(NAME_GROUP); + String version = matcher.group(VERSION_GROUP); + if (name != null && version != null) { + return List.of(name + "-" + version); //$NON-NLS-1$ + } + } + try { // complex filter. Collect all matching EEs + Filter filter = FrameworkUtil.createFilter(eeFilter); + List requiredEEs = new ArrayList<>(); + for (Map ee : AVAILABLE_EE_PROPERTIES) { + if (filter.matches(ee)) { + String name = ee.get(EXECUTION_ENVIRONMENT_NAMESPACE); + String version = ee.get(CAPABILITY_VERSION_ATTRIBUTE); + requiredEEs.add(name + "-" + version); //$NON-NLS-1$ + } + } + return requiredEEs; + } catch (InvalidSyntaxException e) { // should not happen + throw new IllegalArgumentException("Invalid execution environment filter", e); //$NON-NLS-1$ + } + } + }