diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java new file mode 100644 index 0000000000..b62f5fa124 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultDto.java @@ -0,0 +1,18 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.HalRepresentation; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.Collection; + +@Getter +@Setter +@NoArgsConstructor +public class BrowserResultDto extends HalRepresentation { + private String revision; + private String tag; + private String branch; + private Collection files; +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java new file mode 100644 index 0000000000..ecc59900e5 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BrowserResultToBrowserResultDtoMapper.java @@ -0,0 +1,9 @@ +package sonia.scm.api.v2.resources; + +import org.mapstruct.Mapper; +import sonia.scm.repository.BrowserResult; + +@Mapper +public abstract class BrowserResultToBrowserResultDtoMapper extends BaseMapper { + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java new file mode 100644 index 0000000000..2f4c7a07c7 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectDto.java @@ -0,0 +1,28 @@ +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; + +import java.time.Instant; + +@Getter +@Setter +@NoArgsConstructor +public class FileObjectDto extends HalRepresentation { + private String name; + private String path; + private boolean directory; + private String description; + private int length; + // TODO: What about subrepos? + private Instant lastModified; + + @Override + @SuppressWarnings("squid:S1185") // We want to have this method available in this package + protected HalRepresentation add(Links links) { + return super.add(links); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java new file mode 100644 index 0000000000..86a5e5454b --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapper.java @@ -0,0 +1,9 @@ +package sonia.scm.api.v2.resources; + +import org.mapstruct.Mapper; +import sonia.scm.repository.FileObject; + +@Mapper +public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper { + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java index d05cc7ea6e..46d8f02c91 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/SourceRootResource.java @@ -1,20 +1,45 @@ package sonia.scm.api.v2.resources; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.api.BrowseCommandBuilder; +import sonia.scm.repository.api.RepositoryService; +import sonia.scm.repository.api.RepositoryServiceFactory; + +import javax.inject.Inject; +import javax.ws.rs.*; import javax.ws.rs.core.Response; +import java.io.IOException; public class SourceRootResource { + private final RepositoryServiceFactory serviceFactory; + + @Inject + public SourceRootResource(RepositoryServiceFactory serviceFactory) { + this.serviceFactory = serviceFactory; + } + @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(); + public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) { + + BrowserResult browserResult = null; + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + BrowseCommandBuilder browseCommand = repositoryService.getBrowseCommand(); + browseCommand.setPath("/"); + browserResult = browseCommand.getBrowserResult(); + } catch (RepositoryNotFoundException e) { + e.printStackTrace(); + } catch (RepositoryException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return Response.ok(browserResult.toString()).build(); } @GET diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java new file mode 100644 index 0000000000..7babd4b329 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileObjectToFileObjectDtoMapperTest.java @@ -0,0 +1,69 @@ +package sonia.scm.api.v2.resources; + +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.repository.FileObject; + +import java.net.URI; +import java.net.URISyntaxException; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(MockitoJUnitRunner.class) +public class FileObjectToFileObjectDtoMapperTest { + private final URI baseUri = URI.create("http://example.com/base/"); + + @InjectMocks + private FileObjectToFileObjectDtoMapperImpl mapper; + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + + @Before + public void init() throws URISyntaxException { + initMocks(this); + subjectThreadState.bind(); + ThreadContext.bind(subject); + } + + + @Test + public void shouldMapAttributesCorrectly() { + FileObject fileObject = createFileObject(); + FileObjectDto dto = mapper.map(fileObject); + + assertEqualAttributes(fileObject, dto); + } + + + private FileObject createFileObject() { + FileObject fileObject = new FileObject(); + fileObject.setName("foo"); + fileObject.setDescription("bar"); + fileObject.setPath("/foo/bar"); + fileObject.setDirectory(false); + fileObject.setLength(100); + fileObject.setLastModified(123L); + return fileObject; + } + + //TODO: subrepo + private void assertEqualAttributes(FileObject fileObject, FileObjectDto dto) { + assertEquals(fileObject.getName(), dto.getName()); + assertEquals(fileObject.getDescription(), dto.getDescription()); + assertEquals(fileObject.getPath(), dto.getPath()); + assertEquals(fileObject.isDirectory(), dto.isDirectory()); + assertEquals(fileObject.getLength(), dto.getLength()); + assertEquals((long)fileObject.getLastModified(), dto.getLastModified().toEpochMilli()); + } +}