Bug 577118 - Handle multiple Plug-in versions in launching facility
- Take only the latest version of a workspace/target bundle if multiple
versions are present and no version is specified in the launch-config
- Replace selected target-bundles only by a workspace-bundle if it has
the same Major-Minor-Micro version
- When writing bundle entries for launch-configurations, check if there
are other bundles in the same container (workspace or target-platform)
to decide if the version is written and not only check the number of
'active' models
- write versioned-entries to the dev.properties to enable different dev
classpath-entries for different versions of a bundle
Change-Id: Ib559c47ba6dfa5a56da4259c92dbe5d95370a45a
Signed-off-by: Hannes Wellmann <wellmann.hannes1@gmx.net>
Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/187493
Tested-by: PDE Bot <pde-bot@eclipse.org>
Reviewed-by: Julian Honnen <julian.honnen@vector.com>
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ClasspathHelper.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ClasspathHelper.java
index 16655d2..48176ab 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ClasspathHelper.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ClasspathHelper.java
@@ -12,6 +12,7 @@
* IBM Corporation - initial API and implementation
* Hannes Wellmann - Bug 577541 - Clean up ClasspathHelper and TargetWeaver
* Hannes Wellmann - Bug 577543 - Only weave dev.properties for secondary launches if plug-in is from Running-Platform
+ * Hannes Wellmann - Bug 577118 - Handle multiple Plug-in versions in launching facility
*******************************************************************************/
package org.eclipse.pde.internal.core;
@@ -20,9 +21,9 @@
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -51,6 +52,7 @@
import org.eclipse.pde.core.build.IBuild;
import org.eclipse.pde.core.build.IBuildEntry;
import org.eclipse.pde.core.plugin.IFragmentModel;
+import org.eclipse.pde.core.plugin.IPluginBase;
import org.eclipse.pde.core.plugin.IPluginLibrary;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
@@ -64,19 +66,19 @@
private static final String DOT = "."; //$NON-NLS-1$
private static final String FRAGMENT_ANNOTATION = "@fragment@"; //$NON-NLS-1$
+ private static final String DEV_CLASSPATH_ENTRY_SEPARATOR = ","; //$NON-NLS-1$
+ private static final String DEV_CLASSPATH_VERSION_SEPARATOR = ";"; //$NON-NLS-1$
public static String getDevEntriesProperties(String fileName, boolean checkExcluded) throws CoreException {
IPluginModelBase[] models = PluginRegistry.getWorkspaceModels();
- Map<String, IPluginModelBase> bundleModels = new HashMap<>();
- for (IPluginModelBase model : models) {
- bundleModels.put(model.getPluginBase().getId(), model);
- }
+ Map<String, List<IPluginModelBase>> bundleModels = Arrays.stream(models)
+ .collect(Collectors.groupingBy(m -> m.getPluginBase().getId()));
Properties properties = getDevEntriesProperties(bundleModels, checkExcluded);
return writeDevEntries(fileName, properties);
}
- public static String getDevEntriesProperties(String fileName, Map<String, IPluginModelBase> map)
+ public static String getDevEntriesProperties(String fileName, Map<String, List<IPluginModelBase>> map)
throws CoreException {
Properties properties = getDevEntriesProperties(map, true);
return writeDevEntries(fileName, properties);
@@ -99,26 +101,70 @@
}
}
- public static Properties getDevEntriesProperties(Map<String, IPluginModelBase> bundlesMap, boolean checkExcluded) {
- Properties properties = new Properties();
+ public static Properties getDevEntriesProperties(Map<String, List<IPluginModelBase>> bundlesMap,
+ boolean checkExcluded) {
+
+ Set<IPluginModelBase> launchedPlugins = bundlesMap.values().stream().flatMap(Collection::stream)
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+
+ Map<IPluginModelBase, String> modelEntries = new LinkedHashMap<>();
// account for cascading workspaces
- TargetWeaver.weaveRunningPlatformDevProperties(properties, bundlesMap.values());
- for (IPluginModelBase model : bundlesMap.values()) {
- if (model.getUnderlyingResource() != null) {
- String entry = formatEntry(getDevPaths(model, checkExcluded, bundlesMap.keySet()));
- if (!entry.isEmpty()) {
- // overwrite entry, if plug-in from primary Eclipse is also
- // imported into workspace of secondary eclipse
- properties.put(model.getPluginBase().getId(), entry);
+ TargetWeaver.weaveRunningPlatformDevProperties(modelEntries, launchedPlugins);
+
+ for (List<IPluginModelBase> models : bundlesMap.values()) {
+ for (IPluginModelBase model : models) {
+ if (model.getUnderlyingResource() != null) {
+ String entry = formatEntry(getDevPaths(model, checkExcluded, launchedPlugins));
+ if (!entry.isEmpty()) {
+ // overwrite entry, if plug-in from primary Eclipse is
+ // also imported into workspace of secondary eclipse
+ modelEntries.put(model, entry);
+ }
+ }
+ }
+ // Check if there is an entry of a workspace-model or
+ // a target model woven from a primary-workspace plugin with same id
+ if (models.stream().anyMatch(modelEntries::containsKey)) {
+ for (IPluginModelBase model : models) {
+ // in case of multiple models with same id add empty entries
+ // for target-bundles to ensure the non-version entry is not
+ // used to falsely extend their class-path
+ modelEntries.putIfAbsent(model, ""); //$NON-NLS-1$
}
}
}
+
+ Properties properties = new Properties();
+ modelEntries.forEach((m, cp) -> addDevClasspath(m.getPluginBase(), properties, cp, false));
properties.put("@ignoredot@", "true"); //$NON-NLS-1$ //$NON-NLS-2$
return properties;
}
private static String formatEntry(Collection<IPath> paths) {
- return paths.stream().map(IPath::toString).collect(Collectors.joining(",")); //$NON-NLS-1$
+ return paths.stream().map(IPath::toString).collect(Collectors.joining(DEV_CLASSPATH_ENTRY_SEPARATOR));
+ }
+
+ public static void addDevClasspath(IPluginBase model, Properties devProperties, String devCP, boolean append) {
+ // add entries with & without version to be backward-compatible with
+ // 'old' Equinox, that doesn't consider versions, too.
+ String id = model.getId();
+ if (!devCP.isEmpty()) {
+ addDevCPEntry(id, devCP, devProperties, append);
+ }
+ addDevCPEntry(id + DEV_CLASSPATH_VERSION_SEPARATOR + model.getVersion(), devCP, devProperties, append);
+ }
+
+ private static void addDevCPEntry(String id, String devCP, Properties devProperties, boolean append) {
+ if (append) {
+ devProperties.merge(id, devCP, (vOld, vNew) -> vOld + DEV_CLASSPATH_ENTRY_SEPARATOR + vNew);
+ } else {
+ devProperties.put(id, devCP);
+ }
+ }
+
+ public static String getDevClasspath(Properties devProperties, String id, String version) {
+ Object cp = devProperties.get(id + ClasspathHelper.DEV_CLASSPATH_VERSION_SEPARATOR + version);
+ return (String) (cp != null ? cp : devProperties.get(id)); // prefer version-entry
}
// creates a map whose key is a Path to the source directory/jar and the value is a Path output directory or jar.
@@ -213,7 +259,7 @@
return paths;
}
- private static Set<IPath> getDevPaths(IPluginModelBase model, boolean checkExcluded, Set<String> plugins) {
+ private static Set<IPath> getDevPaths(IPluginModelBase model, boolean checkExcluded, Set<IPluginModelBase> plugins) {
IProject project = model.getUnderlyingResource().getProject();
try {
if (project.hasNature(JavaCore.NATURE_ID)) {
@@ -263,10 +309,10 @@
}
// looks for fragments for a plug-in. Then searches the fragments for a specific library. Will return paths which are absolute (required by runtime)
- private static List<IPath> findLibraryFromFragments(String libName, IPluginModelBase model, boolean checkExcluded, Set<String> plugins) {
+ private static List<IPath> findLibraryFromFragments(String libName, IPluginModelBase model, boolean checkExcluded, Set<IPluginModelBase> plugins) {
IFragmentModel[] frags = PDEManager.findFragmentsFor(model);
for (int i = 0; i < frags.length; i++) {
- if (!plugins.contains(frags[i].getBundleDescription().getSymbolicName())) {
+ if (!plugins.contains(frags[i])) {
continue;
}
// look in project first
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/P2Utils.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/P2Utils.java
index e24b015..17e3330 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/P2Utils.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/P2Utils.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2018 IBM Corporation and others.
+ * Copyright (c) 2007, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
@@ -381,7 +382,7 @@
*
* @throws CoreException if the profile cannot be generated
*/
- public static void createProfile(String profileID, File p2DataArea, Collection<?> bundles) throws CoreException {
+ public static void createProfile(String profileID, File p2DataArea, Collection<List<IPluginModelBase>> bundles) throws CoreException {
// Acquire the required p2 services, creating an agent in the target p2 metadata area
IProvisioningAgentProvider provider = PDECore.getDefault().acquireService(IProvisioningAgentProvider.class);
if (provider == null) {
@@ -418,12 +419,9 @@
profile = registry.addProfile(profileID, props);
// Create metadata for the bundles
- Collection<IInstallableUnit> ius = new ArrayList<>(bundles.size());
- for (final Object name : bundles) {
- IPluginModelBase model = (IPluginModelBase) name;
- BundleDescription bundle = model.getBundleDescription();
- ius.add(createBundleIU(bundle));
- }
+ Collection<IInstallableUnit> ius = bundles.stream().flatMap(Collection::stream)
+ .map(IPluginModelBase::getBundleDescription).map(P2Utils::createBundleIU) //
+ .collect(Collectors.toList());
// Add the metadata to the profile
ProvisioningContext context = new ProvisioningContext(agent);
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetPlatformHelper.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetPlatformHelper.java
index 7b4a17c..e791225 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetPlatformHelper.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetPlatformHelper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -26,7 +26,6 @@
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -234,13 +233,12 @@
return null;
}
- public static void checkPluginPropertiesConsistency(Map<?, ?> map, File configDir) {
+ public static void checkPluginPropertiesConsistency(Map<String, List<IPluginModelBase>> map, File configDir) {
File runtimeDir = new File(configDir, IPDEBuildConstants.BUNDLE_CORE_RUNTIME);
if (runtimeDir.exists() && runtimeDir.isDirectory()) {
long timestamp = runtimeDir.lastModified();
- Iterator<?> iter = map.values().iterator();
- while (iter.hasNext()) {
- if (hasChanged((IPluginModelBase) iter.next(), timestamp)) {
+ for (List<IPluginModelBase> models : map.values()) {
+ if (models.stream().anyMatch(m -> hasChanged(m, timestamp))) {
CoreUtility.deleteContent(runtimeDir);
break;
}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetWeaver.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetWeaver.java
index 1d6da8b..8f2081a 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetWeaver.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetWeaver.java
@@ -13,6 +13,7 @@
* EclipseSource Corporation - ongoing enhancements
* Hannes Wellmann - Bug 577541 - Clean up ClasspathHelper and TargetWeaver
* Hannes Wellmann - Bug 577543 - Only weave dev.properties for secondary launches if plug-in is from Running-Platform
+ * Hannes Wellmann - Bug 577118 - Handle multiple Plug-in versions in launching facility
*******************************************************************************/
package org.eclipse.pde.internal.core;
@@ -126,14 +127,14 @@
* @param launchDevProperties dev.properties
* @param launchedPlugins the bundles that participate in secondary runtime
*/
- static void weaveRunningPlatformDevProperties(Properties launchDevProperties,
+ static void weaveRunningPlatformDevProperties(Map<IPluginModelBase, String> launchDevProperties,
Iterable<IPluginModelBase> launchedPlugins) {
if (fgDevPropertiesURL != null) {
Properties platformDevProperties = getDevProperties();
for (IPluginModelBase launchedPlugin : launchedPlugins) {
String devCP = getDevProperty(launchedPlugin, platformDevProperties);
if (devCP != null) {
- launchDevProperties.setProperty(launchedPlugin.getPluginBase().getId(), devCP);
+ launchDevProperties.put(launchedPlugin, devCP);
}
}
}
@@ -186,7 +187,7 @@
}
private static String getDevProperty(Path bundleLocation, String id, String version, Properties devProperties) {
- String devCP = (String) devProperties.get(id);
+ String devCP = ClasspathHelper.getDevClasspath(devProperties, id, version);
return devCP != null && isBundleOfRunningPlatform(bundleLocation, id, version) ? devCP : null;
}
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/BundleLauncherHelper.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/BundleLauncherHelper.java
index 57e588d..f2491cf 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/BundleLauncherHelper.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/BundleLauncherHelper.java
@@ -12,6 +12,7 @@
* IBM Corporation - initial API and implementation
* EclipseSource Corporation - ongoing enhancements
* Hannes Wellmann - Bug 576885: Unify methods to parse bundle-sets from launch-configs
+ * Hannes Wellmann - Bug 577118 - Handle multiple Plug-in versions in launching facility
*******************************************************************************/
package org.eclipse.pde.internal.launching.launcher;
@@ -19,8 +20,9 @@
import java.util.*;
import java.util.Map.Entry;
+import java.util.function.BiPredicate;
import java.util.function.Function;
-import java.util.function.Predicate;
+import java.util.stream.Stream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
@@ -29,6 +31,7 @@
import org.eclipse.pde.internal.build.IPDEBuildConstants;
import org.eclipse.pde.internal.core.*;
import org.eclipse.pde.internal.core.ifeature.*;
+import org.eclipse.pde.internal.core.util.VersionUtil;
import org.eclipse.pde.internal.launching.IPDEConstants;
import org.eclipse.pde.launching.IPDELauncherConstants;
import org.osgi.framework.Version;
@@ -48,11 +51,7 @@
public static final char VERSION_SEPARATOR = '*';
public static Map<IPluginModelBase, String> getWorkspaceBundleMap(ILaunchConfiguration configuration) throws CoreException {
- return getWorkspaceBundleMap(configuration, null);
- }
-
- public static Map<IPluginModelBase, String> getTargetBundleMap(ILaunchConfiguration configuration) throws CoreException {
- return getTargetBundleMap(configuration, null);
+ return getWorkspaceBundleMap(configuration, new HashMap<>());
}
public static Map<IPluginModelBase, String> getMergedBundleMap(ILaunchConfiguration configuration, boolean osgi) throws CoreException {
@@ -79,9 +78,13 @@
return getMergedBundleMapFeatureBased(wc, osgi);
}
- Set<String> set = new HashSet<>();
- Map<IPluginModelBase, String> map = getWorkspaceBundleMap(wc, set);
- map.putAll(getTargetBundleMap(wc, set));
+ return getAllSelectedPluginBundles(wc);
+ }
+
+ public static Map<IPluginModelBase, String> getAllSelectedPluginBundles(ILaunchConfiguration config) throws CoreException {
+ Map<String, List<Version>> idVersions = new HashMap<>();
+ Map<IPluginModelBase, String> map = getWorkspaceBundleMap(config, idVersions);
+ map.putAll(getTargetBundleMap(config, idVersions));
return map;
}
@@ -310,37 +313,33 @@
return map.keySet().toArray(new IPluginModelBase[map.size()]);
}
- public static Map<IPluginModelBase, String> getWorkspaceBundleMap(ILaunchConfiguration configuration, Set<String> pluginIds) throws CoreException {
+ private static final BiPredicate<List<Version>, Version> CONTAINS_SAME_VERSION = List::contains;
+ private static final BiPredicate<List<Version>, Version> CONTAINS_SAME_MMM_VERSION = (versions, toAdd) -> versions.stream().anyMatch(v -> VersionUtil.compareMacroMinorMicro(toAdd, v) == 0);
+
+ private static Map<IPluginModelBase, String> getWorkspaceBundleMap(ILaunchConfiguration configuration, Map<String, List<Version>> idVersions) throws CoreException {
Set<String> workspaceBundles = configuration.getAttribute(IPDELauncherConstants.SELECTED_WORKSPACE_BUNDLES, emptySet());
- Map<IPluginModelBase, String> map = getBundleMap(workspaceBundles, ModelEntry::getWorkspaceModels, pluginIds, id -> true);
+ Map<IPluginModelBase, String> map = getBundleMap(workspaceBundles, ModelEntry::getWorkspaceModels, CONTAINS_SAME_VERSION, idVersions);
if (configuration.getAttribute(IPDELauncherConstants.AUTOMATIC_ADD, true)) {
Set<String> deselectedWorkspaceBundles = configuration.getAttribute(IPDELauncherConstants.DESELECTED_WORKSPACE_BUNDLES, emptySet());
- Set<IPluginModelBase> deselectedPlugins = getBundleMap(deselectedWorkspaceBundles, ModelEntry::getWorkspaceModels, null, id -> true).keySet();
+ Set<IPluginModelBase> deselectedPlugins = getBundleMap(deselectedWorkspaceBundles, ModelEntry::getWorkspaceModels, null, null).keySet();
IPluginModelBase[] models = PluginRegistry.getWorkspaceModels();
for (IPluginModelBase model : models) {
- String id = model.getPluginBase().getId();
- if (id != null && !deselectedPlugins.contains(model)) {
- if (pluginIds != null) {
- pluginIds.add(id);
- }
- if (!map.containsKey(model)) {
- addBundleToMap(map, model, "default:default"); //$NON-NLS-1$
- }
+ if (model.getPluginBase().getId() != null && !deselectedPlugins.contains(model) && !map.containsKey(model)) {
+ addPlugin(map, model, "default:default", idVersions, CONTAINS_SAME_VERSION); //$NON-NLS-1$
}
}
}
return map;
}
- public static Map<IPluginModelBase, String> getTargetBundleMap(ILaunchConfiguration configuration, Set<String> pluginIds) throws CoreException {
+ private static Map<IPluginModelBase, String> getTargetBundleMap(ILaunchConfiguration configuration, Map<String, List<Version>> idVersions) throws CoreException {
Set<String> targetBundles = configuration.getAttribute(IPDELauncherConstants.SELECTED_TARGET_BUNDLES, emptySet());
- Predicate<String> idFilter = pluginIds != null ? id -> !pluginIds.contains(id) : id -> true;
- return getBundleMap(targetBundles, ModelEntry::getExternalModels, null, idFilter);
+ return getBundleMap(targetBundles, ModelEntry::getExternalModels, CONTAINS_SAME_MMM_VERSION, idVersions); // don't add same major-minor-micro-version more than once
}
- private static Map<IPluginModelBase, String> getBundleMap(Set<String> entries, Function<ModelEntry, IPluginModelBase[]> getModels, Set<String> pluginIds, Predicate<String> idFilter) {
+ private static Map<IPluginModelBase, String> getBundleMap(Set<String> entries, Function<ModelEntry, IPluginModelBase[]> getModels, BiPredicate<List<Version>, Version> versionFilter, Map<String, List<Version>> idVersions) {
Map<IPluginModelBase, String> map = new LinkedHashMap<>();
for (String bundleEntry : entries) {
int index = bundleEntry.indexOf('@');
@@ -353,36 +352,46 @@
String id = (versionIndex > 0) ? idVersion.substring(0, versionIndex) : idVersion;
String version = (versionIndex > 0) ? idVersion.substring(versionIndex + 1) : null;
- if (idFilter.test(id)) {
- if (pluginIds != null) {
- pluginIds.add(id);
- }
- ModelEntry entry = PluginRegistry.findEntry(id);
- if (entry != null) {
- IPluginModelBase[] models = getModels.apply(entry);
- String startData = bundleEntry.substring(index + 1);
- addPluginModel(models, version, startData, map);
+ ModelEntry entry = PluginRegistry.findEntry(id);
+ if (entry != null) {
+ IPluginModelBase[] models = getModels.apply(entry);
+ String startData = bundleEntry.substring(index + 1);
+ for (IPluginModelBase model : getSelectedModels(models, version, versionFilter == null)) {
+ addPlugin(map, model, startData, idVersions, versionFilter);
}
}
}
return map;
}
- private static void addPluginModel(IPluginModelBase[] models, String version, String startData, Map<IPluginModelBase, String> map) {
- Set<String> versions = new HashSet<>();
- for (IPluginModelBase model : models) {
- if (model.isEnabled()) { // always true for workspace models, external might be disabled
- IPluginBase base = model.getPluginBase();
- String v = base.getVersion();
- if (versions.add(v)) { // don't add exact same version more than once
- // match only if...
- // a) if we have the same version
- // b) no version
- // c) all else fails, if there's just one bundle available, use it
- if (base.getVersion().equals(version) || version == null || models.length == 1) {
- addBundleToMap(map, model, startData);
- }
- }
+ static final Comparator<IPluginModelBase> VERSION = Comparator.comparing(m -> m.getBundleDescription().getVersion());
+
+ private static Iterable<IPluginModelBase> getSelectedModels(IPluginModelBase[] models, String version, boolean greedy) {
+ // match only if...
+ // a) if we have the same version
+ // b) no version (if greedy take latest, else take all)
+ // c) all else fails, if there's just one bundle available, use it
+ Stream<IPluginModelBase> selectedModels = Arrays.stream(models).filter(IPluginModelBase::isEnabled); // workspace models are always enabled, external might be disabled
+ if (version == null) {
+ if (!greedy) {
+ IPluginModelBase latestModel = selectedModels.max(VERSION).orElseThrow();
+ selectedModels = Stream.of(latestModel); // take only latest
+ } // Otherwise be greedy and take all if versionFilter is null
+ } else {
+ selectedModels = selectedModels.filter(m -> m.getPluginBase().getVersion().equals(version) || models.length == 1);
+ }
+ return selectedModels::iterator;
+ }
+
+ private static void addPlugin(Map<IPluginModelBase, String> map, IPluginModelBase model, String startData, Map<String, List<Version>> idVersions, BiPredicate<List<Version>, Version> containsVersion) {
+ if (containsVersion == null) { // be greedy and just take all (idVersions is null as well)
+ addBundleToMap(map, model, startData);
+ } else {
+ List<Version> pluginVersions = idVersions.computeIfAbsent(model.getPluginBase().getId(), n -> new ArrayList<>());
+ Version version = model.getBundleDescription().getVersion();
+ if (!containsVersion.test(pluginVersions, version)) { // apply version filter
+ pluginVersions.add(version);
+ addBundleToMap(map, model, startData);
}
}
}
@@ -464,22 +473,28 @@
StringBuilder buffer = new StringBuilder(id);
ModelEntry entry = PluginRegistry.findEntry(id);
- if (entry != null && entry.getActiveModels().length > 1) {
- buffer.append(VERSION_SEPARATOR);
- buffer.append(model.getPluginBase().getVersion());
+ if (entry != null) {
+ boolean isWorkspacePlugin = model.getUnderlyingResource() != null;
+ IPluginModelBase[] entryModels = isWorkspacePlugin ? entry.getWorkspaceModels() : entry.getExternalModels();
+ if (entryModels.length > 1) {
+ buffer.append(VERSION_SEPARATOR);
+ buffer.append(model.getPluginBase().getVersion());
+ }
}
- boolean hasStartLevel = (startLevel != null && startLevel.length() > 0);
- boolean hasAutoStart = (autoStart != null && autoStart.length() > 0);
+ boolean hasStartLevel = startLevel != null && !startLevel.isEmpty();
+ boolean hasAutoStart = autoStart != null && !autoStart.isEmpty();
- if (hasStartLevel || hasAutoStart)
+ if (hasStartLevel || hasAutoStart) {
buffer.append('@');
- if (hasStartLevel)
- buffer.append(startLevel);
- if (hasStartLevel || hasAutoStart)
+ if (hasStartLevel) {
+ buffer.append(startLevel);
+ }
buffer.append(':');
- if (hasAutoStart)
- buffer.append(autoStart);
+ if (hasAutoStart) {
+ buffer.append(autoStart);
+ }
+ }
return buffer.toString();
}
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchConfigurationHelper.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchConfigurationHelper.java
index 658c2dd..044353f 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchConfigurationHelper.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchConfigurationHelper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -107,7 +107,7 @@
* @return a properties object containing the properties written out to config.ini
* @throws CoreException
*/
- public static Properties createConfigIniFile(ILaunchConfiguration configuration, String productID, Map<String, IPluginModelBase> bundles, Map<IPluginModelBase, String> bundlesWithStartLevels, File configurationDirectory) throws CoreException {
+ public static Properties createConfigIniFile(ILaunchConfiguration configuration, String productID, Map<String, List<IPluginModelBase>> bundles, Map<IPluginModelBase, String> bundlesWithStartLevels, File configurationDirectory) throws CoreException {
Properties properties = null;
// if we are to generate a config.ini, start with the values in the target platform's config.ini - bug 141918
if (configuration.getAttribute(IPDELauncherConstants.CONFIG_GENERATE_DEFAULT, true)) {
@@ -193,7 +193,7 @@
return properties;
}
- private static void addRequiredProperties(Properties properties, String productID, Map<String, IPluginModelBase> bundles, Map<IPluginModelBase, String> bundlesWithStartLevels) {
+ private static void addRequiredProperties(Properties properties, String productID, Map<String, List<IPluginModelBase>> bundles, Map<IPluginModelBase, String> bundlesWithStartLevels) {
if (!properties.containsKey("osgi.install.area")) //$NON-NLS-1$
properties.setProperty("osgi.install.area", "file:" + TargetPlatform.getLocation()); //$NON-NLS-1$ //$NON-NLS-2$
if (!properties.containsKey("osgi.configuration.cascaded")) //$NON-NLS-1$
@@ -221,7 +221,7 @@
* @param bundlesWithStartLevels map of bundles of start level
* @return string list of osgi bundles
*/
- private static String computeOSGiBundles(String bundleList, Map<String, IPluginModelBase> bundles, Map<IPluginModelBase, String> bundlesWithStartLevels) {
+ private static String computeOSGiBundles(String bundleList, Map<String, List<IPluginModelBase>> bundles, Map<IPluginModelBase, String> bundlesWithStartLevels) {
// if p2 and only simple configurator and
// if simple configurator isn't selected & isn't in bundle list... hack it
@@ -282,7 +282,7 @@
return properties;
}
- private static void addSplashLocation(Properties properties, String productID, Map<String, IPluginModelBase> map) {
+ private static void addSplashLocation(Properties properties, String productID, Map<String, List<IPluginModelBase>> map) {
Properties targetConfig = TargetPlatformHelper.getConfigIniProperties();
String targetProduct = targetConfig == null ? null : targetConfig.getProperty("eclipse.product"); //$NON-NLS-1$
String targetSplash = targetConfig == null ? null : targetConfig.getProperty("osgi.splashPath"); //$NON-NLS-1$
@@ -290,7 +290,7 @@
ArrayList<String> locations = new ArrayList<>();
String plugin = getContributingPlugin(productID);
locations.add(plugin);
- IPluginModelBase model = map.get(plugin);
+ IPluginModelBase model = getLatestModel(plugin, map);
if (model != null) {
BundleDescription desc = model.getBundleDescription();
if (desc != null) {
@@ -304,7 +304,7 @@
resolveLocationPath(targetSplash, properties, map);
}
- private static void resolveLocationPath(String splashPath, Properties properties, Map<String, IPluginModelBase> map) {
+ private static void resolveLocationPath(String splashPath, Properties properties, Map<String, List<IPluginModelBase>> map) {
ArrayList<String> locations = new ArrayList<>();
StringTokenizer tok = new StringTokenizer(splashPath, ","); //$NON-NLS-1$
while (tok.hasMoreTokens())
@@ -312,7 +312,7 @@
resolveLocationPath(locations, properties, map);
}
- private static void resolveLocationPath(ArrayList<String> locations, Properties properties, Map<String, IPluginModelBase> map) {
+ private static void resolveLocationPath(ArrayList<String> locations, Properties properties, Map<String, List<IPluginModelBase>> map) {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < locations.size(); i++) {
String location = locations.get(i);
@@ -338,11 +338,17 @@
* @param includeReference whether to prefix the url with 'reference:'
* @return string url for the bundle location
*/
- public static String getBundleURL(String id, Map<String, IPluginModelBase> pluginMap, boolean includeReference) {
- IPluginModelBase model = pluginMap.get(id.trim());
+ public static String getBundleURL(String id, Map<String, List<IPluginModelBase>> pluginMap, boolean includeReference) {
+ IPluginModelBase model = getLatestModel(id, pluginMap);
return getBundleURL(model, includeReference);
}
+
+ public static IPluginModelBase getLatestModel(String id, Map<String, List<IPluginModelBase>> plugins) {
+ List<IPluginModelBase> models = plugins.getOrDefault(id.trim(), Collections.emptyList());
+ return models.stream().max(BundleLauncherHelper.VERSION).orElse(null);
+ }
+
/**
* Returns a string url representing the install location of the given bundle model
* @param model the model to create the url for
@@ -367,7 +373,7 @@
* @param map map of bundles being launched (id mapped to model)
* @param properties properties for config.ini
*/
- private static void setBundleLocations(Map<String, IPluginModelBase> map, Properties properties, boolean defaultAuto) {
+ private static void setBundleLocations(Map<String, List<IPluginModelBase>> map, Properties properties, boolean defaultAuto) {
String framework = properties.getProperty(PROP_OSGI_FRAMEWORK);
if (framework != null) {
framework = TargetPlatformHelper.stripPathInformation(framework);
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchPluginValidator.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchPluginValidator.java
index 0df5b78..38943ed 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchPluginValidator.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LaunchPluginValidator.java
@@ -39,7 +39,7 @@
return models;
Collection<IPluginModelBase> result = null;
- Map<IPluginModelBase, String> bundles = BundleLauncherHelper.getWorkspaceBundleMap(configuration, null);
+ Map<IPluginModelBase, String> bundles = BundleLauncherHelper.getWorkspaceBundleMap(configuration);
result = bundles.keySet();
return result.toArray(new IPluginModelBase[result.size()]);
}
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LauncherUtils.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LauncherUtils.java
index 6d97912..4a9ecd2 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LauncherUtils.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/LauncherUtils.java
@@ -243,7 +243,7 @@
}
private static void handleSelectedPlugins(ILaunchConfiguration config, String timeStamp, ArrayList<IProject> projects) throws CoreException {
- Map<IPluginModelBase, String> selectedPlugins = BundleLauncherHelper.getWorkspaceBundleMap(config, null);
+ Map<IPluginModelBase, String> selectedPlugins = BundleLauncherHelper.getWorkspaceBundleMap(config);
Iterator<IPluginModelBase> it = selectedPlugins.keySet().iterator();
while (it.hasNext()) {
IPluginModelBase model = it.next();
@@ -258,7 +258,7 @@
}
private static void handleDeselectedPlugins(ILaunchConfiguration config, String launcherTimeStamp, ArrayList<IProject> projects) throws CoreException {
- Map<IPluginModelBase, String> deSelectedPlugins = BundleLauncherHelper.getWorkspaceBundleMap(config, null);
+ Map<IPluginModelBase, String> deSelectedPlugins = BundleLauncherHelper.getWorkspaceBundleMap(config);
IProject[] projs = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (int i = 0; i < projs.length; i++) {
if (!WorkspaceModelManager.isPluginProject(projs[i]))
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EclipseApplicationLaunchConfiguration.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EclipseApplicationLaunchConfiguration.java
index 2566aca..5a1e102 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EclipseApplicationLaunchConfiguration.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EclipseApplicationLaunchConfiguration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
+ * Copyright (c) 2005, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -16,6 +16,8 @@
import java.io.File;
import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.core.runtime.*;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
@@ -23,11 +25,10 @@
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.TargetPlatform;
-import org.eclipse.pde.internal.core.*;
+import org.eclipse.pde.internal.core.ClasspathHelper;
+import org.eclipse.pde.internal.core.TargetPlatformHelper;
import org.eclipse.pde.internal.core.util.CoreUtility;
-import org.eclipse.pde.internal.core.util.VersionUtil;
import org.eclipse.pde.internal.launching.launcher.*;
-import org.osgi.framework.Version;
/**
* A launch delegate for launching Eclipse applications
@@ -43,8 +44,8 @@
public class EclipseApplicationLaunchConfiguration extends AbstractPDELaunchConfiguration {
// used to generate the dev classpath entries
- // key is bundle ID, value is a model
- private Map<String, IPluginModelBase> fAllBundles;
+ // key is bundle ID, value is a List of models
+ private Map<String, List<IPluginModelBase>> fAllBundles;
// key is a model, value is startLevel:autoStart
private Map<IPluginModelBase, String> fModels;
@@ -95,11 +96,6 @@
// add the output folder names
programArgs.add("-dev"); //$NON-NLS-1$
programArgs.add(ClasspathHelper.getDevEntriesProperties(getConfigDir(configuration).toString() + "/dev.properties", fAllBundles)); //$NON-NLS-1$
- // necessary for PDE to know how to load plugins when target platform = host platform
- // see PluginPathFinder.getPluginPaths() and PluginPathFinder.isDevLaunchMode()
- IPluginModelBase base = fAllBundles.get(PDECore.PLUGIN_ID);
- if (base != null && VersionUtil.compareMacroMinorMicro(base.getBundleDescription().getVersion(), new Version("3.3.1")) < 0) //$NON-NLS-1$
- programArgs.add("-pdelaunch"); //$NON-NLS-1$
String[] args = super.getProgramArguments(configuration);
Collections.addAll(programArgs, args);
@@ -181,12 +177,8 @@
fWorkspaceLocation = null;
fModels = BundleLauncherHelper.getMergedBundleMap(configuration, false);
- fAllBundles = new HashMap<>(fModels.size());
- Iterator<IPluginModelBase> iter = fModels.keySet().iterator();
- while (iter.hasNext()) {
- IPluginModelBase model = iter.next();
- fAllBundles.put(model.getPluginBase().getId(), model);
- }
+ fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId()));
+
validateConfigIni(configuration);
super.preLaunchCheck(configuration, launch, monitor);
}
@@ -210,16 +202,9 @@
@Override
public String[] getVMArguments(ILaunchConfiguration configuration) throws CoreException {
String[] vmArgs = super.getVMArguments(configuration);
- IPluginModelBase base = fAllBundles.get(PDECore.PLUGIN_ID);
- if (base != null && VersionUtil.compareMacroMinorMicro(base.getBundleDescription().getVersion(), new Version("3.3.1")) >= 0) { //$NON-NLS-1$
- // necessary for PDE to know how to load plugins when target platform = host platform
- // see PluginPathFinder.getPluginPaths() and PluginPathFinder.isDevLaunchMode()
- String[] result = new String[vmArgs.length + 1];
- System.arraycopy(vmArgs, 0, result, 0, vmArgs.length);
- result[vmArgs.length] = "-Declipse.pde.launch=true"; //$NON-NLS-1$
- return result;
- }
- return vmArgs;
+ // necessary for PDE to know how to load plugins when target platform = host platform
+ // see PluginPathFinder.getPluginPaths() and PluginPathFinder.isDevLaunchMode()
+ return Stream.concat(Arrays.stream(vmArgs), Stream.of("-Declipse.pde.launch=true")).toArray(String[]::new); //$NON-NLS-1$
}
}
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EquinoxLaunchConfiguration.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EquinoxLaunchConfiguration.java
index 3dbd6e2..bff34e1 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EquinoxLaunchConfiguration.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/EquinoxLaunchConfiguration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -18,6 +18,7 @@
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
@@ -44,8 +45,8 @@
public class EquinoxLaunchConfiguration extends AbstractPDELaunchConfiguration {
// used to generate the dev classpath entries
- // key is bundle ID, value is a model
- protected Map<String, IPluginModelBase> fAllBundles;
+ // key is bundle ID, value is a List of models
+ protected Map<String, List<IPluginModelBase>> fAllBundles;
// key is a model, value is startLevel:autoStart
private Map<IPluginModelBase, String> fModels;
@@ -84,7 +85,7 @@
properties.setProperty("org.eclipse.equinox.simpleconfigurator.configUrl", bundlesTxt.toString()); //$NON-NLS-1$
}
StringBuilder buffer = new StringBuilder();
- IPluginModelBase model = fAllBundles.get(IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR);
+ IPluginModelBase model = LaunchConfigurationHelper.getLatestModel(IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR, fAllBundles);
buffer.append(LaunchConfigurationHelper.getBundleURL(model, true));
appendStartData(buffer, fModels.get(model), autostart);
bundles = buffer.toString();
@@ -152,19 +153,14 @@
@Override
protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) throws CoreException {
fModels = BundleLauncherHelper.getMergedBundleMap(configuration, true);
- fAllBundles = new HashMap<>(fModels.size());
- Iterator<IPluginModelBase> iter = fModels.keySet().iterator();
- while (iter.hasNext()) {
- IPluginModelBase model = iter.next();
- fAllBundles.put(model.getPluginBase().getId(), model);
- }
+ fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(), HashMap::new, Collectors.toCollection(ArrayList::new)));
if (!fAllBundles.containsKey(IPDEBuildConstants.BUNDLE_OSGI)) {
// implicitly add it
IPluginModelBase model = PluginRegistry.findModel(IPDEBuildConstants.BUNDLE_OSGI);
if (model != null) {
fModels.put(model, "default:default"); //$NON-NLS-1$
- fAllBundles.put(IPDEBuildConstants.BUNDLE_OSGI, model);
+ fAllBundles.computeIfAbsent(model.getPluginBase().getId(), i -> new ArrayList<>()).add(model);
} else {
String message = PDEMessages.EquinoxLaunchConfiguration_oldTarget;
throw new CoreException(Status.error(message));
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java
index ccbf7b5..73a10db 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java
@@ -19,6 +19,8 @@
import java.io.File;
import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.*;
@@ -33,7 +35,6 @@
import org.eclipse.pde.internal.core.util.VersionUtil;
import org.eclipse.pde.internal.launching.*;
import org.eclipse.pde.internal.launching.launcher.*;
-import org.osgi.framework.Version;
/**
* A launch delegate for launching JUnit Plug-in tests.
@@ -58,7 +59,7 @@
// used to generate the dev classpath entries
// key is bundle ID, value is a model
- private Map<String, IPluginModelBase> fAllBundles;
+ private Map<String, List<IPluginModelBase>> fAllBundles;
// key is a model, value is startLevel:autoStart
private Map<IPluginModelBase, String> fModels;
@@ -78,15 +79,29 @@
return "org.eclipse.core.launcher.Main"; //$NON-NLS-1$
}
- private String getTestPluginId(ILaunchConfiguration configuration) throws CoreException {
+ private IPluginBase getTestPlugin(ILaunchConfiguration configuration) throws CoreException {
IJavaProject javaProject = getJavaProject(configuration);
IPluginModelBase model = PluginRegistry.findModel(javaProject.getProject());
- if (model == null)
+ if (model == null) {
abort(NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_notaplugin, javaProject.getProject().getName()), null, IStatus.OK);
- if (model instanceof IFragmentModel)
- return ((IFragmentModel) model).getFragment().getPluginId();
+ }
+ if (model instanceof IFragmentModel) {
+ IFragment fragment = ((IFragmentModel) model).getFragment();
+ IPluginBase hostModel = getFragmentHostModel(fragment.getPluginId(), fragment.getPluginVersion(), fragment.getRule());
+ if (hostModel == null) {
+ abort(NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_missingPlugin, fragment.getPluginId()), null, IStatus.OK);
+ }
+ model = hostModel.getPluginModel();
+ }
+ return model.getPluginBase();
+ }
- return model.getPluginBase().getId();
+ private IPluginBase getFragmentHostModel(String hostId, String hostVersion, int hostVersionMatchRule) {
+ // return host plug-in model with matching version from bundles selected for launch
+ List<IPluginModelBase> hosts = fAllBundles.getOrDefault(hostId, Collections.emptyList());
+ Stream<IPluginBase> hostPlugins = hosts.stream().map(IPluginModelBase::getPluginBase);
+ return hostPlugins.filter(h -> VersionUtil.compare(h.getVersion(), hostVersion, hostVersionMatchRule)) //
+ .max(Comparator.comparing(IPluginBase::getVersion)).orElse(null);
}
@Override
@@ -143,7 +158,7 @@
// Create the platform configuration for the runtime workbench
String productID = LaunchConfigurationHelper.getProductID(configuration);
- String testPluginId = getTestPluginId(configuration);
+ IPluginBase testPlugin = getTestPlugin(configuration);
LaunchConfigurationHelper.createConfigIniFile(configuration, productID, fAllBundles, fModels, getConfigurationDirectory(configuration));
TargetPlatformHelper.checkPluginPropertiesConsistency(fAllBundles, getConfigurationDirectory(configuration));
@@ -162,7 +177,7 @@
.filter(IClasspathEntry::isTest)//
.filter(entry -> entry.getOutputLocation() != null).forEach(entry -> {
IPath relativePath = entry.getOutputLocation().removeFirstSegments(1).makeRelative();
- devProperties.merge(testPluginId, relativePath.toString(), (vOld, vNew) -> vOld + "," + vNew); //$NON-NLS-1$
+ ClasspathHelper.addDevClasspath(testPlugin, devProperties, relativePath.toString(), true);
});
}
programArgs.add(ClasspathHelper.writeDevEntries(getConfigurationDirectory(configuration).toString() + "/dev.properties", devProperties)); //$NON-NLS-1$
@@ -200,7 +215,7 @@
}
programArgs.add("-testpluginname"); //$NON-NLS-1$
- programArgs.add(testPluginId);
+ programArgs.add(testPlugin.getId());
IVMInstall launcher = VMHelper.createLauncher(configuration);
boolean isModular = JavaRuntime.isModularJava(launcher);
@@ -275,10 +290,7 @@
String vmArgs = LaunchArgumentsHelper.getUserVMArguments(configuration);
// necessary for PDE to know how to load plugins when target platform = host platform
- IPluginModelBase base = fAllBundles.get(PDECore.PLUGIN_ID);
- if (base != null && VersionUtil.compareMacroMinorMicro(base.getBundleDescription().getVersion(), new Version("3.3.1")) >= 0) { //$NON-NLS-1$
- vmArgs = concatArg(vmArgs, "-Declipse.pde.launch=true"); //$NON-NLS-1$
- }
+ vmArgs = concatArg(vmArgs, "-Declipse.pde.launch=true"); //$NON-NLS-1$
// For p2 target, add "-Declipse.p2.data.area=@config.dir/p2" unless already specified by user
if (fAllBundles.containsKey("org.eclipse.equinox.p2.core")) { //$NON-NLS-1$
if (!vmArgs.contains("-Declipse.p2.data.area=")) { //$NON-NLS-1$
@@ -394,12 +406,7 @@
fWorkspaceLocation = null;
fConfigDir = null;
fModels = BundleLauncherHelper.getMergedBundleMap(configuration, false);
- fAllBundles = new LinkedHashMap<>(fModels.size());
- Iterator<IPluginModelBase> iter = fModels.keySet().iterator();
- while (iter.hasNext()) {
- IPluginModelBase model = iter.next();
- fAllBundles.put(model.getPluginBase().getId(), model);
- }
+ fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(), LinkedHashMap::new, Collectors.toCollection(ArrayList::new)));
// implicitly add the plug-ins required for JUnit testing if necessary
String[] requiredPlugins = JUnitLaunchConfigurationDelegate.getRequiredPlugins(configuration);
@@ -407,7 +414,7 @@
String id = requiredPlugin;
if (!fAllBundles.containsKey(id)) {
IPluginModelBase model = findRequiredPluginInTargetOrHost(id);
- fAllBundles.put(id, model);
+ fAllBundles.computeIfAbsent(model.getPluginBase().getId(), i -> new ArrayList<>()).add(model);
fModels.put(model, "default:default"); //$NON-NLS-1$
}
}
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/classpathresolver/ClasspathResolverTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/classpathresolver/ClasspathResolverTest.java
index 36613d4..05bfc3b 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/classpathresolver/ClasspathResolverTest.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/classpathresolver/ClasspathResolverTest.java
@@ -122,6 +122,7 @@
String expectedDevCP = project.getFolder("cpe").getLocation().toPortableString();
assertEquals(expectedDevCP, properties.get(bundleName));
+ assertEquals(expectedDevCP, properties.get(bundleName + ";1.0.0.qualifier"));
}
/**
@@ -155,7 +156,8 @@
assertEquals("true", devProperties.getProperty("@ignoredot@"));
assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID + ";2.0.0"));
+ assertEquals(3, devProperties.size()); // assert no more entries
}
@Test
@@ -173,7 +175,8 @@
assertEquals("true", devProperties.getProperty("@ignoredot@"));
assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID + ";" + hostBundleVersion));
+ assertEquals(3, devProperties.size()); // assert no more entries
}
@Test
@@ -189,8 +192,9 @@
Properties devProperties = createDevEntryProperties(List.of(hostModel));
assertEquals("true", devProperties.getProperty("@ignoredot@"));
- assertEquals("devPath1", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("devPath2", devProperties.getProperty(HOST_BUNDLE_ID));
+ assertEquals("devPath2", devProperties.getProperty(HOST_BUNDLE_ID + ";" + hostBundleVersion));
+ assertEquals(3, devProperties.size()); // assert no more entries
}
@Test
@@ -247,8 +251,10 @@
Properties devProperties = createDevEntryProperties(List.of(hostModel, wsModel));
assertEquals("true", devProperties.getProperty("@ignoredot@"));
- assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID)); // last
+ assertEquals("", devProperties.getProperty(HOST_BUNDLE_ID + ";1.0.0"));
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID + ";2.0.0"));
+ assertEquals(4, devProperties.size()); // assert no more entries
}
@Test
@@ -266,8 +272,10 @@
Properties devProperties = createDevEntryProperties(List.of(tpModel, hostModel));
assertEquals("true", devProperties.getProperty("@ignoredot@"));
- assertEquals("devPath1", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("devPath2", devProperties.getProperty(HOST_BUNDLE_ID)); // last
+ assertEquals("", devProperties.getProperty(HOST_BUNDLE_ID + ";1.0.0"));
+ assertEquals("devPath2", devProperties.getProperty(HOST_BUNDLE_ID + ";" + hostBundleVersion));
+ assertEquals(4, devProperties.size()); // assert no more entries
}
@Test
@@ -284,8 +292,10 @@
Properties devProperties = createDevEntryProperties(List.of(hostModel, wsModel));
assertEquals("true", devProperties.getProperty("@ignoredot@"));
- assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID)); // last
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID + ";2.0.0"));
+ assertEquals("devPath2", devProperties.getProperty(HOST_BUNDLE_ID + ";" + hostBundleVersion));
+ assertEquals(4, devProperties.size()); // assert no more entries
}
@Test
@@ -301,11 +311,15 @@
IPluginModelBase tpModel = findTargetModel(HOST_BUNDLE_ID, "1.0.0");
IPluginModelBase wsModel = findWorkspaceModel(HOST_BUNDLE_ID, "2.0.0");
- Properties devProperties = createDevEntryProperties(List.of(hostModel, tpModel, wsModel));
+ Properties devProperties = createDevEntryProperties(List.of(hostModel, wsModel, tpModel));
assertEquals("true", devProperties.getProperty("@ignoredot@"));
+ // jar-bundle from tp should not be considered for non-version entry
assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID));
- assertEquals(2, devProperties.size()); // assert no more entries
+ assertEquals("", devProperties.getProperty(HOST_BUNDLE_ID + ";1.0.0"));
+ assertEquals("bin", devProperties.getProperty(HOST_BUNDLE_ID + ";2.0.0"));
+ assertEquals("devPath2", devProperties.getProperty(HOST_BUNDLE_ID + ";" + hostBundleVersion));
+ assertEquals(5, devProperties.size()); // assert no more entries
}
// --- utility methods ---
@@ -372,8 +386,7 @@
private Properties createDevEntryProperties(List<IPluginModelBase> launchedBundles)
throws IOException, CoreException {
File devPropertiesFile = tempFolder.newFile("dev.properties").getCanonicalFile();
- Map<String, IPluginModelBase> bundlesMap = Map.of(HOST_BUNDLE_ID,
- launchedBundles.get(launchedBundles.size() - 1));
+ Map<String, List<IPluginModelBase>> bundlesMap = Map.of(HOST_BUNDLE_ID, launchedBundles);
String devPropertiesURL = ClasspathHelper.getDevEntriesProperties(devPropertiesFile.getPath(), bundlesMap);
return loadProperties(devPropertiesURL);
}
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/LaunchConfigurationMigrationTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/LaunchConfigurationMigrationTest.java
index 8b57ff6..604baa1 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/LaunchConfigurationMigrationTest.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/LaunchConfigurationMigrationTest.java
@@ -47,13 +47,12 @@
assertOldPropertiesRemoved(wc);
- Map<IPluginModelBase, String> workspaceBundles = BundleLauncherHelper.getWorkspaceBundleMap(wc);
- assertEquals("default:true", workspaceBundles.get(findWorkspaceModel("org.eclipse.pde.plugin1", null)));
- assertEquals("3:false", workspaceBundles.get(findWorkspaceModel("org.eclipse.pde.plugin2", null)));
+ Map<IPluginModelBase, String> bundles = BundleLauncherHelper.getAllSelectedPluginBundles(wc);
+ assertEquals("default:true", bundles.get(findWorkspaceModel("org.eclipse.pde.plugin1", null)));
+ assertEquals("3:false", bundles.get(findWorkspaceModel("org.eclipse.pde.plugin2", null)));
- Map<IPluginModelBase, String> targetBundles = BundleLauncherHelper.getTargetBundleMap(wc);
- assertEquals("default:true", targetBundles.get(findTargetModel("org.eclipse.core.runtime", null)));
- assertEquals("2:false", targetBundles.get(findTargetModel("org.eclipse.ui", null)));
+ assertEquals("default:true", bundles.get(findTargetModel("org.eclipse.core.runtime", null)));
+ assertEquals("2:false", bundles.get(findTargetModel("org.eclipse.ui", null)));
}
@Test
@@ -66,12 +65,11 @@
assertOldPropertiesRemoved(wc);
- Map<IPluginModelBase, String> workspaceBundles = BundleLauncherHelper.getWorkspaceBundleMap(wc);
- assertEquals("default:default", workspaceBundles.get(findWorkspaceModel("org.eclipse.pde.plugin1", null)));
+ Map<IPluginModelBase, String> bundles = BundleLauncherHelper.getAllSelectedPluginBundles(wc);
+ assertEquals("default:default", bundles.get(findWorkspaceModel("org.eclipse.pde.plugin1", null)));
- Map<IPluginModelBase, String> targetBundles = BundleLauncherHelper.getTargetBundleMap(wc);
- assertEquals("default:true", targetBundles.get(findTargetModel("org.eclipse.core.runtime", null)));
- assertEquals("2:false", targetBundles.get(findTargetModel("org.eclipse.ui", null)));
+ assertEquals("default:true", bundles.get(findTargetModel("org.eclipse.core.runtime", null)));
+ assertEquals("2:false", bundles.get(findTargetModel("org.eclipse.ui", null)));
}
@Test
@@ -84,13 +82,12 @@
assertOldOsgiPropertiesRemoved(wc);
- Map<IPluginModelBase, String> workspaceBundles = BundleLauncherHelper.getWorkspaceBundleMap(wc);
- assertEquals("default:true", workspaceBundles.get(findWorkspaceModel("org.eclipse.pde.plugin1", null)));
- assertEquals("3:false", workspaceBundles.get(findWorkspaceModel("org.eclipse.pde.plugin2", null)));
+ Map<IPluginModelBase, String> bundles = BundleLauncherHelper.getAllSelectedPluginBundles(wc);
+ assertEquals("default:true", bundles.get(findWorkspaceModel("org.eclipse.pde.plugin1", null)));
+ assertEquals("3:false", bundles.get(findWorkspaceModel("org.eclipse.pde.plugin2", null)));
- Map<IPluginModelBase, String> targetBundles = BundleLauncherHelper.getTargetBundleMap(wc);
- assertEquals("default:true", targetBundles.get(findTargetModel("org.eclipse.core.runtime", null)));
- assertEquals("2:false", targetBundles.get(findTargetModel("org.eclipse.ui", null)));
+ assertEquals("default:true", bundles.get(findTargetModel("org.eclipse.core.runtime", null)));
+ assertEquals("2:false", bundles.get(findTargetModel("org.eclipse.ui", null)));
}
@SuppressWarnings("deprecation")
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/PluginBasedLaunchTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/PluginBasedLaunchTest.java
index 58e69c3..412d055 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/PluginBasedLaunchTest.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/PluginBasedLaunchTest.java
@@ -236,7 +236,6 @@
};
Set<BundleLocationDescriptor> expectedBundles = Set.of( //
- workspaceBundle("plugin.a", "1.0.0"), //
workspaceBundle("plugin.a", "2.0.0"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
@@ -549,7 +548,6 @@
wc.setAttribute(IPDELauncherConstants.SELECTED_TARGET_BUNDLES, Set.of("plugin.b"));
};
Set<BundleLocationDescriptor> expectedBundles = Set.of(//
- targetBundle("plugin.b", "1.0.0"), //
targetBundle("plugin.b", "2.0.0"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
@@ -586,12 +584,11 @@
Consumer<ILaunchConfigurationWorkingCopy> launchConfigSetup = wc -> {
wc.setAttribute(IPDELauncherConstants.SELECTED_TARGET_BUNDLES,
- Set.of("plugin.a*1.0.0.2020", "plugin.a*1.0.0.2021"));
- };
+ new LinkedHashSet<>(List.of("plugin.a*1.0.0.2020", "plugin.a*1.0.0.2021")));
+ }; // first entry is selected -> LinkedHashSet ensures its the same
Set<BundleLocationDescriptor> expectedBundles = Set.of( //
- targetBundle("plugin.a", "1.0.0.2020"), //
- targetBundle("plugin.a", "1.0.0.2021"));
+ targetBundle("plugin.a", "1.0.0.2020"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
}
@@ -615,7 +612,9 @@
Set<BundleLocationDescriptor> expectedBundles = Set.of( //
workspaceBundle("plugin.a", "1.0.0"), //
- workspaceBundle("plugin.b", "1.0.0"));
+ workspaceBundle("plugin.b", "1.0.0"), //
+ targetBundle("plugin.a", "1.0.1"), //
+ targetBundle("plugin.b", "2.0.0"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
}
@@ -637,7 +636,9 @@
Set<BundleLocationDescriptor> expectedBundles = Set.of( //
workspaceBundle("plugin.a", "1.0.0"), //
- workspaceBundle("plugin.b", "2.0.0"));
+ workspaceBundle("plugin.b", "2.0.0"), //
+ targetBundle("plugin.a", "1.0.1"), //
+ targetBundle("plugin.b", "3.0.0"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
}
@@ -655,7 +656,8 @@
};
Set<BundleLocationDescriptor> expectedBundles = Set.of( //
- workspaceBundle("plugin.a", "1.0.0"));
+ workspaceBundle("plugin.a", "1.0.0"), //
+ targetBundle("plugin.a", "1.0.2"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
}
@@ -702,7 +704,9 @@
Set<BundleLocationDescriptor> expectedBundles = Set.of( //
workspaceBundle("plugin.a", "1.0.0"), //
- workspaceBundle("plugin.b", "1.0.0"));
+ workspaceBundle("plugin.b", "1.0.0"), //
+ targetBundle("plugin.a", "1.0.1"), //
+ targetBundle("plugin.b", "1.0.1"));
assertGetMergedBundleMap(workspacePlugins, targetPlatformBundles, launchConfigSetup, expectedBundles);
}
@@ -770,7 +774,7 @@
IPluginModelBase plugin = targetBundle("plugin.a", "2.0.0").findModel();
String entry = BundleLauncherHelper.writeBundleEntry(plugin, null, null);
- assertEquals("plugin.a*2.0.0", entry);
+ assertEquals("plugin.a", entry);
}
@Test
@@ -785,7 +789,7 @@
IPluginModelBase plugin = targetBundle("plugin.a", "2.0.0").findModel();
String entry = BundleLauncherHelper.writeBundleEntry(plugin, null, null);
- assertEquals("plugin.a", entry);
+ assertEquals("plugin.a*2.0.0", entry);
}
@Test
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/OSGiBundleBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/OSGiBundleBlock.java
index 1cdb967..099e2ad 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/OSGiBundleBlock.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/OSGiBundleBlock.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
+ * Copyright (c) 2005, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,7 +14,6 @@
*******************************************************************************/
package org.eclipse.pde.internal.ui.launcher;
-import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
@@ -74,10 +73,7 @@
// TODO deal with the discrepency between save/init states of the two blocks
private void initializePluginsState(ILaunchConfiguration configuration) throws CoreException {
- Map<IPluginModelBase, String> selected = new HashMap<>();
- selected.putAll(BundleLauncherHelper.getWorkspaceBundleMap(configuration));
- selected.putAll(BundleLauncherHelper.getTargetBundleMap(configuration, null));
-
+ Map<IPluginModelBase, String> selected = BundleLauncherHelper.getAllSelectedPluginBundles(configuration);
initializePluginsState(selected);
}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/PluginBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/PluginBlock.java
index cb64cc6..3d355a6 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/PluginBlock.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/PluginBlock.java
@@ -94,10 +94,7 @@
}
private void initializePluginsState(ILaunchConfiguration config) throws CoreException {
- Map<IPluginModelBase, String> selected = new HashMap<>();
- selected.putAll(BundleLauncherHelper.getWorkspaceBundleMap(config, null));
- selected.putAll(BundleLauncherHelper.getTargetBundleMap(config, null));
-
+ Map<IPluginModelBase, String> selected = BundleLauncherHelper.getAllSelectedPluginBundles(config);
initializePluginsState(selected);
}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizard.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizard.java
index 64d9655..3514189 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizard.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizard.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,7 +14,8 @@
*******************************************************************************/
package org.eclipse.pde.internal.ui.wizards.imports;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Map;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.*;
@@ -140,9 +141,8 @@
if (configuration == null)
continue;
try {
- Map<?, ?> workspaceBundleMap = BundleLauncherHelper.getWorkspaceBundleMap(configuration);
- for (Object key : workspaceBundleMap.keySet()) {
- IPluginModelBase bm = (IPluginModelBase) key;
+ var workspaceBundles = BundleLauncherHelper.getWorkspaceBundleMap(configuration).keySet();
+ for (IPluginModelBase bm : workspaceBundles) {
BundleDescription description = bm.getBundleDescription();
if (description != null) {
if (imported.contains(description.getSymbolicName())) {
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/product/ProductFromConfigOperation.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/product/ProductFromConfigOperation.java
index 0226657..3d798fe 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/product/ProductFromConfigOperation.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/product/ProductFromConfigOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
+ * Copyright (c) 2005, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -74,9 +74,7 @@
}
// fetch the plug-ins models
- Set<String> set = new HashSet<>();
- Map<IPluginModelBase, String> map = BundleLauncherHelper.getWorkspaceBundleMap(fLaunchConfiguration, set);
- map.putAll(BundleLauncherHelper.getTargetBundleMap(fLaunchConfiguration, set));
+ Map<IPluginModelBase, String> map = BundleLauncherHelper.getAllSelectedPluginBundles(fLaunchConfiguration);
addPlugins(factory, product, map);
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/EquinoxLaunchConfiguration.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/EquinoxLaunchConfiguration.java
index fa3c30b..cf36dde 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/EquinoxLaunchConfiguration.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/EquinoxLaunchConfiguration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -18,6 +18,7 @@
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
@@ -47,8 +48,8 @@
public class EquinoxLaunchConfiguration extends AbstractPDELaunchConfiguration {
// used to generate the dev classpath entries
- // key is bundle ID, value is a model
- protected Map<String, IPluginModelBase> fAllBundles;
+ // key is bundle ID, value is a List of models
+ protected Map<String, List<IPluginModelBase>> fAllBundles;
// key is a model, value is startLevel:autoStart
private Map<IPluginModelBase, String> fModels;
@@ -86,7 +87,7 @@
properties.setProperty("org.eclipse.equinox.simpleconfigurator.configUrl", bundlesTxt.toString()); //$NON-NLS-1$
}
StringBuilder buffer = new StringBuilder();
- IPluginModelBase model = fAllBundles.get(IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR);
+ IPluginModelBase model = LaunchConfigurationHelper.getLatestModel(IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR, fAllBundles);
buffer.append(LaunchConfigurationHelper.getBundleURL(model, true));
appendStartData(buffer, fModels.get(model), autostart);
bundles = buffer.toString();
@@ -154,19 +155,15 @@
@Override
protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) throws CoreException {
fModels = BundleLauncherHelper.getMergedBundleMap(configuration, true);
- fAllBundles = new HashMap<>(fModels.size());
- Iterator<IPluginModelBase> iter = fModels.keySet().iterator();
- while (iter.hasNext()) {
- IPluginModelBase model = iter.next();
- fAllBundles.put(model.getPluginBase().getId(), model);
- }
+ fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(),
+ HashMap::new, Collectors.toCollection(ArrayList::new)));
if (!fAllBundles.containsKey(IPDEBuildConstants.BUNDLE_OSGI)) {
// implicitly add it
IPluginModelBase model = PluginRegistry.findModel(IPDEBuildConstants.BUNDLE_OSGI);
if (model != null) {
fModels.put(model, "default:default"); //$NON-NLS-1$
- fAllBundles.put(IPDEBuildConstants.BUNDLE_OSGI, model);
+ fAllBundles.computeIfAbsent(IPDEBuildConstants.BUNDLE_OSGI, i -> new ArrayList<>()).add(model);
} else {
String message = PDEMessages.EquinoxLaunchConfiguration_oldTarget;
throw new CoreException(Status.error((String) message));
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java
index 0887671..807e90a 100644
--- a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java
@@ -26,15 +26,14 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.plugin.IFragmentModel;
@@ -46,7 +45,6 @@
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.TargetPlatformHelper;
import org.eclipse.pde.internal.core.util.CoreUtility;
-import org.eclipse.pde.internal.core.util.VersionUtil;
import org.eclipse.pde.internal.launching.IPDEConstants;
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
import org.eclipse.pde.internal.launching.launcher.EclipsePluginValidationOperation;
@@ -361,12 +359,8 @@
fWorkspaceLocation = null;
fConfigDir = null;
fModels = BundleLauncherHelper.getMergedBundleMap(configuration, false);
- fAllBundles = new LinkedHashMap<>(fModels.size());
- Iterator<IPluginModelBase> iter = fModels.keySet().iterator();
- while (iter.hasNext()) {
- IPluginModelBase model = iter.next();
- fAllBundles.put(model.getPluginBase().getId(), model);
- }
+ fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(),
+ LinkedHashMap::new, Collectors.toCollection(ArrayList::new)));
// implicitly add the plug-ins required for JUnit testing if necessary
String[] requiredPlugins = getRequiredPlugins(configuration);
@@ -374,7 +368,7 @@
String id = requiredPlugin;
if (!fAllBundles.containsKey(id)) {
IPluginModelBase model = findRequiredPluginInTargetOrHost(id);
- fAllBundles.put(id, model);
+ fAllBundles.computeIfAbsent(id, i -> new ArrayList<>()).add(model);
fModels.put(model, "default:default"); //$NON-NLS-1$
}
}
@@ -988,7 +982,7 @@
// used to generate the dev classpath entries
// key is bundle ID, value is a model
- private Map<String, IPluginModelBase> fAllBundles;
+ private Map<String, List<IPluginModelBase>> fAllBundles;
// key is a model, value is startLevel:autoStart
private Map<IPluginModelBase, String> fModels;
@@ -1079,11 +1073,7 @@
// necessary for PDE to know how to load plugins when target platform = host
// platform
- IPluginModelBase base = fAllBundles.get(PDECore.PLUGIN_ID);
- if (base != null && VersionUtil.compareMacroMinorMicro(base.getBundleDescription().getVersion(),
- new Version("3.3.1")) >= 0) { //$NON-NLS-1$
- vmArgs = concatArg(vmArgs, "-Declipse.pde.launch=true"); //$NON-NLS-1$
- }
+ vmArgs = concatArg(vmArgs, "-Declipse.pde.launch=true"); //$NON-NLS-1$
// For p2 target, add "-Declipse.p2.data.area=@config.dir/p2" unless already
// specified by user
if (fAllBundles.containsKey("org.eclipse.equinox.p2.core")) { //$NON-NLS-1$