001
014
015 package com.liferay.portlet.journal.action;
016
017 import com.liferay.portal.NoSuchLayoutException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.language.LanguageUtil;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.portlet.PortletRequestModel;
023 import com.liferay.portal.kernel.util.HtmlUtil;
024 import com.liferay.portal.kernel.util.ParamUtil;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.Node;
031 import com.liferay.portal.kernel.xml.SAXReaderUtil;
032 import com.liferay.portal.kernel.xml.XPath;
033 import com.liferay.portal.model.Layout;
034 import com.liferay.portal.service.LayoutLocalServiceUtil;
035 import com.liferay.portal.theme.ThemeDisplay;
036 import com.liferay.portal.util.PortalUtil;
037 import com.liferay.portal.util.PortletKeys;
038 import com.liferay.portal.util.WebKeys;
039 import com.liferay.portlet.PortletURLImpl;
040 import com.liferay.portlet.journal.model.JournalArticle;
041 import com.liferay.portlet.journal.model.JournalArticleDisplay;
042 import com.liferay.portlet.journal.model.JournalFeed;
043 import com.liferay.portlet.journal.model.JournalFeedConstants;
044 import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
045 import com.liferay.portlet.journal.service.JournalFeedLocalServiceUtil;
046 import com.liferay.portlet.journal.util.JournalRSSUtil;
047 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
048 import com.liferay.util.RSSUtil;
049
050 import com.sun.syndication.feed.synd.SyndContent;
051 import com.sun.syndication.feed.synd.SyndContentImpl;
052 import com.sun.syndication.feed.synd.SyndEnclosure;
053 import com.sun.syndication.feed.synd.SyndEntry;
054 import com.sun.syndication.feed.synd.SyndEntryImpl;
055 import com.sun.syndication.feed.synd.SyndFeed;
056 import com.sun.syndication.feed.synd.SyndFeedImpl;
057 import com.sun.syndication.feed.synd.SyndLink;
058 import com.sun.syndication.feed.synd.SyndLinkImpl;
059 import com.sun.syndication.io.FeedException;
060
061 import java.util.ArrayList;
062 import java.util.Date;
063 import java.util.List;
064
065 import javax.portlet.PortletRequest;
066 import javax.portlet.PortletURL;
067 import javax.portlet.ResourceRequest;
068 import javax.portlet.ResourceResponse;
069 import javax.portlet.ResourceURL;
070
071
074 public class RSSAction extends com.liferay.portal.struts.RSSAction {
075
076 protected String exportToRSS(
077 ResourceRequest resourceRequest, ResourceResponse resourceResponse,
078 JournalFeed feed, String languageId, Layout layout,
079 ThemeDisplay themeDisplay)
080 throws Exception {
081
082 SyndFeed syndFeed = new SyndFeedImpl();
083
084 syndFeed.setDescription(feed.getDescription());
085
086 List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
087
088 syndFeed.setEntries(syndEntries);
089
090 List<JournalArticle> articles = JournalRSSUtil.getArticles(feed);
091
092 if (_log.isDebugEnabled()) {
093 _log.debug("Syndicating " + articles.size() + " articles");
094 }
095
096 for (JournalArticle article : articles) {
097 SyndEntry syndEntry = new SyndEntryImpl();
098
099 String author = PortalUtil.getUserName(article);
100
101 syndEntry.setAuthor(author);
102
103 SyndContent syndContent = new SyndContentImpl();
104
105 syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
106
107 String value = article.getDescription(languageId);
108
109 try {
110 value = processContent(
111 feed, article, languageId, themeDisplay, syndEntry,
112 syndContent);
113 }
114 catch (Exception e) {
115 if (_log.isWarnEnabled()) {
116 _log.warn(e, e);
117 }
118 }
119
120 syndContent.setValue(value);
121
122 syndEntry.setDescription(syndContent);
123
124 String link = getEntryURL(
125 resourceRequest, feed, article, layout, themeDisplay);
126
127 syndEntry.setLink(link);
128
129 syndEntry.setPublishedDate(article.getDisplayDate());
130 syndEntry.setTitle(article.getTitle(languageId));
131 syndEntry.setUpdatedDate(article.getModifiedDate());
132 syndEntry.setUri(link);
133
134 syndEntries.add(syndEntry);
135 }
136
137 syndFeed.setFeedType(
138 feed.getFeedFormat() + "_" + feed.getFeedVersion());
139
140 List<SyndLink> syndLinks = new ArrayList<SyndLink>();
141
142 syndFeed.setLinks(syndLinks);
143
144 SyndLink selfSyndLink = new SyndLinkImpl();
145
146 syndLinks.add(selfSyndLink);
147
148 ResourceURL feedURL = resourceResponse.createResourceURL();
149
150 feedURL.setCacheability(ResourceURL.FULL);
151 feedURL.setParameter("struts_action", "/journal/rss");
152 feedURL.setParameter("groupId", String.valueOf(feed.getGroupId()));
153 feedURL.setParameter("feedId", String.valueOf(feed.getFeedId()));
154
155 String link = feedURL.toString();
156
157 selfSyndLink.setHref(link);
158
159 selfSyndLink.setRel("self");
160
161 syndFeed.setTitle(feed.getName());
162 syndFeed.setPublishedDate(new Date());
163 syndFeed.setUri(feedURL.toString());
164
165 try {
166 return RSSUtil.export(syndFeed);
167 }
168 catch (FeedException fe) {
169 throw new SystemException(fe);
170 }
171 }
172
173 protected String getEntryURL(
174 ResourceRequest resourceRequest, JournalFeed feed,
175 JournalArticle article, Layout layout, ThemeDisplay themeDisplay)
176 throws Exception {
177
178 List<Long> hitLayoutIds =
179 JournalContentSearchLocalServiceUtil.getLayoutIds(
180 layout.getGroupId(), layout.isPrivateLayout(),
181 article.getArticleId());
182
183 if (!hitLayoutIds.isEmpty()) {
184 Long hitLayoutId = hitLayoutIds.get(0);
185
186 Layout hitLayout = LayoutLocalServiceUtil.getLayout(
187 layout.getGroupId(), layout.isPrivateLayout(),
188 hitLayoutId.longValue());
189
190 return PortalUtil.getLayoutFriendlyURL(hitLayout, themeDisplay);
191 }
192
193 long plid = PortalUtil.getPlidFromFriendlyURL(
194 feed.getCompanyId(), feed.getTargetLayoutFriendlyUrl());
195
196 String portletId = PortletKeys.JOURNAL_CONTENT;
197
198 if (Validator.isNotNull(feed.getTargetPortletId())) {
199 portletId = feed.getTargetPortletId();
200 }
201
202 PortletURL entryURL = new PortletURLImpl(
203 resourceRequest, portletId, plid, PortletRequest.RENDER_PHASE);
204
205 entryURL.setParameter("struts_action", "/journal_content/view");
206 entryURL.setParameter("groupId", String.valueOf(article.getGroupId()));
207 entryURL.setParameter("articleId", article.getArticleId());
208
209 return entryURL.toString();
210 }
211
212 @Override
213 protected byte[] getRSS(
214 ResourceRequest resourceRequest, ResourceResponse resourceResponse)
215 throws Exception {
216
217 ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(
218 WebKeys.THEME_DISPLAY);
219
220 JournalFeed feed = null;
221
222 long id = ParamUtil.getLong(resourceRequest, "id");
223
224 long groupId = ParamUtil.getLong(resourceRequest, "groupId");
225 String feedId = ParamUtil.getString(resourceRequest, "feedId");
226
227 if (id > 0) {
228 feed = JournalFeedLocalServiceUtil.getFeed(id);
229 }
230 else {
231 feed = JournalFeedLocalServiceUtil.getFeed(groupId, feedId);
232 }
233
234 String languageId = LanguageUtil.getLanguageId(resourceRequest);
235
236 long plid = PortalUtil.getPlidFromFriendlyURL(
237 themeDisplay.getCompanyId(), feed.getTargetLayoutFriendlyUrl());
238
239 Layout layout = themeDisplay.getLayout();
240
241 if (plid > 0) {
242 try {
243 layout = LayoutLocalServiceUtil.getLayout(plid);
244 }
245 catch (NoSuchLayoutException nsle) {
246 }
247 }
248
249 String rss = exportToRSS(
250 resourceRequest, resourceResponse, feed, languageId, layout,
251 themeDisplay);
252
253 return rss.getBytes(StringPool.UTF8);
254 }
255
256 protected String processContent(
257 JournalFeed feed, JournalArticle article, String languageId,
258 ThemeDisplay themeDisplay, SyndEntry syndEntry,
259 SyndContent syndContent)
260 throws Exception {
261
262 String content = article.getDescription(languageId);
263
264 String contentField = feed.getContentField();
265
266 if (contentField.equals(JournalFeedConstants.RENDERED_WEB_CONTENT)) {
267 String rendererTemplateId = article.getTemplateId();
268
269 if (Validator.isNotNull(feed.getRendererTemplateId())) {
270 rendererTemplateId = feed.getRendererTemplateId();
271 }
272
273 JournalArticleDisplay articleDisplay =
274 JournalContentUtil.getDisplay(
275 feed.getGroupId(), article.getArticleId(),
276 rendererTemplateId, null, languageId, 1,
277 new PortletRequestModel() {
278
279 @Override
280 public String toXML() {
281 return _XML_REQUUEST;
282 }
283
284 },
285 themeDisplay);
286
287 if (articleDisplay != null) {
288 content = articleDisplay.getContent();
289 }
290 }
291 else if (!contentField.equals(
292 JournalFeedConstants.WEB_CONTENT_DESCRIPTION)) {
293
294 Document document = SAXReaderUtil.read(
295 article.getContentByLocale(languageId));
296
297 contentField = HtmlUtil.escapeXPathAttribute(contentField);
298
299 XPath xPathSelector = SAXReaderUtil.createXPath(
300 "
301
302 List<Node> results = xPathSelector.selectNodes(document);
303
304 if (results.isEmpty()) {
305 return content;
306 }
307
308 Element element = (Element)results.get(0);
309
310 String elType = element.attributeValue("type");
311
312 if (elType.equals("document_library")) {
313 String url = element.elementText("dynamic-content");
314
315 url = processURL(feed, url, themeDisplay, syndEntry);
316 }
317 else if (elType.equals("image") || elType.equals("image_gallery")) {
318 String url = element.elementText("dynamic-content");
319
320 url = processURL(feed, url, themeDisplay, syndEntry);
321
322 content =
323 content + "<br /><br /><img alt='' src='" +
324 themeDisplay.getURLPortal() + url + "' />";
325 }
326 else if (elType.equals("text_box")) {
327 syndContent.setType("text");
328
329 content = element.elementText("dynamic-content");
330 }
331 else {
332 content = element.elementText("dynamic-content");
333 }
334 }
335
336 return content;
337 }
338
339 protected String processURL(
340 JournalFeed feed, String url, ThemeDisplay themeDisplay,
341 SyndEntry syndEntry) {
342
343 url = StringUtil.replace(
344 url,
345 new String[] {
346 "@group_id@", "@image_path@", "@main_path@"
347 },
348 new String[] {
349 String.valueOf(feed.getGroupId()), themeDisplay.getPathImage(),
350 themeDisplay.getPathMain()
351 }
352 );
353
354 List<SyndEnclosure> syndEnclosures = JournalRSSUtil.getDLEnclosures(
355 themeDisplay.getURLPortal(), url);
356
357 syndEnclosures.addAll(
358 JournalRSSUtil.getIGEnclosures(themeDisplay.getURLPortal(), url));
359
360 syndEntry.setEnclosures(syndEnclosures);
361
362 List<SyndLink> syndLinks = JournalRSSUtil.getDLLinks(
363 themeDisplay.getURLPortal(), url);
364
365 syndLinks.addAll(
366 JournalRSSUtil.getIGLinks(themeDisplay.getURLPortal(), url));
367
368 syndEntry.setLinks(syndLinks);
369
370 return url;
371 }
372
373 private static final String _XML_REQUUEST =
374 "<request><parameters><parameter><name>rss</name><value>true</value>" +
375 "</parameter></parameters></request>";
376
377 private static final Log _log = LogFactoryUtil.getLog(RSSAction.class);
378
379 }