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 else {
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(
206 "groupId", String.valueOf(article.getGroupId()));
207 entryURL.setParameter("articleId", article.getArticleId());
208
209 return entryURL.toString();
210 }
211 }
212
213 @Override
214 protected byte[] getRSS(
215 ResourceRequest resourceRequest, ResourceResponse resourceResponse)
216 throws Exception {
217
218 ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(
219 WebKeys.THEME_DISPLAY);
220
221 JournalFeed feed = null;
222
223 long id = ParamUtil.getLong(resourceRequest, "id");
224
225 long groupId = ParamUtil.getLong(resourceRequest, "groupId");
226 String feedId = ParamUtil.getString(resourceRequest, "feedId");
227
228 if (id > 0) {
229 feed = JournalFeedLocalServiceUtil.getFeed(id);
230 }
231 else {
232 feed = JournalFeedLocalServiceUtil.getFeed(groupId, feedId);
233 }
234
235 String languageId = LanguageUtil.getLanguageId(resourceRequest);
236
237 long plid = PortalUtil.getPlidFromFriendlyURL(
238 themeDisplay.getCompanyId(), feed.getTargetLayoutFriendlyUrl());
239
240 Layout layout = themeDisplay.getLayout();
241
242 if (plid > 0) {
243 try {
244 layout = LayoutLocalServiceUtil.getLayout(plid);
245 }
246 catch (NoSuchLayoutException nsle) {
247 }
248 }
249
250 String rss = exportToRSS(
251 resourceRequest, resourceResponse, feed, languageId, layout,
252 themeDisplay);
253
254 return rss.getBytes(StringPool.UTF8);
255 }
256
257 protected String processContent(
258 JournalFeed feed, JournalArticle article, String languageId,
259 ThemeDisplay themeDisplay, SyndEntry syndEntry,
260 SyndContent syndContent)
261 throws Exception {
262
263 String content = article.getDescription(languageId);
264
265 String contentField = feed.getContentField();
266
267 if (contentField.equals(JournalFeedConstants.RENDERED_WEB_CONTENT)) {
268 String rendererTemplateId = article.getTemplateId();
269
270 if (Validator.isNotNull(feed.getRendererTemplateId())) {
271 rendererTemplateId = feed.getRendererTemplateId();
272 }
273
274 JournalArticleDisplay articleDisplay =
275 JournalContentUtil.getDisplay(
276 feed.getGroupId(), article.getArticleId(),
277 rendererTemplateId, null, languageId, themeDisplay, 1,
278 _XML_REQUUEST);
279
280 if (articleDisplay != null) {
281 content = articleDisplay.getContent();
282 }
283 }
284 else if (!contentField.equals(
285 JournalFeedConstants.WEB_CONTENT_DESCRIPTION)) {
286
287 Document document = SAXReaderUtil.read(
288 article.getContentByLocale(languageId));
289
290 contentField = HtmlUtil.escapeXPathAttribute(contentField);
291
292 XPath xPathSelector = SAXReaderUtil.createXPath(
293 "
294
295 List<Node> results = xPathSelector.selectNodes(document);
296
297 if (results.size() == 0) {
298 return content;
299 }
300
301 Element element = (Element)results.get(0);
302
303 String elType = element.attributeValue("type");
304
305 if (elType.equals("document_library")) {
306 String url = element.elementText("dynamic-content");
307
308 url = processURL(feed, url, themeDisplay, syndEntry);
309 }
310 else if (elType.equals("image") || elType.equals("image_gallery")) {
311 String url = element.elementText("dynamic-content");
312
313 url = processURL(feed, url, themeDisplay, syndEntry);
314
315 content =
316 content + "<br /><br /><img alt='' src='" +
317 themeDisplay.getURLPortal() + url + "' />";
318 }
319 else if (elType.equals("text_box")) {
320 syndContent.setType("text");
321
322 content = element.elementText("dynamic-content");
323 }
324 else {
325 content = element.elementText("dynamic-content");
326 }
327 }
328
329 return content;
330 }
331
332 protected String processURL(
333 JournalFeed feed, String url, ThemeDisplay themeDisplay,
334 SyndEntry syndEntry) {
335
336 url = StringUtil.replace(
337 url,
338 new String[] {
339 "@group_id@", "@image_path@", "@main_path@"
340 },
341 new String[] {
342 String.valueOf(feed.getGroupId()), themeDisplay.getPathImage(),
343 themeDisplay.getPathMain()
344 }
345 );
346
347 List<SyndEnclosure> syndEnclosures = JournalRSSUtil.getDLEnclosures(
348 themeDisplay.getURLPortal(), url);
349
350 syndEnclosures.addAll(
351 JournalRSSUtil.getIGEnclosures(themeDisplay.getURLPortal(), url));
352
353 syndEntry.setEnclosures(syndEnclosures);
354
355 List<SyndLink> syndLinks = JournalRSSUtil.getDLLinks(
356 themeDisplay.getURLPortal(), url);
357
358 syndLinks.addAll(
359 JournalRSSUtil.getIGLinks(themeDisplay.getURLPortal(), url));
360
361 syndEntry.setLinks(syndLinks);
362
363 return url;
364 }
365
366 private static final String _XML_REQUUEST =
367 "<request><parameters><parameter><name>rss</name><value>true</value>" +
368 "</parameter></parameters></request>";
369
370 private static Log _log = LogFactoryUtil.getLog(RSSAction.class);
371
372 }