001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.workflow.WorkflowConstants;
024    import com.liferay.portal.model.Company;
025    import com.liferay.portal.model.Group;
026    import com.liferay.portal.model.Organization;
027    import com.liferay.portal.security.permission.ActionKeys;
028    import com.liferay.portal.service.ServiceContext;
029    import com.liferay.portal.theme.ThemeDisplay;
030    import com.liferay.portal.util.PortalUtil;
031    import com.liferay.portal.util.PropsValues;
032    import com.liferay.portlet.blogs.model.BlogsEntry;
033    import com.liferay.portlet.blogs.service.base.BlogsEntryServiceBaseImpl;
034    import com.liferay.portlet.blogs.service.permission.BlogsEntryPermission;
035    import com.liferay.portlet.blogs.service.permission.BlogsPermission;
036    import com.liferay.portlet.blogs.util.comparator.EntryDisplayDateComparator;
037    import com.liferay.util.RSSUtil;
038    
039    import com.sun.syndication.feed.synd.SyndContent;
040    import com.sun.syndication.feed.synd.SyndContentImpl;
041    import com.sun.syndication.feed.synd.SyndEntry;
042    import com.sun.syndication.feed.synd.SyndEntryImpl;
043    import com.sun.syndication.feed.synd.SyndFeed;
044    import com.sun.syndication.feed.synd.SyndFeedImpl;
045    import com.sun.syndication.io.FeedException;
046    
047    import java.io.InputStream;
048    
049    import java.util.ArrayList;
050    import java.util.Date;
051    import java.util.Iterator;
052    import java.util.List;
053    
054    /**
055     * @author Brian Wing Shun Chan
056     */
057    public class BlogsEntryServiceImpl extends BlogsEntryServiceBaseImpl {
058    
059            public BlogsEntry addEntry(
060                            String title, String description, String content,
061                            int displayDateMonth, int displayDateDay, int displayDateYear,
062                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
063                            boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
064                            String smallImageURL, String smallImageFileName,
065                            InputStream smallImageInputStream, ServiceContext serviceContext)
066                    throws PortalException, SystemException {
067    
068                    BlogsPermission.check(
069                            getPermissionChecker(), serviceContext.getScopeGroupId(),
070                            ActionKeys.ADD_ENTRY);
071    
072                    return blogsEntryLocalService.addEntry(
073                            getUserId(), title, description, content, displayDateMonth,
074                            displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
075                            allowPingbacks, allowTrackbacks, trackbacks, smallImage,
076                            smallImageURL, smallImageFileName, smallImageInputStream,
077                            serviceContext);
078            }
079    
080            public void deleteEntry(long entryId)
081                    throws PortalException, SystemException {
082    
083                    BlogsEntryPermission.check(
084                            getPermissionChecker(), entryId, ActionKeys.DELETE);
085    
086                    blogsEntryLocalService.deleteEntry(entryId);
087            }
088    
089            public List<BlogsEntry> getCompanyEntries(
090                            long companyId, int status, int max)
091                    throws PortalException, SystemException {
092    
093                    List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
094    
095                    int lastIntervalStart = 0;
096                    boolean listNotExhausted = true;
097    
098                    while ((entries.size() < max) && listNotExhausted) {
099                            List<BlogsEntry> entryList =
100                                    blogsEntryLocalService.getCompanyEntries(
101                                            companyId, status, lastIntervalStart,
102                                            lastIntervalStart + max, new EntryDisplayDateComparator());
103    
104                            Iterator<BlogsEntry> itr = entryList.iterator();
105    
106                            lastIntervalStart += max;
107                            listNotExhausted = (entryList.size() == max);
108    
109                            while (itr.hasNext() && (entries.size() < max)) {
110                                    BlogsEntry entry = itr.next();
111    
112                                    if (BlogsEntryPermission.contains(
113                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
114    
115                                            entries.add(entry);
116                                    }
117                            }
118                    }
119    
120                    return entries;
121            }
122    
123            public String getCompanyEntriesRSS(
124                            long companyId, int status, int max, String type, double version,
125                            String displayStyle, String feedURL, String entryURL,
126                            ThemeDisplay themeDisplay)
127                    throws PortalException, SystemException {
128    
129                    Company company = companyPersistence.findByPrimaryKey(companyId);
130    
131                    String name = company.getName();
132                    String description = name;
133                    List<BlogsEntry> blogsEntries = getCompanyEntries(
134                            companyId, status, max);
135    
136                    return exportToRSS(
137                            name, description, type, version, displayStyle, feedURL, entryURL,
138                            blogsEntries, themeDisplay);
139            }
140    
141            public BlogsEntry getEntry(long entryId)
142                    throws PortalException, SystemException {
143    
144                    BlogsEntryPermission.check(
145                            getPermissionChecker(), entryId, ActionKeys.VIEW);
146    
147                    return blogsEntryLocalService.getEntry(entryId);
148            }
149    
150            public BlogsEntry getEntry(long groupId, String urlTitle)
151                    throws PortalException, SystemException {
152    
153                    BlogsEntry entry = blogsEntryLocalService.getEntry(groupId, urlTitle);
154    
155                    BlogsEntryPermission.check(
156                            getPermissionChecker(), entry.getEntryId(), ActionKeys.VIEW);
157    
158                    return entry;
159            }
160    
161            public List<BlogsEntry> getGroupEntries(long groupId, int status, int max)
162                    throws SystemException {
163    
164                    if (status == WorkflowConstants.STATUS_ANY) {
165                            return blogsEntryPersistence.filterFindByGroupId(groupId, 0, max);
166                    }
167                    else {
168                            return blogsEntryPersistence.filterFindByG_S(
169                                    groupId, status, 0, max);
170                    }
171            }
172    
173            public List<BlogsEntry> getGroupEntries(
174                            long groupId, int status, int start, int end)
175                    throws SystemException {
176    
177                    if (status == WorkflowConstants.STATUS_ANY) {
178                            return blogsEntryPersistence.filterFindByGroupId(
179                                    groupId, start, end);
180                    }
181                    else {
182                            return blogsEntryPersistence.filterFindByG_S(
183                                    groupId, status, start, end);
184                    }
185            }
186    
187            public int getGroupEntriesCount(long groupId, int status)
188                    throws SystemException {
189    
190                    if (status == WorkflowConstants.STATUS_ANY) {
191                            return blogsEntryPersistence.filterCountByGroupId(groupId);
192                    }
193                    else {
194                            return blogsEntryPersistence.filterCountByG_S(groupId, status);
195                    }
196            }
197    
198            public String getGroupEntriesRSS(
199                            long groupId, int status, int max, String type, double version,
200                            String displayStyle, String feedURL, String entryURL,
201                            ThemeDisplay themeDisplay)
202                    throws PortalException, SystemException {
203    
204                    Group group = groupPersistence.findByPrimaryKey(groupId);
205    
206                    String name = HtmlUtil.escape(group.getDescriptiveName());
207                    String description = name;
208                    List<BlogsEntry> blogsEntries = getGroupEntries(groupId, status, max);
209    
210                    return exportToRSS(
211                            name, description, type, version, displayStyle, feedURL, entryURL,
212                            blogsEntries, themeDisplay);
213            }
214    
215            public List<BlogsEntry> getGroupsEntries(
216                            long companyId, long groupId, int status, int max)
217                    throws PortalException, SystemException {
218    
219                    List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
220    
221                    int lastIntervalStart = 0;
222                    boolean listNotExhausted = true;
223    
224                    while ((entries.size() < max) && listNotExhausted) {
225                            List<BlogsEntry> entryList =
226                                    blogsEntryLocalService.getGroupsEntries(
227                                            companyId, groupId, status, lastIntervalStart,
228                                            lastIntervalStart + max);
229    
230                            Iterator<BlogsEntry> itr = entryList.iterator();
231    
232                            lastIntervalStart += max;
233                            listNotExhausted = (entryList.size() == max);
234    
235                            while (itr.hasNext() && (entries.size() < max)) {
236                                    BlogsEntry entry = itr.next();
237    
238                                    if (BlogsEntryPermission.contains(
239                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
240    
241                                            entries.add(entry);
242                                    }
243                            }
244                    }
245    
246                    return entries;
247            }
248    
249            public List<BlogsEntry> getOrganizationEntries(
250                            long organizationId, int status, int max)
251                    throws PortalException, SystemException {
252    
253                    List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
254    
255                    Date displayDate = new Date();
256                    int lastIntervalStart = 0;
257                    boolean listNotExhausted = true;
258    
259                    while ((entries.size() < max) && listNotExhausted) {
260                            List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
261                                    organizationId, displayDate, status, lastIntervalStart,
262                                    lastIntervalStart + max);
263    
264                            Iterator<BlogsEntry> itr = entryList.iterator();
265    
266                            lastIntervalStart += max;
267                            listNotExhausted = (entryList.size() == max);
268    
269                            while (itr.hasNext() && (entries.size() < max)) {
270                                    BlogsEntry entry = itr.next();
271    
272                                    if (BlogsEntryPermission.contains(
273                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
274    
275                                            entries.add(entry);
276                                    }
277                            }
278                    }
279    
280                    return entries;
281            }
282    
283            public String getOrganizationEntriesRSS(
284                            long organizationId, int status, int max, String type,
285                            double version, String displayStyle, String feedURL,
286                            String entryURL, ThemeDisplay themeDisplay)
287                    throws PortalException, SystemException {
288    
289                    Organization organization = organizationPersistence.findByPrimaryKey(
290                            organizationId);
291    
292                    String name = organization.getName();
293                    String description = name;
294                    List<BlogsEntry> blogsEntries = getOrganizationEntries(
295                            organizationId, status, max);
296    
297                    return exportToRSS(
298                            name, description, type, version, displayStyle, feedURL, entryURL,
299                            blogsEntries, themeDisplay);
300            }
301    
302            public void subscribe(long groupId)
303                    throws PortalException, SystemException {
304    
305                    BlogsPermission.check(
306                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
307    
308                    blogsEntryLocalService.subscribe(getUserId(), groupId);
309            }
310    
311            public void unsubscribe(long groupId)
312                    throws PortalException, SystemException {
313    
314                    BlogsPermission.check(
315                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
316    
317                    blogsEntryLocalService.unsubscribe(getUserId(), groupId);
318            }
319    
320            public BlogsEntry updateEntry(
321                            long entryId, String title, String description, String content,
322                            int displayDateMonth, int displayDateDay, int displayDateYear,
323                            int displayDateHour, int displayDateMinute, boolean allowPingbacks,
324                            boolean allowTrackbacks, String[] trackbacks, boolean smallImage,
325                            String smallImageURL, String smallImageFileName,
326                            InputStream smallImageInputStream, ServiceContext serviceContext)
327                    throws PortalException, SystemException {
328    
329                    BlogsEntryPermission.check(
330                            getPermissionChecker(), entryId, ActionKeys.UPDATE);
331    
332                    return blogsEntryLocalService.updateEntry(
333                            getUserId(), entryId, title, description, content, displayDateMonth,
334                            displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
335                            allowPingbacks, allowTrackbacks, trackbacks, smallImage,
336                            smallImageURL, smallImageFileName, smallImageInputStream,
337                            serviceContext);
338            }
339    
340            protected String exportToRSS(
341                            String name, String description, String type, double version,
342                            String displayStyle, String feedURL, String entryURL,
343                            List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay)
344                    throws SystemException {
345    
346                    SyndFeed syndFeed = new SyndFeedImpl();
347    
348                    syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
349                    syndFeed.setTitle(name);
350                    syndFeed.setLink(feedURL);
351                    syndFeed.setDescription(description);
352    
353                    List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
354    
355                    syndFeed.setEntries(syndEntries);
356    
357                    for (BlogsEntry entry : blogsEntries) {
358                            String author = HtmlUtil.escape(
359                                    PortalUtil.getUserName(entry.getUserId(), entry.getUserName()));
360    
361                            StringBundler link = new StringBundler(4);
362    
363                            if (entryURL.endsWith("/blogs/rss")) {
364                                    link.append(entryURL.substring(0, entryURL.length() - 3));
365                                    link.append(entry.getUrlTitle());
366                            }
367                            else {
368                                    link.append(entryURL);
369    
370                                    if (!entryURL.endsWith(StringPool.QUESTION)) {
371                                            link.append(StringPool.AMPERSAND);
372                                    }
373    
374                                    link.append("entryId=");
375                                    link.append(entry.getEntryId());
376                            }
377    
378                            String value = null;
379    
380                            if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
381                                    value = StringUtil.shorten(
382                                            HtmlUtil.extractText(entry.getContent()),
383                                            PropsValues.BLOGS_RSS_ABSTRACT_LENGTH, StringPool.BLANK);
384                            }
385                            else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
386                                    value = StringPool.BLANK;
387                            }
388                            else {
389                                    value = StringUtil.replace(
390                                            entry.getContent(),
391                                            new String[] {
392                                                    "href=\"/",
393                                                    "src=\"/"
394                                            },
395                                            new String[] {
396                                                    "href=\"" + themeDisplay.getURLPortal() + "/",
397                                                    "src=\"" + themeDisplay.getURLPortal() + "/"
398                                            }
399                                    );
400                            }
401    
402                            SyndEntry syndEntry = new SyndEntryImpl();
403    
404                            syndEntry.setAuthor(author);
405                            syndEntry.setTitle(entry.getTitle());
406                            syndEntry.setLink(link.toString());
407                            syndEntry.setUri(syndEntry.getLink());
408                            syndEntry.setPublishedDate(entry.getCreateDate());
409                            syndEntry.setUpdatedDate(entry.getModifiedDate());
410    
411                            SyndContent syndContent = new SyndContentImpl();
412    
413                            syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
414                            syndContent.setValue(value);
415    
416                            syndEntry.setDescription(syndContent);
417    
418                            syndEntries.add(syndEntry);
419                    }
420    
421                    try {
422                            return RSSUtil.export(syndFeed);
423                    }
424                    catch (FeedException fe) {
425                            throw new SystemException(fe);
426                    }
427            }
428    
429    }