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