001    /**
002     * Copyright (c) 2000-2013 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.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.util.HtmlUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.kernel.workflow.WorkflowConstants;
025    import com.liferay.portal.model.Company;
026    import com.liferay.portal.model.Group;
027    import com.liferay.portal.model.Organization;
028    import com.liferay.portal.security.permission.ActionKeys;
029    import com.liferay.portal.service.ServiceContext;
030    import com.liferay.portal.theme.ThemeDisplay;
031    import com.liferay.portal.util.PortalUtil;
032    import com.liferay.portal.util.PropsValues;
033    import com.liferay.portlet.blogs.model.BlogsEntry;
034    import com.liferay.portlet.blogs.service.base.BlogsEntryServiceBaseImpl;
035    import com.liferay.portlet.blogs.service.permission.BlogsEntryPermission;
036    import com.liferay.portlet.blogs.service.permission.BlogsPermission;
037    import com.liferay.portlet.blogs.util.comparator.EntryDisplayDateComparator;
038    import com.liferay.util.RSSUtil;
039    
040    import com.sun.syndication.feed.synd.SyndContent;
041    import com.sun.syndication.feed.synd.SyndContentImpl;
042    import com.sun.syndication.feed.synd.SyndEntry;
043    import com.sun.syndication.feed.synd.SyndEntryImpl;
044    import com.sun.syndication.feed.synd.SyndFeed;
045    import com.sun.syndication.feed.synd.SyndFeedImpl;
046    import com.sun.syndication.feed.synd.SyndLink;
047    import com.sun.syndication.feed.synd.SyndLinkImpl;
048    import com.sun.syndication.io.FeedException;
049    
050    import java.io.InputStream;
051    
052    import java.util.ArrayList;
053    import java.util.Date;
054    import java.util.Iterator;
055    import java.util.List;
056    
057    /**
058     * @author Brian Wing Shun Chan
059     * @author Mate Thurzo
060     */
061    public class BlogsEntryServiceImpl extends BlogsEntryServiceBaseImpl {
062    
063            @Override
064            public BlogsEntry addEntry(
065                            String title, String description, String content,
066                            int displayDateMonth, int displayDateDay, int displayDateYear,
067                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
068                            boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
069                            String smallImageURL, String smallImageFileName,
070                            InputStream smallImageInputStream, ServiceContext serviceContext)
071                    throws PortalException, SystemException {
072    
073                    BlogsPermission.check(
074                            getPermissionChecker(), serviceContext.getScopeGroupId(),
075                            ActionKeys.ADD_ENTRY);
076    
077                    return blogsEntryLocalService.addEntry(
078                            getUserId(), title, description, content, displayDateMonth,
079                            displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
080                            allowPingbacks, allowTrackbacks, trackbacks, smallImage,
081                            smallImageURL, smallImageFileName, smallImageInputStream,
082                            serviceContext);
083            }
084    
085            @Override
086            public void deleteEntry(long entryId)
087                    throws PortalException, SystemException {
088    
089                    BlogsEntryPermission.check(
090                            getPermissionChecker(), entryId, ActionKeys.DELETE);
091    
092                    blogsEntryLocalService.deleteEntry(entryId);
093            }
094    
095            @Override
096            public List<BlogsEntry> getCompanyEntries(
097                            long companyId, Date displayDate, int status, int max)
098                    throws PortalException, SystemException {
099    
100                    List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
101    
102                    int lastIntervalStart = 0;
103                    boolean listNotExhausted = true;
104    
105                    while ((entries.size() < max) && listNotExhausted) {
106                            List<BlogsEntry> entryList =
107                                    blogsEntryLocalService.getCompanyEntries(
108                                            companyId, displayDate, status, lastIntervalStart,
109                                            lastIntervalStart + max, new EntryDisplayDateComparator());
110    
111                            Iterator<BlogsEntry> itr = entryList.iterator();
112    
113                            lastIntervalStart += max;
114                            listNotExhausted = (entryList.size() == max);
115    
116                            while (itr.hasNext() && (entries.size() < max)) {
117                                    BlogsEntry entry = itr.next();
118    
119                                    if (BlogsEntryPermission.contains(
120                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
121    
122                                            entries.add(entry);
123                                    }
124                            }
125                    }
126    
127                    return entries;
128            }
129    
130            @Override
131            public String getCompanyEntriesRSS(
132                            long companyId, Date displayDate, int status, int max, String type,
133                            double version, String displayStyle, String feedURL,
134                            String entryURL, ThemeDisplay themeDisplay)
135                    throws PortalException, SystemException {
136    
137                    Company company = companyPersistence.findByPrimaryKey(companyId);
138    
139                    String name = company.getName();
140                    String description = name;
141                    List<BlogsEntry> blogsEntries = getCompanyEntries(
142                            companyId, displayDate, status, max);
143    
144                    return exportToRSS(
145                            name, description, type, version, displayStyle, feedURL, entryURL,
146                            blogsEntries, themeDisplay);
147            }
148    
149            @Override
150            public BlogsEntry getEntry(long entryId)
151                    throws PortalException, SystemException {
152    
153                    BlogsEntryPermission.check(
154                            getPermissionChecker(), entryId, ActionKeys.VIEW);
155    
156                    return blogsEntryLocalService.getEntry(entryId);
157            }
158    
159            @Override
160            public BlogsEntry getEntry(long groupId, String urlTitle)
161                    throws PortalException, SystemException {
162    
163                    BlogsEntry entry = blogsEntryLocalService.getEntry(groupId, urlTitle);
164    
165                    BlogsEntryPermission.check(
166                            getPermissionChecker(), entry.getEntryId(), ActionKeys.VIEW);
167    
168                    return entry;
169            }
170    
171            @Override
172            public List<BlogsEntry> getGroupEntries(
173                            long groupId, Date displayDate, int status, int max)
174                    throws SystemException {
175    
176                    if (status == WorkflowConstants.STATUS_ANY) {
177                            return blogsEntryPersistence.filterFindByG_LtD(
178                                    groupId, displayDate, 0, max);
179                    }
180                    else {
181                            return blogsEntryPersistence.filterFindByG_LtD_S(
182                                    groupId, displayDate, status, 0, max);
183                    }
184            }
185    
186            @Override
187            public List<BlogsEntry> getGroupEntries(
188                            long groupId, Date displayDate, int status, int start, int end)
189                    throws SystemException {
190    
191                    if (status == WorkflowConstants.STATUS_ANY) {
192                            return blogsEntryPersistence.filterFindByG_LtD(
193                                    groupId, displayDate, start, end);
194                    }
195                    else {
196                            return blogsEntryPersistence.filterFindByG_LtD_S(
197                                    groupId, displayDate, status, start, end);
198                    }
199            }
200    
201            @Override
202            public List<BlogsEntry> getGroupEntries(long groupId, int status, int max)
203                    throws SystemException {
204    
205                    if (status == WorkflowConstants.STATUS_ANY) {
206                            return blogsEntryPersistence.filterFindByGroupId(groupId, 0, max);
207                    }
208                    else {
209                            return blogsEntryPersistence.filterFindByG_S(
210                                    groupId, status, 0, max);
211                    }
212            }
213    
214            @Override
215            public List<BlogsEntry> getGroupEntries(
216                            long groupId, int status, int start, int end)
217                    throws SystemException {
218    
219                    if (status == WorkflowConstants.STATUS_ANY) {
220                            return blogsEntryPersistence.filterFindByGroupId(
221                                    groupId, start, end);
222                    }
223                    else {
224                            return blogsEntryPersistence.filterFindByG_S(
225                                    groupId, status, start, end);
226                    }
227            }
228    
229            @Override
230            public int getGroupEntriesCount(long groupId, Date displayDate, int status)
231                    throws SystemException {
232    
233                    if (status == WorkflowConstants.STATUS_ANY) {
234                            return blogsEntryPersistence.filterCountByG_LtD(
235                                    groupId, displayDate);
236                    }
237                    else {
238                            return blogsEntryPersistence.filterCountByG_LtD_S(
239                                    groupId, displayDate, status);
240                    }
241            }
242    
243            @Override
244            public int getGroupEntriesCount(long groupId, int status)
245                    throws SystemException {
246    
247                    if (status == WorkflowConstants.STATUS_ANY) {
248                            return blogsEntryPersistence.filterCountByGroupId(groupId);
249                    }
250                    else {
251                            return blogsEntryPersistence.filterCountByG_S(groupId, status);
252                    }
253            }
254    
255            @Override
256            public String getGroupEntriesRSS(
257                            long groupId, Date displayDate, int status, int max, String type,
258                            double version, String displayStyle, String feedURL,
259                            String entryURL, ThemeDisplay themeDisplay)
260                    throws PortalException, SystemException {
261    
262                    Group group = groupPersistence.findByPrimaryKey(groupId);
263    
264                    String name = group.getDescriptiveName();
265                    List<BlogsEntry> blogsEntries = getGroupEntries(
266                            groupId, displayDate, status, max);
267    
268                    return exportToRSS(
269                            name, name, type, version, displayStyle, feedURL, entryURL,
270                            blogsEntries, themeDisplay);
271            }
272    
273            @Override
274            public List<BlogsEntry> getGroupsEntries(
275                            long companyId, long groupId, Date displayDate, int status, int max)
276                    throws PortalException, SystemException {
277    
278                    List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
279    
280                    int lastIntervalStart = 0;
281                    boolean listNotExhausted = true;
282    
283                    while ((entries.size() < max) && listNotExhausted) {
284                            List<BlogsEntry> entryList =
285                                    blogsEntryLocalService.getGroupsEntries(
286                                            companyId, groupId, displayDate, status, lastIntervalStart,
287                                            lastIntervalStart + max);
288    
289                            Iterator<BlogsEntry> itr = entryList.iterator();
290    
291                            lastIntervalStart += max;
292                            listNotExhausted = (entryList.size() == max);
293    
294                            while (itr.hasNext() && (entries.size() < max)) {
295                                    BlogsEntry entry = itr.next();
296    
297                                    if (BlogsEntryPermission.contains(
298                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
299    
300                                            entries.add(entry);
301                                    }
302                            }
303                    }
304    
305                    return entries;
306            }
307    
308            @Override
309            public List<BlogsEntry> getOrganizationEntries(
310                            long organizationId, Date displayDate, int status, int max)
311                    throws PortalException, SystemException {
312    
313                    List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
314    
315                    int lastIntervalStart = 0;
316                    boolean listNotExhausted = true;
317    
318                    while ((entries.size() < max) && listNotExhausted) {
319                            List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
320                                    organizationId, displayDate, status, lastIntervalStart,
321                                    lastIntervalStart + max, new EntryDisplayDateComparator());
322    
323                            Iterator<BlogsEntry> itr = entryList.iterator();
324    
325                            lastIntervalStart += max;
326                            listNotExhausted = (entryList.size() == max);
327    
328                            while (itr.hasNext() && (entries.size() < max)) {
329                                    BlogsEntry entry = itr.next();
330    
331                                    if (BlogsEntryPermission.contains(
332                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
333    
334                                            entries.add(entry);
335                                    }
336                            }
337                    }
338    
339                    return entries;
340            }
341    
342            @Override
343            public String getOrganizationEntriesRSS(
344                            long organizationId, Date displayDate, int status, int max,
345                            String type, double version, String displayStyle, String feedURL,
346                            String entryURL, ThemeDisplay themeDisplay)
347                    throws PortalException, SystemException {
348    
349                    Organization organization = organizationPersistence.findByPrimaryKey(
350                            organizationId);
351    
352                    String name = organization.getName();
353                    String description = name;
354                    List<BlogsEntry> blogsEntries = getOrganizationEntries(
355                            organizationId, displayDate, status, max);
356    
357                    return exportToRSS(
358                            name, description, type, version, displayStyle, feedURL, entryURL,
359                            blogsEntries, themeDisplay);
360            }
361    
362            @Override
363            public void subscribe(long groupId)
364                    throws PortalException, SystemException {
365    
366                    BlogsPermission.check(
367                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
368    
369                    blogsEntryLocalService.subscribe(getUserId(), groupId);
370            }
371    
372            @Override
373            public void unsubscribe(long groupId)
374                    throws PortalException, SystemException {
375    
376                    BlogsPermission.check(
377                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
378    
379                    blogsEntryLocalService.unsubscribe(getUserId(), groupId);
380            }
381    
382            @Override
383            public BlogsEntry updateEntry(
384                            long entryId, String title, String description, String content,
385                            int displayDateMonth, int displayDateDay, int displayDateYear,
386                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
387                            boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
388                            String smallImageURL, String smallImageFileName,
389                            InputStream smallImageInputStream, ServiceContext serviceContext)
390                    throws PortalException, SystemException {
391    
392                    BlogsEntryPermission.check(
393                            getPermissionChecker(), entryId, ActionKeys.UPDATE);
394    
395                    return blogsEntryLocalService.updateEntry(
396                            getUserId(), entryId, title, description, content, displayDateMonth,
397                            displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
398                            allowPingbacks, allowTrackbacks, trackbacks, smallImage,
399                            smallImageURL, smallImageFileName, smallImageInputStream,
400                            serviceContext);
401            }
402    
403            protected String exportToRSS(
404                            String name, String description, String type, double version,
405                            String displayStyle, String feedURL, String entryURL,
406                            List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay)
407                    throws SystemException {
408    
409                    SyndFeed syndFeed = new SyndFeedImpl();
410    
411                    syndFeed.setDescription(description);
412    
413                    List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
414    
415                    syndFeed.setEntries(syndEntries);
416    
417                    for (BlogsEntry entry : blogsEntries) {
418                            SyndEntry syndEntry = new SyndEntryImpl();
419    
420                            String author = PortalUtil.getUserName(entry);
421    
422                            syndEntry.setAuthor(author);
423    
424                            SyndContent syndContent = new SyndContentImpl();
425    
426                            syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
427    
428                            String value = null;
429    
430                            if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
431                                    String summary = entry.getDescription();
432    
433                                    if (Validator.isNull(summary)) {
434                                            summary = entry.getContent();
435                                    }
436    
437                                    value = StringUtil.shorten(
438                                            HtmlUtil.extractText(summary),
439                                            PropsValues.BLOGS_RSS_ABSTRACT_LENGTH, StringPool.BLANK);
440                            }
441                            else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
442                                    value = StringPool.BLANK;
443                            }
444                            else {
445                                    value = StringUtil.replace(
446                                            entry.getContent(),
447                                            new String[] {
448                                                    "href=\"/", "src=\"/"
449                                            },
450                                            new String[] {
451                                                    "href=\"" + themeDisplay.getURLPortal() + "/",
452                                                    "src=\"" + themeDisplay.getURLPortal() + "/"
453                                            });
454                            }
455    
456                            syndContent.setValue(value);
457    
458                            syndEntry.setDescription(syndContent);
459    
460                            StringBundler sb = new StringBundler(4);
461    
462                            if (entryURL.endsWith("/blogs/rss")) {
463                                    sb.append(entryURL.substring(0, entryURL.length() - 3));
464                                    sb.append(entry.getUrlTitle());
465                            }
466                            else {
467                                    sb.append(entryURL);
468    
469                                    if (!entryURL.endsWith(StringPool.QUESTION)) {
470                                            sb.append(StringPool.AMPERSAND);
471                                    }
472    
473                                    sb.append("entryId=");
474                                    sb.append(entry.getEntryId());
475                            }
476    
477                            String link = sb.toString();
478    
479                            syndEntry.setLink(link);
480    
481                            syndEntry.setPublishedDate(entry.getDisplayDate());
482                            syndEntry.setTitle(entry.getTitle());
483                            syndEntry.setUpdatedDate(entry.getModifiedDate());
484                            syndEntry.setUri(link);
485    
486                            syndEntries.add(syndEntry);
487                    }
488    
489                    syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
490    
491                    List<SyndLink> syndLinks = new ArrayList<SyndLink>();
492    
493                    syndFeed.setLinks(syndLinks);
494    
495                    SyndLink selfSyndLink = new SyndLinkImpl();
496    
497                    syndLinks.add(selfSyndLink);
498    
499                    selfSyndLink.setHref(feedURL);
500                    selfSyndLink.setRel("self");
501    
502                    if (feedURL.endsWith("/-/blogs/rss")) {
503                            SyndLink alternateSyndLink = new SyndLinkImpl();
504    
505                            syndLinks.add(alternateSyndLink);
506    
507                            alternateSyndLink.setHref(
508                                    feedURL.substring(0, feedURL.length() - 12));
509                            alternateSyndLink.setRel("alternate");
510                    }
511    
512                    syndFeed.setPublishedDate(new Date());
513                    syndFeed.setTitle(name);
514                    syndFeed.setUri(feedURL);
515    
516                    try {
517                            return RSSUtil.export(syndFeed);
518                    }
519                    catch (FeedException fe) {
520                            throw new SystemException(fe);
521                    }
522            }
523    
524    }