summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2011-11-04 22:28:32 -0400
committerJames Moger <james.moger@gitblit.com>2011-11-04 22:28:32 -0400
commite33b91aa4d43246ad62832e66e2acfad3dfb3608 (patch)
tree5777a8c9ca438f62605e7fe8a9ca25b407946158
parentfa5e6f97aab0faca8e11ab8a264b0190c145b07f (diff)
downloadgitblit-e33b91aa4d43246ad62832e66e2acfad3dfb3608.tar.gz
gitblit-e33b91aa4d43246ad62832e66e2acfad3dfb3608.zip
Support pagination in RSS feeds. Standardize pg as page parameter.
-rw-r--r--docs/02_rpc.mkd3
-rw-r--r--src/com/gitblit/SyndicationServlet.java14
-rw-r--r--src/com/gitblit/client/FeedsPanel.java70
-rw-r--r--src/com/gitblit/client/GitblitClient.java16
-rw-r--r--src/com/gitblit/client/SearchDialog.java49
-rw-r--r--src/com/gitblit/utils/SyndicationUtils.java16
-rw-r--r--src/com/gitblit/wicket/WicketUtils.java14
-rw-r--r--tests/com/gitblit/tests/SyndicationUtilsTest.java22
8 files changed, 151 insertions, 53 deletions
diff --git a/docs/02_rpc.mkd b/docs/02_rpc.mkd
index bb58d68f..d1bb1f33 100644
--- a/docs/02_rpc.mkd
+++ b/docs/02_rpc.mkd
@@ -42,6 +42,7 @@ The Gitblit API includes methods for retrieving and interpreting RSS feeds. The
<tr><td><em>repository</em></td><td><em>required</em></td><td>repository name is part of the url (see examples below)</td></tr>
<tr><td>h=</td><td><em>optional</em><br/>default: HEAD</td><td>starting branch, ref, or commit id</td></tr>
<tr><td>l=</td><td><em>optional</em><br/>default: web.syndicationEntries</td><td>maximum return count</td></tr>
+<tr><td>pg=</td><td><em>optional</em><br/>default: 0</td><td>page number for paging<br/>(offset into history = pagenumber*maximum return count)</td></tr>
<tr><td colspan='3'><b>search query</b></td></tr>
<tr><td>s=</td><td><em>required</em></td><td>search string</td></tr>
<tr><td>st=</td><td><em>optional</em><br/>default: COMMIT</td><td>search type</td></tr>
@@ -51,7 +52,7 @@ The Gitblit API includes methods for retrieving and interpreting RSS feeds. The
https://localhost:8443/feed/gitblit.git?l=50&h=refs/heads/master
https://localhost:8443/feed/gitblit.git?l=50&h=refs/heads/master&s=documentation
- https://localhost:8443/feed/gitblit.git?l=50&h=refs/heads/master&s=james&st=author
+ https://localhost:8443/feed/gitblit.git?l=50&h=refs/heads/master&s=james&st=author&pg=2
## JSON Remote Procedure Call (RPC) Interface
diff --git a/src/com/gitblit/SyndicationServlet.java b/src/com/gitblit/SyndicationServlet.java
index 128df43f..39e37ca9 100644
--- a/src/com/gitblit/SyndicationServlet.java
+++ b/src/com/gitblit/SyndicationServlet.java
@@ -129,6 +129,7 @@ public class SyndicationServlet extends HttpServlet {
String repositoryName = url;
String objectId = request.getParameter("h");
String l = request.getParameter("l");
+ String page = request.getParameter("pg");
String searchString = request.getParameter("s");
Constants.SearchType searchType = Constants.SearchType.COMMIT;
if (!StringUtils.isEmpty(request.getParameter("st"))) {
@@ -147,6 +148,13 @@ public class SyndicationServlet extends HttpServlet {
} catch (NumberFormatException x) {
}
}
+ int offset = 0;
+ if (!StringUtils.isEmpty(page)) {
+ try {
+ offset = length * Integer.parseInt(page);
+ } catch (NumberFormatException x) {
+ }
+ }
response.setContentType("application/rss+xml; charset=UTF-8");
Repository repository = GitBlit.self().getRepository(repositoryName);
@@ -154,11 +162,11 @@ public class SyndicationServlet extends HttpServlet {
List<RevCommit> commits;
if (StringUtils.isEmpty(searchString)) {
// standard log/history lookup
- commits = JGitUtils.getRevLog(repository, objectId, 0, length);
+ commits = JGitUtils.getRevLog(repository, objectId, offset, length);
} else {
// repository search
- commits = JGitUtils.searchRevlogs(repository, objectId, searchString, searchType, 0,
- length);
+ commits = JGitUtils.searchRevlogs(repository, objectId, searchString, searchType,
+ offset, length);
}
Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);
List<SyndicatedEntryModel> entries = new ArrayList<SyndicatedEntryModel>();
diff --git a/src/com/gitblit/client/FeedsPanel.java b/src/com/gitblit/client/FeedsPanel.java
index a8094f80..97764db7 100644
--- a/src/com/gitblit/client/FeedsPanel.java
+++ b/src/com/gitblit/client/FeedsPanel.java
@@ -18,6 +18,7 @@ package com.gitblit.client;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Insets;
+import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
@@ -76,6 +77,12 @@ public abstract class FeedsPanel extends JPanel {
private JComboBox authorSelector;
+ private int page;
+
+ private JButton prev;
+
+ private JButton next;
+
public FeedsPanel(GitblitClient gitblit) {
super();
this.gitblit = gitblit;
@@ -83,10 +90,29 @@ public abstract class FeedsPanel extends JPanel {
}
private void initialize() {
+
+ prev = new JButton("<");
+ prev.setToolTipText(Translation.get("gb.pagePrevious"));
+ prev.setEnabled(false);
+ prev.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ refreshFeeds(--page);
+ }
+ });
+
+ next = new JButton(">");
+ next.setToolTipText(Translation.get("gb.pageNext"));
+ next.setEnabled(false);
+ next.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ refreshFeeds(++page);
+ }
+ });
+
JButton refreshFeeds = new JButton(Translation.get("gb.refresh"));
refreshFeeds.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- refreshFeeds();
+ refreshFeeds(0);
}
});
@@ -205,6 +231,8 @@ public abstract class FeedsPanel extends JPanel {
northControls.add(repositorySelector);
northControls.add(new JLabel(Translation.get("gb.author")));
northControls.add(authorSelector);
+// northControls.add(prev);
+// northControls.add(next);
JPanel northPanel = new JPanel(new BorderLayout(0, Utils.MARGIN));
northPanel.add(header, BorderLayout.NORTH);
@@ -221,11 +249,12 @@ public abstract class FeedsPanel extends JPanel {
return Utils.INSETS;
}
- protected void refreshFeeds() {
+ protected void refreshFeeds(final int page) {
+ this.page = page;
GitblitWorker worker = new GitblitWorker(FeedsPanel.this, null) {
@Override
protected Boolean doRequest() throws IOException {
- gitblit.refreshSubscribedFeeds();
+ gitblit.refreshSubscribedFeeds(page);
return true;
}
@@ -244,24 +273,33 @@ public abstract class FeedsPanel extends JPanel {
tableModel.entries.addAll(gitblit.getSyndicatedEntries());
tableModel.fireTableDataChanged();
header.setText(Translation.get("gb.activity") + " ("
- + gitblit.getSyndicatedEntries().size() + ")");
+ + gitblit.getSyndicatedEntries().size() + (page > 0 ? (", pg " + (page + 1)) : "")
+ + ")");
if (pack) {
Utils.packColumns(table, Utils.MARGIN);
}
- // determine unique repositories
- Set<String> uniqueRepositories = new HashSet<String>();
- for (SyndicatedEntryModel entry : tableModel.entries) {
- uniqueRepositories.add(entry.repository);
- }
+ table.scrollRectToVisible(new Rectangle(table.getCellRect(0, 0, true)));
- // repositories
- List<String> sortedRespositories = new ArrayList<String>(uniqueRepositories);
- StringUtils.sortRepositorynames(sortedRespositories);
- repositoryChoices.removeAllElements();
- repositoryChoices.addElement(ALL);
- for (String repo : sortedRespositories) {
- repositoryChoices.addElement(repo);
+ if (page == 0) {
+ // determine unique repositories
+ Set<String> uniqueRepositories = new HashSet<String>();
+ for (SyndicatedEntryModel entry : tableModel.entries) {
+ uniqueRepositories.add(entry.repository);
+ }
+
+ // repositories
+ List<String> sortedRespositories = new ArrayList<String>(uniqueRepositories);
+ StringUtils.sortRepositorynames(sortedRespositories);
+ repositoryChoices.removeAllElements();
+ repositoryChoices.addElement(ALL);
+ for (String repo : sortedRespositories) {
+ repositoryChoices.addElement(repo);
+ }
}
+
+ // update pagination buttons
+ next.setEnabled(tableModel.entries.size() > 0);
+ prev.setEnabled(page > 0);
}
private void updateAuthors() {
diff --git a/src/com/gitblit/client/GitblitClient.java b/src/com/gitblit/client/GitblitClient.java
index e8460f5f..588b6d80 100644
--- a/src/com/gitblit/client/GitblitClient.java
+++ b/src/com/gitblit/client/GitblitClient.java
@@ -101,13 +101,7 @@ public class GitblitClient implements Serializable {
refreshSettings();
refreshAvailableFeeds();
refreshRepositories();
-
- try {
- // RSS feeds may be disabled by server
- refreshSubscribedFeeds();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ refreshSubscribedFeeds(0);
try {
// credentials may not have administrator access
@@ -253,14 +247,14 @@ public class GitblitClient implements Serializable {
return availableFeeds;
}
- public List<SyndicatedEntryModel> refreshSubscribedFeeds() throws IOException {
+ public List<SyndicatedEntryModel> refreshSubscribedFeeds(int page) throws IOException {
Set<SyndicatedEntryModel> allEntries = new HashSet<SyndicatedEntryModel>();
if (reg.feeds.size() > 0) {
for (FeedModel feed : reg.feeds) {
feed.lastRefreshDate = feed.currentRefreshDate;
feed.currentRefreshDate = new Date();
List<SyndicatedEntryModel> entries = SyndicationUtils.readFeed(url,
- feed.repository, feed.branch, -1, account, password);
+ feed.repository, feed.branch, -1, page, account, password);
allEntries.addAll(entries);
}
}
@@ -308,9 +302,9 @@ public class GitblitClient implements Serializable {
}
public List<SyndicatedEntryModel> search(String repository, String branch, String fragment,
- Constants.SearchType type, int numberOfEntries) throws IOException {
+ Constants.SearchType type, int numberOfEntries, int page) throws IOException {
return SyndicationUtils.readSearchFeed(url, repository, branch, fragment, type,
- numberOfEntries, account, password);
+ numberOfEntries, page, account, password);
}
public List<FederationModel> refreshFederationRegistrations() throws IOException {
diff --git a/src/com/gitblit/client/SearchDialog.java b/src/com/gitblit/client/SearchDialog.java
index 2f45611e..5dbea789 100644
--- a/src/com/gitblit/client/SearchDialog.java
+++ b/src/com/gitblit/client/SearchDialog.java
@@ -18,6 +18,7 @@ package com.gitblit.client;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Insets;
+import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
@@ -77,6 +78,12 @@ public class SearchDialog extends JFrame {
private JComboBox maxHitsSelector;
+ private int page;
+
+ private JButton prev;
+
+ private JButton next;
+
public SearchDialog(GitblitClient gitblit) {
super();
this.gitblit = gitblit;
@@ -88,10 +95,28 @@ public class SearchDialog extends JFrame {
private void initialize() {
+ prev = new JButton("<");
+ prev.setToolTipText(Translation.get("gb.pagePrevious"));
+ prev.setEnabled(false);
+ prev.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ search(--page);
+ }
+ });
+
+ next = new JButton(">");
+ next.setToolTipText(Translation.get("gb.pageNext"));
+ next.setEnabled(false);
+ next.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ search(++page);
+ }
+ });
+
final JButton search = new JButton(Translation.get("gb.search"));
search.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- search();
+ search(0);
}
});
@@ -194,12 +219,12 @@ public class SearchDialog extends JFrame {
searchTypeSelector.setSelectedItem(Constants.SearchType.COMMIT);
maxHitsSelector = new JComboBox(new Integer[] { 25, 50, 75, 100 });
- maxHitsSelector.setSelectedIndex(-1);
+ maxHitsSelector.setSelectedIndex(0);
searchFragment = new JTextField(25);
searchFragment.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
- search();
+ search(0);
}
});
@@ -214,6 +239,8 @@ public class SearchDialog extends JFrame {
northControls.add(maxHitsSelector);
northControls.add(searchFragment);
northControls.add(search);
+ northControls.add(prev);
+ northControls.add(next);
JPanel northPanel = new JPanel(new BorderLayout(0, Utils.MARGIN));
northPanel.add(header, BorderLayout.NORTH);
@@ -263,7 +290,8 @@ public class SearchDialog extends JFrame {
}
}
- protected void search() {
+ protected void search(final int page) {
+ this.page = page;
final String repository = repositorySelector.getSelectedItem().toString();
final String branch = branchSelector.getSelectedIndex() > -1 ? branchSelector
.getSelectedItem().toString() : null;
@@ -272,13 +300,15 @@ public class SearchDialog extends JFrame {
final String fragment = searchFragment.getText();
final int maxEntryCount = maxHitsSelector.getSelectedIndex() > -1 ? ((Integer) maxHitsSelector
.getSelectedItem()) : -1;
+
if (StringUtils.isEmpty(fragment)) {
return;
}
SwingWorker<List<SyndicatedEntryModel>, Void> worker = new SwingWorker<List<SyndicatedEntryModel>, Void>() {
@Override
protected List<SyndicatedEntryModel> doInBackground() throws IOException {
- return gitblit.search(repository, branch, fragment, searchType, maxEntryCount);
+ return gitblit
+ .search(repository, branch, fragment, searchType, maxEntryCount, page);
}
@Override
@@ -298,11 +328,18 @@ public class SearchDialog extends JFrame {
tableModel.entries.clear();
tableModel.entries.addAll(entries);
tableModel.fireTableDataChanged();
- setTitle(Translation.get("gb.search") + ": " + fragment + " (" + entries.size() + ")");
+ setTitle(Translation.get("gb.search") + ": " + fragment + " (" + entries.size()
+ + (page > 0 ? (", pg " + (page + 1)) : "") + ")");
header.setText(getTitle());
if (pack) {
Utils.packColumns(table, Utils.MARGIN);
}
+ table.scrollRectToVisible(new Rectangle(table.getCellRect(0, 0, true)));
+
+ // update pagination buttons
+ int maxHits = (Integer) maxHitsSelector.getSelectedItem();
+ next.setEnabled(entries.size() == maxHits);
+ prev.setEnabled(page > 0);
}
protected SyndicatedEntryModel getSelectedSyndicatedEntry() {
diff --git a/src/com/gitblit/utils/SyndicationUtils.java b/src/com/gitblit/utils/SyndicationUtils.java
index 4ba56223..6919cd24 100644
--- a/src/com/gitblit/utils/SyndicationUtils.java
+++ b/src/com/gitblit/utils/SyndicationUtils.java
@@ -100,7 +100,7 @@ public class SyndicationUtils {
content.setType(entryModel.contentType);
content.setValue(entryModel.content);
entry.setDescription(content);
-
+
entries.add(entry);
}
feed.setEntries(entries);
@@ -123,18 +123,23 @@ public class SyndicationUtils {
* @param numberOfEntries
* the number of entries to retrieve. if <= 0 the server default
* is used.
+ * @param page
+ * 0-indexed. used to paginate the results.
* @param username
* @param password
* @return a list of SyndicationModel entries
* @throws {@link IOException}
*/
public static List<SyndicatedEntryModel> readFeed(String url, String repository, String branch,
- int numberOfEntries, String username, char[] password) throws IOException {
+ int numberOfEntries, int page, String username, char[] password) throws IOException {
// build feed url
List<String> parameters = new ArrayList<String>();
if (numberOfEntries > 0) {
parameters.add("l=" + numberOfEntries);
}
+ if (page > 0) {
+ parameters.add("pg=" + page);
+ }
if (!StringUtils.isEmpty(branch)) {
parameters.add("h=" + branch);
}
@@ -155,6 +160,8 @@ public class SyndicationUtils {
* @param numberOfEntries
* the number of entries to retrieve. if <= 0 the server default
* is used.
+ * @param page
+ * 0-indexed. used to paginate the results.
* @param username
* @param password
* @return a list of SyndicationModel entries
@@ -162,13 +169,16 @@ public class SyndicationUtils {
*/
public static List<SyndicatedEntryModel> readSearchFeed(String url, String repository,
String branch, String fragment, Constants.SearchType searchType, int numberOfEntries,
- String username, char[] password) throws IOException {
+ int page, String username, char[] password) throws IOException {
// determine parameters
List<String> parameters = new ArrayList<String>();
parameters.add("s=" + StringUtils.encodeURL(fragment));
if (numberOfEntries > 0) {
parameters.add("l=" + numberOfEntries);
}
+ if (page > 0) {
+ parameters.add("pg=" + page);
+ }
if (!StringUtils.isEmpty(branch)) {
parameters.add("h=" + branch);
}
diff --git a/src/com/gitblit/wicket/WicketUtils.java b/src/com/gitblit/wicket/WicketUtils.java
index f47663ca..37b44472 100644
--- a/src/com/gitblit/wicket/WicketUtils.java
+++ b/src/com/gitblit/wicket/WicketUtils.java
@@ -284,9 +284,9 @@ public class WicketUtils {
return newObjectParameter(repositoryName, objectId);
}
if (StringUtils.isEmpty(objectId)) {
- return new PageParameters("r=" + repositoryName + ",page=" + pageNumber);
+ return new PageParameters("r=" + repositoryName + ",pg=" + pageNumber);
}
- return new PageParameters("r=" + repositoryName + ",h=" + objectId + ",page=" + pageNumber);
+ return new PageParameters("r=" + repositoryName + ",h=" + objectId + ",pg=" + pageNumber);
}
public static PageParameters newHistoryPageParameter(String repositoryName, String objectId,
@@ -295,10 +295,10 @@ public class WicketUtils {
return newObjectParameter(repositoryName, objectId);
}
if (StringUtils.isEmpty(objectId)) {
- return new PageParameters("r=" + repositoryName + ",f=" + path + ",page=" + pageNumber);
+ return new PageParameters("r=" + repositoryName + ",f=" + path + ",pg=" + pageNumber);
}
return new PageParameters("r=" + repositoryName + ",h=" + objectId + ",f=" + path
- + ",page=" + pageNumber);
+ + ",pg=" + pageNumber);
}
public static PageParameters newBlobDiffParameter(String repositoryName, String baseCommitId,
@@ -323,10 +323,10 @@ public class WicketUtils {
String search, Constants.SearchType type, int pageNumber) {
if (StringUtils.isEmpty(commitId)) {
return new PageParameters("r=" + repositoryName + ",s=" + search + ",st=" + type.name()
- + ",page=" + pageNumber);
+ + ",pg=" + pageNumber);
}
return new PageParameters("r=" + repositoryName + ",h=" + commitId + ",s=" + search
- + ",st=" + type.name() + ",page=" + pageNumber);
+ + ",st=" + type.name() + ",pg=" + pageNumber);
}
public static String getRepositoryName(PageParameters params) {
@@ -355,7 +355,7 @@ public class WicketUtils {
public static int getPage(PageParameters params) {
// index from 1
- return params.getInt("page", 1);
+ return params.getInt("pg", 1);
}
public static String getUsername(PageParameters params) {
diff --git a/tests/com/gitblit/tests/SyndicationUtilsTest.java b/tests/com/gitblit/tests/SyndicationUtilsTest.java
index 98bdd4bf..e0a32bf3 100644
--- a/tests/com/gitblit/tests/SyndicationUtilsTest.java
+++ b/tests/com/gitblit/tests/SyndicationUtilsTest.java
@@ -18,7 +18,9 @@ package com.gitblit.tests;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import junit.framework.TestCase;
@@ -51,16 +53,24 @@ public class SyndicationUtilsTest extends TestCase {
}
public void testFeedRead() throws Exception {
- List<SyndicatedEntryModel> feed = SyndicationUtils.readFeed("https://localhost:8443",
- "ticgit.git", "master", 5, "admin", "admin".toCharArray());
- assertTrue(feed != null);
- assertTrue(feed.size() > 0);
- assertEquals(5, feed.size());
+ Set<String> links = new HashSet<String>();
+ for (int i = 0; i < 2; i++) {
+ List<SyndicatedEntryModel> feed = SyndicationUtils.readFeed("https://localhost:8443",
+ "ticgit.git", "master", 5, i, "admin", "admin".toCharArray());
+ assertTrue(feed != null);
+ assertTrue(feed.size() > 0);
+ assertEquals(5, feed.size());
+ for (SyndicatedEntryModel entry : feed) {
+ links.add(entry.link);
+ }
+ }
+ // confirm we have 10 unique commits
+ assertEquals("Feed pagination failed", 10, links.size());
}
public void testSearchFeedRead() throws Exception {
List<SyndicatedEntryModel> feed = SyndicationUtils.readSearchFeed("https://localhost:8443",
- "ticgit.git", null, "documentation", null, 5, "admin", "admin".toCharArray());
+ "ticgit.git", null, "documentation", null, 5, 0, "admin", "admin".toCharArray());
assertTrue(feed != null);
assertTrue(feed.size() > 0);
assertEquals(2, feed.size());