mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 11:35:57 +01:00
custom subversion collection renderer
This commit is contained in:
@@ -33,23 +33,42 @@ package sonia.scm.web;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- 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 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.SVNErrorMessage;
|
||||||
import org.tmatesoft.svn.core.SVNException;
|
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.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.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.Template;
|
||||||
import sonia.scm.template.TemplateEngine;
|
import sonia.scm.template.TemplateEngine;
|
||||||
import sonia.scm.template.TemplateEngineFactory;
|
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 ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -61,18 +80,31 @@ public class SvnCollectionRenderer implements CollectionRenderer
|
|||||||
private static final String RESOURCE_SVNINDEX =
|
private static final String RESOURCE_SVNINDEX =
|
||||||
"sonia/scm/svn.index.mustache";
|
"sonia/scm/svn.index.mustache";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the logger for SvnCollectionRenderer
|
||||||
|
*/
|
||||||
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger(SvnCollectionRenderer.class);
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs ...
|
* Constructs ...
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
* @param templateEngineFactory
|
* @param templateEngineFactory
|
||||||
|
* @param repositoryProvider
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public SvnCollectionRenderer(TemplateEngineFactory templateEngineFactory)
|
public SvnCollectionRenderer(ScmConfiguration configuration,
|
||||||
|
TemplateEngineFactory templateEngineFactory,
|
||||||
|
RepositoryProvider repositoryProvider)
|
||||||
{
|
{
|
||||||
|
this.configuration = configuration;
|
||||||
this.templateEngineFactory = templateEngineFactory;
|
this.templateEngineFactory = templateEngineFactory;
|
||||||
|
this.repositoryProvider = repositoryProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -98,19 +130,354 @@ public class SvnCollectionRenderer implements CollectionRenderer
|
|||||||
{
|
{
|
||||||
Template template = engine.getTemplate(RESOURCE_SVNINDEX);
|
Template template = engine.getTemplate(RESOURCE_SVNINDEX);
|
||||||
|
|
||||||
template.execute(writer, new Object());
|
template.execute(writer, createRepositoryWrapper(resource));
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
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();
|
writer.flush();
|
||||||
buffer.append(writer.toString());
|
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 ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private final ScmConfiguration configuration;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private final RepositoryProvider repositoryProvider;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private final TemplateEngineFactory templateEngineFactory;
|
private final TemplateEngineFactory templateEngineFactory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>SCM :: Manager - Subversion Repository</title>
|
<title>SCM :: Manager - Subversion Repository - {{name}}</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
@@ -93,21 +93,35 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<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>
|
<h2>Notes</h2>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
This page is only a quick source view for subversion.
|
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>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="">Commits</a>
|
<a href="{{commitViewLink}}">Commits</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="">Source</a>
|
<a href="{{sourceViewLink}}">Source</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user