mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 03:25:56 +01:00
use mapstruct for dto mapping and fix missing fields
This commit is contained in:
@@ -46,11 +46,11 @@
|
||||
<!--- the current version of the plugin -->
|
||||
<!ELEMENT version (#PCDATA)>
|
||||
|
||||
<!--- plugin displayName -->
|
||||
<!ELEMENT displayName (#PCDATA)>
|
||||
<!--- plugin displayName -->
|
||||
<!ELEMENT displayName (#PCDATA)>
|
||||
|
||||
<!--- url of the plugin avatar -->
|
||||
<!ELEMENT avatarUrl (#PCDATA)>
|
||||
<!--- url of the plugin avatar -->
|
||||
<!ELEMENT avatarUrl (#PCDATA)>
|
||||
|
||||
<!--- true if the plugin should load child classes first, the default is false -->
|
||||
<!ELEMENT child-first-classloader (#PCDATA)>
|
||||
|
||||
@@ -73,9 +73,7 @@ public class ScmConfiguration implements Configuration {
|
||||
* Default plugin url
|
||||
*/
|
||||
public static final String DEFAULT_PLUGINURL =
|
||||
"http://download.scm-manager.org/api/v2/plugins.json";
|
||||
// Keep the parameters
|
||||
// "http://plugins.scm-manager.org/scm-plugin-backend/api/{version}/plugins?os={os}&arch={arch}&snapshot=false";
|
||||
"http://download.scm-manager.org/api/v2/plugins.json?os={os}&arch={arch}&snapshot=false&version={version}";
|
||||
|
||||
/**
|
||||
* Default plugin url from version 1.0
|
||||
|
||||
@@ -35,10 +35,7 @@ package sonia.scm.plugin;
|
||||
|
||||
import com.github.sdorra.ssp.PermissionObject;
|
||||
import com.github.sdorra.ssp.StaticPermissions;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.Data;
|
||||
import sonia.scm.Validateable;
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
@@ -52,6 +49,7 @@ import java.io.Serializable;
|
||||
/**
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Data
|
||||
@StaticPermissions(
|
||||
value = "plugin",
|
||||
generatedClass = "PluginPermissions",
|
||||
@@ -61,40 +59,34 @@ import java.io.Serializable;
|
||||
)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "plugin-information")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@ToString
|
||||
public class PluginInformation implements PermissionObject, Validateable, Cloneable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 461382048865977206L;
|
||||
|
||||
private String author;
|
||||
private String category;
|
||||
private PluginCondition condition;
|
||||
private String description;
|
||||
private String name;
|
||||
private PluginState state;
|
||||
private String version;
|
||||
private String displayName;
|
||||
private String description;
|
||||
private String author;
|
||||
private String category;
|
||||
private String avatarUrl;
|
||||
private PluginCondition condition;
|
||||
private PluginState state;
|
||||
|
||||
@Override
|
||||
public PluginInformation clone() {
|
||||
PluginInformation clone = new PluginInformation();
|
||||
clone.setName(name);
|
||||
clone.setAuthor(author);
|
||||
clone.setCategory(category);
|
||||
clone.setDescription(description);
|
||||
clone.setState(state);
|
||||
clone.setVersion(version);
|
||||
clone.setDisplayName(displayName);
|
||||
clone.setDescription(description);
|
||||
clone.setAuthor(author);
|
||||
clone.setCategory(category);
|
||||
clone.setAvatarUrl(avatarUrl);
|
||||
|
||||
clone.setState(state);
|
||||
if (condition != null) {
|
||||
clone.setCondition(condition.clone());
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>scm-git-plugin</artifactId>
|
||||
<name>scm-git-plugin</name>
|
||||
<name>Git</name>
|
||||
<packaging>smp</packaging>
|
||||
<url>https://bitbucket.org/sdorra/scm-manager</url>
|
||||
<description>Plugin for the version control system Git</description>
|
||||
|
||||
@@ -47,13 +47,7 @@
|
||||
|
||||
<information>
|
||||
<author>Sebastian Sdorra</author>
|
||||
<category>Git</category>
|
||||
<tags>
|
||||
<tag>git</tag>
|
||||
<tag>scm</tag>
|
||||
<tag>vcs</tag>
|
||||
<tag>dvcs</tag>
|
||||
</tags>
|
||||
<category>Source Code Management</category>
|
||||
</information>
|
||||
|
||||
<conditions>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>scm-hg-plugin</artifactId>
|
||||
<name>scm-hg-plugin</name>
|
||||
<name>Mercurial</name>
|
||||
<packaging>smp</packaging>
|
||||
<url>https://bitbucket.org/sdorra/scm-manager</url>
|
||||
<description>Plugin for the version control system Mercurial</description>
|
||||
|
||||
@@ -47,14 +47,7 @@ jo
|
||||
|
||||
<information>
|
||||
<author>Sebastian Sdorra</author>
|
||||
<category>Mercurial</category>
|
||||
<tags>
|
||||
<tag>mercurial</tag>
|
||||
<tag>hg</tag>
|
||||
<tag>scm</tag>
|
||||
<tag>vcs</tag>
|
||||
<tag>dvcs</tag>
|
||||
</tags>
|
||||
<category>Source Code Management</category>
|
||||
</information>
|
||||
|
||||
<conditions>
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
<artifactId>scm-plugins</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>sonia.scm.plugins</groupId>
|
||||
|
||||
<artifactId>scm-legacy-plugin</artifactId>
|
||||
<name>Legacy</name>
|
||||
<description>Support migrated repository urls and v1 passwords</description>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<packaging>smp</packaging>
|
||||
|
||||
@@ -21,6 +23,7 @@
|
||||
<version>${servlet.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>scm-svn-plugin</artifactId>
|
||||
<name>scm-svn-plugin</name>
|
||||
<name>Subversion</name>
|
||||
<packaging>smp</packaging>
|
||||
<url>https://bitbucket.org/sdorra/scm-manager</url>
|
||||
<description>Plugin for the version control system Subversion</description>
|
||||
|
||||
@@ -47,13 +47,7 @@
|
||||
|
||||
<information>
|
||||
<author>Sebastian Sdorra</author>
|
||||
<category>Subversion</category>
|
||||
<tags>
|
||||
<tag>subversion</tag>
|
||||
<tag>scm</tag>
|
||||
<tag>vcs</tag>
|
||||
<tag>svn</tag>
|
||||
</tags>
|
||||
<category>Source Code Management</category>
|
||||
</information>
|
||||
|
||||
<conditions>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
//@flow
|
||||
import type {Collection, Links} from "./hal";
|
||||
|
||||
|
||||
export type Plugin = {
|
||||
name: string,
|
||||
type: string,
|
||||
version: string,
|
||||
author: string,
|
||||
displayName: string,
|
||||
avatarUrl: string,
|
||||
description?: string,
|
||||
author: string,
|
||||
category: string,
|
||||
avatarUrl: string,
|
||||
_links: Links
|
||||
};
|
||||
|
||||
|
||||
@@ -54,5 +54,7 @@ public class MapperModule extends AbstractModule {
|
||||
bind(UIPluginDtoCollectionMapper.class);
|
||||
|
||||
bind(ScmPathInfoStore.class).in(ServletScopes.REQUEST);
|
||||
|
||||
bind(PluginDtoMapper.class).to(Mappers.getMapper(PluginDtoMapper.class).getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.plugin.PluginCondition;
|
||||
import sonia.scm.plugin.PluginInformation;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PluginCenterDtoMapper {
|
||||
|
||||
public static Set<PluginInformation> map(List<PluginCenterDto.Plugin> plugins) {
|
||||
HashSet<PluginInformation> pluginInformationSet = new HashSet<>();
|
||||
|
||||
for (PluginCenterDto.Plugin plugin : plugins) {
|
||||
|
||||
PluginInformation pluginInformation = new PluginInformation();
|
||||
pluginInformation.setName(plugin.getName());
|
||||
pluginInformation.setAuthor(plugin.getAuthor());
|
||||
pluginInformation.setCategory(plugin.getCategory());
|
||||
pluginInformation.setVersion(plugin.getVersion());
|
||||
pluginInformation.setDescription(plugin.getDescription());
|
||||
|
||||
if (plugin.getConditions() != null) {
|
||||
PluginCenterDto.Condition condition = plugin.getConditions();
|
||||
pluginInformation.setCondition(new PluginCondition(condition.getMinVersion(), condition.getOs(), condition.getArch()));
|
||||
}
|
||||
|
||||
pluginInformationSet.add(pluginInformation);
|
||||
}
|
||||
return pluginInformationSet;
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,12 @@ import lombok.Setter;
|
||||
public class PluginDto extends HalRepresentation {
|
||||
|
||||
private String name;
|
||||
private String category;
|
||||
private String version;
|
||||
private String author;
|
||||
private String avatarUrl;
|
||||
private String displayName;
|
||||
private String description;
|
||||
private String author;
|
||||
private String category;
|
||||
private String avatarUrl;
|
||||
|
||||
public PluginDto(Links links) {
|
||||
add(links);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.Links;
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.ObjectFactory;
|
||||
import sonia.scm.plugin.PluginInformation;
|
||||
import sonia.scm.plugin.PluginState;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
@@ -10,20 +14,27 @@ import javax.inject.Inject;
|
||||
import static de.otto.edison.hal.Link.link;
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
|
||||
public class PluginDtoMapper {
|
||||
|
||||
private final ResourceLinks resourceLinks;
|
||||
@Mapper
|
||||
public abstract class PluginDtoMapper {
|
||||
|
||||
@Inject
|
||||
public PluginDtoMapper(ResourceLinks resourceLinks) {
|
||||
this.resourceLinks = resourceLinks;
|
||||
}
|
||||
private ResourceLinks resourceLinks;
|
||||
|
||||
public PluginDto map(PluginWrapper plugin) {
|
||||
return map(plugin.getPlugin().getInformation());
|
||||
}
|
||||
|
||||
public PluginDto map(PluginInformation pluginInformation) {
|
||||
public abstract PluginDto map(PluginInformation plugin);
|
||||
|
||||
@AfterMapping
|
||||
protected void appendCategory(@MappingTarget PluginDto dto) {
|
||||
if (dto.getCategory() == null) {
|
||||
dto.setCategory("Miscellaneous");
|
||||
}
|
||||
}
|
||||
|
||||
@ObjectFactory
|
||||
public PluginDto createDto(PluginInformation pluginInformation) {
|
||||
Links.Builder linksBuilder;
|
||||
if (pluginInformation.getState() != null && pluginInformation.getState().equals(PluginState.AVAILABLE)) {
|
||||
linksBuilder = linkingTo()
|
||||
@@ -38,14 +49,6 @@ public class PluginDtoMapper {
|
||||
.self(pluginInformation.getName()));
|
||||
}
|
||||
|
||||
PluginDto pluginDto = new PluginDto(linksBuilder.build());
|
||||
pluginDto.setName(pluginInformation.getName());
|
||||
pluginDto.setCategory(pluginInformation.getCategory() != null ? pluginInformation.getCategory() : "Miscellaneous");
|
||||
pluginDto.setVersion(pluginInformation.getVersion());
|
||||
pluginDto.setAuthor(pluginInformation.getAuthor());
|
||||
pluginDto.setDescription(pluginInformation.getDescription());
|
||||
pluginDto.setAvatarUrl(pluginInformation.getAvatarUrl());
|
||||
|
||||
return pluginDto;
|
||||
return new PluginDto(linksBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.SCMContextProvider;
|
||||
import sonia.scm.api.v2.resources.PluginCenterDto;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
@@ -79,7 +78,7 @@ import javax.xml.bind.JAXB;
|
||||
|
||||
import sonia.scm.net.ahc.AdvancedHttpClient;
|
||||
|
||||
import static sonia.scm.api.v2.resources.PluginCenterDtoMapper.*;
|
||||
import static sonia.scm.plugin.PluginCenterDtoMapper.*;
|
||||
|
||||
/**
|
||||
* TODO replace aether stuff.
|
||||
@@ -595,14 +594,8 @@ public class DefaultPluginManager implements PluginManager
|
||||
{
|
||||
synchronized (DefaultPluginManager.class)
|
||||
{
|
||||
String pluginUrl = configuration.getPluginUrl();
|
||||
|
||||
pluginUrl = buildPluginUrl(pluginUrl);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("fetch plugin informations from {}", pluginUrl);
|
||||
}
|
||||
String pluginUrl = buildPluginUrl(configuration.getPluginUrl());
|
||||
logger.info("fetch plugin information from {}", pluginUrl);
|
||||
|
||||
if (REMOTE_PLUGINS_ENABLED && Util.isNotEmpty(pluginUrl))
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
package sonia.scm.plugin;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -45,10 +45,10 @@ public final class PluginCenterDto implements Serializable {
|
||||
public static class Plugin {
|
||||
|
||||
private String name;
|
||||
private String version;
|
||||
private String displayName;
|
||||
private String description;
|
||||
private String category;
|
||||
private String version;
|
||||
private String author;
|
||||
private String avatarUrl;
|
||||
private String sha256;
|
||||
@@ -86,6 +86,5 @@ public final class PluginCenterDto implements Serializable {
|
||||
@Getter
|
||||
static class Link {
|
||||
private String href;
|
||||
private boolean templated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package sonia.scm.plugin;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Mapper
|
||||
public interface PluginCenterDtoMapper {
|
||||
|
||||
@Mapping(source = "conditions", target = "condition")
|
||||
PluginInformation map(PluginCenterDto.Plugin plugin);
|
||||
|
||||
PluginCondition map(PluginCenterDto.Condition condition);
|
||||
|
||||
static Set<PluginInformation> map(List<PluginCenterDto.Plugin> dtos) {
|
||||
PluginCenterDtoMapper mapper = Mappers.getMapper(PluginCenterDtoMapper.class);
|
||||
Set<PluginInformation> plugins = new HashSet<>();
|
||||
for (PluginCenterDto.Plugin plugin : dtos) {
|
||||
plugins.add(mapper.map(plugin));
|
||||
}
|
||||
return plugins;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.plugin.PluginInformation;
|
||||
import sonia.scm.plugin.PluginState;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PluginDtoMapperTest {
|
||||
|
||||
@SuppressWarnings("unused") // Is injected
|
||||
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(URI.create("https://hitchhiker.com/"));
|
||||
|
||||
@InjectMocks
|
||||
private PluginDtoMapperImpl mapper;
|
||||
|
||||
@Test
|
||||
void shouldMapInformation() {
|
||||
PluginInformation information = createPluginInformation();
|
||||
|
||||
PluginDto dto = mapper.map(information);
|
||||
|
||||
assertThat(dto.getName()).isEqualTo("scm-cas-plugin");
|
||||
assertThat(dto.getVersion()).isEqualTo("1.0.0");
|
||||
assertThat(dto.getDisplayName()).isEqualTo("CAS");
|
||||
assertThat(dto.getAuthor()).isEqualTo("Sebastian Sdorra");
|
||||
assertThat(dto.getCategory()).isEqualTo("Authentication");
|
||||
assertThat(dto.getAvatarUrl()).isEqualTo("https://avatar.scm-manager.org/plugins/cas.png");
|
||||
}
|
||||
|
||||
private PluginInformation createPluginInformation() {
|
||||
PluginInformation information = new PluginInformation();
|
||||
information.setName("scm-cas-plugin");
|
||||
information.setVersion("1.0.0");
|
||||
information.setDisplayName("CAS");
|
||||
information.setAuthor("Sebastian Sdorra");
|
||||
information.setCategory("Authentication");
|
||||
information.setAvatarUrl("https://avatar.scm-manager.org/plugins/cas.png");
|
||||
return information;
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAppendInstalledSelfLink() {
|
||||
PluginInformation information = createPluginInformation();
|
||||
information.setState(PluginState.INSTALLED);
|
||||
|
||||
PluginDto dto = mapper.map(information);
|
||||
assertThat(dto.getLinks().getLinkBy("self").get().getHref())
|
||||
.isEqualTo("https://hitchhiker.com/v2/plugins/installed/scm-cas-plugin");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAppendAvailableSelfLink() {
|
||||
PluginInformation information = createPluginInformation();
|
||||
information.setState(PluginState.AVAILABLE);
|
||||
|
||||
PluginDto dto = mapper.map(information);
|
||||
assertThat(dto.getLinks().getLinkBy("self").get().getHref())
|
||||
.isEqualTo("https://hitchhiker.com/v2/plugins/available/scm-cas-plugin/1.0.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAppendInstallLink() {
|
||||
PluginInformation information = createPluginInformation();
|
||||
information.setState(PluginState.AVAILABLE);
|
||||
|
||||
PluginDto dto = mapper.map(information);
|
||||
assertThat(dto.getLinks().getLinkBy("install").get().getHref())
|
||||
.isEqualTo("https://hitchhiker.com/v2/plugins/available/scm-cas-plugin/1.0.0/install");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnMiscellaneousIfCategoryIsNull() {
|
||||
PluginInformation information = createPluginInformation();
|
||||
information.setCategory(null);
|
||||
|
||||
PluginDto dto = mapper.map(information);
|
||||
assertThat(dto.getCategory()).isEqualTo("Miscellaneous");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
package sonia.scm.plugin;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sonia.scm.plugin.PluginInformation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -12,19 +10,11 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static sonia.scm.api.v2.resources.PluginCenterDto.Condition;
|
||||
import static sonia.scm.api.v2.resources.PluginCenterDto.Dependency;
|
||||
import static sonia.scm.api.v2.resources.PluginCenterDto.Plugin;
|
||||
import static sonia.scm.plugin.PluginCenterDto.Plugin;
|
||||
import static sonia.scm.plugin.PluginCenterDto.*;
|
||||
|
||||
class PluginCenterDtoMapperTest {
|
||||
|
||||
private PluginCenterDtoMapper pluginCenterDtoMapper;
|
||||
|
||||
@BeforeEach
|
||||
void initMapper() {
|
||||
pluginCenterDtoMapper = new PluginCenterDtoMapper();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMapSinglePlugin() {
|
||||
Plugin plugin = new Plugin(
|
||||
@@ -82,10 +72,10 @@ class PluginCenterDtoMapperTest {
|
||||
|
||||
Set<PluginInformation> resultSet = PluginCenterDtoMapper.map(Arrays.asList(plugin1, plugin2));
|
||||
|
||||
List pluginsList = new ArrayList(resultSet);
|
||||
List<PluginInformation> pluginsList = new ArrayList<>(resultSet);
|
||||
|
||||
PluginInformation pluginInformation1 = (PluginInformation) pluginsList.get(1);
|
||||
PluginInformation pluginInformation2 = (PluginInformation) pluginsList.get(0);
|
||||
PluginInformation pluginInformation1 = pluginsList.get(1);
|
||||
PluginInformation pluginInformation2 = pluginsList.get(0);
|
||||
|
||||
assertThat(pluginInformation1.getAuthor()).isEqualTo(plugin1.getAuthor());
|
||||
assertThat(pluginInformation1.getVersion()).isEqualTo(plugin1.getVersion());
|
||||
Reference in New Issue
Block a user