From 5adea3f28bf8b717ab601ca2e8380a027f47fde4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 18 Jun 2011 16:41:23 +0200 Subject: [PATCH] improve repository browser api --- .../scm/repository/GitRepositoryBrowser.java | 56 +++++---- .../scm/repository/HgRepositoryBrowser.java | 17 ++- .../scm/repository/SvnRepositoryBrowser.java | 37 +++--- .../scm/repository/RepositoryBrowser.java | 6 +- .../rest/resources/RepositoryResource.java | 108 +++++++++++++----- 5 files changed, 149 insertions(+), 75 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index bfde6aaf2c..a56405df0e 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -37,7 +37,6 @@ package sonia.scm.repository; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; -import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; @@ -52,7 +51,7 @@ import sonia.scm.util.Util; import java.io.File; import java.io.IOException; -import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -86,14 +85,14 @@ public class GitRepositoryBrowser implements RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ @Override - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { throw new UnsupportedOperationException("Not supported yet."); @@ -123,9 +122,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser try { - ObjectId revId = getRevisionId(repo, revision); - DirCache cache = new DirCache(directory, FS.DETECTED); TreeWalk treeWalk = new TreeWalk(repo); @@ -159,21 +156,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser return result; } - - - private ObjectId getRevisionId( org.eclipse.jgit.lib.Repository repo, String revision ) throws IOException{ - ObjectId revId = null; - - if (Util.isNotEmpty(revision)) - { - revId = repo.resolve(revision); - } - else - { - revId = repo.resolve(Constants.HEAD); - } - return revId; - } //~--- methods -------------------------------------------------------------- @@ -187,7 +169,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser * @return * * @throws IOException - * @throws MissingObjectException */ private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo, TreeWalk treeWalk) @@ -209,6 +190,37 @@ public class GitRepositoryBrowser implements RepositoryBrowser return file; } + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param repo + * @param revision + * + * @return + * + * @throws IOException + */ + private ObjectId getRevisionId(org.eclipse.jgit.lib.Repository repo, + String revision) + throws IOException + { + ObjectId revId = null; + + if (Util.isNotEmpty(revision)) + { + revId = repo.resolve(revision); + } + else + { + revId = repo.resolve(Constants.HEAD); + } + + return revId; + } + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java index 342d25da5a..838f23c03a 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java @@ -109,14 +109,14 @@ public class HgRepositoryBrowser implements RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ @Override - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { if (Util.isEmpty(revision)) @@ -141,7 +141,18 @@ public class HgRepositoryBrowser implements RepositoryBrowser logger.debug(msg.toString()); } - return builder.directory(directory).start().getInputStream(); + Process p = builder.directory(directory).start(); + InputStream input = null; + + try + { + input = p.getInputStream(); + IOUtil.copy(input, output); + } + finally + { + IOUtil.close(input); + } } /** diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java index eef15c2767..fb6f287f81 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java @@ -50,11 +50,9 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; @@ -95,30 +93,23 @@ public class SvnRepositoryBrowser implements RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ @Override - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { - - // TODO change the api, to remove the ByteArray streams - InputStream content = null; long revisionNumber = getRevisionNumber(revision); SVNRepository svnRepository = null; try { svnRepository = getSvnRepository(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - svnRepository.getFile(path, revisionNumber, new SVNProperties(), baos); - content = new ByteArrayInputStream(baos.toByteArray()); + svnRepository.getFile(path, revisionNumber, new SVNProperties(), output); } catch (SVNException ex) { @@ -126,10 +117,8 @@ public class SvnRepositoryBrowser implements RepositoryBrowser } finally { - svnRepository.closeSession(); + close(svnRepository); } - - return content; } /** @@ -202,7 +191,7 @@ public class SvnRepositoryBrowser implements RepositoryBrowser } finally { - svnRepository.closeSession(); + close(svnRepository); } return result; @@ -210,6 +199,20 @@ public class SvnRepositoryBrowser implements RepositoryBrowser //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param svnRepository + */ + private void close(SVNRepository svnRepository) + { + if (svnRepository != null) + { + svnRepository.closeSession(); + } + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java index e3d9efbefd..7edc92df5f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java @@ -36,7 +36,7 @@ package sonia.scm.repository; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; -import java.io.InputStream; +import java.io.OutputStream; /** * @@ -52,13 +52,13 @@ public interface RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException;; /** diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 06aaedbb26..fcb2558275 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -50,6 +50,7 @@ import sonia.scm.repository.ChangesetPreProcessor; import sonia.scm.repository.ChangesetViewer; import sonia.scm.repository.FileObject; import sonia.scm.repository.FileObjectNameComparator; +import sonia.scm.repository.PathNotFoundException; import sonia.scm.repository.Permission; import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; @@ -58,15 +59,14 @@ import sonia.scm.repository.RepositoryBrowser; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.RevisionNotFoundException; import sonia.scm.util.HttpUtil; -import sonia.scm.util.IOUtil; import sonia.scm.util.Util; import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -275,34 +275,7 @@ public class RepositoryResource if (browser != null) { - final InputStream content = browser.getContent(revision, path); - - if (content != null) - { - output = new StreamingOutput() - { - @Override - public void write(OutputStream output) - throws IOException, WebApplicationException - { - try - { - IOUtil.copy(content, output); - } - finally - { - IOUtil.close(content); - } - } - }; - } - else if (logger.isWarnEnabled()) - { - logger.warn( - "could not find content, repository: {}, path: {}, revision: {}", - new Object[] { repository.getId(), - path, revision }); - } + output = new BrowserStreamingOutput(browser, revision, path); } else if (logger.isWarnEnabled()) { @@ -516,6 +489,81 @@ public class RepositoryResource PermissionType.OWNER); } + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 11/06/18 + * @author Enter your name here... + */ + private static class BrowserStreamingOutput implements StreamingOutput + { + + /** + * Constructs ... + * + * + * @param browser + * @param revision + * @param path + */ + public BrowserStreamingOutput(RepositoryBrowser browser, String revision, + String path) + { + this.browser = browser; + this.revision = revision; + this.path = path; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param output + * + * @throws IOException + * @throws WebApplicationException + */ + @Override + public void write(OutputStream output) + throws IOException, WebApplicationException + { + try + { + browser.getContent(revision, path, output); + } + catch (PathNotFoundException ex) + { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + catch (RevisionNotFoundException ex) + { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + catch (RepositoryException ex) + { + throw new WebApplicationException( + ex, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private RepositoryBrowser browser; + + /** Field description */ + private String path; + + /** Field description */ + private String revision; + } + + //~--- fields --------------------------------------------------------------- /** Field description */