custom subversion collection renderer

This commit is contained in:
Sebastian Sdorra
2013-11-10 15:56:54 +01:00
parent e1d3344f9e
commit 2b9fe1d671
2 changed files with 390 additions and 9 deletions

View File

@@ -33,23 +33,42 @@ package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.io.Closeables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Ordering;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.internal.server.dav.CollectionRenderer;
import org.tmatesoft.svn.core.internal.server.dav.DAVPathUtil;
import org.tmatesoft.svn.core.internal.server.dav.DAVResource;
import org.tmatesoft.svn.core.internal.server.dav.DAVResourceURI;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryProvider;
import sonia.scm.template.Template;
import sonia.scm.template.TemplateEngine;
import sonia.scm.template.TemplateEngineFactory;
import sonia.scm.url.RepositoryUrlProvider;
import sonia.scm.url.UrlProvider;
import sonia.scm.url.UrlProviderFactory;
import sonia.scm.util.HttpUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
/**
*
* @author Sebastian Sdorra
@@ -61,18 +80,31 @@ public class SvnCollectionRenderer implements CollectionRenderer
private static final String RESOURCE_SVNINDEX =
"sonia/scm/svn.index.mustache";
/**
* the logger for SvnCollectionRenderer
*/
private static final Logger logger =
LoggerFactory.getLogger(SvnCollectionRenderer.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
*
* @param configuration
* @param templateEngineFactory
* @param repositoryProvider
*/
@Inject
public SvnCollectionRenderer(TemplateEngineFactory templateEngineFactory)
public SvnCollectionRenderer(ScmConfiguration configuration,
TemplateEngineFactory templateEngineFactory,
RepositoryProvider repositoryProvider)
{
this.configuration = configuration;
this.templateEngineFactory = templateEngineFactory;
this.repositoryProvider = repositoryProvider;
}
//~--- methods --------------------------------------------------------------
@@ -98,19 +130,354 @@ public class SvnCollectionRenderer implements CollectionRenderer
{
Template template = engine.getTemplate(RESOURCE_SVNINDEX);
template.execute(writer, new Object());
template.execute(writer, createRepositoryWrapper(resource));
}
catch (IOException ex)
{
throw new SVNException(SVNErrorMessage.UNKNOWN_ERROR_MESSAGE);
logger.error("could not render directory", ex);
throw new SVNException(SVNErrorMessage.UNKNOWN_ERROR_MESSAGE, ex);
}
writer.flush();
buffer.append(writer.toString());
}
/**
* Method description
*
*
* @param resource
*
* @return
*
* @throws SVNException
*/
private RepositoryWrapper createRepositoryWrapper(DAVResource resource)
throws SVNException
{
Builder<DirectoryEntry> entries = ImmutableList.builder();
DAVResourceURI uri = resource.getResourceURI();
String path = uri.getPath();
if (!HttpUtil.SEPARATOR_PATH.equals(path))
{
String completePath = HttpUtil.append(uri.getContext(), path);
String parent = DAVPathUtil.removeTail(completePath, true);
entries.add(new DirectoryEntry("..", parent, true));
}
for (Iterator iterator = resource.getEntries().iterator();
iterator.hasNext(); )
{
SVNDirEntry entry = (SVNDirEntry) iterator.next();
entries.add(new DirectoryEntry(resource, entry));
}
UrlProvider urlProvider =
UrlProviderFactory.createUrlProvider(configuration.getBaseUrl(),
UrlProviderFactory.TYPE_WUI);
//J-
return new RepositoryWrapper(
urlProvider.getRepositoryUrlProvider(),
repositoryProvider.get(),
resource,
new DirectoryOrdering().immutableSortedCopy(entries.build())
);
//J+
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 13/11/10
* @author Enter your name here...
*/
private static class DirectoryEntry
{
/**
* Constructs ...
*
*
* @param resource
* @param entry
*/
public DirectoryEntry(DAVResource resource, SVNDirEntry entry)
{
this.name = entry.getName();
this.url = createUrl(resource, entry);
this.directory = entry.getKind() == SVNNodeKind.DIR;
}
/**
* Constructs ...
*
*
* @param name
* @param url
* @param directory
*/
public DirectoryEntry(String name, String url, boolean directory)
{
this.name = name;
this.url = url;
this.directory = directory;
}
//~--- get methods --------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public String getName()
{
return name;
}
/**
* Method description
*
*
* @return
*/
public String getUrl()
{
return url;
}
/**
* Method description
*
*
* @return
*/
public boolean isDirectory()
{
return directory;
}
//~--- methods ------------------------------------------------------------
/**
* Method description
*
*
* @param resource
* @param entry
*
* @return
*/
private String createUrl(DAVResource resource, SVNDirEntry entry)
{
StringBuilder buffer = new StringBuilder();
buffer.append(resource.getResourceURI().getContext());
String path = resource.getResourceURI().getPath();
if (!HttpUtil.SEPARATOR_PATH.equals(path))
{
buffer.append(path);
}
buffer.append(DAVPathUtil.standardize(entry.getName()));
if (isDirectory())
{
buffer.append(HttpUtil.SEPARATOR_PATH);
}
return buffer.toString();
}
//~--- fields -------------------------------------------------------------
/** Field description */
private final boolean directory;
/** Field description */
private final String name;
/** Field description */
private final String url;
}
/**
* Class description
*
*
* @version Enter version here..., 13/11/10
* @author Enter your name here...
*/
private static class DirectoryOrdering extends Ordering<DirectoryEntry>
{
/**
* Method description
*
*
* @param left
* @param right
*
* @return
*/
@Override
public int compare(DirectoryEntry left, DirectoryEntry right)
{
int result;
if (left.isDirectory() &&!right.isDirectory())
{
result = -1;
}
else if (!left.isDirectory() && right.isDirectory())
{
result = 1;
}
else
{
if ("..".equals(left.getName()))
{
result = -1;
}
else if ("..".equals(right.getName()))
{
result = 1;
}
else
{
result = left.getName().compareTo(right.getName());
}
}
return result;
}
}
/**
* Class description
*
*
* @version Enter version here..., 13/11/10
* @author Enter your name here...
*/
private static class RepositoryWrapper
{
/**
* Constructs ...
*
*
*
* @param repositoryUrlProvider
* @param repository
* @param resource
* @param entries
*/
public RepositoryWrapper(RepositoryUrlProvider repositoryUrlProvider,
Repository repository, DAVResource resource, List<DirectoryEntry> entries)
{
this.repositoryUrlProvider = repositoryUrlProvider;
this.repository = repository;
this.resource = resource;
this.entries = entries;
}
//~--- get methods --------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public String getCommitViewLink()
{
return repositoryUrlProvider.getChangesetUrl(repository.getId(), 0, 20);
}
/**
* Method description
*
*
* @return
*/
public List<DirectoryEntry> getEntries()
{
return entries;
}
/**
* Method description
*
*
* @return
*/
public String getName()
{
return repository.getName();
}
/**
* Method description
*
*
* @return
*/
public Repository getRepository()
{
return repository;
}
/**
* Method description
*
*
* @return
*/
public String getSourceViewLink()
{
return repositoryUrlProvider.getBrowseUrl(repository.getId(),
resource.getResourceURI().getPath(), null);
}
//~--- fields -------------------------------------------------------------
/** Field description */
private final List<DirectoryEntry> entries;
/** Field description */
private final Repository repository;
/** Field description */
private final RepositoryUrlProvider repositoryUrlProvider;
/** Field description */
private final DAVResource resource;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final ScmConfiguration configuration;
/** Field description */
private final RepositoryProvider repositoryProvider;
/** Field description */
private final TemplateEngineFactory templateEngineFactory;
}

View File

@@ -33,7 +33,7 @@
<html>
<head>
<title>SCM :: Manager - Subversion Repository</title>
<title>SCM :: Manager - Subversion Repository - {{name}}</title>
<style type="text/css">
body {
background-color: #ffffff;
@@ -93,21 +93,35 @@
</head>
<body>
<h1>SCM :: Manager - Subversion Repository</h1>
<h1>SCM :: Manager - Subversion Repository - {{name}}</h1>
<table>
<tbody>
{{#entries}}
<tr>
<td>
<a href="{{url}}">
{{name}}{{#directory}}/{{/directory}}
</a>
</td>
</tr>
{{/entries}}
</tbody>
</table>
<h2>Notes</h2>
<div>
<p>
This page is only a quick source view for subversion.
The full source view is <a href="">here</a>.
The full source view is <a href="{{sourceViewLink}}">here</a>.
</p>
<ul>
<li>
<a href="">Commits</a>
<a href="{{commitViewLink}}">Commits</a>
</li>
<li>
<a href="">Source</a>
<a href="{{sourceViewLink}}">Source</a>
</li>
</ul>
</div>