Paul Martin
2016-04-16 eecaad8b8e2c447429c31a01d49260ddd6b4ee03
commit | author | age
c22722 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.utils;
17
18 import java.io.IOException;
565ee0 19 import java.io.InputStream;
c22722 20 import java.io.OutputStream;
JM 21 import java.io.OutputStreamWriter;
565ee0 22 import java.net.URLConnection;
c22722 23 import java.text.MessageFormat;
JM 24 import java.util.ArrayList;
25 import java.util.List;
26
8c9a20 27 import com.gitblit.Constants;
9ff0c1 28 import com.gitblit.Constants.FeedObjectType;
4cac0d 29 import com.gitblit.GitBlitException;
ee458f 30 import com.gitblit.models.FeedEntryModel;
eecaad 31 import com.rometools.rome.feed.synd.SyndCategory;
PM 32 import com.rometools.rome.feed.synd.SyndCategoryImpl;
33 import com.rometools.rome.feed.synd.SyndContent;
34 import com.rometools.rome.feed.synd.SyndContentImpl;
35 import com.rometools.rome.feed.synd.SyndEntry;
36 import com.rometools.rome.feed.synd.SyndEntryImpl;
37 import com.rometools.rome.feed.synd.SyndFeed;
38 import com.rometools.rome.feed.synd.SyndFeedImpl;
39 import com.rometools.rome.feed.synd.SyndImageImpl;
40 import com.rometools.rome.io.FeedException;
41 import com.rometools.rome.io.SyndFeedInput;
42 import com.rometools.rome.io.SyndFeedOutput;
43 import com.rometools.rome.io.XmlReader;
c22722 44
d9f687 45 /**
JM 46  * Utility class for RSS feeds.
699e71 47  *
d9f687 48  * @author James Moger
699e71 49  *
d9f687 50  */
c22722 51 public class SyndicationUtils {
JM 52
d9f687 53     /**
38688b 54      * Outputs an RSS feed of the list of entries to the outputstream.
699e71 55      *
d9f687 56      * @param hostUrl
ec5a88 57      * @param feedLink
d9f687 58      * @param title
JM 59      * @param description
38688b 60      * @param entryModels
d9f687 61      * @param os
JM 62      * @throws IOException
63      * @throws FeedException
64      */
ec5a88 65     public static void toRSS(String hostUrl, String feedLink, String title, String description,
13a3f5 66             List<FeedEntryModel> entryModels, OutputStream os)
ec5a88 67             throws IOException, FeedException {
c22722 68
JM 69         SyndFeed feed = new SyndFeedImpl();
8c9a20 70         feed.setFeedType("rss_2.0");
4cac0d 71         feed.setEncoding("UTF-8");
c22722 72         feed.setTitle(title);
ec5a88 73         feed.setLink(feedLink);
2916cf 74         if (StringUtils.isEmpty(description)) {
JM 75             feed.setDescription(title);
76         } else {
77             feed.setDescription(description);
78         }
8c9a20 79         SyndImageImpl image = new SyndImageImpl();
JM 80         image.setTitle(Constants.NAME);
5450d0 81         image.setUrl(hostUrl + "/gitblt_25.png");
8c9a20 82         image.setLink(hostUrl);
JM 83         feed.setImage(image);
c22722 84
JM 85         List<SyndEntry> entries = new ArrayList<SyndEntry>();
ee458f 86         for (FeedEntryModel entryModel : entryModels) {
c22722 87             SyndEntry entry = new SyndEntryImpl();
38688b 88             entry.setTitle(entryModel.title);
JM 89             entry.setAuthor(entryModel.author);
90             entry.setLink(entryModel.link);
91             entry.setPublishedDate(entryModel.published);
c22722 92
9bdb91 93             if (entryModel.tags != null && entryModel.tags.size() > 0) {
JM 94                 List<SyndCategory> tags = new ArrayList<SyndCategory>();
95                 for (String tag : entryModel.tags) {
96                     SyndCategoryImpl cat = new SyndCategoryImpl();
97                     cat.setName(tag);
98                     tags.add(cat);
99                 }
100                 entry.setCategories(tags);
101             }
102
c22722 103             SyndContent content = new SyndContentImpl();
e493cf 104             if (StringUtils.isEmpty(entryModel.contentType)
JM 105                     || entryModel.contentType.equalsIgnoreCase("text/plain")) {
106                 content.setType("text/html");
107                 content.setValue(StringUtils.breakLinesForHtml(entryModel.content));
108             } else {
109                 content.setType(entryModel.contentType);
110                 content.setValue(entryModel.content);
111             }
c22722 112             entry.setDescription(content);
e33b91 113
c22722 114             entries.add(entry);
JM 115         }
116         feed.setEntries(entries);
117
4cac0d 118         OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8");
c22722 119         SyndFeedOutput output = new SyndFeedOutput();
JM 120         output.output(feed, writer);
121         writer.close();
122     }
565ee0 123
JM 124     /**
125      * Reads a Gitblit RSS feed.
699e71 126      *
565ee0 127      * @param url
JM 128      *            the url of the Gitblit server
129      * @param repository
130      *            the repository name
131      * @param branch
132      *            the branch name (optional)
133      * @param numberOfEntries
134      *            the number of entries to retrieve. if <= 0 the server default
135      *            is used.
e33b91 136      * @param page
JM 137      *            0-indexed. used to paginate the results.
565ee0 138      * @param username
JM 139      * @param password
4cac0d 140      * @return a list of SyndicationModel entries
565ee0 141      * @throws {@link IOException}
JM 142      */
ee458f 143     public static List<FeedEntryModel> readFeed(String url, String repository, String branch,
e33b91 144             int numberOfEntries, int page, String username, char[] password) throws IOException {
9ff0c1 145         return readFeed(url, repository, branch, FeedObjectType.COMMIT, numberOfEntries,
JM 146                 page, username, password);
147     }
148
149     /**
150      * Reads tags from the specified repository.
151      *
152      * @param url
153      *            the url of the Gitblit server
154      * @param repository
155      *            the repository name
156      * @param branch
157      *            the branch name (optional)
158      * @param numberOfEntries
159      *            the number of entries to retrieve. if <= 0 the server default
160      *            is used.
161      * @param page
162      *            0-indexed. used to paginate the results.
163      * @param username
164      * @param password
165      * @return a list of SyndicationModel entries
166      * @throws {@link IOException}
167      */
168     public static List<FeedEntryModel> readTags(String url, String repository,
169             int numberOfEntries, int page, String username, char[] password) throws IOException {
170         return readFeed(url, repository, null, FeedObjectType.TAG, numberOfEntries,
171                 page, username, password);
172     }
173
174     /**
175      * Reads a Gitblit RSS feed.
176      *
177      * @param url
178      *            the url of the Gitblit server
179      * @param repository
180      *            the repository name
181      * @param branch
182      *            the branch name (optional)
183      * @param objectType
184      *            the object type to return (optional, COMMIT assummed)
185      * @param numberOfEntries
186      *            the number of entries to retrieve. if <= 0 the server default
187      *            is used.
188      * @param page
189      *            0-indexed. used to paginate the results.
190      * @param username
191      * @param password
192      * @return a list of SyndicationModel entries
193      * @throws {@link IOException}
194      */
195     private static List<FeedEntryModel> readFeed(String url, String repository, String branch,
196             FeedObjectType objectType, int numberOfEntries, int page, String username,
197             char[] password) throws IOException {
c25a1d 198         // build feed url
JM 199         List<String> parameters = new ArrayList<String>();
200         if (numberOfEntries > 0) {
201             parameters.add("l=" + numberOfEntries);
e33b91 202         }
JM 203         if (page > 0) {
204             parameters.add("pg=" + page);
c25a1d 205         }
JM 206         if (!StringUtils.isEmpty(branch)) {
207             parameters.add("h=" + branch);
208         }
9ff0c1 209         if (objectType != null) {
JM 210             parameters.add("ot=" + objectType.name());
211         }
9bdb91 212         return readFeed(url, parameters, repository, branch, username, password);
JM 213     }
214
215     /**
216      * Reads a Gitblit RSS search feed.
699e71 217      *
9bdb91 218      * @param url
JM 219      *            the url of the Gitblit server
220      * @param repository
221      *            the repository name
222      * @param fragment
223      *            the search fragment
224      * @param searchType
225      *            the search type (optional, defaults to COMMIT)
226      * @param numberOfEntries
227      *            the number of entries to retrieve. if <= 0 the server default
228      *            is used.
e33b91 229      * @param page
JM 230      *            0-indexed. used to paginate the results.
9bdb91 231      * @param username
JM 232      * @param password
233      * @return a list of SyndicationModel entries
234      * @throws {@link IOException}
235      */
e493cf 236     public static List<FeedEntryModel> readSearchFeed(String url, String repository, String branch,
JM 237             String fragment, Constants.SearchType searchType, int numberOfEntries, int page,
238             String username, char[] password) throws IOException {
9bdb91 239         // determine parameters
JM 240         List<String> parameters = new ArrayList<String>();
241         parameters.add("s=" + StringUtils.encodeURL(fragment));
242         if (numberOfEntries > 0) {
243             parameters.add("l=" + numberOfEntries);
244         }
e33b91 245         if (page > 0) {
JM 246             parameters.add("pg=" + page);
247         }
9bdb91 248         if (!StringUtils.isEmpty(branch)) {
JM 249             parameters.add("h=" + branch);
250         }
251         if (searchType != null) {
252             parameters.add("st=" + searchType.name());
253         }
254         return readFeed(url, parameters, repository, branch, username, password);
255     }
256
257     /**
258      * Reads a Gitblit RSS feed.
699e71 259      *
9bdb91 260      * @param url
JM 261      *            the url of the Gitblit server
262      * @param parameters
263      *            the list of RSS parameters
264      * @param repository
265      *            the repository name
266      * @param username
267      * @param password
268      * @return a list of SyndicationModel entries
269      * @throws {@link IOException}
270      */
ee458f 271     private static List<FeedEntryModel> readFeed(String url, List<String> parameters,
9bdb91 272             String repository, String branch, String username, char[] password) throws IOException {
JM 273         // build url
c25a1d 274         StringBuilder sb = new StringBuilder();
92e2df 275         sb.append(MessageFormat.format("{0}" + Constants.SYNDICATION_PATH + "{1}", url, repository));
c25a1d 276         if (parameters.size() > 0) {
JM 277             boolean first = true;
278             for (String parameter : parameters) {
279                 if (first) {
280                     sb.append('?');
281                     first = false;
282                 } else {
283                     sb.append('&');
284                 }
285                 sb.append(parameter);
565ee0 286             }
JM 287         }
c25a1d 288         String feedUrl = sb.toString();
565ee0 289         URLConnection conn = ConnectionUtils.openReadConnection(feedUrl, username, password);
JM 290         InputStream is = conn.getInputStream();
291         SyndFeedInput input = new SyndFeedInput();
4cac0d 292         SyndFeed feed = null;
JM 293         try {
294             feed = input.build(new XmlReader(is));
295         } catch (FeedException f) {
296             throw new GitBlitException(f);
297         }
565ee0 298         is.close();
ee458f 299         List<FeedEntryModel> entries = new ArrayList<FeedEntryModel>();
4cac0d 300         for (Object o : feed.getEntries()) {
JM 301             SyndEntryImpl entry = (SyndEntryImpl) o;
ee458f 302             FeedEntryModel model = new FeedEntryModel();
4cac0d 303             model.repository = repository;
JM 304             model.branch = branch;
305             model.title = entry.getTitle();
306             model.author = entry.getAuthor();
307             model.published = entry.getPublishedDate();
308             model.link = entry.getLink();
309             model.content = entry.getDescription().getValue();
310             model.contentType = entry.getDescription().getType();
9bdb91 311             if (entry.getCategories() != null && entry.getCategories().size() > 0) {
JM 312                 List<String> tags = new ArrayList<String>();
313                 for (Object p : entry.getCategories()) {
314                     SyndCategory cat = (SyndCategory) p;
315                     tags.add(cat.getName());
316                 }
317                 model.tags = tags;
318             }
4cac0d 319             entries.add(model);
JM 320         }
321         return entries;
565ee0 322     }
c22722 323 }