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