You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PluginWSCommons.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.plugins.ws;
  21. import com.google.common.collect.ImmutableMap;
  22. import com.google.common.collect.Maps;
  23. import com.google.common.collect.Ordering;
  24. import java.util.Collections;
  25. import java.util.Comparator;
  26. import java.util.List;
  27. import java.util.Optional;
  28. import javax.annotation.Nullable;
  29. import org.sonar.core.platform.PluginInfo;
  30. import org.sonar.db.plugin.PluginDto;
  31. import org.sonar.server.plugins.ServerPlugin;
  32. import org.sonar.server.plugins.UpdateCenterMatrixFactory;
  33. import org.sonar.updatecenter.common.Artifact;
  34. import org.sonar.updatecenter.common.Plugin;
  35. import org.sonar.updatecenter.common.PluginUpdate;
  36. import org.sonar.updatecenter.common.UpdateCenter;
  37. import org.sonarqube.ws.Plugins.PluginDetails;
  38. import org.sonarqube.ws.Plugins.Release;
  39. import org.sonarqube.ws.Plugins.Require;
  40. import org.sonarqube.ws.Plugins.UpdateStatus;
  41. import static java.lang.String.CASE_INSENSITIVE_ORDER;
  42. import static java.util.Optional.ofNullable;
  43. import static org.apache.commons.lang.StringUtils.isNotBlank;
  44. import static org.sonar.api.utils.DateUtils.formatDate;
  45. import static org.sonar.server.plugins.edition.EditionBundledPlugins.isEditionBundled;
  46. import static org.sonarqube.ws.Plugins.UpdateStatus.COMPATIBLE;
  47. import static org.sonarqube.ws.Plugins.UpdateStatus.DEPS_REQUIRE_SYSTEM_UPGRADE;
  48. import static org.sonarqube.ws.Plugins.UpdateStatus.INCOMPATIBLE;
  49. import static org.sonarqube.ws.Plugins.UpdateStatus.REQUIRES_SYSTEM_UPGRADE;
  50. public class PluginWSCommons {
  51. public static final Ordering<PluginInfo> NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural()
  52. .onResultOf(PluginInfo::getName)
  53. .compound(Ordering.natural().onResultOf(PluginInfo::getKey));
  54. public static final Comparator<ServerPlugin> NAME_KEY_COMPARATOR = Comparator
  55. .comparing((java.util.function.Function<ServerPlugin, String>) installedPluginFile -> installedPluginFile.getPluginInfo().getName())
  56. .thenComparing(f -> f.getPluginInfo().getKey());
  57. public static final Comparator<Plugin> NAME_KEY_PLUGIN_ORDERING = Ordering.from(CASE_INSENSITIVE_ORDER)
  58. .onResultOf(Plugin::getName)
  59. .compound(
  60. Ordering.from(CASE_INSENSITIVE_ORDER).onResultOf(Artifact::getKey));
  61. public static final Comparator<PluginUpdate> NAME_KEY_PLUGIN_UPDATE_ORDERING = Ordering.from(NAME_KEY_PLUGIN_ORDERING)
  62. .onResultOf(PluginUpdate::getPlugin);
  63. private PluginWSCommons() {
  64. // prevent instantiation
  65. }
  66. public static PluginDetails buildPluginDetails(@Nullable ServerPlugin installedPlugin, PluginInfo pluginInfo,
  67. @Nullable PluginDto pluginDto, @Nullable Plugin updateCenterPlugin) {
  68. PluginDetails.Builder builder = PluginDetails.newBuilder()
  69. .setKey(pluginInfo.getKey())
  70. .setName(pluginInfo.getName())
  71. .setEditionBundled(isEditionBundled(pluginInfo))
  72. .setSonarLintSupported(pluginInfo.isSonarLintSupported());
  73. ofNullable(installedPlugin).ifPresent(serverPlugin -> {
  74. builder.setFilename(installedPlugin.getJar().getFile().getName());
  75. builder.setHash(installedPlugin.getJar().getMd5());
  76. builder.setType(installedPlugin.getType().name());
  77. });
  78. ofNullable(pluginInfo.getVersion()).ifPresent(v -> builder.setVersion(isNotBlank(pluginInfo.getDisplayVersion()) ? pluginInfo.getDisplayVersion() : v.getName()));
  79. ofNullable(updateCenterPlugin).flatMap(p -> ofNullable(p.getCategory())).ifPresent(builder::setCategory);
  80. ofNullable(pluginDto).ifPresent(p -> builder.setUpdatedAt(p.getUpdatedAt()));
  81. ofNullable(pluginInfo.getDescription()).ifPresent(builder::setDescription);
  82. ofNullable(pluginInfo.getLicense()).ifPresent(builder::setLicense);
  83. ofNullable(pluginInfo.getOrganizationName()).ifPresent(builder::setOrganizationName);
  84. ofNullable(pluginInfo.getOrganizationUrl()).ifPresent(builder::setOrganizationUrl);
  85. ofNullable(pluginInfo.getHomepageUrl()).ifPresent(builder::setHomepageUrl);
  86. ofNullable(pluginInfo.getIssueTrackerUrl()).ifPresent(builder::setIssueTrackerUrl);
  87. ofNullable(pluginInfo.getImplementationBuild()).ifPresent(builder::setImplementationBuild);
  88. ofNullable(pluginInfo.getDocumentationPath()).ifPresent(builder::setDocumentationPath);
  89. builder.addAllRequiredForLanguages(pluginInfo.getRequiredForLanguages());
  90. return builder.build();
  91. }
  92. static Release buildRelease(org.sonar.updatecenter.common.Release release) {
  93. String version = isNotBlank(release.getDisplayVersion()) ? release.getDisplayVersion() : release.getVersion().toString();
  94. Release.Builder releaseBuilder = Release.newBuilder().setVersion(version);
  95. ofNullable(release.getDate()).ifPresent(date -> releaseBuilder.setDate(formatDate(date)));
  96. ofNullable(release.getChangelogUrl()).ifPresent(releaseBuilder::setChangeLogUrl);
  97. ofNullable(release.getDescription()).ifPresent(releaseBuilder::setDescription);
  98. return releaseBuilder.build();
  99. }
  100. static List<Require> buildRequires(PluginUpdate pluginUpdate) {
  101. return pluginUpdate.getRelease().getOutgoingDependencies().stream().map(
  102. org.sonar.updatecenter.common.Release::getArtifact)
  103. .filter(Plugin.class::isInstance)
  104. .map(Plugin.class::cast)
  105. .map(artifact -> {
  106. Require.Builder builder = Require.newBuilder()
  107. .setKey(artifact.getKey());
  108. ofNullable(artifact.getName()).ifPresent(builder::setName);
  109. ofNullable(artifact.getDescription()).ifPresent(builder::setDescription);
  110. return builder.build();
  111. })
  112. .toList();
  113. }
  114. static UpdateStatus convertUpdateCenterStatus(PluginUpdate.Status status) {
  115. switch (status) {
  116. case COMPATIBLE:
  117. return COMPATIBLE;
  118. case INCOMPATIBLE:
  119. return INCOMPATIBLE;
  120. case REQUIRE_SONAR_UPGRADE:
  121. return REQUIRES_SYSTEM_UPGRADE;
  122. case DEPENDENCIES_REQUIRE_SONAR_UPGRADE:
  123. return DEPS_REQUIRE_SYSTEM_UPGRADE;
  124. default:
  125. throw new IllegalArgumentException("Unsupported value of PluginUpdate.Status " + status);
  126. }
  127. }
  128. private static List<Plugin> compatiblePlugins(UpdateCenterMatrixFactory updateCenterMatrixFactory) {
  129. Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(false);
  130. return updateCenter.isPresent() ? updateCenter.get().findAllCompatiblePlugins() : Collections.emptyList();
  131. }
  132. static ImmutableMap<String, Plugin> compatiblePluginsByKey(UpdateCenterMatrixFactory updateCenterMatrixFactory) {
  133. List<Plugin> compatiblePlugins = compatiblePlugins(updateCenterMatrixFactory);
  134. return Maps.uniqueIndex(compatiblePlugins, Artifact::getKey);
  135. }
  136. }