added paging to ChangesetViewer

This commit is contained in:
Sebastian Sdorra
2011-04-03 14:24:52 +02:00
parent a8598ffdc7
commit 8b7774d284
6 changed files with 213 additions and 63 deletions

View File

@@ -54,7 +54,6 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -73,9 +72,12 @@ public class HgChangesetViewer implements ChangesetViewer
public static final String ID_TIP = "tip"; public static final String ID_TIP = "tip";
/** Field description */ /** Field description */
public static final String TEMPLATE = public static final String TEMPLATE_CHANGESETS =
"<changeset><id>{rev}:{node|short}</id><author>{author|escape}</author><description>{desc|escape}</description><date>{date|isodatesec}</date></changeset>\n"; "<changeset><id>{rev}:{node|short}</id><author>{author|escape}</author><description>{desc|escape}</description><date>{date|isodatesec}</date></changeset>\n";
/** Field description */
public static final String TEMPLATE_TOTAL = "{rev}";
/** the logger for HgChangesetViewer */ /** the logger for HgChangesetViewer */
private static final Logger logger = private static final Logger logger =
LoggerFactory.getLogger(HgChangesetViewer.class); LoggerFactory.getLogger(HgChangesetViewer.class);
@@ -104,23 +106,34 @@ public class HgChangesetViewer implements ChangesetViewer
/** /**
* *
* @param startId *
* @param start
* @param max * @param max
* *
* @return * @return
*/ */
@Override @Override
public List<Changeset> getChangesets(String startId, int max) public ChangesetPagingResult getChangesets(int start, int max)
{ {
List<Changeset> changesets = null; ChangesetPagingResult changesets = null;
InputStream in = null; InputStream in = null;
try try
{ {
String repositoryPath = getRepositoryPath(repository); String repositoryPath = getRepositoryPath(repository);
int total = getTotalChangesets(repositoryPath);
int startRev = total - start;
int endRev = startRev - max;
if (endRev < 0)
{
endRev = 0;
}
Command command = new SimpleCommand(handler.getConfig().getHgBinary(), Command command = new SimpleCommand(handler.getConfig().getHgBinary(),
"-R", repositoryPath, "log", "-r", "tip:0", "-l", "-R", repositoryPath, "log", "-r",
String.valueOf(max), "--template", TEMPLATE); startRev + ":" + endRev, "--template",
TEMPLATE_CHANGESETS);
CommandResult result = command.execute(); CommandResult result = command.execute();
if (result.isSuccessfull()) if (result.isSuccessfull())
@@ -132,12 +145,12 @@ public class HgChangesetViewer implements ChangesetViewer
if ((cs != null) && Util.isNotEmpty(cs.getChangesets())) if ((cs != null) && Util.isNotEmpty(cs.getChangesets()))
{ {
changesets = cs.getChangesets(); changesets = new ChangesetPagingResult(total, cs.getChangesets());
} }
else if (logger.isWarnEnabled()) else if (logger.isWarnEnabled())
{ {
logger.warn("could not find any changeset from {} to +{}", startId, logger.warn("could not find any changeset from {} to {}", start,
max); start + max);
} }
} }
else else
@@ -166,20 +179,6 @@ public class HgChangesetViewer implements ChangesetViewer
return changesets; return changesets;
} }
/**
* Method description
*
*
* @param max
*
* @return
*/
@Override
public List<Changeset> getLastChangesets(int max)
{
return getChangesets(ID_TIP, max);
}
/** /**
* Method description * Method description
* *
@@ -231,6 +230,32 @@ public class HgChangesetViewer implements ChangesetViewer
return handler.getDirectory(repository).getAbsolutePath(); return handler.getDirectory(repository).getAbsolutePath();
} }
/**
* Method description
*
*
* @param repositoryPath
*
* @return
*
* @throws IOException
*/
private int getTotalChangesets(String repositoryPath) throws IOException
{
int total = 0;
Command command = new SimpleCommand(handler.getConfig().getHgBinary(),
"-R", repositoryPath, "tip", "--template",
TEMPLATE_TOTAL);
CommandResult result = command.execute();
if (result.isSuccessfull())
{
total = Integer.parseInt(result.getOutput().trim());
}
return total;
}
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------
/** Field description */ /** Field description */

View File

@@ -117,7 +117,14 @@ public class SimpleCommand implements Command
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("start external process {}", command); StringBuilder cmd = new StringBuilder();
for (String c : command)
{
cmd.append(c).append(" ");
}
logger.debug("start external process '{}'", cmd.toString());
} }
ProcessBuilder processBuilder = new ProcessBuilder(command); ProcessBuilder processBuilder = new ProcessBuilder(command);

View File

@@ -0,0 +1,131 @@
/**
* 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;
//~--- JDK imports ------------------------------------------------------------
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "changeset-paging")
@XmlAccessorType(XmlAccessType.FIELD)
public class ChangesetPagingResult
{
/**
* Constructs ...
*
*/
public ChangesetPagingResult() {}
/**
* Constructs ...
*
*
* @param total
* @param changesets
*/
public ChangesetPagingResult(int total, List<Changeset> changesets)
{
this.total = total;
this.changesets = changesets;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public List<Changeset> getChangesets()
{
return changesets;
}
/**
* Method description
*
*
* @return
*/
public int getTotal()
{
return total;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param changesets
*/
public void setChangesets(List<Changeset> changesets)
{
this.changesets = changesets;
}
/**
* Method description
*
*
* @param total
*/
public void setTotal(int total)
{
this.total = total;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@XmlElement(name = "changeset")
@XmlElementWrapper(name = "changesets")
private List<Changeset> changesets;
/** Field description */
private int total;
}

View File

@@ -33,10 +33,6 @@
package sonia.scm.repository; package sonia.scm.repository;
//~--- JDK imports ------------------------------------------------------------
import java.util.List;
/** /**
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
@@ -49,20 +45,11 @@ public interface ChangesetViewer
* *
* *
* *
* @param startId *
* @param start
* @param max * @param max
* *
* @return * @return
*/ */
public List<Changeset> getChangesets(String startId, int max); public ChangesetPagingResult getChangesets(int start, int max);
/**
* Method description
*
*
* @param max
*
* @return
*/
public List<Changeset> getLastChangesets(int max);
} }

View File

@@ -40,7 +40,7 @@ import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import sonia.scm.config.ScmConfiguration; import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.ChangesetViewer; import sonia.scm.repository.ChangesetViewer;
import sonia.scm.repository.Permission; import sonia.scm.repository.Permission;
import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionType;
@@ -50,14 +50,12 @@ import sonia.scm.repository.RepositoryException;
import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryHandler;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
import sonia.scm.util.HttpUtil; import sonia.scm.util.HttpUtil;
import sonia.scm.util.Util;
import sonia.scm.web.security.WebSecurityContext; import sonia.scm.web.security.WebSecurityContext;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -116,8 +114,8 @@ public class RepositoryResource
* *
* *
* @param id * @param id
* @param startId * @param start
* @param max * @param limit
* *
* @return * @return
* *
@@ -127,8 +125,8 @@ public class RepositoryResource
@Path("{id}/changesets") @Path("{id}/changesets")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getChangesets(@PathParam("id") String id, public Response getChangesets(@PathParam("id") String id,
@QueryParam("changeset") String startId, @DefaultValue("0") @QueryParam("start") int start,
@DefaultValue("25") @QueryParam("max") int max) @DefaultValue("25") @QueryParam("limit") int limit)
throws RepositoryException throws RepositoryException
{ {
Response response = null; Response response = null;
@@ -141,19 +139,10 @@ public class RepositoryResource
if (changesetViewer != null) if (changesetViewer != null)
{ {
List<Changeset> changesets = null; ChangesetPagingResult changesets = changesetViewer.getChangesets(start,
limit);
if (Util.isNotEmpty(startId)) response = Response.ok(changesets).build();
{
changesets = changesetViewer.getChangesets(startId, max);
}
else
{
changesets = changesetViewer.getLastChangesets(max);
}
response = Response.ok(new GenericEntity<List<Changeset>>(changesets) {}
).build();
} }
else else
{ {

View File

@@ -695,9 +695,14 @@ Sonia.repository.ChangesetViewerGrid = Ext.extend(Ext.grid.GridPanel, {
var changesetStore = new Ext.data.JsonStore({ var changesetStore = new Ext.data.JsonStore({
id: 'changesetStore', id: 'changesetStore',
proxy: new Ext.data.HttpProxy({
url: restUrl + 'repositories/' + this.repository.id + '/changesets.json', url: restUrl + 'repositories/' + this.repository.id + '/changesets.json',
method: 'GET'
}),
fields: ['id', 'date', 'author', 'description'], fields: ['id', 'date', 'author', 'description'],
root: 'changesets',
idProperty: 'id', idProperty: 'id',
totalProperty: 'total',
autoLoad: true, autoLoad: true,
autoDestroy: true autoDestroy: true
}); });
@@ -718,7 +723,13 @@ Sonia.repository.ChangesetViewerGrid = Ext.extend(Ext.grid.GridPanel, {
autoExpandColumn: 'changeset', autoExpandColumn: 'changeset',
autoHeight: true, autoHeight: true,
store: changesetStore, store: changesetStore,
colModel: changesetColModel colModel: changesetColModel,
bbar: new Ext.PagingToolbar({
store: changesetStore,
displayInfo: true,
pageSize: 25,
prependButtons: true
})
} }
Ext.apply(this, Ext.apply(this.initialConfig, config)); Ext.apply(this, Ext.apply(this.initialConfig, config));