mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-11 16:05:44 +01:00
merge with feature/ui-extensions branch
This commit is contained in:
@@ -30,6 +30,10 @@ public class MapperModule extends AbstractModule {
|
||||
|
||||
bind(FileObjectToFileObjectDtoMapper.class).to(Mappers.getMapper(FileObjectToFileObjectDtoMapper.class).getClass());
|
||||
|
||||
// no mapstruct required
|
||||
bind(UIPluginDtoMapper.class);
|
||||
bind(UIPluginDtoCollectionMapper.class);
|
||||
|
||||
bind(UriInfoStore.class).in(ServletScopes.REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,4 +349,37 @@ class ResourceLinks {
|
||||
return permissionLinkBuilder.method("getRepositoryResource").parameters(repositoryNamespace, repositoryName).method("permissions").parameters().method(methodName).parameters(permissionName).href();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public UIPluginLinks uiPlugin() {
|
||||
return new UIPluginLinks(uriInfoStore.get());
|
||||
}
|
||||
|
||||
static class UIPluginLinks {
|
||||
private final LinkBuilder uiPluginLinkBuilder;
|
||||
|
||||
UIPluginLinks(UriInfo uriInfo) {
|
||||
uiPluginLinkBuilder = new LinkBuilder(uriInfo, UIRootResource.class, UIPluginResource.class);
|
||||
}
|
||||
|
||||
String self(String id) {
|
||||
return uiPluginLinkBuilder.method("plugins").parameters().method("getInstalledPlugin").parameters(id).href();
|
||||
}
|
||||
}
|
||||
|
||||
public UIPluginCollectionLinks uiPluginCollection() {
|
||||
return new UIPluginCollectionLinks(uriInfoStore.get());
|
||||
}
|
||||
|
||||
static class UIPluginCollectionLinks {
|
||||
private final LinkBuilder uiPluginCollectionLinkBuilder;
|
||||
|
||||
UIPluginCollectionLinks(UriInfo uriInfo) {
|
||||
uiPluginCollectionLinkBuilder = new LinkBuilder(uriInfo, UIRootResource.class, UIPluginResource.class);
|
||||
}
|
||||
|
||||
String self() {
|
||||
return uiPluginCollectionLinkBuilder.method("plugins").parameters().method("getInstalledPlugins").parameters().href();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import de.otto.edison.hal.Links;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter @Setter @NoArgsConstructor
|
||||
public class UIPluginDto extends HalRepresentation {
|
||||
|
||||
private String name;
|
||||
private Iterable<String> bundles;
|
||||
|
||||
public UIPluginDto(String name, Iterable<String> bundles) {
|
||||
this.name = name;
|
||||
this.bundles = bundles;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HalRepresentation add(Links links) {
|
||||
return super.add(links);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import de.otto.edison.hal.Embedded;
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import de.otto.edison.hal.Links;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static de.otto.edison.hal.Embedded.embeddedBuilder;
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class UIPluginDtoCollectionMapper {
|
||||
|
||||
private final ResourceLinks resourceLinks;
|
||||
private final UIPluginDtoMapper mapper;
|
||||
|
||||
@Inject
|
||||
public UIPluginDtoCollectionMapper(ResourceLinks resourceLinks, UIPluginDtoMapper mapper) {
|
||||
this.resourceLinks = resourceLinks;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public HalRepresentation map(Collection<PluginWrapper> plugins) {
|
||||
List<UIPluginDto> dtos = plugins.stream().map(mapper::map).collect(toList());
|
||||
return new HalRepresentation(createLinks(), embedDtos(dtos));
|
||||
}
|
||||
|
||||
private Links createLinks() {
|
||||
String baseUrl = resourceLinks.uiPluginCollection().self();
|
||||
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.with(Links.linkingTo().self(baseUrl).build());
|
||||
return linksBuilder.build();
|
||||
}
|
||||
|
||||
private Embedded embedDtos(List<UIPluginDto> dtos) {
|
||||
return embeddedBuilder()
|
||||
.with("plugins", dtos)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import de.otto.edison.hal.Links;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
|
||||
public class UIPluginDtoMapper {
|
||||
|
||||
private final ResourceLinks resourceLinks;
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@Inject
|
||||
public UIPluginDtoMapper(ResourceLinks resourceLinks, HttpServletRequest request) {
|
||||
this.resourceLinks = resourceLinks;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public UIPluginDto map(PluginWrapper plugin) {
|
||||
UIPluginDto dto = new UIPluginDto(
|
||||
plugin.getPlugin().getInformation().getName(),
|
||||
getScriptResources(plugin)
|
||||
);
|
||||
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.self(resourceLinks.uiPlugin()
|
||||
.self(plugin.getId()));
|
||||
|
||||
dto.add(linksBuilder.build());
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private Set<String> getScriptResources(PluginWrapper wrapper) {
|
||||
Set<String> scriptResources = wrapper.getPlugin().getResources().getScriptResources();
|
||||
if (scriptResources != null) {
|
||||
return scriptResources.stream()
|
||||
.map(this::addContextPath)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
private String addContextPath(String resource) {
|
||||
String ctxPath = request.getContextPath();
|
||||
if (Strings.isNullOrEmpty(ctxPath)) {
|
||||
return resource;
|
||||
}
|
||||
return HttpUtil.append(ctxPath, resource);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import sonia.scm.plugin.PluginLoader;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UIPluginResource {
|
||||
|
||||
private final PluginLoader pluginLoader;
|
||||
private final UIPluginDtoCollectionMapper collectionMapper;
|
||||
private final UIPluginDtoMapper mapper;
|
||||
|
||||
@Inject
|
||||
public UIPluginResource(PluginLoader pluginLoader, UIPluginDtoCollectionMapper collectionMapper, UIPluginDtoMapper mapper) {
|
||||
this.pluginLoader = pluginLoader;
|
||||
this.collectionMapper = collectionMapper;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of installed plugins and their ui bundles.
|
||||
*
|
||||
* @return collection of installed plugins.
|
||||
*/
|
||||
@GET
|
||||
@Path("")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(CollectionDto.class)
|
||||
@Produces(VndMediaType.UI_PLUGIN_COLLECTION)
|
||||
public Response getInstalledPlugins() {
|
||||
List<PluginWrapper> plugins = pluginLoader.getInstalledPlugins()
|
||||
.stream()
|
||||
.filter(this::filter)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Response.ok(collectionMapper.map(plugins)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the installed plugin with the given id.
|
||||
*
|
||||
* @param id id of plugin
|
||||
*
|
||||
* @return installed plugin with specified id
|
||||
*/
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 404, condition = "not found"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(UIPluginDto.class)
|
||||
@Produces(VndMediaType.UI_PLUGIN)
|
||||
public Response getInstalledPlugin(@PathParam("id") String id) {
|
||||
Optional<UIPluginDto> uiPluginDto = pluginLoader.getInstalledPlugins()
|
||||
.stream()
|
||||
.filter(this::filter)
|
||||
.filter(plugin -> id.equals(plugin.getId()))
|
||||
.map(mapper::map)
|
||||
.findFirst();
|
||||
|
||||
if (uiPluginDto.isPresent()) {
|
||||
return Response.ok(uiPluginDto.get()).build();
|
||||
} else {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean filter(PluginWrapper plugin) {
|
||||
return plugin.getPlugin().getResources() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
@Path("v2/ui")
|
||||
public class UIRootResource {
|
||||
|
||||
private Provider<UIPluginResource> uiPluginResourceProvider;
|
||||
|
||||
@Inject
|
||||
public UIRootResource(Provider<UIPluginResource> uiPluginResourceProvider) {
|
||||
this.uiPluginResourceProvider = uiPluginResourceProvider;
|
||||
}
|
||||
|
||||
@Path("plugins")
|
||||
public UIPluginResource plugins() {
|
||||
return uiPluginResourceProvider.get();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user