diff --git a/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java index 2cf7ae5a86..d2db6856a7 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java @@ -38,6 +38,7 @@ package sonia.scm.repository.api; import com.google.common.base.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.NotFoundException; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; import sonia.scm.repository.BrowserResult; @@ -135,7 +136,7 @@ public final class BrowseCommandBuilder * * @throws IOException */ - public BrowserResult getBrowserResult() throws IOException, RevisionNotFoundException { + public BrowserResult getBrowserResult() throws IOException, NotFoundException { BrowserResult result = null; if (disableCache) diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java index 2c9fff589c..74cf91997d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java @@ -35,8 +35,8 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- +import sonia.scm.NotFoundException; import sonia.scm.repository.BrowserResult; -import sonia.scm.repository.RevisionNotFoundException; import java.io.IOException; @@ -60,4 +60,4 @@ public interface BrowseCommand * * @throws IOException */ - BrowserResult getBrowserResult(BrowseCommandRequest request) throws IOException, RevisionNotFoundException;} + BrowserResult getBrowserResult(BrowseCommandRequest request) throws IOException, NotFoundException;} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java index e459d79653..7eb45c8719 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java @@ -35,9 +35,7 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.eclipse.jgit.errors.MissingObjectException; @@ -53,6 +51,7 @@ import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.NotFoundException; import sonia.scm.repository.BrowserResult; import sonia.scm.repository.FileObject; import sonia.scm.repository.GitSubModuleParser; @@ -64,7 +63,6 @@ import sonia.scm.repository.SubRepository; import sonia.scm.util.Util; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.List; @@ -107,7 +105,7 @@ public class GitBrowseCommand extends AbstractGitCommand @Override @SuppressWarnings("unchecked") public BrowserResult getBrowserResult(BrowseCommandRequest request) - throws IOException, RevisionNotFoundException { + throws IOException, NotFoundException { logger.debug("try to create browse result for {}", request); BrowserResult result; @@ -276,7 +274,7 @@ public class GitBrowseCommand extends AbstractGitCommand return result; } - private FileObject getEntry(org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId) throws IOException, RevisionNotFoundException { + private FileObject getEntry(org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId) throws IOException, NotFoundException { RevWalk revWalk = null; TreeWalk treeWalk = null; @@ -328,7 +326,7 @@ public class GitBrowseCommand extends AbstractGitCommand return Strings.isNullOrEmpty(request.getPath()) || "/".equals(request.getPath()); } - private FileObject findChildren(FileObject parent, org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, RevisionNotFoundException { + private FileObject findChildren(FileObject parent, org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, NotFoundException { List files = Lists.newArrayList(); while (treeWalk.next()) { @@ -360,11 +358,26 @@ public class GitBrowseCommand extends AbstractGitCommand } private FileObject first(org.eclipse.jgit.lib.Repository repo, - BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, RevisionNotFoundException { - if (!treeWalk.next()) { - throw new IOException("tree seams to be empty"); + BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, NotFoundException { + String[] parts = request.getPath().split("/"); + int current = 0; + int limit = parts.length; + + while (treeWalk.next()) { + String name = treeWalk.getNameString(); + + if (name.equalsIgnoreCase(parts[current])) { + current++; + + if (current >= limit) { + return createFileObject(repo, request, revId, treeWalk); + } else { + treeWalk.enterSubtree(); + } + } } - return createFileObject(repo, request, revId, treeWalk); + + throw new NotFoundException("file", request.getPath()); } @SuppressWarnings("unchecked") diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java index 9029e732d0..7b00419a43 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java @@ -36,10 +36,10 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- import org.junit.Test; +import sonia.scm.NotFoundException; import sonia.scm.repository.BrowserResult; import sonia.scm.repository.FileObject; import sonia.scm.repository.GitConstants; -import sonia.scm.repository.RevisionNotFoundException; import java.io.IOException; import java.util.List; @@ -60,7 +60,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase { @Test - public void testGetFile() throws IOException, RevisionNotFoundException { + public void testGetFile() throws IOException, NotFoundException { BrowseCommandRequest request = new BrowseCommandRequest(); request.setPath("a.txt"); BrowserResult result = createCommand().getBrowserResult(request); @@ -72,7 +72,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase * Test browse command with default branch. */ @Test - public void testDefaultBranch() throws IOException, RevisionNotFoundException { + public void testDefaultBranch() throws IOException, NotFoundException { // without default branch, the repository head should be used FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile(); assertNotNull(root); @@ -104,7 +104,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase } @Test - public void testBrowse() throws IOException, RevisionNotFoundException { + public void testBrowse() throws IOException, NotFoundException { FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile(); assertNotNull(root); @@ -143,7 +143,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase } @Test - public void testBrowseSubDirectory() throws IOException, RevisionNotFoundException { + public void testBrowseSubDirectory() throws IOException, NotFoundException { BrowseCommandRequest request = new BrowseCommandRequest(); request.setPath("c"); @@ -190,7 +190,7 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase } @Test - public void testRecursive() throws IOException, RevisionNotFoundException { + public void testRecursive() throws IOException, NotFoundException { BrowseCommandRequest request = new BrowseCommandRequest(); request.setRecursive(true); 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 d2b9b382d2..ce15a1a76b 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 @@ -3,8 +3,6 @@ package sonia.scm.api.v2.resources; import sonia.scm.NotFoundException; import sonia.scm.repository.BrowserResult; import sonia.scm.repository.NamespaceAndName; -import sonia.scm.repository.RepositoryNotFoundException; -import sonia.scm.repository.RevisionNotFoundException; import sonia.scm.repository.api.BrowseCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; @@ -33,14 +31,14 @@ public class SourceRootResource { @GET @Produces(VndMediaType.SOURCE) @Path("") - public Response getAllWithoutRevision(@PathParam("namespace") String namespace, @PathParam("name") String name) throws RevisionNotFoundException, RepositoryNotFoundException, IOException { + public Response getAllWithoutRevision(@PathParam("namespace") String namespace, @PathParam("name") String name) throws NotFoundException, IOException { 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) throws RevisionNotFoundException, RepositoryNotFoundException, IOException { + public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) throws NotFoundException, IOException { return getSource(namespace, name, "/", revision); } @@ -51,7 +49,7 @@ public class SourceRootResource { return getSource(namespace, name, path, revision); } - private Response getSource(String namespace, String repoName, String path, String revision) throws IOException, RevisionNotFoundException, RepositoryNotFoundException { + private Response getSource(String namespace, String repoName, String path, String revision) throws IOException, NotFoundException { NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, repoName); try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { BrowseCommandBuilder browseCommand = repositoryService.getBrowseCommand(); @@ -59,6 +57,7 @@ public class SourceRootResource { if (revision != null && !revision.isEmpty()) { browseCommand.setRevision(revision); } + browseCommand.setDisableCache(true); BrowserResult browserResult = browseCommand.getBrowserResult(); if (browserResult != null) { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/SourceRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/SourceRootResourceTest.java index 66c7c487c1..c3059355cd 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/SourceRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/SourceRootResourceTest.java @@ -10,11 +10,11 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.NotFoundException; import sonia.scm.repository.BrowserResult; import sonia.scm.repository.FileObject; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.RepositoryNotFoundException; -import sonia.scm.repository.RevisionNotFoundException; import sonia.scm.repository.api.BrowseCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; @@ -22,8 +22,6 @@ import sonia.scm.repository.api.RepositoryServiceFactory; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -69,7 +67,7 @@ public class SourceRootResourceTest extends RepositoryTestBase { } @Test - public void shouldReturnSources() throws URISyntaxException, IOException, RevisionNotFoundException { + public void shouldReturnSources() throws URISyntaxException, IOException, NotFoundException { BrowserResult result = createBrowserResult(); when(browseCommandBuilder.getBrowserResult()).thenReturn(result); MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/sources"); @@ -92,7 +90,7 @@ public class SourceRootResourceTest extends RepositoryTestBase { } @Test - public void shouldGetResultForSingleFile() throws URISyntaxException, IOException, RevisionNotFoundException { + public void shouldGetResultForSingleFile() throws URISyntaxException, IOException, NotFoundException { FileObject fileObject = new FileObject(); fileObject.setName("File Object!"); BrowserResult browserResult = new BrowserResult("revision", fileObject);