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