mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 00:15:44 +01:00
Merge with 2.0.0-m3
This commit is contained in:
@@ -6,18 +6,13 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class BrowserResultDto extends HalRepresentation implements Iterable<FileObjectDto> {
|
||||
public class BrowserResultDto extends HalRepresentation {
|
||||
private String revision;
|
||||
private String tag;
|
||||
private String branch;
|
||||
// REVIEW files nicht embedded?
|
||||
private List<FileObjectDto> files;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||
@@ -25,16 +20,7 @@ public class BrowserResultDto extends HalRepresentation implements Iterable<File
|
||||
return super.add(links);
|
||||
}
|
||||
|
||||
// REVIEW return null?
|
||||
@Override
|
||||
public Iterator<FileObjectDto> iterator() {
|
||||
Iterator<FileObjectDto> it = null;
|
||||
|
||||
if (files != null)
|
||||
{
|
||||
it = files.iterator();
|
||||
}
|
||||
|
||||
return it;
|
||||
public void setFiles(List<FileObjectDto> files) {
|
||||
this.withEmbedded("files", files);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,9 @@ public class BrowserResultToBrowserResultDtoMapper {
|
||||
@Inject
|
||||
private ResourceLinks resourceLinks;
|
||||
|
||||
public BrowserResultDto map(BrowserResult browserResult, NamespaceAndName namespaceAndName) {
|
||||
public BrowserResultDto map(BrowserResult browserResult, NamespaceAndName namespaceAndName, String path) {
|
||||
BrowserResultDto browserResultDto = new BrowserResultDto();
|
||||
|
||||
browserResultDto.setTag(browserResult.getTag());
|
||||
browserResultDto.setBranch(browserResult.getBranch());
|
||||
browserResultDto.setRevision(browserResult.getRevision());
|
||||
|
||||
List<FileObjectDto> fileObjectDtoList = new ArrayList<>();
|
||||
@@ -30,7 +28,7 @@ public class BrowserResultToBrowserResultDtoMapper {
|
||||
}
|
||||
|
||||
browserResultDto.setFiles(fileObjectDtoList);
|
||||
this.addLinks(browserResult, browserResultDto, namespaceAndName);
|
||||
this.addLinks(browserResult, browserResultDto, namespaceAndName, path);
|
||||
return browserResultDto;
|
||||
}
|
||||
|
||||
@@ -38,13 +36,14 @@ public class BrowserResultToBrowserResultDtoMapper {
|
||||
return fileObjectToFileObjectDtoMapper.map(fileObject, namespaceAndName, revision);
|
||||
}
|
||||
|
||||
private void addLinks(BrowserResult browserResult, BrowserResultDto dto, NamespaceAndName namespaceAndName) {
|
||||
private void addLinks(BrowserResult browserResult, BrowserResultDto dto, NamespaceAndName namespaceAndName, String path) {
|
||||
if (path.equals("/")) {
|
||||
path = "";
|
||||
}
|
||||
if (browserResult.getRevision() == null) {
|
||||
dto.add(Links.linkingTo().self(resourceLinks.source().selfWithoutRevision(namespaceAndName.getNamespace(), namespaceAndName.getName())).build());
|
||||
throw new IllegalStateException("missing revision in browser result for repository " + namespaceAndName + " and path " + path);
|
||||
} else {
|
||||
dto.add(Links.linkingTo().self(resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), browserResult.getRevision())).build());
|
||||
dto.add(Links.linkingTo().self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), browserResult.getRevision(), path)).build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.SubRepository;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.net.URI;
|
||||
|
||||
@Mapper
|
||||
public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper<FileObject, FileObjectDto> {
|
||||
@@ -27,19 +26,14 @@ public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper<FileObj
|
||||
String path = removeFirstSlash(fileObject.getPath());
|
||||
Links.Builder links = Links.linkingTo();
|
||||
if (dto.isDirectory()) {
|
||||
links.self(addPath(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, ""), path));
|
||||
links.self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, path));
|
||||
} else {
|
||||
links.self(addPath(resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, ""), path));
|
||||
links.self(resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, path));
|
||||
}
|
||||
|
||||
dto.add(links.build());
|
||||
}
|
||||
|
||||
// we have to add the file path using URI, so that path separators (aka '/') will not be encoded as '%2F'
|
||||
private String addPath(String sourceWithPath, String path) {
|
||||
return URI.create(sourceWithPath).resolve(path).toASCIIString();
|
||||
}
|
||||
|
||||
private String removeFirstSlash(String source) {
|
||||
return source.startsWith("/") ? source.substring(1) : source;
|
||||
}
|
||||
|
||||
@@ -213,8 +213,8 @@ class ResourceLinks {
|
||||
tagLinkBuilder = new LinkBuilder(uriInfo, RepositoryRootResource.class, RepositoryResource.class, TagRootResource.class);
|
||||
}
|
||||
|
||||
String self(String namespace, String name, String id) {
|
||||
return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("get").parameters(id).href();
|
||||
String self(String namespace, String name, String tagName) {
|
||||
return tagLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("tags").parameters().method("get").parameters(tagName).href();
|
||||
}
|
||||
|
||||
String all(String namespace, String name) {
|
||||
@@ -326,15 +326,16 @@ class ResourceLinks {
|
||||
}
|
||||
|
||||
public String sourceWithPath(String namespace, String name, String revision, String path) {
|
||||
if (revision == null) {
|
||||
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(null, path).href();
|
||||
} else {
|
||||
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(revision, path).href();
|
||||
}
|
||||
return addPath(sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(revision, "").href(), path);
|
||||
}
|
||||
|
||||
public String content(String namespace, String name, String revision, String path) {
|
||||
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("content").parameters().method("get").parameters(revision, path).href();
|
||||
return addPath(sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("content").parameters().method("get").parameters(revision, "").href(), path);
|
||||
}
|
||||
|
||||
// we have to add the file path using URI, so that path separators (aka '/') will not be encoded as '%2F'
|
||||
private String addPath(String sourceWithPath, String path) {
|
||||
return URI.create(sourceWithPath).resolve(path).toASCIIString();
|
||||
}
|
||||
}
|
||||
public PermissionLinks permission() {
|
||||
|
||||
@@ -62,7 +62,7 @@ public class SourceRootResource {
|
||||
BrowserResult browserResult = browseCommand.getBrowserResult();
|
||||
|
||||
if (browserResult != null) {
|
||||
return Response.ok(browserResultToBrowserResultDtoMapper.map(browserResult, namespaceAndName)).build();
|
||||
return Response.ok(browserResultToBrowserResultDtoMapper.map(browserResult, namespaceAndName, path)).build();
|
||||
} else {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.NotFoundException;
|
||||
|
||||
public class TagNotFoundException extends NotFoundException {
|
||||
|
||||
}
|
||||
@@ -1,27 +1,100 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.Tag;
|
||||
import sonia.scm.repository.Tags;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagRootResource {
|
||||
|
||||
private final RepositoryServiceFactory serviceFactory;
|
||||
private final TagCollectionToDtoMapper tagCollectionToDtoMapper;
|
||||
private final TagToTagDtoMapper tagToTagDtoMapper;
|
||||
|
||||
@Inject
|
||||
public TagRootResource(RepositoryServiceFactory serviceFactory,
|
||||
TagCollectionToDtoMapper tagCollectionToDtoMapper,
|
||||
TagToTagDtoMapper tagToTagDtoMapper) {
|
||||
this.serviceFactory = serviceFactory;
|
||||
this.tagCollectionToDtoMapper = tagCollectionToDtoMapper;
|
||||
this.tagToTagDtoMapper = tagToTagDtoMapper;
|
||||
}
|
||||
|
||||
|
||||
@GET
|
||||
@Path("")
|
||||
public Response getAll(@DefaultValue("0") @QueryParam("page") int page,
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize,
|
||||
@QueryParam("sortBy") String sortBy,
|
||||
@DefaultValue("false") @QueryParam("desc") boolean desc) {
|
||||
throw new UnsupportedOperationException();
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
|
||||
@ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the tags"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@Produces(VndMediaType.TAG_COLLECTION)
|
||||
@TypeHint(CollectionDto.class)
|
||||
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) throws IOException, RepositoryNotFoundException {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
Tags tags = getTags(repositoryService);
|
||||
if (tags != null && tags.getTags() != null) {
|
||||
return Response.ok(tagCollectionToDtoMapper.map(namespace, name, tags.getTags())).build();
|
||||
} else {
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Error on getting tag from repository.")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
public Response get(String id) {
|
||||
throw new UnsupportedOperationException();
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
|
||||
@ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the tags"),
|
||||
@ResponseCode(code = 404, condition = "not found, no tag available in the repository"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@Produces(VndMediaType.TAG)
|
||||
@TypeHint(TagDto.class)
|
||||
@Path("{tagName}")
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("tagName") String tagName) throws IOException, RepositoryNotFoundException, TagNotFoundException {
|
||||
NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name);
|
||||
try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
|
||||
Tags tags = getTags(repositoryService);
|
||||
if (tags != null && tags.getTags() != null) {
|
||||
Tag tag = tags.getTags().stream()
|
||||
.filter(t -> tagName.equals(t.getName()))
|
||||
.findFirst()
|
||||
.orElseThrow(TagNotFoundException::new);
|
||||
return Response.ok(tagToTagDtoMapper.map(tag, namespaceAndName)).build();
|
||||
} else {
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Error on getting tag from repository.")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Tags getTags(RepositoryService repositoryService) throws IOException {
|
||||
Repository repository = repositoryService.getRepository();
|
||||
RepositoryPermissions.read(repository).check();
|
||||
return repositoryService.getTagsCommand().getTags();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import sonia.scm.repository.Tag;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static de.otto.edison.hal.Link.link;
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
|
||||
@Mapper
|
||||
@@ -25,7 +26,9 @@ public abstract class TagToTagDtoMapper {
|
||||
@AfterMapping
|
||||
void appendLinks(@MappingTarget TagDto target, @Context NamespaceAndName namespaceAndName) {
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getName()));
|
||||
.self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getName()))
|
||||
.single(link("sources", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())))
|
||||
.single(link("changesets", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())));
|
||||
target.add(linksBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user