added browser support for git submodules

This commit is contained in:
Sebastian Sdorra
2012-01-07 15:25:22 +01:00
parent ddfac458a4
commit 01534177c2
4 changed files with 374 additions and 5 deletions

View File

@@ -54,12 +54,15 @@ import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
*
@@ -68,6 +71,9 @@ import java.util.List;
public class GitRepositoryBrowser implements RepositoryBrowser
{
/** Field description */
public static final String PATH_MODULES = ".gitmodules";
/** the logger for GitRepositoryBrowser */
private static final Logger logger =
LoggerFactory.getLogger(GitRepositoryBrowser.class);
@@ -98,7 +104,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser
* @param path
* @param output
*
*
* @throws IOException
* @throws RepositoryException
*/
@@ -108,6 +113,37 @@ public class GitRepositoryBrowser implements RepositoryBrowser
{
File directory = handler.getDirectory(repository);
org.eclipse.jgit.lib.Repository repo = GitUtil.open(directory);
try
{
ObjectId revId = GitUtil.getRevisionId(repo, revision);
getContent(repo, revId, path, output);
}
finally
{
GitUtil.close(repo);
}
}
/**
* Method description
*
*
*
* @param repo
* @param revId
* @param path
* @param output
*
*
* @throws IOException
* @throws RepositoryException
*/
public void getContent(org.eclipse.jgit.lib.Repository repo, ObjectId revId,
String path, OutputStream output)
throws IOException, RepositoryException
{
TreeWalk treeWalk = null;
RevWalk revWalk = null;
@@ -116,8 +152,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser
treeWalk = new TreeWalk(repo);
treeWalk.setRecursive(Util.nonNull(path).contains("/"));
ObjectId revId = GitUtil.getRevisionId(repo, revision);
if (logger.isDebugEnabled())
{
logger.debug("load content for {} at {}", path, revId.name());
@@ -166,7 +200,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser
{
GitUtil.release(revWalk);
GitUtil.release(treeWalk);
GitUtil.close(repo);
}
}
@@ -232,6 +265,64 @@ public class GitRepositoryBrowser implements RepositoryBrowser
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param files
* @param repo
* @param revId
* @param path
*
* @throws IOException
* @throws RepositoryException
*/
private void appendSubModules(List<FileObject> files,
org.eclipse.jgit.lib.Repository repo,
ObjectId revId, String path)
throws IOException, RepositoryException
{
path = Util.nonNull(path);
Map<String, SubRepository> subRepositories = getSubRepositories(repo,
revId);
if (subRepositories != null)
{
for (Entry<String, SubRepository> e : subRepositories.entrySet())
{
String p = e.getKey();
if (p.startsWith(path))
{
p = p.substring(path.length());
if (p.startsWith("/"))
{
p = p.substring(1);
}
if (p.endsWith("/"))
{
p = p.substring(0, p.length() - 1);
}
if (!p.contains("/"))
{
FileObject fo = new FileObject();
fo.setDirectory(true);
fo.setPath(path);
fo.setName(p);
fo.setSubRepository(e.getValue());
files.add(fo);
}
}
}
}
}
/**
* Method description
*
@@ -349,10 +440,11 @@ public class GitRepositoryBrowser implements RepositoryBrowser
* @return
*
* @throws IOException
* @throws RepositoryException
*/
private BrowserResult getResult(org.eclipse.jgit.lib.Repository repo,
ObjectId revId, String path)
throws IOException
throws IOException, RepositoryException
{
BrowserResult result = null;
RevWalk revWalk = null;
@@ -383,6 +475,8 @@ public class GitRepositoryBrowser implements RepositoryBrowser
List<FileObject> files = new ArrayList<FileObject>();
appendSubModules(files, repo, revId, path);
if (Util.isEmpty(path))
{
while (treeWalk.next())
@@ -439,6 +533,44 @@ public class GitRepositoryBrowser implements RepositoryBrowser
return result;
}
/**
* Method description
*
*
* @param repo
* @param revision
*
* @return
*
* @throws IOException
* @throws RepositoryException
*/
private Map<String, SubRepository> getSubRepositories(
org.eclipse.jgit.lib.Repository repo, ObjectId revision)
throws IOException, RepositoryException
{
if (logger.isDebugEnabled())
{
logger.debug("read submodules of {} at {}", repository.getName(),
revision);
}
Map<String, SubRepository> subRepositories = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
getContent(repo, revision, PATH_MODULES, baos);
subRepositories = GitSubModuleParser.parse(baos.toString());
}
catch (PathNotFoundException ex)
{
logger.trace("could not find .gitmodules", ex);
}
return subRepositories;
}
//~--- fields ---------------------------------------------------------------
/** Field description */

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
*
* @author Sebastian Sdorra
*/
public class GitSubModuleParser
{
/**
* //~--- methods --------------------------------------------------------------
*
*
* Method description
*
*
* @param content
*
* @return
*/
public static Map<String, SubRepository> parse(String content)
{
Map<String, SubRepository> subRepositories = new HashMap<String,
SubRepository>();
Scanner scanner = new Scanner(content);
SubRepository repository = null;
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
if (Util.isNotEmpty(line))
{
line = line.trim();
if (line.startsWith("[") && line.endsWith("]"))
{
repository = new SubRepository();
}
else if (line.startsWith("path"))
{
subRepositories.put(getValue(line), repository);
}
else if (line.startsWith("url"))
{
repository.setRepositoryUrl(getValue(line));
}
}
}
return subRepositories;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param line
*
* @return
*/
private static String getValue(String line)
{
return line.split("=")[1].trim();
}
}