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(feed.getFeedType() + "_" + feed.getFeedVersion());
137
138 List<SyndLink> syndLinks = new ArrayList<SyndLink>();
139
140 syndFeed.setLinks(syndLinks);
141
142 SyndLink selfSyndLink = new SyndLinkImpl();
143
144 syndLinks.add(selfSyndLink);
145
146 ResourceURL feedURL = resourceResponse.createResourceURL();
147
148 feedURL.setCacheability(ResourceURL.FULL);
149 feedURL.setParameter("struts_action", "/journal/rss");
150 feedURL.setParameter("groupId", String.valueOf(feed.getGroupId()));
151 feedURL.setParameter("feedId", String.valueOf(feed.getFeedId()));
152
153 String link = feedURL.toString();
154
155 selfSyndLink.setHref(link);
156
157 selfSyndLink.setRel("self");
158
159 syndFeed.setTitle(feed.getName());
160 syndFeed.setPublishedDate(new Date());
161 syndFeed.setUri(feedURL.toString());
162
163 try {
164 return RSSUtil.export(syndFeed);
165 }
166 catch (FeedException fe) {
167 throw new SystemException(fe);
168 }
169 }
170
171 protected String getEntryURL(
172 ResourceRequest resourceRequest, JournalFeed feed,
173 JournalArticle article, Layout layout, ThemeDisplay themeDisplay)
174 throws Exception {
175
176 List<Long> hitLayoutIds =
177 JournalContentSearchLocalServiceUtil.getLayoutIds(
178 layout.getGroupId(), layout.isPrivateLayout(),
179 article.getArticleId());
180
181 if (hitLayoutIds.size() > 0) {
182 Long hitLayoutId = hitLayoutIds.get(0);
183
184 Layout hitLayout = LayoutLocalServiceUtil.getLayout(
185 layout.getGroupId(), layout.isPrivateLayout(),
186 hitLayoutId.longValue());
187
188 return PortalUtil.getLayoutFriendlyURL(hitLayout, themeDisplay);
189 }
190 else {
191 long plid = PortalUtil.getPlidFromFriendlyURL(
192 feed.getCompanyId(), feed.getTargetLayoutFriendlyUrl());
193
194 String portletId = PortletKeys.JOURNAL_CONTENT;
195
196 if (Validator.isNotNull(feed.getTargetPortletId())) {
197 portletId = feed.getTargetPortletId();
198 }
199
200 PortletURL entryURL = new PortletURLImpl(
201 resourceRequest, portletId, plid, PortletRequest.RENDER_PHASE);
202
203 entryURL.setParameter("struts_action", "/journal_content/view");
204 entryURL.setParameter(
205 "groupId", String.valueOf(article.getGroupId()));
206 entryURL.setParameter("articleId", article.getArticleId());
207
208 return entryURL.toString();
209 }
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, themeDisplay, 1,
277 _XML_REQUUEST);
278
279 if (articleDisplay != null) {
280 content = articleDisplay.getContent();
281 }
282 }
283 else if (!contentField.equals(
284 JournalFeedConstants.WEB_CONTENT_DESCRIPTION)) {
285
286 Document document = SAXReaderUtil.read(
287 article.getContentByLocale(languageId));
288
289 contentField = HtmlUtil.escapeXPathAttribute(contentField);
290
291 XPath xPathSelector = SAXReaderUtil.createXPath(
292 "
293
294 List<Node> results = xPathSelector.selectNodes(document);
295
296 if (results.size() == 0) {
297 return content;
298 }
299
300 Element element = (Element)results.get(0);
301
302 String elType = element.attributeValue("type");
303
304 if (elType.equals("document_library")) {
305 String url = element.elementText("dynamic-content");
306
307 url = processURL(feed, url, themeDisplay, syndEntry);
308 }
309 else if (elType.equals("image") || elType.equals("image_gallery")) {
310 String url = element.elementText("dynamic-content");
311
312 url = processURL(feed, url, themeDisplay, syndEntry);
313
314 content =
315 content + "<br /><br /><img alt='' src='" +
316 themeDisplay.getURLPortal() + url + "' />";
317 }
318 else if (elType.equals("text_box")) {
319 syndContent.setType("text");
320
321 content = element.elementText("dynamic-content");
322 }
323 else {
324 content = element.elementText("dynamic-content");
325 }
326 }
327
328 return content;
329 }
330
331 protected String processURL(
332 JournalFeed feed, String url, ThemeDisplay themeDisplay,
333 SyndEntry syndEntry) {
334
335 url = StringUtil.replace(
336 url,
337 new String[] {
338 "@group_id@", "@image_path@", "@main_path@"
339 },
340 new String[] {
341 String.valueOf(feed.getGroupId()), themeDisplay.getPathImage(),
342 themeDisplay.getPathMain()
343 }
344 );
345
346 List<SyndEnclosure> syndEnclosures = JournalRSSUtil.getDLEnclosures(
347 themeDisplay.getURLPortal(), url);
348
349 syndEnclosures.addAll(
350 JournalRSSUtil.getIGEnclosures(themeDisplay.getURLPortal(), url));
351
352 syndEntry.setEnclosures(syndEnclosures);
353
354 List<SyndLink> syndLinks = JournalRSSUtil.getDLLinks(
355 themeDisplay.getURLPortal(), url);
356
357 syndLinks.addAll(
358 JournalRSSUtil.getIGLinks(themeDisplay.getURLPortal(), url));
359
360 syndEntry.setLinks(syndLinks);
361
362 return url;
363 }
364
365 private static final String _XML_REQUUEST =
366 "<request><parameters><parameter><name>rss</name><value>true</value>" +
367 "</parameter></parameters></request>";
368
369 private static Log _log = LogFactoryUtil.getLog(RSSAction.class);
370
371 }