From 0afbb1a75b53220acced6dc9213b3d3d297a9df7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 20 Apr 2015 13:53:02 +0200 Subject: [PATCH] SONAR-6383 SONAR-6376 factor plugin WSs code into PluginWSCommons class share constants for JSON properties and some objects share PluginMetadata class to JSON writing share PluginMetadata ordering --- .../server/platform/ServerComponents.java | 22 +-- .../plugins/ws/AvailablePluginsWsAction.java | 56 ++++---- .../plugins/ws/InstalledPluginsWsAction.java | 100 ++------------ .../plugins/ws/PendingPluginsWsAction.java | 52 ++----- .../server/plugins/ws/PluginWSCommons.java | 114 ++++++++++++++++ .../plugins/ws/example-pending_plugins.json | 18 ++- .../ws/InstalledPluginsWsActionTest.java | 106 +++++++-------- .../ws/PendingPluginsWsActionTest.java | 48 ++++--- .../plugins/ws/PluginWSCommonsTest.java | 127 ++++++++++++++++++ 9 files changed, 391 insertions(+), 252 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 392d4294672..37c4f3c2687 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -219,6 +219,7 @@ import org.sonar.server.plugins.UpdateCenterMatrixFactory; import org.sonar.server.plugins.ws.AvailablePluginsWsAction; import org.sonar.server.plugins.ws.InstalledPluginsWsAction; import org.sonar.server.plugins.ws.PendingPluginsWsAction; +import org.sonar.server.plugins.ws.PluginWSCommons; import org.sonar.server.plugins.ws.PluginsWs; import org.sonar.server.properties.ProjectSettingsFactory; import org.sonar.server.qualitygate.QgateProjectFinder; @@ -875,18 +876,19 @@ class ServerComponents { // System pico.addSingletons(Arrays.asList( - SystemRestartWsAction.class, - SystemInfoWsAction.class, - SystemWs.class, - SystemMonitor.class, - SonarQubeMonitor.class, - EsMonitor.class, - PluginsMonitor.class, - JvmPropertiesMonitor.class, - DatabaseMonitor.class - )); + SystemRestartWsAction.class, + SystemInfoWsAction.class, + SystemWs.class, + SystemMonitor.class, + SonarQubeMonitor.class, + EsMonitor.class, + PluginsMonitor.class, + JvmPropertiesMonitor.class, + DatabaseMonitor.class + )); // Plugins WS + pico.addSingleton(PluginWSCommons.class); pico.addSingleton(InstalledPluginsWsAction.class); pico.addSingleton(AvailablePluginsWsAction.class); pico.addSingleton(PendingPluginsWsAction.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java index 0d9a949efcd..cc465f64426 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java @@ -31,27 +31,28 @@ import org.sonar.updatecenter.common.Plugin; import org.sonar.updatecenter.common.PluginUpdate; import org.sonar.updatecenter.common.Release; +import javax.annotation.Nullable; import java.util.List; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; +import static org.sonar.server.plugins.ws.PluginWSCommons.OBJECT_ARTIFACT; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_DATE; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_DESCRIPTION; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_KEY; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_NAME; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_ORGANIZATION_NAME; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_ORGANIZATION_URL; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_STATUS; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_TERMS_AND_CONDITIONS_URL; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_URL; +import static org.sonar.server.plugins.ws.PluginWSCommons.PROPERTY_VERSION; public class AvailablePluginsWsAction implements PluginsWsAction { private static final boolean DO_NOT_FORCE_REFRESH = false; - private static final String PROPERTY_KEY = "key"; - private static final String PROPERTY_NAME = "name"; - private static final String PROPERTY_DESCRIPTION = "description"; - private static final String PROPERTY_ORGANIZATION_NAME = "organizationName"; - private static final String PROPERTY_ORGANIZATION_URL = "organizationUrl"; - private static final String PROPERTY_URL = "url"; - private static final String PROPERTY_TERMS_AND_CONDITIONS_URL = "termsAndConditionsUrl"; private static final String OBJECT_UPDATE = "update"; - private static final String OBJECT_ARTIFACT = "artifact"; private static final String OBJECT_RELEASE = "release"; - private static final String PROPERTY_VERSION = "version"; - private static final String PROPERTY_DATE = "date"; - private static final String PROPERTY_STATUS = "status"; private static final String ARRAY_REQUIRES = "requires"; private static final String ARRAY_PLUGINS = "plugins"; private static final String PROPERTY_CATEGORY = "category"; @@ -66,7 +67,7 @@ public class AvailablePluginsWsAction implements PluginsWsAction { @Override public void define(WebService.NewController controller) { controller.createAction("available") - .setDescription("Get the list of all the plugins available for installation on the SonarQube instance, sorted by name." + + .setDescription("Get the list of all the plugins available for installation on the SonarQube instance, sorted by plugin name." + "
" + "Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]") .setSince("5.2") @@ -94,18 +95,15 @@ public class AvailablePluginsWsAction implements PluginsWsAction { jsonWriter.endObject(); } + private List retrieveAvailablePlugins() { + return updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH).findAvailablePlugins(); + } + private void writePluginUpdate(JsonWriter jsonWriter, PluginUpdate pluginUpdate) { jsonWriter.beginObject(); Plugin plugin = pluginUpdate.getPlugin(); - jsonWriter.prop(PROPERTY_KEY, plugin.getKey()); - jsonWriter.prop(PROPERTY_NAME, plugin.getName()); - jsonWriter.prop(PROPERTY_CATEGORY, plugin.getCategory()); - jsonWriter.prop(PROPERTY_DESCRIPTION, plugin.getDescription()); - jsonWriter.prop(PROPERTY_LICENSE, plugin.getLicense()); - jsonWriter.prop(PROPERTY_TERMS_AND_CONDITIONS_URL, plugin.getTermsConditionsUrl()); - jsonWriter.prop(PROPERTY_ORGANIZATION_NAME, plugin.getOrganization()); - jsonWriter.prop(PROPERTY_ORGANIZATION_URL, plugin.getOrganizationUrl()); + writeMetadata(jsonWriter, plugin); writeRelease(jsonWriter, pluginUpdate.getRelease()); @@ -114,8 +112,15 @@ public class AvailablePluginsWsAction implements PluginsWsAction { jsonWriter.endObject(); } - private List retrieveAvailablePlugins() { - return updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH).findAvailablePlugins(); + private void writeMetadata(JsonWriter jsonWriter, Plugin plugin) { + jsonWriter.prop(PROPERTY_KEY, plugin.getKey()); + jsonWriter.prop(PROPERTY_NAME, plugin.getName()); + jsonWriter.prop(PROPERTY_CATEGORY, plugin.getCategory()); + jsonWriter.prop(PROPERTY_DESCRIPTION, plugin.getDescription()); + jsonWriter.prop(PROPERTY_LICENSE, plugin.getLicense()); + jsonWriter.prop(PROPERTY_TERMS_AND_CONDITIONS_URL, plugin.getTermsConditionsUrl()); + jsonWriter.prop(PROPERTY_ORGANIZATION_NAME, plugin.getOrganization()); + jsonWriter.prop(PROPERTY_ORGANIZATION_URL, plugin.getOrganizationUrl()); } private void writeRelease(JsonWriter jsonWriter, Release release) { @@ -146,7 +151,7 @@ public class AvailablePluginsWsAction implements PluginsWsAction { for (Plugin child : filter(transform(release.getOutgoingDependencies(), ReleaseToArtifact.INSTANCE), Plugin.class)) { jsonWriter.beginObject(); jsonWriter.prop(PROPERTY_KEY, child.getKey()); - jsonWriter.prop(AvailablePluginsWsAction.PROPERTY_NAME, child.getName()); + jsonWriter.prop(PROPERTY_NAME, child.getName()); jsonWriter.prop(PROPERTY_DESCRIPTION, child.getDescription()); jsonWriter.endObject(); } @@ -174,7 +179,10 @@ public class AvailablePluginsWsAction implements PluginsWsAction { INSTANCE; @Override - public Artifact apply(Release input) { + public Artifact apply(@Nullable Release input) { + if (input == null) { + return null; + } return input.getArtifact(); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java index a93bf04e013..c84b730c96c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java @@ -19,10 +19,8 @@ */ package org.sonar.server.plugins.ws; -import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.Ordering; import com.google.common.io.Resources; import org.sonar.api.platform.PluginMetadata; import org.sonar.api.platform.PluginRepository; @@ -36,38 +34,27 @@ import java.util.Collection; import java.util.SortedSet; import static com.google.common.collect.Iterables.filter; +import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; /** * Implementation of the {@code installed} action for the Plugins WebService. */ public class InstalledPluginsWsAction implements PluginsWsAction { - private static final String PROPERTY_KEY = "key"; - private static final String PROPERTY_NAME = "name"; - private static final String PROPERTY_DESCRIPTION = "description"; - private static final String PROPERTY_LICENSE = "license"; - private static final String PROPERTY_VERSION = "version"; private static final String ARRAY_PLUGINS = "plugins"; - private static final String PROPERTY_ORGANIZATION_NAME = "organizationName"; - private static final String PROPERTY_ORGANIZATION_URL = "organizationUrl"; - private static final String OBJECT_URLS = "urls"; - private static final String PROPERTY_HOMEPAGE = "homepage"; - private static final String PROPERTY_ISSUE_TRACKER = "issueTracker"; - private static final String OBJECT_ARTIFACT = "artifact"; private final PluginRepository pluginRepository; + private final PluginWSCommons pluginWSCommons; - public static final Ordering NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural() - .onResultOf(PluginMetadataToName.INSTANCE) - .compound(Ordering.natural().onResultOf(PluginMetadataToKey.INSTANCE)); - - public InstalledPluginsWsAction(PluginRepository pluginRepository) { + public InstalledPluginsWsAction(PluginRepository pluginRepository, + PluginWSCommons pluginWSCommons) { this.pluginRepository = pluginRepository; + this.pluginWSCommons = pluginWSCommons; } @Override public void define(WebService.NewController controller) { controller.createAction("installed") - .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by name") + .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name") .setSince("5.2") .setHandler(this) .setResponseExample(Resources.getResource(this.getClass(), "example-installed_plugins.json")); @@ -95,53 +82,12 @@ public class InstalledPluginsWsAction implements PluginsWsAction { } private void writeMetadataList(JsonWriter jsonWriter, Collection pluginMetadatas) { - jsonWriter.name(ARRAY_PLUGINS); - jsonWriter.beginArray(); - for (PluginMetadata pluginMetadata : pluginMetadatas) { - writePluginMetadata(jsonWriter, pluginMetadata); - } - jsonWriter.endArray(); - } - - private void writePluginMetadata(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - jsonWriter.beginObject(); - - writeMetadata(jsonWriter, pluginMetadata); - - writeUrls(jsonWriter, pluginMetadata); - - writeArtifact(jsonWriter, pluginMetadata); - - jsonWriter.endObject(); - } - - private void writeMetadata(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - jsonWriter.prop(PROPERTY_KEY, pluginMetadata.getKey()); - jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getName()); - jsonWriter.prop(PROPERTY_DESCRIPTION, pluginMetadata.getDescription()); - jsonWriter.prop(PROPERTY_VERSION, pluginMetadata.getVersion()); - jsonWriter.prop(PROPERTY_LICENSE, pluginMetadata.getLicense()); - jsonWriter.prop(PROPERTY_ORGANIZATION_NAME, pluginMetadata.getOrganization()); - jsonWriter.prop(PROPERTY_ORGANIZATION_URL, pluginMetadata.getOrganizationUrl()); - } - - private void writeUrls(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - jsonWriter.name(OBJECT_URLS); - jsonWriter.beginObject(); - jsonWriter.prop(PROPERTY_HOMEPAGE, pluginMetadata.getHomepage()); - jsonWriter.prop(PROPERTY_ISSUE_TRACKER, pluginMetadata.getIssueTrackerUrl()); - jsonWriter.endObject(); - } - - private void writeArtifact(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - if (pluginMetadata.getFile() == null) { - return; + jsonWriter.name(ARRAY_PLUGINS); + jsonWriter.beginArray(); + for (PluginMetadata pluginMetadata : pluginMetadatas) { + pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); } - - jsonWriter.name(OBJECT_ARTIFACT); - jsonWriter.beginObject(); - jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getFile().getName()); - jsonWriter.endObject(); + jsonWriter.endArray(); } private enum NotCorePluginsPredicate implements Predicate { @@ -152,28 +98,4 @@ public class InstalledPluginsWsAction implements PluginsWsAction { return input != null && !input.isCore(); } } - - private enum PluginMetadataToName implements Function { - INSTANCE; - - @Override - public String apply(@Nullable PluginMetadata input) { - if (input == null) { - return null; - } - return input.getName(); - } - } - - private enum PluginMetadataToKey implements Function { - INSTANCE; - - @Override - public String apply(@Nullable PluginMetadata input) { - if (input == null) { - return null; - } - return input.getKey(); - } - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java index 22147405287..8c55caeaf68 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java @@ -29,11 +29,10 @@ import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.ServerPluginJarsInstaller; import java.util.Collection; -import java.util.List; import static com.google.common.collect.ImmutableSortedSet.copyOf; import static com.google.common.io.Resources.getResource; -import static org.sonar.server.plugins.ws.InstalledPluginsWsAction.NAME_KEY_PLUGIN_METADATA_COMPARATOR; +import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; /** * Implementation of the {@code pending} action for the Plugins WebService. @@ -42,21 +41,23 @@ public class PendingPluginsWsAction implements PluginsWsAction { private static final String ARRAY_INSTALLING = "installing"; private static final String ARRAY_REMOVING = "removing"; - private static final String OBJECT_ARTIFACT = "artifact"; - private static final String PROPERTY_NAME = "name"; private final PluginDownloader pluginDownloader; private final ServerPluginJarsInstaller serverPluginJarsInstaller; + private final PluginWSCommons pluginWSCommons; - public PendingPluginsWsAction(PluginDownloader pluginDownloader, ServerPluginJarsInstaller serverPluginJarsInstaller) { + public PendingPluginsWsAction(PluginDownloader pluginDownloader, + ServerPluginJarsInstaller serverPluginJarsInstaller, + PluginWSCommons pluginWSCommons) { this.pluginDownloader = pluginDownloader; this.serverPluginJarsInstaller = serverPluginJarsInstaller; + this.pluginWSCommons = pluginWSCommons; } @Override public void define(WebService.NewController controller) { controller.createAction("pending") - .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by archive name") + .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by plugin name") .setSince("5.2") .setHandler(this) .setResponseExample(getResource(this.getClass(), "example-pending_plugins.json")); @@ -79,9 +80,9 @@ public class PendingPluginsWsAction implements PluginsWsAction { private void writeInstalling(JsonWriter jsonWriter) { jsonWriter.name(ARRAY_INSTALLING); jsonWriter.beginArray(); - List plugins = pluginDownloader.getDownloadedPlugins(); + Collection plugins = pluginDownloader.getDownloadedPlugins(); for (PluginMetadata pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { - writePlugin(jsonWriter, pluginMetadata); + pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); } jsonWriter.endArray(); } @@ -91,42 +92,9 @@ public class PendingPluginsWsAction implements PluginsWsAction { jsonWriter.beginArray(); Collection plugins = serverPluginJarsInstaller.getUninstalledPlugins(); for (PluginMetadata pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { - writePlugin(jsonWriter, pluginMetadata); + pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); } jsonWriter.endArray(); } - private void writePlugin(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - jsonWriter.beginObject(); - - writeMetadata(jsonWriter, pluginMetadata); - - jsonWriter.prop("homepageUrl", pluginMetadata.getHomepage()); - jsonWriter.prop("issueTrackerUrl", pluginMetadata.getIssueTrackerUrl()); - - writeArchive(jsonWriter, pluginMetadata); - - jsonWriter.endObject(); - } - - private void writeMetadata(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - jsonWriter.prop("key", pluginMetadata.getKey()); - jsonWriter.prop("name", pluginMetadata.getName()); - jsonWriter.prop("description", pluginMetadata.getDescription()); - jsonWriter.prop("version", pluginMetadata.getVersion()); - jsonWriter.prop("license", pluginMetadata.getLicense()); - jsonWriter.prop("organizationName", pluginMetadata.getOrganization()); - jsonWriter.prop("organizationUrl", pluginMetadata.getOrganizationUrl()); - } - - private void writeArchive(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { - if (pluginMetadata.getFile() == null) { - return; - } - - jsonWriter.name(OBJECT_ARTIFACT); - jsonWriter.beginObject(); - jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getFile().getName()); - jsonWriter.endObject(); - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java new file mode 100644 index 00000000000..65cee10963d --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java @@ -0,0 +1,114 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.plugins.ws; + +import com.google.common.base.Function; +import com.google.common.collect.Ordering; +import org.sonar.api.platform.PluginMetadata; +import org.sonar.api.utils.text.JsonWriter; + +import javax.annotation.Nullable; + +public class PluginWSCommons { + static final String PROPERTY_KEY = "key"; + static final String PROPERTY_NAME = "name"; + static final String PROPERTY_DESCRIPTION = "description"; + static final String PROPERTY_LICENSE = "license"; + static final String PROPERTY_VERSION = "version"; + static final String PROPERTY_ORGANIZATION_NAME = "organizationName"; + static final String PROPERTY_ORGANIZATION_URL = "organizationUrl"; + static final String PROPERTY_DATE = "date"; + static final String PROPERTY_STATUS = "status"; + static final String OBJECT_URLS = "urls"; + static final String PROPERTY_HOMEPAGE = "homepage"; + static final String PROPERTY_ISSUE_TRACKER = "issueTracker"; + static final String OBJECT_ARTIFACT = "artifact"; + static final String PROPERTY_URL = "url"; + static final String PROPERTY_TERMS_AND_CONDITIONS_URL = "termsAndConditionsUrl"; + + public static final Ordering NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural() + .onResultOf(PluginMetadataToName.INSTANCE) + .compound(Ordering.natural().onResultOf(PluginMetadataToKey.INSTANCE)); + + public void writePluginMetadata(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { + jsonWriter.beginObject(); + + writeMetadata(jsonWriter, pluginMetadata); + + writeUrls(jsonWriter, pluginMetadata); + + writeArtifact(jsonWriter, pluginMetadata); + + jsonWriter.endObject(); + } + + public void writeMetadata(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { + jsonWriter.prop(PROPERTY_KEY, pluginMetadata.getKey()); + jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getName()); + jsonWriter.prop(PROPERTY_DESCRIPTION, pluginMetadata.getDescription()); + jsonWriter.prop(PROPERTY_VERSION, pluginMetadata.getVersion()); + jsonWriter.prop(PROPERTY_LICENSE, pluginMetadata.getLicense()); + jsonWriter.prop(PROPERTY_ORGANIZATION_NAME, pluginMetadata.getOrganization()); + jsonWriter.prop(PROPERTY_ORGANIZATION_URL, pluginMetadata.getOrganizationUrl()); + } + + public void writeUrls(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { + jsonWriter.name(OBJECT_URLS); + jsonWriter.beginObject(); + jsonWriter.prop(PROPERTY_HOMEPAGE, pluginMetadata.getHomepage()); + jsonWriter.prop(PROPERTY_ISSUE_TRACKER, pluginMetadata.getIssueTrackerUrl()); + jsonWriter.endObject(); + } + + public void writeArtifact(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { + if (pluginMetadata.getFile() == null) { + return; + } + + jsonWriter.name(OBJECT_ARTIFACT); + jsonWriter.beginObject(); + jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getFile().getName()); + jsonWriter.endObject(); + } + + private enum PluginMetadataToName implements Function { + INSTANCE; + + @Override + public String apply(@Nullable PluginMetadata input) { + if (input == null) { + return null; + } + return input.getName(); + } + } + + private enum PluginMetadataToKey implements Function { + INSTANCE; + + @Override + public String apply(@Nullable PluginMetadata input) { + if (input == null) { + return null; + } + return input.getKey(); + } + } +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json b/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json index 841fd21996e..46de6372348 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json @@ -9,8 +9,10 @@ "license": "GNU LGPL 3", "organizationName": "SonarSource", "organizationUrl": "http://www.sonarsource.com", - "homepageUrl": "http://redirect.sonarsource.com/plugins/scmgit.html", - "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARSCGIT", + "urls": { + "homepage": "http://redirect.sonarsource.com/plugins/scmgit.html", + "issueTracker": "http://jira.codehaus.org/browse/SONARSCGIT" + }, "artifact": { "name": "sonar-scm-git-plugin-1.0.jar" } @@ -23,8 +25,10 @@ "license": "GNU LGPL 3", "organizationName": "SonarSource", "organizationUrl": "http://www.sonarsource.com", - "homepageUrl": "http://redirect.sonarsource.com/plugins/java.html", - "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARJAVA", + "urls": { + "homepage": "http://redirect.sonarsource.com/plugins/java.html", + "issueTracker": "http://jira.codehaus.org/browse/SONARJAVA" + }, "artifact": { "name": "sonar-java-plugin-3.0.jar" } @@ -40,8 +44,10 @@ "license": "GNU LGPL 3", "organizationName": "SonarSource", "organizationUrl": "http://www.sonarsource.com", - "homepageUrl": "http://redirect.sonarsource.com/plugins/scmsvn.html", - "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARSCSVN", + "urls": { + "homepage": "http://redirect.sonarsource.com/plugins/scmsvn.html", + "issueTracker": "http://jira.codehaus.org/browse/SONARSCSVN" + }, "artifact": { "name": "sonar-scm-svn-plugin-1.0.jar" } diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java index 2773a269cc9..36cb35e5692 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java @@ -19,10 +19,7 @@ */ package org.sonar.server.plugins.ws; -import org.junit.Before; import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.sonar.api.platform.PluginMetadata; import org.sonar.api.platform.PluginRepository; import org.sonar.api.server.ws.Request; @@ -37,7 +34,6 @@ import static java.lang.String.valueOf; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; import static org.sonar.test.JsonAssert.assertJson; public class InstalledPluginsWsActionTest { @@ -47,21 +43,13 @@ public class InstalledPluginsWsActionTest { " \"plugins\":" + "[]" + "}"; - @Mock - private PluginRepository pluginRepository; - @InjectMocks - private InstalledPluginsWsAction underTest; + private PluginRepository pluginRepository = mock(PluginRepository.class); + private InstalledPluginsWsAction underTest = new InstalledPluginsWsAction(pluginRepository, new PluginWSCommons()); - @Mock private Request request = mock(Request.class); private WsTester.TestResponse response = new WsTester.TestResponse(); private PluginMetadata corePlugin = corePlugin("core1", 10); - @Before - public void createMocks() throws Exception { - initMocks(this); - } - @Test public void action_installed_is_defined() throws Exception { WsTester wsTester = new WsTester(); @@ -98,10 +86,10 @@ public class InstalledPluginsWsActionTest { @Test public void empty_fields_are_not_serialized_to_json() throws Exception { when(pluginRepository.getMetadata()).thenReturn( - of( - (PluginMetadata) DefaultPluginMetadata.create("").setName("").setCore(false) - ) - ); + of( + (PluginMetadata) DefaultPluginMetadata.create("").setName("").setCore(false) + ) + ); underTest.handle(request, response); @@ -127,30 +115,30 @@ public class InstalledPluginsWsActionTest { underTest.handle(request, response); assertJson(response.outputAsString()).isSimilarTo( - "{" + - " \"plugins\":" + - " [" + - " {" + - " \"key\": \"plugKey\"," + - " \"name\": \"plugName\"," + - " \"description\": \"desc_it\"," + - " \"version\": \"10\"," + - " \"license\": \"license_hey\"," + - " \"organizationName\": \"org_name\"," + - " \"organizationUrl\": \"org_url\"," + - " \"urls\":" + - " {" + - " \"homepage\": \"homepage_url\"," + - " \"issueTracker\": \"issueTracker_url\"" + - " }," + - " \"artifact\":" + - " {" + - " \"name\": \"some.jar\"" + - " }" + - " }" + - " ]" + - "}" - ); + "{" + + " \"plugins\":" + + " [" + + " {" + + " \"key\": \"plugKey\"," + + " \"name\": \"plugName\"," + + " \"description\": \"desc_it\"," + + " \"version\": \"10\"," + + " \"license\": \"license_hey\"," + + " \"organizationName\": \"org_name\"," + + " \"organizationUrl\": \"org_url\"," + + " \"urls\":" + + " {" + + " \"homepage\": \"homepage_url\"," + + " \"issueTracker\": \"issueTracker_url\"" + + " }," + + " \"artifact\":" + + " {" + + " \"name\": \"some.jar\"" + + " }" + + " }" + + " ]" + + "}" + ); } @Test @@ -167,16 +155,16 @@ public class InstalledPluginsWsActionTest { underTest.handle(request, response); assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"plugins\":" + - " [" + - " {\"key\": \"C\"}" + "," + - " {\"key\": \"D\"}" + "," + - " {\"key\": \"B\"}" + "," + - " {\"key\": \"A\"}" + - " ]" + - "}" - ); + "{" + + " \"plugins\":" + + " [" + + " {\"key\": \"C\"}" + "," + + " {\"key\": \"D\"}" + "," + + " {\"key\": \"B\"}" + "," + + " {\"key\": \"A\"}" + + " ]" + + "}" + ); } @Test @@ -191,13 +179,13 @@ public class InstalledPluginsWsActionTest { underTest.handle(request, response); assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"plugins\":" + - " [" + - " {\"key\": \"A\"}" + - " ]" + - "}" - ); + "{" + + " \"plugins\":" + + " [" + + " {\"key\": \"A\"}" + + " ]" + + "}" + ); assertThat(response.outputAsString()).containsOnlyOnce("name2"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java index 5d3f544bab9..f54b49f80f6 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java @@ -55,7 +55,7 @@ public class PendingPluginsWsActionTest { private PluginDownloader pluginDownloader = mock(PluginDownloader.class); private ServerPluginJarsInstaller serverPluginJarsInstaller = mock(ServerPluginJarsInstaller.class); - private PendingPluginsWsAction underTest = new PendingPluginsWsAction(pluginDownloader, serverPluginJarsInstaller); + private PendingPluginsWsAction underTest = new PendingPluginsWsAction(pluginDownloader, serverPluginJarsInstaller, new PluginWSCommons()); private Request request = mock(Request.class); private WsTester.TestResponse response = new WsTester.TestResponse(); @@ -107,8 +107,10 @@ public class PendingPluginsWsActionTest { " \"license\": \"GNU LGPL 3\"," + " \"organizationName\": \"SonarSource\"," + " \"organizationUrl\": \"http://www.sonarsource.com\"," + - " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + - " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + + " \"urls\": {" + + " \"homepage\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTracker\": \"http://jira.codehaus.org/browse/SONARSCGIT\"" + + " }," + " \"artifact\": {" + " \"name\": \"sonar-scm-git-plugin-1.0.jar\"" + " }" + @@ -138,8 +140,10 @@ public class PendingPluginsWsActionTest { " \"license\": \"GNU LGPL 3\"," + " \"organizationName\": \"SonarSource\"," + " \"organizationUrl\": \"http://www.sonarsource.com\"," + - " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + - " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + + " \"urls\": {" + + " \"homepage\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTracker\": \"http://jira.codehaus.org/browse/SONARSCGIT\"" + + " }," + " \"artifact\": {" + " \"name\": \"sonar-scm-git-plugin-1.0.jar\"" + " }" + @@ -185,11 +189,11 @@ public class PendingPluginsWsActionTest { @Test public void removing_plugin_are_sorted_and_unique() throws Exception { when(serverPluginJarsInstaller.getUninstalledPlugins()).thenReturn(of( - PLUGIN_2_2, - PLUGIN_2_1, - PLUGIN_2_2, - PLUGIN_0_0 - )); + PLUGIN_2_2, + PLUGIN_2_1, + PLUGIN_2_2, + PLUGIN_0_0 + )); underTest.handle(request, response); @@ -198,18 +202,18 @@ public class PendingPluginsWsActionTest { " \"installing\": []," + " \"removing\": " + " [" + - " {" + - " \"key\": \"key0\"," + - " \"name\": \"name0\"," + - " }," + - " {" + - " \"key\": \"key1\"," + - " \"name\": \"name2\"," + - " }," + - " {" + - " \"key\": \"key2\"," + - " \"name\": \"name2\"," + - " }" + + " {" + + " \"key\": \"key0\"," + + " \"name\": \"name0\"," + + " }," + + " {" + + " \"key\": \"key1\"," + + " \"name\": \"name2\"," + + " }," + + " {" + + " \"key\": \"key2\"," + + " \"name\": \"name2\"," + + " }" + " ]" + "}" ); diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java new file mode 100644 index 00000000000..679ab5fc278 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java @@ -0,0 +1,127 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.plugins.ws; + +import org.junit.Test; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.plugins.DefaultPluginMetadata; +import org.sonar.server.ws.WsTester; + +import java.io.File; + +import static org.sonar.core.plugins.DefaultPluginMetadata.create; +import static org.sonar.test.JsonAssert.assertJson; + +public class PluginWSCommonsTest { + public static final DefaultPluginMetadata GIT_PLUGIN_METADATA = create("scmgit") + .setName("Git") + .setDescription("Git SCM Provider.") + .setVersion("1.0") + .setLicense("GNU LGPL 3") + .setOrganization("SonarSource") + .setOrganizationUrl("http://www.sonarsource.com") + .setHomepage("http://redirect.sonarsource.com/plugins/scmgit.html") + .setIssueTrackerUrl("http://jira.codehaus.org/browse/SONARSCGIT") + .setFile(new File("/home/user/sonar-scm-git-plugin-1.0.jar")); + + private WsTester.TestResponse response = new WsTester.TestResponse(); + private JsonWriter jsonWriter = response.newJsonWriter(); + private PluginWSCommons underTest = new PluginWSCommons(); + + @Test + public void verify_properties_written_by_writePluginMetadata() throws Exception { + underTest.writePluginMetadata(jsonWriter, GIT_PLUGIN_METADATA); + + jsonWriter.close(); + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{" + + " \"key\": \"scmgit\"," + + " \"name\": \"Git\"," + + " \"description\": \"Git SCM Provider.\"," + + " \"version\": \"1.0\"," + + " \"license\": \"GNU LGPL 3\"," + + " \"organizationName\": \"SonarSource\"," + + " \"organizationUrl\": \"http://www.sonarsource.com\"," + + " \"urls\": {" + + " \"homepage\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTracker\": \"http://jira.codehaus.org/browse/SONARSCGIT\"" + + " }," + + " \"artifact\": {" + + " \"name\": \"sonar-scm-git-plugin-1.0.jar\"" + + " }" + + "}"); + } + + @Test + public void verify_properties_written_by_writeMetadata() throws Exception { + jsonWriter.beginObject(); + underTest.writeMetadata(jsonWriter, GIT_PLUGIN_METADATA); + jsonWriter.endObject(); + + jsonWriter.close(); + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{" + + " \"key\": \"scmgit\"," + + " \"name\": \"Git\"," + + " \"description\": \"Git SCM Provider.\"," + + " \"version\": \"1.0\"," + + " \"license\": \"GNU LGPL 3\"," + + " \"organizationName\": \"SonarSource\"," + + " \"organizationUrl\": \"http://www.sonarsource.com\"," + + "}"); + } + + @Test + public void verify_properties_written_by_writeUrls() throws Exception { + jsonWriter.beginObject(); + underTest.writeUrls(jsonWriter, GIT_PLUGIN_METADATA); + jsonWriter.endObject(); + + jsonWriter.close(); + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{" + + " \"urls\": {" + + " \"homepage\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTracker\": \"http://jira.codehaus.org/browse/SONARSCGIT\"" + + " }," + + "}"); + } + + @Test + public void writeArtifact_supports_null_file() throws Exception { + jsonWriter.beginObject(); + underTest.writeArtifact(jsonWriter, DefaultPluginMetadata.create("key")); + jsonWriter.endObject(); + + jsonWriter.close(); + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{}"); + } + + @Test + public void writeArtifact_writes_artifact_object_and_file_name() throws Exception { + jsonWriter.beginObject(); + underTest.writeArtifact(jsonWriter, GIT_PLUGIN_METADATA); + jsonWriter.endObject(); + + jsonWriter.close(); + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{" + + " \"artifact\": {" + + " \"name\": \"sonar-scm-git-plugin-1.0.jar\"" + + " }" + + "}"); + } +} \ No newline at end of file -- 2.39.5