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