001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.blogs.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryDefinition;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.repository.model.FileEntry;
021    import com.liferay.portal.kernel.servlet.taglib.ui.ImageSelector;
022    import com.liferay.portal.kernel.util.HtmlUtil;
023    import com.liferay.portal.kernel.util.MimeTypesUtil;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.TempFileEntryUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.kernel.workflow.WorkflowConstants;
031    import com.liferay.portal.model.Company;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.model.Organization;
034    import com.liferay.portal.security.permission.ActionKeys;
035    import com.liferay.portal.service.ServiceContext;
036    import com.liferay.portal.theme.ThemeDisplay;
037    import com.liferay.portal.util.PortalUtil;
038    import com.liferay.portal.util.PropsValues;
039    import com.liferay.portlet.blogs.model.BlogsEntry;
040    import com.liferay.portlet.blogs.service.base.BlogsEntryServiceBaseImpl;
041    import com.liferay.portlet.blogs.service.permission.BlogsEntryPermission;
042    import com.liferay.portlet.blogs.service.permission.BlogsPermission;
043    import com.liferay.portlet.blogs.util.comparator.EntryDisplayDateComparator;
044    import com.liferay.util.RSSUtil;
045    
046    import com.sun.syndication.feed.synd.SyndContent;
047    import com.sun.syndication.feed.synd.SyndContentImpl;
048    import com.sun.syndication.feed.synd.SyndEntry;
049    import com.sun.syndication.feed.synd.SyndEntryImpl;
050    import com.sun.syndication.feed.synd.SyndFeed;
051    import com.sun.syndication.feed.synd.SyndFeedImpl;
052    import com.sun.syndication.feed.synd.SyndLink;
053    import com.sun.syndication.feed.synd.SyndLinkImpl;
054    import com.sun.syndication.io.FeedException;
055    
056    import java.io.InputStream;
057    
058    import java.util.ArrayList;
059    import java.util.Date;
060    import java.util.List;
061    
062    /**
063     * Provides the remote service for accessing, adding, deleting, subscription
064     * handling of, trash handling of, and updating blog entries. Its methods
065     * include permission checks.
066     *
067     * @author Brian Wing Shun Chan
068     * @author Mate Thurzo
069     */
070    public class BlogsEntryServiceImpl extends BlogsEntryServiceBaseImpl {
071    
072            /**
073             * @deprecated As of 7.0.0, replaced by {@link #addEntry(String, String,
074             *             String, String, int, int, int, int, int, boolean, boolean,
075             *             String[], String, ImageSelector, ImageSelector,
076             *             ServiceContext)}
077             */
078            @Deprecated
079            @Override
080            public BlogsEntry addEntry(
081                            String title, String description, String content,
082                            int displayDateMonth, int displayDateDay, int displayDateYear,
083                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
084                            boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
085                            String smallImageURL, String smallImageFileName,
086                            InputStream smallImageInputStream, ServiceContext serviceContext)
087                    throws PortalException {
088    
089                    BlogsPermission.check(
090                            getPermissionChecker(), serviceContext.getScopeGroupId(),
091                            ActionKeys.ADD_ENTRY);
092    
093                    ImageSelector coverImageImageSelector = null;
094                    ImageSelector smallImageImageSelector = null;
095    
096                    if (smallImage && Validator.isNotNull(smallImageFileName) &&
097                            (smallImageInputStream != null)) {
098    
099                            FileEntry fileEntry = TempFileEntryUtil.addTempFileEntry(
100                                    serviceContext.getScopeGroupId(), getUserId(),
101                                    BlogsEntry.class.getName(), smallImageFileName,
102                                    smallImageInputStream,
103                                    MimeTypesUtil.getContentType(smallImageFileName));
104    
105                            smallImageImageSelector = new ImageSelector(
106                                    fileEntry.getFileEntryId(), smallImageURL, null);
107                    }
108    
109                    return addEntry(
110                            title, StringPool.BLANK, description, content, displayDateMonth,
111                            displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
112                            allowPingbacks, allowTrackbacks, trackbacks, StringPool.BLANK,
113                            coverImageImageSelector, smallImageImageSelector, serviceContext);
114            }
115    
116            @Override
117            public BlogsEntry addEntry(
118                            String title, String subtitle, String description, String content,
119                            int displayDateMonth, int displayDateDay, int displayDateYear,
120                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
121                            boolean allowTrackbacks, String[] trackbacks,
122                            String coverImageCaption, ImageSelector coverImageImageSelector,
123                            ImageSelector smallImageImageSelector,
124                            ServiceContext serviceContext)
125                    throws PortalException {
126    
127                    BlogsPermission.check(
128                            getPermissionChecker(), serviceContext.getScopeGroupId(),
129                            ActionKeys.ADD_ENTRY);
130    
131                    return blogsEntryLocalService.addEntry(
132                            getUserId(), title, subtitle, description, content,
133                            displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
134                            displayDateMinute, allowPingbacks, allowTrackbacks, trackbacks,
135                            coverImageCaption, coverImageImageSelector, smallImageImageSelector,
136                            serviceContext);
137            }
138    
139            @Override
140            public void deleteEntry(long entryId) throws PortalException {
141                    BlogsEntryPermission.check(
142                            getPermissionChecker(), entryId, ActionKeys.DELETE);
143    
144                    blogsEntryLocalService.deleteEntry(entryId);
145            }
146    
147            @Override
148            public List<BlogsEntry> getCompanyEntries(
149                            long companyId, Date displayDate, int status, int max)
150                    throws PortalException {
151    
152                    List<BlogsEntry> entries = new ArrayList<>();
153    
154                    boolean listNotExhausted = true;
155    
156                    QueryDefinition<BlogsEntry> queryDefinition = new QueryDefinition<>(
157                            status, false, 0, 0, new EntryDisplayDateComparator());
158    
159                    if (status == WorkflowConstants.STATUS_ANY) {
160                            queryDefinition.setStatus(WorkflowConstants.STATUS_IN_TRASH, true);
161                    }
162    
163                    while ((entries.size() < max) && listNotExhausted) {
164                            queryDefinition.setEnd(queryDefinition.getStart() + max);
165    
166                            List<BlogsEntry> entryList =
167                                    blogsEntryLocalService.getCompanyEntries(
168                                            companyId, displayDate, queryDefinition);
169    
170                            queryDefinition.setStart(queryDefinition.getStart() + max);
171    
172                            listNotExhausted = (entryList.size() == max);
173    
174                            for (BlogsEntry entry : entryList) {
175                                    if (entries.size() >= max) {
176                                            break;
177                                    }
178    
179                                    if (BlogsEntryPermission.contains(
180                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
181    
182                                            entries.add(entry);
183                                    }
184                            }
185                    }
186    
187                    return entries;
188            }
189    
190            @Override
191            public String getCompanyEntriesRSS(
192                            long companyId, Date displayDate, int status, int max, String type,
193                            double version, String displayStyle, String feedURL,
194                            String entryURL, ThemeDisplay themeDisplay)
195                    throws PortalException {
196    
197                    Company company = companyPersistence.findByPrimaryKey(companyId);
198    
199                    String name = company.getName();
200                    List<BlogsEntry> blogsEntries = getCompanyEntries(
201                            companyId, displayDate, status, max);
202    
203                    return exportToRSS(
204                            name, name, type, version, displayStyle, feedURL, entryURL,
205                            blogsEntries, themeDisplay);
206            }
207    
208            @Override
209            public BlogsEntry getEntry(long entryId) throws PortalException {
210                    BlogsEntryPermission.check(
211                            getPermissionChecker(), entryId, ActionKeys.VIEW);
212    
213                    return blogsEntryLocalService.getEntry(entryId);
214            }
215    
216            @Override
217            public BlogsEntry getEntry(long groupId, String urlTitle)
218                    throws PortalException {
219    
220                    BlogsEntry entry = blogsEntryLocalService.getEntry(groupId, urlTitle);
221    
222                    BlogsEntryPermission.check(
223                            getPermissionChecker(), entry.getEntryId(), ActionKeys.VIEW);
224    
225                    return entry;
226            }
227    
228            @Override
229            public List<BlogsEntry> getGroupEntries(
230                    long groupId, Date displayDate, int status, int max) {
231    
232                    return getGroupEntries(groupId, displayDate, status, 0, max);
233            }
234    
235            @Override
236            public List<BlogsEntry> getGroupEntries(
237                    long groupId, Date displayDate, int status, int start, int end) {
238    
239                    if (status == WorkflowConstants.STATUS_ANY) {
240                            return blogsEntryPersistence.filterFindByG_LtD_NotS(
241                                    groupId, displayDate, WorkflowConstants.STATUS_IN_TRASH, start,
242                                    end);
243                    }
244                    else {
245                            return blogsEntryPersistence.filterFindByG_LtD_S(
246                                    groupId, displayDate, status, start, end);
247                    }
248            }
249    
250            @Override
251            public List<BlogsEntry> getGroupEntries(long groupId, int status, int max) {
252                    return getGroupEntries(groupId, status, 0, max);
253            }
254    
255            @Override
256            public List<BlogsEntry> getGroupEntries(
257                    long groupId, int status, int start, int end) {
258    
259                    if (status == WorkflowConstants.STATUS_ANY) {
260                            return blogsEntryPersistence.filterFindByG_NotS(
261                                    groupId, WorkflowConstants.STATUS_IN_TRASH, start, end);
262                    }
263                    else {
264                            return blogsEntryPersistence.filterFindByG_S(
265                                    groupId, status, start, end);
266                    }
267            }
268    
269            @Override
270            public List<BlogsEntry> getGroupEntries(
271                    long groupId, int status, int start, int end,
272                    OrderByComparator<BlogsEntry> obc) {
273    
274                    if (status == WorkflowConstants.STATUS_ANY) {
275                            return blogsEntryPersistence.filterFindByG_NotS(
276                                    groupId, WorkflowConstants.STATUS_IN_TRASH, start, end, obc);
277                    }
278                    else {
279                            return blogsEntryPersistence.filterFindByG_S(
280                                    groupId, status, start, end, obc);
281                    }
282            }
283    
284            @Override
285            public int getGroupEntriesCount(
286                    long groupId, Date displayDate, int status) {
287    
288                    if (status == WorkflowConstants.STATUS_ANY) {
289                            return blogsEntryPersistence.filterCountByG_LtD_NotS(
290                                    groupId, displayDate, WorkflowConstants.STATUS_IN_TRASH);
291                    }
292                    else {
293                            return blogsEntryPersistence.filterCountByG_LtD_S(
294                                    groupId, displayDate, status);
295                    }
296            }
297    
298            @Override
299            public int getGroupEntriesCount(long groupId, int status) {
300                    if (status == WorkflowConstants.STATUS_ANY) {
301                            return blogsEntryPersistence.filterCountByG_NotS(
302                                    groupId, WorkflowConstants.STATUS_IN_TRASH);
303                    }
304                    else {
305                            return blogsEntryPersistence.filterCountByG_S(groupId, status);
306                    }
307            }
308    
309            @Override
310            public String getGroupEntriesRSS(
311                            long groupId, Date displayDate, int status, int max, String type,
312                            double version, String displayStyle, String feedURL,
313                            String entryURL, ThemeDisplay themeDisplay)
314                    throws PortalException {
315    
316                    Group group = groupPersistence.findByPrimaryKey(groupId);
317    
318                    String name = group.getDescriptiveName();
319                    List<BlogsEntry> blogsEntries = getGroupEntries(
320                            groupId, displayDate, status, max);
321    
322                    return exportToRSS(
323                            name, name, type, version, displayStyle, feedURL, entryURL,
324                            blogsEntries, themeDisplay);
325            }
326    
327            @Override
328            public List<BlogsEntry> getGroupsEntries(
329                            long companyId, long groupId, Date displayDate, int status, int max)
330                    throws PortalException {
331    
332                    List<BlogsEntry> entries = new ArrayList<>();
333    
334                    boolean listNotExhausted = true;
335    
336                    QueryDefinition<BlogsEntry> queryDefinition = new QueryDefinition<>(
337                            status, false, 0, 0, new EntryDisplayDateComparator());
338    
339                    if (status == WorkflowConstants.STATUS_ANY) {
340                            queryDefinition.setStatus(WorkflowConstants.STATUS_IN_TRASH, true);
341                    }
342    
343                    while ((entries.size() < max) && listNotExhausted) {
344                            queryDefinition.setEnd(queryDefinition.getStart() + max);
345    
346                            List<BlogsEntry> entryList =
347                                    blogsEntryLocalService.getGroupsEntries(
348                                            companyId, groupId, displayDate, queryDefinition);
349    
350                            queryDefinition.setStart(queryDefinition.getStart() + max);
351    
352                            listNotExhausted = (entryList.size() == max);
353    
354                            for (BlogsEntry entry : entryList) {
355                                    if (entries.size() >= max) {
356                                            break;
357                                    }
358    
359                                    if (BlogsEntryPermission.contains(
360                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
361    
362                                            entries.add(entry);
363                                    }
364                            }
365                    }
366    
367                    return entries;
368            }
369    
370            @Override
371            public List<BlogsEntry> getGroupUserEntries(
372                    long groupId, long userId, int status, int start, int end,
373                    OrderByComparator<BlogsEntry> obc) {
374    
375                    if (status == WorkflowConstants.STATUS_ANY) {
376                            return blogsEntryPersistence.filterFindByG_U_NotS(
377                                    groupId, userId, WorkflowConstants.STATUS_IN_TRASH, start, end,
378                                    obc);
379                    }
380                    else {
381                            return blogsEntryPersistence.filterFindByG_U_S(
382                                    groupId, userId, status, start, end, obc);
383                    }
384            }
385    
386            @Override
387            public int getGroupUserEntriesCount(long groupId, long userId, int status) {
388                    if (status == WorkflowConstants.STATUS_ANY) {
389                            return blogsEntryPersistence.filterCountByG_U_NotS(
390                                    groupId, userId, WorkflowConstants.STATUS_IN_TRASH);
391                    }
392                    else {
393                            return blogsEntryPersistence.filterCountByG_U_S(
394                                    groupId, userId, status);
395                    }
396            }
397    
398            @Override
399            public List<BlogsEntry> getOrganizationEntries(
400                            long organizationId, Date displayDate, int status, int max)
401                    throws PortalException {
402    
403                    List<BlogsEntry> entries = new ArrayList<>();
404    
405                    boolean listNotExhausted = true;
406    
407                    QueryDefinition<BlogsEntry> queryDefinition = new QueryDefinition<>(
408                            status, false, 0, 0, new EntryDisplayDateComparator());
409    
410                    if (status == WorkflowConstants.STATUS_ANY) {
411                            queryDefinition.setStatus(WorkflowConstants.STATUS_IN_TRASH, true);
412                    }
413    
414                    while ((entries.size() < max) && listNotExhausted) {
415                            queryDefinition.setEnd(queryDefinition.getStart() + max);
416    
417                            List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
418                                    organizationId, displayDate, queryDefinition);
419    
420                            queryDefinition.setStart(queryDefinition.getStart() + max);
421    
422                            listNotExhausted = (entryList.size() == max);
423    
424                            for (BlogsEntry entry : entryList) {
425                                    if (entries.size() >= max) {
426                                            break;
427                                    }
428    
429                                    if (BlogsEntryPermission.contains(
430                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
431    
432                                            entries.add(entry);
433                                    }
434                            }
435                    }
436    
437                    return entries;
438            }
439    
440            @Override
441            public String getOrganizationEntriesRSS(
442                            long organizationId, Date displayDate, int status, int max,
443                            String type, double version, String displayStyle, String feedURL,
444                            String entryURL, ThemeDisplay themeDisplay)
445                    throws PortalException {
446    
447                    Organization organization = organizationPersistence.findByPrimaryKey(
448                            organizationId);
449    
450                    String name = organization.getName();
451                    List<BlogsEntry> blogsEntries = getOrganizationEntries(
452                            organizationId, displayDate, status, max);
453    
454                    return exportToRSS(
455                            name, name, type, version, displayStyle, feedURL, entryURL,
456                            blogsEntries, themeDisplay);
457            }
458    
459            @Override
460            public BlogsEntry moveEntryToTrash(long entryId) throws PortalException {
461                    BlogsEntryPermission.check(
462                            getPermissionChecker(), entryId, ActionKeys.DELETE);
463    
464                    return blogsEntryLocalService.moveEntryToTrash(getUserId(), entryId);
465            }
466    
467            @Override
468            public void restoreEntryFromTrash(long entryId) throws PortalException {
469                    BlogsEntryPermission.check(
470                            getPermissionChecker(), entryId, ActionKeys.DELETE);
471    
472                    blogsEntryLocalService.restoreEntryFromTrash(getUserId(), entryId);
473            }
474    
475            @Override
476            public void subscribe(long groupId) throws PortalException {
477                    BlogsPermission.check(
478                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
479    
480                    blogsEntryLocalService.subscribe(getUserId(), groupId);
481            }
482    
483            @Override
484            public void unsubscribe(long groupId) throws PortalException {
485                    BlogsPermission.check(
486                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
487    
488                    blogsEntryLocalService.unsubscribe(getUserId(), groupId);
489            }
490    
491            /**
492             * @deprecated As of 7.0.0, replaced by {@link #updateEntry(long, String,
493             *             String, String, String, int, int, int, int, int, boolean,
494             *             boolean, String[], String, ImageSelector, ImageSelector,
495             *             ServiceContext)}
496             */
497            @Deprecated
498            @Override
499            public BlogsEntry updateEntry(
500                            long entryId, String title, String description, String content,
501                            int displayDateMonth, int displayDateDay, int displayDateYear,
502                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
503                            boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
504                            String smallImageURL, String smallImageFileName,
505                            InputStream smallImageInputStream, ServiceContext serviceContext)
506                    throws PortalException {
507    
508                    BlogsPermission.check(
509                            getPermissionChecker(), serviceContext.getScopeGroupId(),
510                            ActionKeys.UPDATE);
511    
512                    ImageSelector coverImageImageSelector = null;
513                    ImageSelector smallImageImageSelector = null;
514    
515                    if (smallImage) {
516                            if (Validator.isNotNull(smallImageFileName) &&
517                                    (smallImageInputStream != null)) {
518    
519                                    FileEntry fileEntry = TempFileEntryUtil.addTempFileEntry(
520                                            serviceContext.getScopeGroupId(), getUserId(),
521                                            BlogsEntry.class.getName(), smallImageFileName,
522                                            smallImageInputStream,
523                                            MimeTypesUtil.getContentType(smallImageFileName));
524    
525                                    smallImageImageSelector = new ImageSelector(
526                                            fileEntry.getFileEntryId(), smallImageURL, null);
527                            }
528                    }
529                    else {
530                            smallImageImageSelector = new ImageSelector(0);
531                    }
532    
533                    return updateEntry(
534                            entryId, title, StringPool.BLANK, description, content,
535                            displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
536                            displayDateMinute, allowPingbacks, allowTrackbacks, trackbacks,
537                            StringPool.BLANK, coverImageImageSelector, smallImageImageSelector,
538                            serviceContext);
539            }
540    
541            @Override
542            public BlogsEntry updateEntry(
543                            long entryId, String title, String subtitle, String description,
544                            String content, int displayDateMonth, int displayDateDay,
545                            int displayDateYear, int displayDateHour, int displayDateMinute,
546                            boolean allowPingbacks, boolean allowTrackbacks,
547                            String[] trackbacks, String coverImageCaption,
548                            ImageSelector coverImageImageSelector,
549                            ImageSelector smallImageImageSelector,
550                            ServiceContext serviceContext)
551                    throws PortalException {
552    
553                    BlogsEntryPermission.check(
554                            getPermissionChecker(), entryId, ActionKeys.UPDATE);
555    
556                    return blogsEntryLocalService.updateEntry(
557                            getUserId(), entryId, title, subtitle, description, content,
558                            displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
559                            displayDateMinute, allowPingbacks, allowTrackbacks, trackbacks,
560                            coverImageCaption, coverImageImageSelector, smallImageImageSelector,
561                            serviceContext);
562            }
563    
564            protected String exportToRSS(
565                    String name, String description, String type, double version,
566                    String displayStyle, String feedURL, String entryURL,
567                    List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay) {
568    
569                    SyndFeed syndFeed = new SyndFeedImpl();
570    
571                    syndFeed.setDescription(description);
572    
573                    List<SyndEntry> syndEntries = new ArrayList<>();
574    
575                    syndFeed.setEntries(syndEntries);
576    
577                    for (BlogsEntry entry : blogsEntries) {
578                            SyndEntry syndEntry = new SyndEntryImpl();
579    
580                            String author = PortalUtil.getUserName(entry);
581    
582                            syndEntry.setAuthor(author);
583    
584                            SyndContent syndContent = new SyndContentImpl();
585    
586                            syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
587    
588                            String value = null;
589    
590                            if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
591                                    String summary = entry.getDescription();
592    
593                                    if (Validator.isNull(summary)) {
594                                            summary = entry.getContent();
595                                    }
596    
597                                    value = StringUtil.shorten(
598                                            HtmlUtil.extractText(summary),
599                                            PropsValues.BLOGS_RSS_ABSTRACT_LENGTH, StringPool.BLANK);
600                            }
601                            else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
602                                    value = StringPool.BLANK;
603                            }
604                            else {
605                                    value = StringUtil.replace(
606                                            entry.getContent(), new String[] {"href=\"/", "src=\"/"},
607                                            new String[] {
608                                                    "href=\"" + themeDisplay.getURLPortal() + "/",
609                                                    "src=\"" + themeDisplay.getURLPortal() + "/"
610                                            });
611                            }
612    
613                            syndContent.setValue(value);
614    
615                            syndEntry.setDescription(syndContent);
616    
617                            StringBundler sb = new StringBundler(4);
618    
619                            sb.append(entryURL);
620    
621                            if (!entryURL.endsWith(StringPool.QUESTION)) {
622                                    sb.append(StringPool.AMPERSAND);
623                            }
624    
625                            sb.append("entryId=");
626                            sb.append(entry.getEntryId());
627    
628                            String link = sb.toString();
629    
630                            syndEntry.setLink(link);
631    
632                            syndEntry.setPublishedDate(entry.getDisplayDate());
633                            syndEntry.setTitle(entry.getTitle());
634                            syndEntry.setUpdatedDate(entry.getModifiedDate());
635                            syndEntry.setUri(link);
636    
637                            syndEntries.add(syndEntry);
638                    }
639    
640                    syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
641    
642                    List<SyndLink> syndLinks = new ArrayList<>();
643    
644                    syndFeed.setLinks(syndLinks);
645    
646                    SyndLink selfSyndLink = new SyndLinkImpl();
647    
648                    syndLinks.add(selfSyndLink);
649    
650                    selfSyndLink.setHref(feedURL);
651                    selfSyndLink.setRel("self");
652    
653                    syndFeed.setPublishedDate(new Date());
654                    syndFeed.setTitle(name);
655                    syndFeed.setUri(feedURL);
656    
657                    try {
658                            return RSSUtil.export(syndFeed);
659                    }
660                    catch (FeedException fe) {
661                            throw new SystemException(fe);
662                    }
663            }
664    
665    }