From 9f50735a8b0f73e9ef73bdabfb1dcefaad55f4f2 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sat, 19 Dec 2020 20:50:14 +0100 Subject: [PATCH] [JENKINS-64445] - Fix null safety for plugin categories (#5121) * [JENKINS-64445] - Fix null safety for plugin categories * Update core/src/main/java/hudson/model/UpdateSite.java Co-authored-by: Ramon Leon * Update core/src/main/java/hudson/model/UpdateSite.java Co-authored-by: Ramon Leon --- core/src/main/java/hudson/PluginManager.java | 18 +++------- .../main/java/hudson/model/UpdateSite.java | 33 +++++++++++++++---- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index d2d3269276..0c388c1db2 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -1363,8 +1363,8 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas return StringUtils.containsIgnoreCase(plugin.name, query) || StringUtils.containsIgnoreCase(plugin.title, query) || StringUtils.containsIgnoreCase(plugin.excerpt, query) || - Arrays.asList(plugin.categories).contains(query) || - Arrays.stream(plugin.categories) + plugin.hasCategory(query) || + plugin.getCategoriesStream() .map(UpdateCenter::getCategoryDisplayName) .anyMatch(category -> StringUtils.containsIgnoreCase(category, query)) || plugin.hasWarnings() && query.equalsIgnoreCase("warning:"); @@ -1396,7 +1396,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas jsonObject.put("title", plugin.title); jsonObject.put("displayName", plugin.getDisplayName()); jsonObject.put("wiki", plugin.wiki); - jsonObject.put("categories", Arrays.stream(plugin.categories) + jsonObject.put("categories", plugin.getCategoriesStream() .filter(PluginManager::isNonMetaLabel) .map(UpdateCenter::getCategoryDisplayName) .collect(toList()) @@ -2406,11 +2406,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas @Restricted(DoNotUse.class) // Used from table.jelly public boolean hasAdoptThisPluginLabel(UpdateSite.Plugin plugin) { - final String[] categories = plugin.categories; - if (categories == null) { - return false; - } - return Arrays.asList(categories).contains("adopt-this-plugin"); + return plugin.hasCategory("adopt-this-plugin"); } @Restricted(DoNotUse.class) // Used from table.jelly @@ -2427,11 +2423,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas if (pluginMeta == null) { return false; } - final String[] categories = pluginMeta.categories; - if (categories == null) { - return false; - } - return Arrays.asList(categories).contains("adopt-this-plugin"); + return pluginMeta.hasCategory("adopt-this-plugin"); } /** diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java index 5174756bb2..3f69bcf69e 100644 --- a/core/src/main/java/hudson/model/UpdateSite.java +++ b/core/src/main/java/hudson/model/UpdateSite.java @@ -66,6 +66,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Stream; + import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -626,11 +628,9 @@ public class UpdateSite { // compatibility with update sites that have no separate 'deprecated' top-level entry. // Also do this even if there are deprecations to potentially allow limiting the top-level entry to overridden URLs. - if (p.categories != null) { - if (Arrays.asList(p.categories).contains("deprecated")) { - if (!this.deprecations.containsKey(p.name)) { - this.deprecations.put(p.name, new Deprecation(p.wiki)); - } + if (p.hasCategory("deprecated")) { + if (!this.deprecations.containsKey(p.name)) { + this.deprecations.put(p.name, new Deprecation(p.wiki)); } } } @@ -1091,9 +1091,10 @@ public class UpdateSite { public final String minimumJavaVersion; /** * Categories for grouping plugins, taken from labels assigned to wiki page. - * Can be null. + * Can be {@code null} if the update center does not return categories. */ @Exported + @CheckForNull public final String[] categories; /** @@ -1510,6 +1511,26 @@ public class UpdateSite { return warnings; } + /** + * Checks whether a plugin has a desired category + * @since TODO + */ + public boolean hasCategory(String category) { + if (categories == null) { + return false; + } + // TODO: cache it in a hashset for performance improvements + return Arrays.asList(categories).contains(category); + } + + /** + * Get categories stream for further search. + * @since TODO + */ + public Stream getCategoriesStream() { + return categories != null ? Arrays.stream(categories) : Stream.empty(); + } + /** * @since 2.40 */