From cb285cbfddfc0b633d6b8cdb4dc0d2bd2b8b51ef Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Thu, 05 Jan 2012 17:34:05 -0500 Subject: [PATCH] Fixed bug in receive hook for repositories in subfolders --- src/com/gitblit/utils/SyndicationUtils.java | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 201 insertions(+), 16 deletions(-) diff --git a/src/com/gitblit/utils/SyndicationUtils.java b/src/com/gitblit/utils/SyndicationUtils.java index 80a1b28..061d12a 100644 --- a/src/com/gitblit/utils/SyndicationUtils.java +++ b/src/com/gitblit/utils/SyndicationUtils.java @@ -16,15 +16,19 @@ package com.gitblit.utils; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.net.URLConnection; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; -import org.eclipse.jgit.revwalk.RevCommit; - import com.gitblit.Constants; +import com.gitblit.GitBlitException; +import com.gitblit.models.FeedEntryModel; +import com.sun.syndication.feed.synd.SyndCategory; +import com.sun.syndication.feed.synd.SyndCategoryImpl; import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndEntry; @@ -33,18 +37,40 @@ import com.sun.syndication.feed.synd.SyndFeedImpl; import com.sun.syndication.feed.synd.SyndImageImpl; import com.sun.syndication.io.FeedException; +import com.sun.syndication.io.SyndFeedInput; import com.sun.syndication.io.SyndFeedOutput; +import com.sun.syndication.io.XmlReader; +/** + * Utility class for RSS feeds. + * + * @author James Moger + * + */ public class SyndicationUtils { - public static void toRSS(String hostUrl, String title, String description, String repository, - List<RevCommit> commits, OutputStream os) throws IOException, FeedException { + /** + * Outputs an RSS feed of the list of entries to the outputstream. + * + * @param hostUrl + * @param feedLink + * @param title + * @param description + * @param repository + * @param entryModels + * @param os + * @throws IOException + * @throws FeedException + */ + public static void toRSS(String hostUrl, String feedLink, String title, String description, + String repository, List<FeedEntryModel> entryModels, OutputStream os) + throws IOException, FeedException { SyndFeed feed = new SyndFeedImpl(); feed.setFeedType("rss_2.0"); + feed.setEncoding("UTF-8"); feed.setTitle(title); - feed.setLink(MessageFormat.format("{0}/summary/{1}", hostUrl, - StringUtils.encodeURL(repository))); + feed.setLink(feedLink); feed.setDescription(description); SyndImageImpl image = new SyndImageImpl(); image.setTitle(Constants.NAME); @@ -53,26 +79,185 @@ feed.setImage(image); List<SyndEntry> entries = new ArrayList<SyndEntry>(); - for (RevCommit commit : commits) { + for (FeedEntryModel entryModel : entryModels) { SyndEntry entry = new SyndEntryImpl(); - entry.setTitle(commit.getShortMessage()); - entry.setAuthor(commit.getAuthorIdent().getName()); - entry.setLink(MessageFormat.format("{0}/commit/{1}/{2}", hostUrl, - StringUtils.encodeURL(repository), commit.getName())); - entry.setPublishedDate(commit.getCommitterIdent().getWhen()); + entry.setTitle(entryModel.title); + entry.setAuthor(entryModel.author); + entry.setLink(entryModel.link); + entry.setPublishedDate(entryModel.published); + + if (entryModel.tags != null && entryModel.tags.size() > 0) { + List<SyndCategory> tags = new ArrayList<SyndCategory>(); + for (String tag : entryModel.tags) { + SyndCategoryImpl cat = new SyndCategoryImpl(); + cat.setName(tag); + tags.add(cat); + } + entry.setCategories(tags); + } SyndContent content = new SyndContentImpl(); - content.setType("text/html"); - String html = StringUtils.escapeForHtml(commit.getFullMessage(), false); - content.setValue(StringUtils.breakLinesForHtml(html)); + if (StringUtils.isEmpty(entryModel.contentType) + || entryModel.contentType.equalsIgnoreCase("text/plain")) { + content.setType("text/html"); + content.setValue(StringUtils.breakLinesForHtml(entryModel.content)); + } else { + content.setType(entryModel.contentType); + content.setValue(entryModel.content); + } entry.setDescription(content); + entries.add(entry); } feed.setEntries(entries); - OutputStreamWriter writer = new OutputStreamWriter(os); + OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8"); SyndFeedOutput output = new SyndFeedOutput(); output.output(feed, writer); writer.close(); } + + /** + * Reads a Gitblit RSS feed. + * + * @param url + * the url of the Gitblit server + * @param repository + * the repository name + * @param branch + * the branch name (optional) + * @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<FeedEntryModel> readFeed(String url, String repository, String branch, + 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); + } + return readFeed(url, parameters, repository, branch, username, password); + } + + /** + * Reads a Gitblit RSS search feed. + * + * @param url + * the url of the Gitblit server + * @param repository + * the repository name + * @param fragment + * the search fragment + * @param searchType + * the search type (optional, defaults to COMMIT) + * @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<FeedEntryModel> readSearchFeed(String url, String repository, String branch, + String fragment, Constants.SearchType searchType, int numberOfEntries, 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); + } + if (searchType != null) { + parameters.add("st=" + searchType.name()); + } + return readFeed(url, parameters, repository, branch, username, password); + } + + /** + * Reads a Gitblit RSS feed. + * + * @param url + * the url of the Gitblit server + * @param parameters + * the list of RSS parameters + * @param repository + * the repository name + * @param username + * @param password + * @return a list of SyndicationModel entries + * @throws {@link IOException} + */ + private static List<FeedEntryModel> readFeed(String url, List<String> parameters, + String repository, String branch, String username, char[] password) throws IOException { + // build url + StringBuilder sb = new StringBuilder(); + sb.append(MessageFormat.format("{0}" + Constants.SYNDICATION_PATH + "{1}", url, repository)); + if (parameters.size() > 0) { + boolean first = true; + for (String parameter : parameters) { + if (first) { + sb.append('?'); + first = false; + } else { + sb.append('&'); + } + sb.append(parameter); + } + } + String feedUrl = sb.toString(); + URLConnection conn = ConnectionUtils.openReadConnection(feedUrl, username, password); + InputStream is = conn.getInputStream(); + SyndFeedInput input = new SyndFeedInput(); + SyndFeed feed = null; + try { + feed = input.build(new XmlReader(is)); + } catch (FeedException f) { + throw new GitBlitException(f); + } + is.close(); + List<FeedEntryModel> entries = new ArrayList<FeedEntryModel>(); + for (Object o : feed.getEntries()) { + SyndEntryImpl entry = (SyndEntryImpl) o; + FeedEntryModel model = new FeedEntryModel(); + model.repository = repository; + model.branch = branch; + model.title = entry.getTitle(); + model.author = entry.getAuthor(); + model.published = entry.getPublishedDate(); + model.link = entry.getLink(); + model.content = entry.getDescription().getValue(); + model.contentType = entry.getDescription().getType(); + if (entry.getCategories() != null && entry.getCategories().size() > 0) { + List<String> tags = new ArrayList<String>(); + for (Object p : entry.getCategories()) { + SyndCategory cat = (SyndCategory) p; + tags.add(cat.getName()); + } + model.tags = tags; + } + entries.add(model); + } + return entries; + } } -- Gitblit v1.9.1