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