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