Bug 575112 - improve runtime behavior of PluginRegistry.findModels()

Change-Id: I293217f9d23f72b24dff748d30a04c84b454216a
Signed-off-by: Hannes Wellmann <wellmann.hannes1@gmx.net>
Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/183469
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/core/plugin/PluginRegistry.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/PluginRegistry.java
index f4b4cfe..e847358 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
@@ -222,29 +222,6 @@
 	}
 
 	/**
-	 * Returns whether the given model matches the given id, version, and match rule.
-	 *
-	 * @param base match candidate
-	 * @param id id to match
-	 * @param version version to match or <code>null</code>
-	 * @param match version match rule
-	 * @return whether the model is a match
-	 */
-	private static boolean isMatch(IPluginBase base, String id, String version, int match) {
-		// if version is null, then match any version with same ID
-		if (base == null) {
-			return false; // guard against invalid plug-ins
-		}
-		if (base.getId() == null) {
-			return false; // guard against invalid plug-ins
-		}
-		if (version == null) {
-			return base.getId().equals(id);
-		}
-		return VersionUtil.compare(base.getId(), base.getVersion(), id, version, match);
-	}
-
-	/**
 	 * Returns a model matching the given id, version, match rule, and optional
 	 * filter, or <code>null</code> if none.
 	 * <p>
@@ -304,14 +281,19 @@
 	 * @since 3.6
 	 */
 	public static IPluginModelBase[] findModels(String id, String version, int match, PluginFilter filter) {
-		IPluginModelBase[] models = PluginRegistry.getAllModels();
+		IPluginModelBase[] models = findModels(id);
 		List<IPluginModelBase> results = new ArrayList<>();
 		for (IPluginModelBase model : models) {
-			if ((filter == null || filter.accept(model)) && isMatch(model.getPluginBase(), id, version, match)) {
+			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(new IPluginModelBase[results.size()]);
+		return results.toArray(IPluginModelBase[]::new);
 	}
 
 	/**
@@ -390,10 +372,10 @@
 	 * @since 3.6
 	 */
 	public static IPluginModelBase[] findModels(String id, VersionRange range, PluginFilter filter) {
-		IPluginModelBase[] models = PluginRegistry.getAllModels();
+		IPluginModelBase[] models = findModels(id);
 		List<IPluginModelBase> results = new ArrayList<>();
 		for (IPluginModelBase model : models) {
-			if ((filter == null || filter.accept(model)) && id.equals(model.getPluginBase().getId())) {
+			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)) {
@@ -401,7 +383,15 @@
 				}
 			}
 		}
-		return results.toArray(new IPluginModelBase[results.size()]);
+		return results.toArray(IPluginModelBase[]::new);
+	}
+
+	private static IPluginModelBase[] findModels(String id) {
+		ModelEntry entry = PluginRegistry.findEntry(id);
+		if (entry != null) {
+			return entry.hasWorkspaceModels() ? entry.getWorkspaceModels() : entry.getExternalModels();
+		}
+		return new IPluginModelBase[0];
 	}
 
 	/**
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 1a0e019..14ea45a 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, 2013 IBM Corporation and others.
+ *  Copyright (c) 2006, 2021 IBM Corporation and others.
  *
  *  This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License 2.0
@@ -22,6 +22,9 @@
 
 public class VersionUtil {
 
+	private VersionUtil() { // static use only
+	}
+
 	public static IStatus validateVersion(String versionString) {
 		try {
 			if (versionString != null) {
@@ -46,22 +49,27 @@
 		if (!(id1.equals(id2))) {
 			return false;
 		}
+		return compare(version1, version2, match);
+	}
+
+	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 :
+			switch (match)
+				{
+				case IMatchRules.NONE:
+				case IMatchRules.COMPATIBLE:
 					return isCompatibleWith(v1, v2);
-				case IMatchRules.EQUIVALENT :
+				case IMatchRules.EQUIVALENT:
 					return isEquivalentTo(v1, v2);
-				case IMatchRules.PERFECT :
+				case IMatchRules.PERFECT:
 					return v1.equals(v2);
-				case IMatchRules.GREATER_OR_EQUAL :
+				case IMatchRules.GREATER_OR_EQUAL:
 					return isGreaterOrEqualTo(v1, v2);
-			}
-		} catch (RuntimeException e) {
+				}
+		} catch (RuntimeException e) { // ignore
 		}
 		return version1.equals(version2);
 	}