com.liferay.journal.web.util.JournalRSSUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.journal.web.util.JournalRSSUtil.java

Source

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.journal.web.util;

import com.liferay.document.library.kernel.model.DLFolderConstants;
import com.liferay.document.library.kernel.service.DLAppLocalService;
import com.liferay.document.library.kernel.util.ImageProcessorUtil;
import com.liferay.journal.exception.NoSuchFeedException;
import com.liferay.journal.model.JournalArticle;
import com.liferay.journal.model.JournalArticleConstants;
import com.liferay.journal.model.JournalArticleDisplay;
import com.liferay.journal.model.JournalFeed;
import com.liferay.journal.model.JournalFeedConstants;
import com.liferay.journal.service.JournalArticleLocalService;
import com.liferay.journal.service.JournalContentSearchLocalService;
import com.liferay.journal.service.JournalFeedLocalService;
import com.liferay.journal.util.JournalContent;
import com.liferay.journal.util.comparator.ArticleDisplayDateComparator;
import com.liferay.journal.util.comparator.ArticleModifiedDateComparator;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Image;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.portlet.PortletRequestModel;
import com.liferay.portal.kernel.portlet.PortletURLFactoryUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.service.ImageLocalService;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.Node;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.portal.kernel.xml.XPath;
import com.liferay.rss.util.RSSUtil;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl;
import com.sun.syndication.io.FeedException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.portlet.PortletRequest;
import javax.portlet.PortletURL;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ResourceURL;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * @author Raymond Aug
 */
@Component(service = JournalRSSUtil.class)
public class JournalRSSUtil {

    public List<JournalArticle> getArticles(JournalFeed feed) {
        long companyId = feed.getCompanyId();
        long groupId = feed.getGroupId();
        List<Long> folderIds = Collections.emptyList();
        String articleId = null;
        Double version = null;
        String title = null;
        String description = null;
        String content = null;

        String ddmStructureKey = feed.getDDMStructureKey();

        if (Validator.isNull(ddmStructureKey)) {
            ddmStructureKey = null;
        }

        String ddmTemplateKey = feed.getDDMTemplateKey();

        if (Validator.isNull(ddmTemplateKey)) {
            ddmTemplateKey = null;
        }

        Date displayDateGT = null;
        Date displayDateLT = new Date();
        int status = WorkflowConstants.STATUS_APPROVED;
        Date reviewDate = null;
        boolean andOperator = true;
        int start = 0;
        int end = feed.getDelta();

        String orderByCol = feed.getOrderByCol();

        String orderByType = feed.getOrderByType();

        boolean orderByAsc = orderByType.equals("asc");

        OrderByComparator<JournalArticle> obc = new ArticleModifiedDateComparator(orderByAsc);

        if (orderByCol.equals("display-date")) {
            obc = new ArticleDisplayDateComparator(orderByAsc);
        }

        return _journalArticleLocalService.search(companyId, groupId, folderIds,
                JournalArticleConstants.CLASSNAME_ID_DEFAULT, articleId, version, title, description, content,
                ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT, status, reviewDate, andOperator,
                start, end, obc);
    }

    public List<SyndEnclosure> getDLEnclosures(String portalURL, String url) {
        List<SyndEnclosure> syndEnclosures = new ArrayList<>();

        FileEntry fileEntry = getFileEntry(url);

        if (fileEntry == null) {
            return syndEnclosures;
        }

        SyndEnclosure syndEnclosure = new SyndEnclosureImpl();

        syndEnclosure.setLength(fileEntry.getSize());
        syndEnclosure.setType(fileEntry.getMimeType());
        syndEnclosure.setUrl(portalURL + url);

        syndEnclosures.add(syndEnclosure);

        return syndEnclosures;
    }

    public List<SyndLink> getDLLinks(String portalURL, String url) {
        List<SyndLink> syndLinks = new ArrayList<>();

        FileEntry fileEntry = getFileEntry(url);

        if (fileEntry == null) {
            return syndLinks;
        }

        SyndLink syndLink = new SyndLinkImpl();

        syndLink.setHref(portalURL + url);
        syndLink.setLength(fileEntry.getSize());
        syndLink.setRel("enclosure");
        syndLink.setType(fileEntry.getMimeType());

        syndLinks.add(syndLink);

        return syndLinks;
    }

    public FileEntry getFileEntry(String url) {
        FileEntry fileEntry = null;

        String queryString = HttpUtil.getQueryString(url);

        Map<String, String[]> parameters = HttpUtil.parameterMapFromString(queryString);

        if (url.startsWith("/documents/")) {
            String[] pathArray = StringUtil.split(url, CharPool.SLASH);

            String uuid = null;
            long groupId = GetterUtil.getLong(pathArray[2]);
            long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
            String title = null;

            if (pathArray.length == 4) {
                uuid = pathArray[3];
            } else if (pathArray.length == 5) {
                folderId = GetterUtil.getLong(pathArray[3]);
                title = HttpUtil.decodeURL(pathArray[4]);
            } else if (pathArray.length > 5) {
                uuid = pathArray[5];
            }

            try {
                if (Validator.isNotNull(uuid)) {
                    fileEntry = _dlAppLocalService.getFileEntryByUuidAndGroupId(uuid, groupId);
                } else {
                    fileEntry = _dlAppLocalService.getFileEntry(groupId, folderId, title);
                }
            } catch (Exception e) {
                if (_log.isWarnEnabled()) {
                    _log.warn(e, e);
                }
            }
        } else if (parameters.containsKey("folderId") && parameters.containsKey("name")) {

            try {
                long fileEntryId = GetterUtil.getLong(parameters.get("fileEntryId")[0]);

                fileEntry = _dlAppLocalService.getFileEntry(fileEntryId);
            } catch (Exception e) {
                if (_log.isWarnEnabled()) {
                    _log.warn(e, e);
                }
            }
        } else if (parameters.containsKey("uuid") && parameters.containsKey("groupId")) {

            try {
                String uuid = parameters.get("uuid")[0];
                long groupId = GetterUtil.getLong(parameters.get("groupId")[0]);

                fileEntry = _dlAppLocalService.getFileEntryByUuidAndGroupId(uuid, groupId);
            } catch (Exception e) {
                if (_log.isWarnEnabled()) {
                    _log.warn(e, e);
                }
            }
        }

        return fileEntry;
    }

    public List<SyndEnclosure> getIGEnclosures(String portalURL, String url) {
        List<SyndEnclosure> syndEnclosures = new ArrayList<>();

        Object[] imageProperties = getImageProperties(url);

        if (imageProperties == null) {
            return syndEnclosures;
        }

        SyndEnclosure syndEnclosure = new SyndEnclosureImpl();

        syndEnclosure.setLength((Long) imageProperties[1]);
        syndEnclosure.setType(MimeTypesUtil.getExtensionContentType(imageProperties[0].toString()));
        syndEnclosure.setUrl(portalURL + url);

        syndEnclosures.add(syndEnclosure);

        return syndEnclosures;
    }

    public List<SyndLink> getIGLinks(String portalURL, String url) {
        List<SyndLink> syndLinks = new ArrayList<>();

        Object[] imageProperties = getImageProperties(url);

        if (imageProperties == null) {
            return syndLinks;
        }

        SyndLink syndLink = new SyndLinkImpl();

        syndLink.setHref(portalURL + url);
        syndLink.setLength((Long) imageProperties[1]);
        syndLink.setRel("enclosure");
        syndLink.setType(MimeTypesUtil.getExtensionContentType(imageProperties[0].toString()));

        syndLinks.add(syndLink);

        return syndLinks;
    }

    public Image getImage(String url) {
        Image image = null;

        String queryString = HttpUtil.getQueryString(url);

        Map<String, String[]> parameters = HttpUtil.parameterMapFromString(queryString);

        if (parameters.containsKey("image_id") || parameters.containsKey("img_id")
                || parameters.containsKey("i_id")) {

            try {
                long imageId = 0;

                if (parameters.containsKey("image_id")) {
                    imageId = GetterUtil.getLong(parameters.get("image_id")[0]);
                } else if (parameters.containsKey("img_id")) {
                    imageId = GetterUtil.getLong(parameters.get("img_id")[0]);
                } else if (parameters.containsKey("i_id")) {
                    imageId = GetterUtil.getLong(parameters.get("i_id")[0]);
                }

                image = _imageLocalService.getImage(imageId);
            } catch (Exception e) {
                if (_log.isWarnEnabled()) {
                    _log.warn(e, e);
                }
            }
        }

        return image;
    }

    public byte[] getRSS(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws Exception {

        ThemeDisplay themeDisplay = (ThemeDisplay) resourceRequest.getAttribute(WebKeys.THEME_DISPLAY);

        JournalFeed feed = null;

        long id = ParamUtil.getLong(resourceRequest, "id");

        if (id > 0) {
            try {
                feed = _journalFeedLocalService.getFeed(id);
            } catch (NoSuchFeedException nsfe) {

                // Backward compatibility with old URLs

                feed = _journalFeedLocalService.getFeed(themeDisplay.getScopeGroupId(), String.valueOf(id));
            }
        } else {
            long groupId = ParamUtil.getLong(resourceRequest, "groupId");
            String feedId = ParamUtil.getString(resourceRequest, "feedId");

            feed = _journalFeedLocalService.getFeed(groupId, feedId);
        }

        String languageId = LanguageUtil.getLanguageId(resourceRequest);

        long plid = _portal.getPlidFromFriendlyURL(themeDisplay.getCompanyId(), feed.getTargetLayoutFriendlyUrl());

        Layout layout = null;

        if (plid > 0) {
            layout = _layoutLocalService.fetchLayout(plid);
        }

        if (layout == null) {
            layout = themeDisplay.getLayout();
        }

        String rss = exportToRSS(resourceRequest, resourceResponse, feed, languageId, layout, themeDisplay);

        return rss.getBytes(StringPool.UTF8);
    }

    protected String exportToRSS(ResourceRequest resourceRequest, ResourceResponse resourceResponse,
            JournalFeed feed, String languageId, Layout layout, ThemeDisplay themeDisplay) throws Exception {

        SyndFeed syndFeed = new SyndFeedImpl();

        syndFeed.setDescription(feed.getDescription());

        List<SyndEntry> syndEntries = new ArrayList<>();

        syndFeed.setEntries(syndEntries);

        List<JournalArticle> articles = getArticles(feed);

        if (_log.isDebugEnabled()) {
            _log.debug("Syndicating " + articles.size() + " articles");
        }

        for (JournalArticle article : articles) {
            SyndEntry syndEntry = new SyndEntryImpl();

            String author = _portal.getUserName(article);

            syndEntry.setAuthor(author);

            SyndContent syndContent = new SyndContentImpl();

            syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);

            String value = article.getDescription(languageId);

            try {
                value = processContent(feed, article, languageId, themeDisplay, syndEntry, syndContent);
            } catch (Exception e) {
                if (_log.isWarnEnabled()) {
                    _log.warn(e, e);
                }
            }

            syndContent.setValue(value);

            syndEntry.setDescription(syndContent);

            String link = getEntryURL(resourceRequest, feed, article, layout, themeDisplay);

            syndEntry.setLink(link);

            syndEntry.setPublishedDate(article.getDisplayDate());
            syndEntry.setTitle(article.getTitle(languageId));
            syndEntry.setUpdatedDate(article.getModifiedDate());
            syndEntry.setUri(link);

            syndEntries.add(syndEntry);
        }

        syndFeed.setFeedType(feed.getFeedFormat() + "_" + feed.getFeedVersion());

        SyndLink selfSyndLink = new SyndLinkImpl();

        ResourceURL feedURL = resourceResponse.createResourceURL();

        feedURL.setCacheability(ResourceURL.FULL);
        feedURL.setParameter("groupId", String.valueOf(feed.getGroupId()));
        feedURL.setParameter("feedId", String.valueOf(feed.getFeedId()));
        feedURL.setResourceID("rss");

        selfSyndLink.setHref(feedURL.toString());

        selfSyndLink.setRel("self");

        List<SyndLink> syndLinks = new ArrayList<>();

        syndLinks.add(selfSyndLink);

        syndFeed.setLinks(syndLinks);

        syndFeed.setPublishedDate(new Date());
        syndFeed.setTitle(feed.getName());
        syndFeed.setUri(feedURL.toString());

        try {
            return RSSUtil.export(syndFeed);
        } catch (FeedException fe) {
            throw new SystemException(fe);
        }
    }

    protected String getEntryURL(ResourceRequest resourceRequest, JournalFeed feed, JournalArticle article,
            Layout layout, ThemeDisplay themeDisplay) throws Exception {

        List<Long> hitLayoutIds = _journalContentSearchLocalService.getLayoutIds(layout.getGroupId(),
                layout.isPrivateLayout(), article.getArticleId());

        if (!hitLayoutIds.isEmpty()) {
            Long hitLayoutId = hitLayoutIds.get(0);

            Layout hitLayout = _layoutLocalService.getLayout(layout.getGroupId(), layout.isPrivateLayout(),
                    hitLayoutId.longValue());

            return _portal.getLayoutFriendlyURL(hitLayout, themeDisplay);
        }

        String portletId = feed.getTargetPortletId();

        if (Validator.isNull(portletId)) {
            return StringPool.BLANK;
        }

        long plid = _portal.getPlidFromFriendlyURL(feed.getCompanyId(), feed.getTargetLayoutFriendlyUrl());

        PortletURL entryURL = PortletURLFactoryUtil.create(resourceRequest, portletId, plid,
                PortletRequest.RENDER_PHASE);

        entryURL.setParameter("groupId", String.valueOf(article.getGroupId()));
        entryURL.setParameter("articleId", article.getArticleId());

        return entryURL.toString();
    }

    protected Object[] getImageProperties(String url) {
        String type = null;
        long size = 0;

        Image image = getImage(url);

        if (image != null) {
            type = image.getType();
            size = image.getSize();
        } else {
            FileEntry fileEntry = getFileEntry(url);

            Set<String> imageMimeTypes = ImageProcessorUtil.getImageMimeTypes();

            if ((fileEntry != null) && imageMimeTypes.contains(fileEntry.getMimeType())) {

                type = fileEntry.getExtension();
                size = fileEntry.getSize();
            }
        }

        if (Validator.isNotNull(type)) {
            return new Object[] { type, size };
        }

        return null;
    }

    protected String processContent(JournalFeed feed, JournalArticle article, String languageId,
            ThemeDisplay themeDisplay, SyndEntry syndEntry, SyndContent syndContent) throws Exception {

        String content = article.getDescription(languageId);

        String contentField = feed.getContentField();

        if (contentField.equals(JournalFeedConstants.RENDERED_WEB_CONTENT)) {
            String ddmRendererTemplateKey = article.getDDMTemplateKey();

            if (Validator.isNotNull(feed.getDDMRendererTemplateKey())) {
                ddmRendererTemplateKey = feed.getDDMRendererTemplateKey();
            }

            JournalArticleDisplay articleDisplay = _journalContent.getDisplay(feed.getGroupId(),
                    article.getArticleId(), ddmRendererTemplateKey, null, languageId, 1, new PortletRequestModel() {

                        @Override
                        public String toXML() {
                            return _XML_REQUUEST;
                        }

                    }, themeDisplay);

            if (articleDisplay != null) {
                content = articleDisplay.getContent();
            }
        } else if (!contentField.equals(JournalFeedConstants.WEB_CONTENT_DESCRIPTION)) {

            Document document = SAXReaderUtil.read(article.getContentByLocale(languageId));

            contentField = HtmlUtil.escapeXPathAttribute(contentField);

            XPath xPathSelector = SAXReaderUtil.createXPath("//dynamic-element[@name=" + contentField + "]");

            List<Node> results = xPathSelector.selectNodes(document);

            if (results.isEmpty()) {
                return content;
            }

            Element element = (Element) results.get(0);

            String elType = element.attributeValue("type");

            if (elType.equals("document_library")) {
                String url = element.elementText("dynamic-content");

                url = processURL(feed, url, themeDisplay, syndEntry);
            } else if (elType.equals("image") || elType.equals("image_gallery")) {
                String url = element.elementText("dynamic-content");

                url = processURL(feed, url, themeDisplay, syndEntry);

                content = content + "<br /><br /><img alt='' src='" + themeDisplay.getURLPortal() + url + "' />";
            } else if (elType.equals("text_box")) {
                syndContent.setType("text");

                content = element.elementText("dynamic-content");
            } else {
                content = element.elementText("dynamic-content");
            }
        }

        return content;
    }

    protected String processURL(JournalFeed feed, String url, ThemeDisplay themeDisplay, SyndEntry syndEntry) {

        url = StringUtil.replace(url, new String[] { "@group_id@", "@image_path@", "@main_path@" }, new String[] {
                String.valueOf(feed.getGroupId()), themeDisplay.getPathImage(), themeDisplay.getPathMain() });

        List<SyndEnclosure> syndEnclosures = getDLEnclosures(themeDisplay.getURLPortal(), url);

        syndEnclosures.addAll(getIGEnclosures(themeDisplay.getURLPortal(), url));

        syndEntry.setEnclosures(syndEnclosures);

        List<SyndLink> syndLinks = getDLLinks(themeDisplay.getURLPortal(), url);

        syndLinks.addAll(getIGLinks(themeDisplay.getURLPortal(), url));

        syndEntry.setLinks(syndLinks);

        return url;
    }

    @Reference(unbind = "-")
    protected void setDLAppLocalService(DLAppLocalService dlAppLocalService) {
        _dlAppLocalService = dlAppLocalService;
    }

    @Reference(unbind = "-")
    protected void setImageLocalService(ImageLocalService imageLocalService) {
        _imageLocalService = imageLocalService;
    }

    @Reference(unbind = "-")
    protected void setJournalArticleLocalService(JournalArticleLocalService journalArticleLocalService) {

        _journalArticleLocalService = journalArticleLocalService;
    }

    @Reference(unbind = "-")
    protected void setJournalContent(JournalContent journalContent) {
        _journalContent = journalContent;
    }

    @Reference(unbind = "-")
    protected void setJournalContentSearchLocalService(
            JournalContentSearchLocalService journalContentSearchLocalService) {

        _journalContentSearchLocalService = journalContentSearchLocalService;
    }

    @Reference(unbind = "-")
    protected void setJournalFeedLocalService(JournalFeedLocalService journalFeedLocalService) {

        _journalFeedLocalService = journalFeedLocalService;
    }

    @Reference(unbind = "-")
    protected void setLayoutLocalService(LayoutLocalService layoutLocalService) {

        _layoutLocalService = layoutLocalService;
    }

    private static final String _XML_REQUUEST = "<request><parameters><parameter><name>rss</name><value>true</value>"
            + "</parameter></parameters></request>";

    private static final Log _log = LogFactoryUtil.getLog(JournalRSSUtil.class);

    private DLAppLocalService _dlAppLocalService;
    private ImageLocalService _imageLocalService;
    private JournalArticleLocalService _journalArticleLocalService;
    private JournalContent _journalContent;
    private JournalContentSearchLocalService _journalContentSearchLocalService;
    private JournalFeedLocalService _journalFeedLocalService;
    private LayoutLocalService _layoutLocalService;

    @Reference
    private Portal _portal;

}