mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 00:15:44 +01:00
Peer review
This commit is contained in:
@@ -11,6 +11,8 @@ import org.junit.runners.Parameterized;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assume.assumeFalse;
|
import static org.junit.Assume.assumeFalse;
|
||||||
import static sonia.scm.it.RestUtil.given;
|
import static sonia.scm.it.RestUtil.given;
|
||||||
@@ -64,4 +66,34 @@ public class RepositoryAccessITCase {
|
|||||||
|
|
||||||
assertNotNull(branchName);
|
assertNotNull(branchName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReadContent() throws IOException, InterruptedException {
|
||||||
|
repositoryUtil.createAndCommitFile("a.txt", "a");
|
||||||
|
|
||||||
|
sleep(1000);
|
||||||
|
|
||||||
|
String sourcesUrl = given()
|
||||||
|
.when()
|
||||||
|
.get(TestData.getDefaultRepositoryUrl(repositoryType))
|
||||||
|
.then()
|
||||||
|
.statusCode(HttpStatus.SC_OK)
|
||||||
|
.extract()
|
||||||
|
.path("_links.sources.href");
|
||||||
|
|
||||||
|
String contentUrl = given()
|
||||||
|
.when()
|
||||||
|
.get(sourcesUrl)
|
||||||
|
.then()
|
||||||
|
.statusCode(HttpStatus.SC_OK)
|
||||||
|
.extract()
|
||||||
|
.path("files[0]._links.content.href");
|
||||||
|
|
||||||
|
given()
|
||||||
|
.when()
|
||||||
|
.get(contentUrl)
|
||||||
|
.then()
|
||||||
|
.statusCode(HttpStatus.SC_OK)
|
||||||
|
.body(equalTo("a"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,8 @@ package sonia.scm.repository;
|
|||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||||
import org.tmatesoft.svn.core.SVNLogEntryPath;
|
import org.tmatesoft.svn.core.SVNLogEntryPath;
|
||||||
@@ -52,20 +50,17 @@ import org.tmatesoft.svn.core.internal.util.SVNXMLUtil;
|
|||||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||||
import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry;
|
import org.tmatesoft.svn.core.wc.admin.SVNChangeEntry;
|
||||||
|
|
||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -366,6 +361,7 @@ public final class SvnUtil
|
|||||||
public static long getRevisionNumber(String revision)
|
public static long getRevisionNumber(String revision)
|
||||||
throws RepositoryException
|
throws RepositoryException
|
||||||
{
|
{
|
||||||
|
// REVIEW Bei SVN wird ohne Revision die -1 genommen, was zu einem Fehler führt
|
||||||
long revisionNumber = -1;
|
long revisionNumber = -1;
|
||||||
|
|
||||||
if (Util.isNotEmpty(revision))
|
if (Util.isNotEmpty(revision))
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public class BrowserResultDto extends HalRepresentation implements Iterable<File
|
|||||||
private String revision;
|
private String revision;
|
||||||
private String tag;
|
private String tag;
|
||||||
private String branch;
|
private String branch;
|
||||||
|
// REVIEW files nicht embedded?
|
||||||
private List<FileObjectDto> files;
|
private List<FileObjectDto> files;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -24,6 +25,7 @@ public class BrowserResultDto extends HalRepresentation implements Iterable<File
|
|||||||
return super.add(links);
|
return super.add(links);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// REVIEW return null?
|
||||||
@Override
|
@Override
|
||||||
public Iterator<FileObjectDto> iterator() {
|
public Iterator<FileObjectDto> iterator() {
|
||||||
Iterator<FileObjectDto> it = null;
|
Iterator<FileObjectDto> it = null;
|
||||||
|
|||||||
@@ -39,8 +39,12 @@ public class BrowserResultMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addLinks(BrowserResult browserResult, BrowserResultDto dto, NamespaceAndName namespaceAndName) {
|
private void addLinks(BrowserResult browserResult, BrowserResultDto dto, NamespaceAndName namespaceAndName) {
|
||||||
|
if (browserResult.getRevision() == null) {
|
||||||
|
dto.add(Links.linkingTo().self(resourceLinks.source().selfWithoutRevision(namespaceAndName.getNamespace(), namespaceAndName.getName())).build());
|
||||||
|
} else {
|
||||||
dto.add(Links.linkingTo().self(resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), browserResult.getRevision())).build());
|
dto.add(Links.linkingTo().self(resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), browserResult.getRevision())).build());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,12 @@ public abstract class FileObjectMapper extends BaseMapper<FileObject, FileObject
|
|||||||
|
|
||||||
@AfterMapping
|
@AfterMapping
|
||||||
void addLinks(FileObject fileObject, @MappingTarget FileObjectDto dto, @Context NamespaceAndName namespaceAndName, @Context String revision) {
|
void addLinks(FileObject fileObject, @MappingTarget FileObjectDto dto, @Context NamespaceAndName namespaceAndName, @Context String revision) {
|
||||||
dto.add(Links.linkingTo()
|
Links.Builder links = Links.linkingTo()
|
||||||
.self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getName()))
|
.self(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getPath()));
|
||||||
.single(link("content", resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getName())))
|
if (!dto.isDirectory()) {
|
||||||
.build());
|
links.single(link("content", resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, fileObject.getPath())));
|
||||||
|
}
|
||||||
|
|
||||||
|
dto.add(links.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,11 +291,11 @@ class ResourceLinks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String self(String namespace, String name, String revision) {
|
String self(String namespace, String name, String revision) {
|
||||||
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name, revision).method("sources").parameters().method("getAll").parameters("").href();
|
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("getAll").parameters(revision).href();
|
||||||
}
|
}
|
||||||
|
|
||||||
String selfWithoutRevision(String namespace, String name) {
|
String selfWithoutRevision(String namespace, String name) {
|
||||||
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("getAll").parameters("").href();
|
return sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("getAllWithoutRevision").parameters().href();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String source(String namespace, String name, String revision) {
|
public String source(String namespace, String name, String revision) {
|
||||||
@@ -303,8 +303,12 @@ class ResourceLinks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String sourceWithPath(String namespace, String name, String revision, String path) {
|
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 sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("sources").parameters().method("get").parameters(revision, path).href();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String content(String namespace, String name, String revision, String 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 sourceLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("content").parameters().method("get").parameters(revision, path).href();
|
||||||
|
|||||||
@@ -31,7 +31,14 @@ public class SourceRootResource {
|
|||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(VndMediaType.SOURCE)
|
@Produces(VndMediaType.SOURCE)
|
||||||
@Path("{revision : (\\w+)?}")
|
@Path("")
|
||||||
|
public Response getAllWithoutRevision(@PathParam("namespace") String namespace, @PathParam("name") String name) {
|
||||||
|
return getSource(namespace, name, "/", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(VndMediaType.SOURCE)
|
||||||
|
@Path("{revision}")
|
||||||
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) {
|
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) {
|
||||||
return getSource(namespace, name, "/", revision);
|
return getSource(namespace, name, "/", revision);
|
||||||
}
|
}
|
||||||
@@ -44,8 +51,6 @@ public class SourceRootResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Response getSource(String namespace, String repoName, String path, String revision) {
|
private Response getSource(String namespace, String repoName, String path, String revision) {
|
||||||
BrowserResult browserResult;
|
|
||||||
Response response;
|
|
||||||
NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, repoName);
|
NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, repoName);
|
||||||
try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
|
try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
|
||||||
BrowseCommandBuilder browseCommand = repositoryService.getBrowseCommand();
|
BrowseCommandBuilder browseCommand = repositoryService.getBrowseCommand();
|
||||||
@@ -53,19 +58,18 @@ public class SourceRootResource {
|
|||||||
if (revision != null && !revision.isEmpty()) {
|
if (revision != null && !revision.isEmpty()) {
|
||||||
browseCommand.setRevision(revision);
|
browseCommand.setRevision(revision);
|
||||||
}
|
}
|
||||||
browserResult = browseCommand.getBrowserResult();
|
BrowserResult browserResult = browseCommand.getBrowserResult();
|
||||||
|
|
||||||
if (browserResult != null) {
|
if (browserResult != null) {
|
||||||
response = Response.ok(browserResultMapper.map(browserResult, namespaceAndName)).build();
|
return Response.ok(browserResultMapper.map(browserResult, namespaceAndName)).build();
|
||||||
} else {
|
} else {
|
||||||
response = Response.status(Response.Status.NOT_FOUND).build();
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (RepositoryNotFoundException e) {
|
} catch (RepositoryNotFoundException e) {
|
||||||
response = Response.status(Response.Status.NOT_FOUND).build();
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
} catch (RepositoryException | IOException e) {
|
} catch (RepositoryException | IOException e) {
|
||||||
response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||||
}
|
}
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class FileObjectMapperTest {
|
|||||||
FileObject fileObject = createFileObject();
|
FileObject fileObject = createFileObject();
|
||||||
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision");
|
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision");
|
||||||
|
|
||||||
assertThat(dto.getLinks().getLinkBy("self").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/sources/revision/foo").toString());
|
assertThat(dto.getLinks().getLinkBy("self").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/sources/revision/foo%2Fbar").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -62,14 +62,14 @@ public class FileObjectMapperTest {
|
|||||||
FileObject fileObject = createFileObject();
|
FileObject fileObject = createFileObject();
|
||||||
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision");
|
FileObjectDto dto = mapper.map(fileObject, new NamespaceAndName("namespace", "name"), "revision");
|
||||||
|
|
||||||
assertThat(dto.getLinks().getLinkBy("content").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/content/revision/foo").toString());
|
assertThat(dto.getLinks().getLinkBy("content").get().getHref()).isEqualTo(expectedBaseUri.resolve("namespace/name/content/revision/foo%2Fbar").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileObject createFileObject() {
|
private FileObject createFileObject() {
|
||||||
FileObject fileObject = new FileObject();
|
FileObject fileObject = new FileObject();
|
||||||
fileObject.setName("foo");
|
fileObject.setName("foo");
|
||||||
fileObject.setDescription("bar");
|
fileObject.setDescription("bar");
|
||||||
fileObject.setPath("/foo/bar");
|
fileObject.setPath("foo/bar");
|
||||||
fileObject.setDirectory(false);
|
fileObject.setDirectory(false);
|
||||||
fileObject.setLength(100);
|
fileObject.setLength(100);
|
||||||
fileObject.setLastModified(123L);
|
fileObject.setLastModified(123L);
|
||||||
|
|||||||
Reference in New Issue
Block a user