From 80ab9c5ffe3aec51e0ed4461383afc751d9981cd Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Sun, 14 Jul 2024 23:19:03 +0200 Subject: [PATCH 1/2] Add VersionMatchRule enum as replacement for IMatchRules interface --- .../eclipse/pde/core/plugin/IMatchRules.java | 13 +- .../pde/core/plugin/PluginRegistry.java | 2 +- .../pde/core/plugin/VersionMatchRule.java | 112 ++++++++++++++++++ .../pde/internal/core/util/VersionUtil.java | 86 +++----------- 4 files changed, 136 insertions(+), 77 deletions(-) create mode 100644 ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/VersionMatchRule.java diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/IMatchRules.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/IMatchRules.java index 6c90d2b9c2..eb5717d3dd 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/IMatchRules.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/IMatchRules.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -14,10 +14,13 @@ package org.eclipse.pde.core.plugin; /** - * This interface contains constants used throughout the plug-in - * for plug-in reference matching. These rules are used to - * control when determining if two compared versions are - * equivalent. + * This interface contains constants used throughout the plug-in for plug-in + * reference matching. These rules are used to control when determining if two + * compared versions are equivalent. + * + *

+ * New code should use {@link VersionMatchRule} instead. + *

* * @noimplement This interface is not intended to be implemented by clients. * @noextend This interface is not intended to be extended by clients. diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java index 8764c950b8..69236ab345 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java @@ -365,7 +365,7 @@ private static IPluginModelBase getMax(IPluginModelBase[] models) { max = model; maxV = version; } else { - if (VersionUtil.isGreaterOrEqualTo(version, maxV)) { + if (VersionMatchRule.GREATER_OR_EQUAL.matches(version, maxV)) { max = model; maxV = version; } diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/VersionMatchRule.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/VersionMatchRule.java new file mode 100644 index 0000000000..33f085d65e --- /dev/null +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/VersionMatchRule.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2024, 2024 Hannes Wellmann and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Hannes Wellmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.core.plugin; + +import org.osgi.framework.Version; +import org.osgi.framework.VersionRange; + +/** + * @since 3.19 + */ +public enum VersionMatchRule { + /** No rule. */ + NONE("none") { //$NON-NLS-1$ // TODO: check this?! + @Override + public VersionRange rangeFor(Version reference) { + // TODO: or include all range? + return COMPATIBLE.rangeFor(reference); + } + + @Override + public boolean matches(Version version, Version reference) { + // TODO: or always true? + return COMPATIBLE.matches(version, reference); + } + }, + /** + * A rule that matches if a version is equivalent to a reference. + */ + EQUIVALENT("equivalent") { //$NON-NLS-1$ + @Override + public VersionRange rangeFor(Version reference) { + Version upperBound = new Version(reference.getMajor(), reference.getMinor() + 1, 0); + return new VersionRange(VersionRange.LEFT_CLOSED, reference, upperBound, VersionRange.RIGHT_OPEN); + } + + @Override + public boolean matches(Version version, Version reference) { + return version.getMajor() == reference.getMajor() && version.getMinor() == reference.getMinor() + && version.compareTo(reference) >= 0; + } + }, + /** + * A rule that matches if a version is compatible to a reference. + */ + COMPATIBLE("compatible") { //$NON-NLS-1$ + @Override + public VersionRange rangeFor(Version reference) { + Version upperBound = new Version(reference.getMajor() + 1, 0, 0); + return new VersionRange(VersionRange.LEFT_CLOSED, reference, upperBound, VersionRange.RIGHT_OPEN); + } + + @Override + public boolean matches(Version version, Version reference) { + return version.getMajor() == reference.getMajor() && version.compareTo(reference) >= 0; + } + }, + /** + * A rule that matches if a version is perfectly + * {@link Version#equals(Object) equals} to a reference. + */ + PERFECT("perfect") { //$NON-NLS-1$ + @Override + public VersionRange rangeFor(Version reference) { + return new VersionRange(VersionRange.LEFT_CLOSED, reference, reference, VersionRange.RIGHT_CLOSED); + } + + @Override + public boolean matches(Version version, Version reference) { + return reference.equals(version); + } + }, + /** + * A rule that matches if a version is greater or equal to a reference. + */ + GREATER_OR_EQUAL("greaterOrEqual") { //$NON-NLS-1$ + @Override + public VersionRange rangeFor(Version reference) { + return new VersionRange(VersionRange.LEFT_CLOSED, reference, null, VersionRange.RIGHT_OPEN); + } + + @Override + public boolean matches(Version version, Version reference) { + return version.compareTo(reference) >= 0; + } + }; + + private final String name; + + VersionMatchRule(String name) { + this.name = name; + } + + public abstract VersionRange rangeFor(Version version); + + public abstract boolean matches(Version version, Version reference); + + @Override + public String toString() { + return name; + } +} diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java index b0aa81a7f9..73333edbd7 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2021 IBM Corporation and others. + * Copyright (c) 2006, 2024 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,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.pde.core.plugin.IMatchRules; +import org.eclipse.pde.core.plugin.VersionMatchRule; import org.osgi.framework.Version; import org.osgi.framework.VersionRange; @@ -44,23 +45,22 @@ public static IStatus validateVersionRange(String versionRangeString) { return Status.OK_STATUS; } + public static VersionMatchRule matchRuleFromLiteral(int literal) { + return switch (literal) { + case IMatchRules.NONE -> VersionMatchRule.NONE; + case IMatchRules.EQUIVALENT -> VersionMatchRule.EQUIVALENT; + case IMatchRules.COMPATIBLE -> VersionMatchRule.COMPATIBLE; + case IMatchRules.PERFECT -> VersionMatchRule.PERFECT; + case IMatchRules.GREATER_OR_EQUAL -> VersionMatchRule.GREATER_OR_EQUAL; + default -> throw new IllegalArgumentException("Unsupported match rule literal: " + literal); //$NON-NLS-1 + }; + } + public static boolean compare(String version1, String version2, int match) { try { Version v1 = Version.parseVersion(version1); Version v2 = Version.parseVersion(version2); - - switch (match) - { - case IMatchRules.NONE: - case IMatchRules.COMPATIBLE: - return isCompatibleWith(v1, v2); - case IMatchRules.EQUIVALENT: - return isEquivalentTo(v1, v2); - case IMatchRules.PERFECT: - return v1.equals(v2); - case IMatchRules.GREATER_OR_EQUAL: - return isGreaterOrEqualTo(v1, v2); - } + return matchRuleFromLiteral(match).matches(v1, v2); } catch (RuntimeException e) { // ignore } return version1.equals(version2); @@ -82,69 +82,15 @@ public static boolean isEmptyVersion(String version) { return version.length() == 0 || version.equals(Version.emptyVersion.toString()); } - public static boolean isCompatibleWith(Version v1, Version v2) { - if (v1.getMajor() != v2.getMajor()) { - return false; - } - if (v1.getMinor() > v2.getMinor()) { - return true; - } - if (v1.getMinor() < v2.getMinor()) { - return false; - } - if (v1.getMicro() > v2.getMicro()) { - return true; - } - if (v1.getMicro() < v2.getMicro()) { - return false; - } - return v1.getQualifier().compareTo(v2.getQualifier()) >= 0; - } - - public static boolean isEquivalentTo(Version v1, Version v2) { - if (v1.getMajor() != v2.getMajor() || v1.getMinor() != v2.getMinor()) { - return false; - } - if (v1.getMicro() > v2.getMicro()) { - return true; - } - if (v1.getMicro() < v2.getMicro()) { - return false; - } - return v1.getQualifier().compareTo(v2.getQualifier()) >= 0; - } - - public static boolean isGreaterOrEqualTo(Version v1, Version v2) { - if (v1.getMajor() > v2.getMajor()) { - return true; - } - if (v1.getMajor() == v2.getMajor()) { - if (v1.getMinor() > v2.getMinor()) { - return true; - } - if (v1.getMinor() == v2.getMinor()) { - if (v1.getMicro() > v2.getMicro()) { - return true; - } - if (v1.getMicro() == v2.getMicro()) { - return v1.getQualifier().compareTo(v2.getQualifier()) >= 0; - } - } - } - return false; - } - public static int compareMacroMinorMicro(Version v1, Version v2) { int result = v1.getMajor() - v2.getMajor(); if (result != 0) { return result; } - result = v1.getMinor() - v2.getMinor(); if (result != 0) { return result; } - result = v1.getMicro() - v2.getMicro(); return result; } @@ -152,10 +98,8 @@ public static int compareMacroMinorMicro(Version v1, Version v2) { public static String computeInitialPluginVersion(String version) { if (version != null && VersionUtil.validateVersion(version).isOK()) { Version pvi = Version.parseVersion(version); - return pvi.getMajor() + "." + pvi.getMinor() //$NON-NLS-1$ - + "." + pvi.getMicro(); //$NON-NLS-1$ + return pvi.getMajor() + "." + pvi.getMinor() + "." + pvi.getMicro(); //$NON-NLS-1$//$NON-NLS-2$ } - return version; } From f6d15ecdead9b6f0dc5b5b38ee938b7595f25580 Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Wed, 16 Feb 2022 22:38:06 +0100 Subject: [PATCH 2/2] Rework PluginRegistry API and replace Equinox resolver's VersionRange Besides replacing the Equinox resolver VersionRange by the osgi VersionRange, this also remove the rarely used filter parameter from the findModel(s)() methods. Instead of a List the findModels() methods now return a stream that can also be filtered if desired. In all cases plug-ins with null IPluginBase or ID are now discarded. Part of https://github.com/eclipse-pde/eclipse.pde/issues/1069 --- .../.settings/.api_filters | 8 + .../pde/core/plugin/PluginRegistry.java | 208 ++++++++++-------- .../pde/internal/core/util/VersionUtil.java | 16 ++ .../ui/tests/project/PluginRegistryTests.java | 2 +- 4 files changed, 141 insertions(+), 93 deletions(-) diff --git a/ui/org.eclipse.pde.core/.settings/.api_filters b/ui/org.eclipse.pde.core/.settings/.api_filters index f26c3f1cfb..6afc70c004 100644 --- a/ui/org.eclipse.pde.core/.settings/.api_filters +++ b/ui/org.eclipse.pde.core/.settings/.api_filters @@ -1,5 +1,13 @@ + + + + + + + + diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java index 69236ab345..df791bd43d 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java @@ -13,21 +13,22 @@ *******************************************************************************/ package org.eclipse.pde.core.plugin; -import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Stream; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.osgi.service.resolver.BundleDescription; -import org.eclipse.osgi.service.resolver.VersionRange; import org.eclipse.pde.core.build.IBuildModel; import org.eclipse.pde.internal.core.PDECore; import org.eclipse.pde.internal.core.build.WorkspaceBuildModel; import org.eclipse.pde.internal.core.project.PDEProject; import org.eclipse.pde.internal.core.util.VersionUtil; import org.osgi.framework.Version; +import org.osgi.framework.VersionRange; import org.osgi.resource.Resource; /** @@ -45,15 +46,24 @@ */ public class PluginRegistry { + private PluginRegistry() { // static use only + } + /** * Filter used when searching for plug-in models. *

* Clients may subclass this class to implement custom filters. *

- * @see PluginRegistry#findModel(String, String, int, PluginFilter) - * @see PluginRegistry#findModel(String, VersionRange, PluginFilter) + * + * @see PluginRegistry#findModels(String, String, VersionMatchRule) + * @see PluginRegistry#findModels(String, VersionRange) * @since 3.6 + * @deprecated Instead use {@link Predicate} and filter the stream returned + * by + * {@link PluginRegistry#findModels(String, String, VersionMatchRule)} + * or {@link PluginRegistry#findModels(String, VersionRange)} */ + @Deprecated(forRemoval = true, since = "3.19 (removal in 2026-09 or later)") public static class PluginFilter { /** @@ -68,6 +78,10 @@ public boolean accept(IPluginModelBase model) { } + private static Predicate asPredicate(PluginFilter filter) { + return filter != null ? filter::accept : p -> true; + } + /** * Returns a model entry containing all workspace and target plug-ins by the given ID * @@ -126,7 +140,7 @@ public static IPluginModelBase findModel(IProject project) { * null if none exists * @deprecated Instead use {@link #findModel(Resource)} */ - @Deprecated(forRemoval = true) + @Deprecated(forRemoval = true, since = "3.18 (removal in 2026-06 or later)") public static IPluginModelBase findModel(BundleDescription desc) { return findModel((Resource) desc); } @@ -242,8 +256,8 @@ public static IPluginModelBase[] getExternalModels() { } /** - * Returns a model matching the given id, version, match rule, and optional - * filter, or null if none. + * Returns a model matching the given id, version, match rule, or + * null if none. *

* A workspace plug-in is always preferably returned over a target plug-in. * A plug-in that is checked/enabled on the Target Platform preference page @@ -264,61 +278,79 @@ public static IPluginModelBase[] getExternalModels() { * @param version * minimum version, or null to only match on * symbolic name - * @param match - * one of {@link IMatchRules#COMPATIBLE}, - * {@link IMatchRules#EQUIVALENT}, - * {@link IMatchRules#GREATER_OR_EQUAL}, - * {@link IMatchRules#PERFECT}, or {@link IMatchRules#NONE} when - * a version is unspecified - * @param filter - * a plug-in filter or null + * @param matchRule + * the {@link VersionMatchRule match rule} a plug-in's version + * must fulfill with respect to the specified reference version + * in order to be selected. May not be null. * * @return a matching model or null + * @since 3.19 + */ + public static IPluginModelBase findModel(String id, String version, VersionMatchRule matchRule) { + return findModels(id, version, matchRule).findFirst().orElse(null); + } + + /** + * @see #findModel(String, String, VersionMatchRule) + * @see #findModels(String, String, VersionMatchRule) * @since 3.6 + * @deprecated If no filter is passed use + * {@link #findModel(String, String, VersionMatchRule)}, else + * filter the {@code Stream} returned by + * {@link #findModels(String, String, VersionMatchRule)}. */ + @Deprecated(forRemoval = true, since = "3.19 (removal in 2026-09 or later)") public static IPluginModelBase findModel(String id, String version, int match, PluginFilter filter) { - return getMax(findModels(id, version, match, filter)); + VersionMatchRule rule = VersionUtil.matchRuleFromLiteral(match); + return findModels(id, version, rule).filter(asPredicate(filter)).findFirst().orElse(null); } /** - * Returns all models matching the given id, version, match rule, and optional filter. + * Returns all models matching the given id, version and match rule sorted + * by descending version. *

- * Target (external) plug-ins/fragments with the same ID as workspace counterparts are not - * considered. + * Target (external) plug-ins/fragments with the same ID as workspace + * counterparts are not considered. *

*

- * Returns plug-ins regardless of whether they are checked/enabled or unchecked/disabled - * on the Target Platform preference page. + * Returns plug-ins regardless of whether they are checked/enabled or + * unchecked/disabled on the Target Platform preference page. *

- * @param id symbolic name of a plug-ins to find - * @param version minimum version, or null to only match on symbolic name - * @param match one of {@link IMatchRules#COMPATIBLE}, {@link IMatchRules#EQUIVALENT}, - * {@link IMatchRules#GREATER_OR_EQUAL}, {@link IMatchRules#PERFECT}, or {@link IMatchRules#NONE} - * when a version is unspecified - * @param filter a plug-in filter or null + * + * @param id + * symbolic name of a plug-ins to find + * @param version + * minimum version, or null to only match on + * symbolic name + * @param matchRule + * the {@link VersionMatchRule match rule} a plug-in's version + * must fulfill with respect to the specified reference version + * in order to be selected. May not be null. * * @return a matching models, possibly an empty collection + * @since 3.19 + */ + public static Stream findModels(String id, String version, VersionMatchRule matchRule) { + Version reference = version != null ? Version.valueOf(version) : null; + return selectModels(id, version != null ? p -> matchRule.matches(VersionUtil.getVersion(p), reference) : null); + } + + /** + * @see #findModels(String, String, VersionMatchRule) * @since 3.6 + * @deprecated Instead use + * {@link #findModels(String, String, VersionMatchRule)} and + * filter the returned {@code Stream} if a filter is passed. */ + @Deprecated(forRemoval = true, since = "3.19 (removal in 2026-09 or later)") public static IPluginModelBase[] findModels(String id, String version, int match, PluginFilter filter) { - IPluginModelBase[] models = findModels(id); - List results = new ArrayList<>(); - for (IPluginModelBase model : models) { - IPluginBase base = model.getPluginBase(); - if (base == null || base.getId() == null) { - continue; // guard against invalid plug-ins - } - if ((filter == null || filter.accept(model)) - && (version == null || VersionUtil.compare(base.getVersion(), version, match))) { - results.add(model); - } - } - return results.toArray(IPluginModelBase[]::new); + VersionMatchRule rule = VersionUtil.matchRuleFromLiteral(match); + return findModels(id, version, rule).filter(asPredicate(filter)).toArray(IPluginModelBase[]::new); } /** - * Returns a model matching the given id, version range, and optional filter, - * or null if none. + * Returns a model matching the given id, version range, or + * null if none. *

* A workspace plug-in is always preferably returned over a target plug-in. * A plug-in that is checked/enabled on the Target Platform preference page is always @@ -334,48 +366,31 @@ public static IPluginModelBase[] findModels(String id, String version, int match *

* @param id symbolic name of plug-in to find * @param range acceptable version range to match, or null for any range - * @param filter a plug-in filter or null * * @return a matching model or null - * @since 3.6 + * @since 3.19 */ - public static IPluginModelBase findModel(String id, VersionRange range, PluginFilter filter) { - return getMax(findModels(id, range, filter)); + public static IPluginModelBase findModel(String id, VersionRange range) { + return findModels(id, range).findFirst().orElse(null); } /** - * Returns the plug-in with the highest version, or null if empty. - * - * @param models models - * @return plug-in with the highest version or null + * @see #findModel(String, VersionRange) + * @since 3.6 + * @deprecated If no filter is passed use + * {@link #findModel(String, VersionRange)}, else filter the + * {@code Stream} returned by + * {@link #findModels(String, VersionRange)}. */ - private static IPluginModelBase getMax(IPluginModelBase[] models) { - if (models.length == 0) { - return null; - } - if (models.length == 1) { - return models[0]; - } - IPluginModelBase max = null; - Version maxV = null; - for (IPluginModelBase model : models) { - String versionStr = model.getPluginBase().getVersion(); - Version version = VersionUtil.validateVersion(versionStr).isOK() ? new Version(versionStr) : Version.emptyVersion; - if (max == null) { - max = model; - maxV = version; - } else { - if (VersionMatchRule.GREATER_OR_EQUAL.matches(version, maxV)) { - max = model; - maxV = version; - } - } - } - return max; + @Deprecated(forRemoval = true, since = "3.19 (removal in 2026-09 or later)") + public static IPluginModelBase findModel(String id, org.eclipse.osgi.service.resolver.VersionRange range, + PluginFilter filter) { + return findModels(id, range).filter(asPredicate(filter)).findFirst().orElse(null); } /** - * Returns all models matching the given id, version range, and optional filter. + * Returns all models matching the given id and version range sorted by + * descending version. *

* Target (external) plug-ins/fragments with the same ID as workspace counterparts are not * considered. @@ -386,32 +401,41 @@ private static IPluginModelBase getMax(IPluginModelBase[] models) { *

* @param id symbolic name of plug-ins to find * @param range acceptable version range to match, or null for any range - * @param filter a plug-in filter or null * * @return a matching models, possibly empty + * @since 3.19 + */ + public static Stream findModels(String id, VersionRange range) { + return selectModels(id, range != null ? p -> range.includes(VersionUtil.getVersion(p)) : null); + } + + /** + * @see #findModels(String, VersionRange) * @since 3.6 + * @deprecated Instead use {@link #findModels(String, VersionRange)} and + * filter the returned {@code Stream} if a filter is passed. */ - public static IPluginModelBase[] findModels(String id, VersionRange range, PluginFilter filter) { - IPluginModelBase[] models = findModels(id); - List results = new ArrayList<>(); - for (IPluginModelBase model : models) { - if (filter == null || filter.accept(model)) { - String versionStr = model.getPluginBase().getVersion(); - Version version = VersionUtil.validateVersion(versionStr).isOK() ? new Version(versionStr) : Version.emptyVersion; - if (range == null || range.isIncluded(version)) { - results.add(model); - } - } - } - return results.toArray(IPluginModelBase[]::new); + @Deprecated(forRemoval = true, since = "3.19 (removal in 2026-09 or later)") + public static IPluginModelBase[] findModels(String id, org.eclipse.osgi.service.resolver.VersionRange range, + PluginFilter filter) { + return findModels(id, range).filter(asPredicate(filter)).toArray(IPluginModelBase[]::new); } - private static IPluginModelBase[] findModels(String id) { + private static Stream selectModels(String id, Predicate versionFilter) { ModelEntry entry = PluginRegistry.findEntry(id); - if (entry != null) { - return entry.hasWorkspaceModels() ? entry.getWorkspaceModels() : entry.getExternalModels(); + if (entry == null) { + return Stream.empty(); + } + List models = entry.hasWorkspaceModels() ? entry.fWorkspaceEntries : entry.fExternalEntries; + Stream plugins = models.stream().filter(m -> { + IPluginBase base = m.getPluginBase(); + // guard against invalid plug-ins + return base != null && base.getId() != null; + }); + if (versionFilter != null) { + plugins = plugins.filter(versionFilter); } - return new IPluginModelBase[0]; + return plugins.sorted(VersionUtil.BY_DESCENDING_PLUGIN_VERSION); } /** diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java index 73333edbd7..84378a58e3 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/VersionUtil.java @@ -10,12 +10,16 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Hannes Wellmann - Rework PluginRegistry API and replace Equinox resolver's VersionRange *******************************************************************************/ package org.eclipse.pde.internal.core.util; +import java.util.Comparator; + import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.pde.core.plugin.IMatchRules; +import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.core.plugin.VersionMatchRule; import org.osgi.framework.Version; import org.osgi.framework.VersionRange; @@ -45,6 +49,18 @@ public static IStatus validateVersionRange(String versionRangeString) { return Status.OK_STATUS; } + public static final Comparator BY_DESCENDING_PLUGIN_VERSION = Comparator + .comparing(VersionUtil::getVersion).reversed(); + + public static Version getVersion(IPluginModelBase model) { + String version = model.getPluginBase().getVersion(); + try { + return Version.parseVersion(version); + } catch (IllegalArgumentException e) { + } + return Version.emptyVersion; + } + public static VersionMatchRule matchRuleFromLiteral(int literal) { return switch (literal) { case IMatchRules.NONE -> VersionMatchRule.NONE; diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/project/PluginRegistryTests.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/project/PluginRegistryTests.java index 32d32468b2..d4a3b60188 100644 --- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/project/PluginRegistryTests.java +++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/project/PluginRegistryTests.java @@ -85,7 +85,7 @@ public void testMatchPrefix() { @Test public void testRangeNone() { - IPluginModelBase model = PluginRegistry.findModel("org.eclipse.jdt.debug", null, null); + IPluginModelBase model = PluginRegistry.findModel("org.eclipse.jdt.debug", null, (PluginFilter) null); assertNotNull(model); assertEquals("org.eclipse.jdt.debug", model.getPluginBase().getId()); }