1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.blogs.service.impl;
16  
17  import com.liferay.portal.kernel.exception.PortalException;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.util.GetterUtil;
20  import com.liferay.portal.kernel.util.HtmlUtil;
21  import com.liferay.portal.kernel.util.PropsKeys;
22  import com.liferay.portal.kernel.util.StringBundler;
23  import com.liferay.portal.kernel.util.StringPool;
24  import com.liferay.portal.kernel.util.StringUtil;
25  import com.liferay.portal.model.Company;
26  import com.liferay.portal.model.Group;
27  import com.liferay.portal.model.Organization;
28  import com.liferay.portal.security.permission.ActionKeys;
29  import com.liferay.portal.service.ServiceContext;
30  import com.liferay.portal.theme.ThemeDisplay;
31  import com.liferay.portal.util.PortalUtil;
32  import com.liferay.portal.util.PropsUtil;
33  import com.liferay.portlet.blogs.model.BlogsEntry;
34  import com.liferay.portlet.blogs.service.base.BlogsEntryServiceBaseImpl;
35  import com.liferay.portlet.blogs.service.permission.BlogsEntryPermission;
36  import com.liferay.portlet.blogs.service.permission.BlogsPermission;
37  import com.liferay.portlet.blogs.util.comparator.EntryDisplayDateComparator;
38  import com.liferay.util.RSSUtil;
39  
40  import com.sun.syndication.feed.synd.SyndContent;
41  import com.sun.syndication.feed.synd.SyndContentImpl;
42  import com.sun.syndication.feed.synd.SyndEntry;
43  import com.sun.syndication.feed.synd.SyndEntryImpl;
44  import com.sun.syndication.feed.synd.SyndFeed;
45  import com.sun.syndication.feed.synd.SyndFeedImpl;
46  import com.sun.syndication.io.FeedException;
47  
48  import java.util.ArrayList;
49  import java.util.Date;
50  import java.util.Iterator;
51  import java.util.List;
52  
53  /**
54   * <a href="BlogsEntryServiceImpl.java.html"><b><i>View Source</i></b></a>
55   *
56   * @author Brian Wing Shun Chan
57   */
58  public class BlogsEntryServiceImpl extends BlogsEntryServiceBaseImpl {
59  
60      public BlogsEntry addEntry(
61              String title, String content, int displayDateMonth,
62              int displayDateDay, int displayDateYear, int displayDateHour,
63              int displayDateMinute, boolean allowPingbacks,
64              boolean allowTrackbacks, String[] trackbacks,
65              ServiceContext serviceContext)
66          throws PortalException, SystemException {
67  
68          BlogsPermission.check(
69              getPermissionChecker(), serviceContext.getScopeGroupId(),
70              ActionKeys.ADD_ENTRY);
71  
72          return blogsEntryLocalService.addEntry(
73              null, getUserId(), title, content, displayDateMonth, displayDateDay,
74              displayDateYear, displayDateHour, displayDateMinute,
75              allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
76      }
77  
78      public void deleteEntry(long entryId)
79          throws PortalException, SystemException {
80  
81          BlogsEntryPermission.check(
82              getPermissionChecker(), entryId, ActionKeys.DELETE);
83  
84          blogsEntryLocalService.deleteEntry(entryId);
85      }
86  
87      public List<BlogsEntry> getCompanyEntries(
88              long companyId, int status, int max)
89          throws PortalException, SystemException {
90  
91          List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
92  
93          int lastIntervalStart = 0;
94          boolean listNotExhausted = true;
95  
96          while ((entries.size() < max) && listNotExhausted) {
97              List<BlogsEntry> entryList =
98                  blogsEntryLocalService.getCompanyEntries(
99                      companyId, status, lastIntervalStart,
100                     lastIntervalStart + max, new EntryDisplayDateComparator());
101 
102             Iterator<BlogsEntry> itr = entryList.iterator();
103 
104             lastIntervalStart += max;
105             listNotExhausted = (entryList.size() == max);
106 
107             while (itr.hasNext() && (entries.size() < max)) {
108                 BlogsEntry entry = itr.next();
109 
110                 if (BlogsEntryPermission.contains(
111                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
112 
113                     entries.add(entry);
114                 }
115             }
116         }
117 
118         return entries;
119     }
120 
121     public String getCompanyEntriesRSS(
122             long companyId, int status, int max, String type, double version,
123             String displayStyle, String feedURL, String entryURL,
124             ThemeDisplay themeDisplay)
125         throws PortalException, SystemException {
126 
127         Company company = companyPersistence.findByPrimaryKey(companyId);
128 
129         String name = company.getName();
130         String description = name;
131         List<BlogsEntry> blogsEntries = getCompanyEntries(
132             companyId, status, max);
133 
134         return exportToRSS(
135             name, description, type, version, displayStyle, feedURL, entryURL,
136             blogsEntries, themeDisplay);
137     }
138 
139     public BlogsEntry getEntry(long entryId)
140         throws PortalException, SystemException {
141 
142         BlogsEntryPermission.check(
143             getPermissionChecker(), entryId, ActionKeys.VIEW);
144 
145         return blogsEntryLocalService.getEntry(entryId);
146     }
147 
148     public BlogsEntry getEntry(long groupId, String urlTitle)
149         throws PortalException, SystemException {
150 
151         BlogsEntry entry = blogsEntryLocalService.getEntry(groupId, urlTitle);
152 
153         BlogsEntryPermission.check(
154             getPermissionChecker(), entry.getEntryId(), ActionKeys.VIEW);
155 
156         return entry;
157     }
158 
159     public List<BlogsEntry> getGroupEntries(long groupId, int status, int max)
160         throws PortalException, SystemException {
161 
162         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
163 
164         int lastIntervalStart = 0;
165         boolean listNotExhausted = true;
166 
167         while ((entries.size() < max) && listNotExhausted) {
168             List<BlogsEntry> entryList =
169                 blogsEntryLocalService.getGroupEntries(
170                     groupId, status, lastIntervalStart,
171                     lastIntervalStart + max);
172 
173             Iterator<BlogsEntry> itr = entryList.iterator();
174 
175             lastIntervalStart += max;
176             listNotExhausted = (entryList.size() == max);
177 
178             while (itr.hasNext() && (entries.size() < max)) {
179                 BlogsEntry entry = itr.next();
180 
181                 if (BlogsEntryPermission.contains(
182                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
183 
184                     entries.add(entry);
185                 }
186             }
187         }
188 
189         return entries;
190     }
191 
192     public String getGroupEntriesRSS(
193             long groupId, int status, int max, String type, double version,
194             String displayStyle, String feedURL, String entryURL,
195             ThemeDisplay themeDisplay)
196         throws PortalException, SystemException {
197 
198         Group group = groupPersistence.findByPrimaryKey(groupId);
199 
200         String name = HtmlUtil.escape(group.getDescriptiveName());
201         String description = name;
202         List<BlogsEntry> blogsEntries = getGroupEntries(groupId, status, max);
203 
204         return exportToRSS(
205             name, description, type, version, displayStyle, feedURL, entryURL,
206             blogsEntries, themeDisplay);
207     }
208 
209     public List<BlogsEntry> getGroupsEntries(
210             long companyId, long groupId, int status, int max)
211         throws PortalException, SystemException {
212 
213         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
214 
215         int lastIntervalStart = 0;
216         boolean listNotExhausted = true;
217 
218         while ((entries.size() < max) && listNotExhausted) {
219             List<BlogsEntry> entryList =
220                 blogsEntryLocalService.getGroupsEntries(
221                     companyId, groupId, status, lastIntervalStart,
222                     lastIntervalStart + max);
223 
224             Iterator<BlogsEntry> itr = entryList.iterator();
225 
226             lastIntervalStart += max;
227             listNotExhausted = (entryList.size() == max);
228 
229             while (itr.hasNext() && (entries.size() < max)) {
230                 BlogsEntry entry = itr.next();
231 
232                 if (BlogsEntryPermission.contains(
233                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
234 
235                     entries.add(entry);
236                 }
237             }
238         }
239 
240         return entries;
241     }
242 
243     public List<BlogsEntry> getOrganizationEntries(
244             long organizationId, int status, int max)
245         throws PortalException, SystemException {
246 
247         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
248 
249         Date displayDate = new Date();
250         int lastIntervalStart = 0;
251         boolean listNotExhausted = true;
252 
253         while ((entries.size() < max) && listNotExhausted) {
254             List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
255                 organizationId, displayDate, status, lastIntervalStart,
256                 lastIntervalStart + max);
257 
258             Iterator<BlogsEntry> itr = entryList.iterator();
259 
260             lastIntervalStart += max;
261             listNotExhausted = (entryList.size() == max);
262 
263             while (itr.hasNext() && (entries.size() < max)) {
264                 BlogsEntry entry = itr.next();
265 
266                 if (BlogsEntryPermission.contains(
267                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
268 
269                     entries.add(entry);
270                 }
271             }
272         }
273 
274         return entries;
275     }
276 
277     public String getOrganizationEntriesRSS(
278             long organizationId, int status, int max, String type,
279             double version, String displayStyle, String feedURL,
280             String entryURL, ThemeDisplay themeDisplay)
281         throws PortalException, SystemException {
282 
283         Organization organization = organizationPersistence.findByPrimaryKey(
284             organizationId);
285 
286         String name = organization.getName();
287         String description = name;
288         List<BlogsEntry> blogsEntries = getOrganizationEntries(
289             organizationId, status, max);
290 
291         return exportToRSS(
292             name, description, type, version, displayStyle, feedURL, entryURL,
293             blogsEntries, themeDisplay);
294     }
295 
296     public BlogsEntry updateEntry(
297             long entryId, String title, String content, int displayDateMonth,
298             int displayDateDay, int displayDateYear, int displayDateHour,
299             int displayDateMinute, boolean allowPingbacks,
300             boolean allowTrackbacks, String[] trackbacks,
301             ServiceContext serviceContext)
302         throws PortalException, SystemException {
303 
304         BlogsEntryPermission.check(
305             getPermissionChecker(), entryId, ActionKeys.UPDATE);
306 
307         return blogsEntryLocalService.updateEntry(
308             getUserId(), entryId, title, content, displayDateMonth,
309             displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
310             allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
311     }
312 
313     protected String exportToRSS(
314             String name, String description, String type, double version,
315             String displayStyle, String feedURL, String entryURL,
316             List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay)
317         throws SystemException {
318 
319         SyndFeed syndFeed = new SyndFeedImpl();
320 
321         syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
322         syndFeed.setTitle(name);
323         syndFeed.setLink(feedURL);
324         syndFeed.setDescription(description);
325 
326         List<SyndEntry> entries = new ArrayList<SyndEntry>();
327 
328         syndFeed.setEntries(entries);
329 
330         for (BlogsEntry entry : blogsEntries) {
331             String author = HtmlUtil.escape(
332                 PortalUtil.getUserName(entry.getUserId(), entry.getUserName()));
333 
334             StringBundler link = new StringBundler(4);
335 
336             if (entryURL.endsWith("/blogs/rss")) {
337                 link.append(entryURL.substring(0, entryURL.length() - 3));
338                 link.append(entry.getUrlTitle());
339             }
340             else {
341                 link.append(entryURL);
342 
343                 if (!entryURL.endsWith(StringPool.QUESTION)) {
344                     link.append(StringPool.AMPERSAND);
345                 }
346 
347                 link.append("entryId=");
348                 link.append(entry.getEntryId());
349             }
350 
351             String value = null;
352 
353             if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
354                 value = StringUtil.shorten(
355                     HtmlUtil.extractText(entry.getContent()),
356                     _RSS_ABSTRACT_LENGTH, StringPool.BLANK);
357             }
358             else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
359                 value = StringPool.BLANK;
360             }
361             else {
362                 value = StringUtil.replace(
363                     entry.getContent(),
364                     new String[] {
365                         "href=\"/",
366                         "src=\"/"
367                     },
368                     new String[] {
369                         "href=\"" + themeDisplay.getURLPortal() + "/",
370                         "src=\"" + themeDisplay.getURLPortal() + "/"
371                     }
372                 );
373             }
374 
375             SyndEntry syndEntry = new SyndEntryImpl();
376 
377             syndEntry.setAuthor(author);
378             syndEntry.setTitle(entry.getTitle());
379             syndEntry.setLink(link.toString());
380             syndEntry.setUri(syndEntry.getLink());
381             syndEntry.setPublishedDate(entry.getCreateDate());
382             syndEntry.setUpdatedDate(entry.getModifiedDate());
383 
384             SyndContent syndContent = new SyndContentImpl();
385 
386             syndContent.setType(RSSUtil.DEFAULT_ENTRY_TYPE);
387             syndContent.setValue(value);
388 
389             syndEntry.setDescription(syndContent);
390 
391             entries.add(syndEntry);
392         }
393 
394         try {
395             return RSSUtil.export(syndFeed);
396         }
397         catch (FeedException fe) {
398             throw new SystemException(fe);
399         }
400     }
401 
402     private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
403         PropsUtil.get(PropsKeys.BLOGS_RSS_ABSTRACT_LENGTH));
404 
405 }