001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.assetpublisher.action;
016    
017    import com.liferay.portal.kernel.language.LanguageUtil;
018    import com.liferay.portal.kernel.portlet.LiferayPortletRequest;
019    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
020    import com.liferay.portal.kernel.util.ContentTypes;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.HtmlUtil;
023    import com.liferay.portal.kernel.util.Http;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.Layout;
028    import com.liferay.portal.struts.PortletAction;
029    import com.liferay.portal.theme.PortletDisplay;
030    import com.liferay.portal.theme.ThemeDisplay;
031    import com.liferay.portal.util.Portal;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.WebKeys;
034    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
035    import com.liferay.portlet.asset.model.AssetEntry;
036    import com.liferay.portlet.asset.model.AssetRenderer;
037    import com.liferay.portlet.asset.model.AssetRendererFactory;
038    import com.liferay.portlet.asset.service.AssetEntryServiceUtil;
039    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
040    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
041    import com.liferay.util.RSSUtil;
042    
043    import com.sun.syndication.feed.synd.SyndContent;
044    import com.sun.syndication.feed.synd.SyndContentImpl;
045    import com.sun.syndication.feed.synd.SyndEntry;
046    import com.sun.syndication.feed.synd.SyndEntryImpl;
047    import com.sun.syndication.feed.synd.SyndFeed;
048    import com.sun.syndication.feed.synd.SyndFeedImpl;
049    
050    import java.io.OutputStream;
051    
052    import java.util.ArrayList;
053    import java.util.List;
054    
055    import javax.portlet.PortletConfig;
056    import javax.portlet.PortletPreferences;
057    import javax.portlet.PortletRequest;
058    import javax.portlet.PortletResponse;
059    import javax.portlet.ResourceRequest;
060    import javax.portlet.ResourceResponse;
061    
062    import org.apache.struts.action.ActionForm;
063    import org.apache.struts.action.ActionMapping;
064    
065    /**
066     * @author Brian Wing Shun Chan
067     * @author Julio Camarero
068     */
069    public class RSSAction extends PortletAction {
070    
071            @Override
072            public void serveResource(
073                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
074                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
075                    throws Exception {
076    
077                    resourceResponse.setContentType(ContentTypes.TEXT_XML_UTF8);
078    
079                    OutputStream outputStream = resourceResponse.getPortletOutputStream();
080    
081                    try {
082                            byte[] bytes = getRSS(resourceRequest, resourceResponse);
083    
084                            outputStream.write(bytes);
085                    }
086                    finally {
087                            outputStream.close();
088                    }
089            }
090    
091            protected String exportToRSS(
092                            PortletRequest portletRequest, PortletResponse portletResponse,
093                            String name, String description, String type, double version,
094                            String displayStyle, String linkBehavior,
095                            List<AssetEntry> assetEntries)
096                    throws Exception {
097    
098                    SyndFeed syndFeed = new SyndFeedImpl();
099    
100                    syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
101                    syndFeed.setTitle(name);
102                    syndFeed.setLink(getFeedURL(portletRequest));
103                    syndFeed.setDescription(GetterUtil.getString(description, name));
104    
105                    List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
106    
107                    syndFeed.setEntries(syndEntries);
108    
109                    for (AssetEntry assetEntry : assetEntries) {
110                            String link = getEntryURL(
111                                    portletRequest, portletResponse, linkBehavior, assetEntry);
112    
113                            String author = HtmlUtil.escape(
114                                    PortalUtil.getUserName(
115                                            assetEntry.getUserId(), assetEntry.getUserName()));
116    
117                            String value = null;
118    
119                            String languageId = LanguageUtil.getLanguageId(portletRequest);
120    
121                            if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
122                                    value = StringPool.BLANK;
123                            }
124                            else {
125                                    value = assetEntry.getSummary(languageId, true);
126                            }
127    
128                            SyndEntry syndEntry = new SyndEntryImpl();
129    
130                            syndEntry.setAuthor(author);
131    
132                            syndEntry.setTitle(assetEntry.getTitle(languageId, true));
133    
134                            syndEntry.setLink(link);
135                            syndEntry.setUri(syndEntry.getLink());
136                            syndEntry.setPublishedDate(assetEntry.getCreateDate());
137                            syndEntry.setUpdatedDate(assetEntry.getModifiedDate());
138    
139                            SyndContent syndContent = new SyndContentImpl();
140    
141                            syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
142                            syndContent.setValue(value);
143    
144                            syndEntry.setDescription(syndContent);
145    
146                            syndEntries.add(syndEntry);
147                    }
148    
149                    return RSSUtil.export(syndFeed);
150            }
151    
152            protected List<AssetEntry> getAssetEntries(
153                            PortletRequest portletRequest, PortletPreferences preferences)
154                    throws Exception {
155    
156                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
157                            WebKeys.THEME_DISPLAY);
158    
159                    AssetEntryQuery assetEntryQuery = AssetPublisherUtil.getAssetEntryQuery(
160                            preferences, new long[] {themeDisplay.getScopeGroupId()});
161    
162                    boolean anyAssetType = GetterUtil.getBoolean(
163                            preferences.getValue("anyAssetType", null), true);
164    
165                    if (!anyAssetType) {
166                            long[] availableClassNameIds =
167                                    AssetRendererFactoryRegistryUtil.getClassNameIds();
168    
169                            long[] classNameIds = AssetPublisherUtil.getClassNameIds(
170                                    preferences, availableClassNameIds);
171    
172                            assetEntryQuery.setClassNameIds(classNameIds);
173                    }
174    
175                    long[] classTypeIds = GetterUtil.getLongValues(
176                            preferences.getValues("classTypeIds", null));
177    
178                    assetEntryQuery.setClassTypeIds(classTypeIds);
179    
180                    boolean enablePermissions = GetterUtil.getBoolean(
181                            preferences.getValue("enablePermissions", null));
182    
183                    assetEntryQuery.setEnablePermissions(enablePermissions);
184    
185                    int rssDelta = GetterUtil.getInteger(
186                            preferences.getValue("rssDelta", "20"));
187    
188                    assetEntryQuery.setEnd(rssDelta);
189    
190                    boolean excludeZeroViewCount = GetterUtil.getBoolean(
191                            preferences.getValue("excludeZeroViewCount", null));
192    
193                    assetEntryQuery.setExcludeZeroViewCount(excludeZeroViewCount);
194    
195                    long[] groupIds = AssetPublisherUtil.getGroupIds(
196                            preferences, themeDisplay.getScopeGroupId(),
197                            themeDisplay.getLayout());
198    
199                    assetEntryQuery.setGroupIds(groupIds);
200    
201                    boolean showOnlyLayoutAssets = GetterUtil.getBoolean(
202                            preferences.getValue("showOnlyLayoutAssets", null));
203    
204                    if (showOnlyLayoutAssets) {
205                            assetEntryQuery.setLayout(themeDisplay.getLayout());
206                    }
207    
208                    String orderByColumn1 = GetterUtil.getString(
209                            preferences.getValue("orderByColumn1", "modifiedDate"));
210    
211                    assetEntryQuery.setOrderByCol1(orderByColumn1);
212    
213                    String orderByColumn2 = GetterUtil.getString(
214                            preferences.getValue("orderByColumn2", "title"));
215    
216                    assetEntryQuery.setOrderByCol2(orderByColumn2);
217    
218                    String orderByType1 = GetterUtil.getString(
219                            preferences.getValue("orderByType1", "DESC"));
220    
221                    assetEntryQuery.setOrderByType1(orderByType1);
222    
223                    String orderByType2 = GetterUtil.getString(
224                            preferences.getValue("orderByType2", "ASC"));
225    
226                    assetEntryQuery.setOrderByType2(orderByType2);
227    
228                    assetEntryQuery.setStart(0);
229    
230                    return AssetEntryServiceUtil.getEntries(assetEntryQuery);
231            }
232    
233            protected String getAssetPublisherURL(PortletRequest portletRequest)
234                    throws Exception {
235    
236                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
237                            WebKeys.THEME_DISPLAY);
238    
239                    Layout layout = themeDisplay.getLayout();
240    
241                    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
242    
243                    StringBundler sb = new StringBundler(7);
244    
245                    String layoutFriendlyURL = GetterUtil.getString(
246                            PortalUtil.getLayoutFriendlyURL(layout, themeDisplay));
247    
248                    if (!layoutFriendlyURL.startsWith(Http.HTTP_WITH_SLASH) &&
249                            !layoutFriendlyURL.startsWith(Http.HTTPS_WITH_SLASH)) {
250    
251                            sb.append(themeDisplay.getPortalURL());
252                    }
253    
254                    sb.append(layoutFriendlyURL);
255                    sb.append(Portal.FRIENDLY_URL_SEPARATOR);
256                    sb.append("asset_publisher/");
257                    sb.append(portletDisplay.getInstanceId());
258                    sb.append(StringPool.SLASH);
259    
260                    return sb.toString();
261            }
262    
263            protected String getEntryURL(
264                            PortletRequest portletRequest, PortletResponse portletResponse,
265                            String linkBehavior, AssetEntry assetEntry)
266                    throws Exception {
267    
268                    if (linkBehavior.equals("viewInPortlet")) {
269                            return getEntryURLViewInContext(
270                                    portletRequest, portletResponse, assetEntry);
271                    }
272                    else {
273                            return getEntryURLAssetPublisher(
274                                    portletRequest, portletResponse, assetEntry);
275                    }
276            }
277    
278            protected String getEntryURLAssetPublisher(
279                            PortletRequest portletRequest, PortletResponse portletResponse,
280                            AssetEntry assetEntry)
281                    throws Exception {
282    
283                    AssetRendererFactory assetRendererFactory =
284                            AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName(
285                                    assetEntry.getClassName());
286    
287                    StringBundler sb = new StringBundler(4);
288    
289                    sb.append(getAssetPublisherURL(portletRequest));
290                    sb.append(assetRendererFactory.getType());
291                    sb.append("/id/");
292                    sb.append(assetEntry.getEntryId());
293    
294                    return sb.toString();
295            }
296    
297            protected String getEntryURLViewInContext(
298                            PortletRequest portletRequest, PortletResponse portletResponse,
299                            AssetEntry assetEntry)
300                    throws Exception {
301    
302                    AssetRendererFactory assetRendererFactory =
303                            AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName(
304                                    assetEntry.getClassName());
305    
306                    AssetRenderer assetRenderer = assetRendererFactory.getAssetRenderer(
307                            assetEntry.getClassPK());
308    
309                    String viewInContextURL = assetRenderer.getURLViewInContext(
310                            (LiferayPortletRequest)portletRequest,
311                            (LiferayPortletResponse)portletResponse, null);
312    
313                    if (Validator.isNotNull(viewInContextURL) &&
314                            !viewInContextURL.startsWith(Http.HTTP_WITH_SLASH) &&
315                            !viewInContextURL.startsWith(Http.HTTPS_WITH_SLASH)) {
316    
317                            ThemeDisplay themeDisplay =
318                                    (ThemeDisplay)portletRequest.getAttribute(
319                                            WebKeys.THEME_DISPLAY);
320    
321                            viewInContextURL = themeDisplay.getPortalURL() + viewInContextURL;
322                    }
323    
324                    return viewInContextURL;
325            }
326    
327            protected String getFeedURL(PortletRequest portletRequest)
328                    throws Exception {
329    
330                    String feedURL = getAssetPublisherURL(portletRequest);
331    
332                    return feedURL.concat("rss");
333            }
334    
335            protected byte[] getRSS(
336                            PortletRequest portletRequest, PortletResponse portletResponse)
337                    throws Exception {
338    
339                    PortletPreferences preferences = portletRequest.getPreferences();
340    
341                    String selectionStyle = preferences.getValue(
342                            "selectionStyle", "dynamic");
343    
344                    if (!selectionStyle.equals("dynamic")) {
345                            return new byte[0];
346                    }
347    
348                    String rssName = preferences.getValue("rssName", null);
349                    String rssFormat = preferences.getValue("rssFormat", "atom10");
350                    String rssDisplayStyle = preferences.getValue(
351                            "rssDisplayStyle", RSSUtil.DISPLAY_STYLE_ABSTRACT);
352                    String assetLinkBehavior = preferences.getValue(
353                            "assetLinkBehavior", "showFullContent");
354    
355                    String rss = exportToRSS(
356                            portletRequest, portletResponse, rssName, null,
357                            RSSUtil.getFormatType(rssFormat),
358                            RSSUtil.getFormatVersion(rssFormat), rssDisplayStyle,
359                            assetLinkBehavior, getAssetEntries(portletRequest, preferences));
360    
361                    return rss.getBytes(StringPool.UTF8);
362            }
363    
364    }