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 = 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> getOrganizationEntries(
210             long organizationId, int status, int max)
211         throws PortalException, SystemException {
212 
213         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
214 
215         Date displayDate = new Date();
216         int lastIntervalStart = 0;
217         boolean listNotExhausted = true;
218 
219         while ((entries.size() < max) && listNotExhausted) {
220             List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
221                 organizationId, displayDate, 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 String getOrganizationEntriesRSS(
244             long organizationId, int status, int max, String type,
245             double version, String displayStyle, String feedURL,
246             String entryURL, ThemeDisplay themeDisplay)
247         throws PortalException, SystemException {
248 
249         Organization organization = organizationPersistence.findByPrimaryKey(
250             organizationId);
251 
252         String name = organization.getName();
253         String description = name;
254         List<BlogsEntry> blogsEntries = getOrganizationEntries(
255             organizationId, status, max);
256 
257         return exportToRSS(
258             name, description, type, version, displayStyle, feedURL, entryURL,
259             blogsEntries, themeDisplay);
260     }
261 
262     public BlogsEntry updateEntry(
263             long entryId, String title, String content, int displayDateMonth,
264             int displayDateDay, int displayDateYear, int displayDateHour,
265             int displayDateMinute, boolean allowPingbacks,
266             boolean allowTrackbacks, String[] trackbacks,
267             ServiceContext serviceContext)
268         throws PortalException, SystemException {
269 
270         BlogsEntryPermission.check(
271             getPermissionChecker(), entryId, ActionKeys.UPDATE);
272 
273         return blogsEntryLocalService.updateEntry(
274             getUserId(), entryId, title, content, displayDateMonth,
275             displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
276             allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
277     }
278 
279     protected String exportToRSS(
280             String name, String description, String type, double version,
281             String displayStyle, String feedURL, String entryURL,
282             List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay)
283         throws SystemException {
284 
285         SyndFeed syndFeed = new SyndFeedImpl();
286 
287         syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
288         syndFeed.setTitle(name);
289         syndFeed.setLink(feedURL);
290         syndFeed.setDescription(description);
291 
292         List<SyndEntry> entries = new ArrayList<SyndEntry>();
293 
294         syndFeed.setEntries(entries);
295 
296         for (BlogsEntry entry : blogsEntries) {
297             String author = PortalUtil.getUserName(
298                 entry.getUserId(), entry.getUserName());
299 
300             StringBundler link = new StringBundler(4);
301 
302             if (entryURL.endsWith("/blogs/rss")) {
303                 link.append(entryURL.substring(0, entryURL.length() - 3));
304                 link.append(entry.getUrlTitle());
305             }
306             else {
307                 link.append(entryURL);
308 
309                 if (!entryURL.endsWith(StringPool.QUESTION)) {
310                     link.append(StringPool.AMPERSAND);
311                 }
312 
313                 link.append("entryId=");
314                 link.append(entry.getEntryId());
315             }
316 
317             String value = null;
318 
319             if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
320                 value = StringUtil.shorten(
321                     HtmlUtil.extractText(entry.getContent()),
322                     _RSS_ABSTRACT_LENGTH, StringPool.BLANK);
323             }
324             else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
325                 value = StringPool.BLANK;
326             }
327             else {
328                 value = StringUtil.replace(
329                     entry.getContent(),
330                     new String[] {
331                         "href=\"/",
332                         "src=\"/"
333                     },
334                     new String[] {
335                         "href=\"" + themeDisplay.getURLPortal() + "/",
336                         "src=\"" + themeDisplay.getURLPortal() + "/"
337                     }
338                 );
339             }
340 
341             SyndEntry syndEntry = new SyndEntryImpl();
342 
343             syndEntry.setAuthor(author);
344             syndEntry.setTitle(entry.getTitle());
345             syndEntry.setLink(link.toString());
346             syndEntry.setUri(syndEntry.getLink());
347             syndEntry.setPublishedDate(entry.getCreateDate());
348             syndEntry.setUpdatedDate(entry.getModifiedDate());
349 
350             SyndContent syndContent = new SyndContentImpl();
351 
352             syndContent.setType(RSSUtil.DEFAULT_ENTRY_TYPE);
353             syndContent.setValue(value);
354 
355             syndEntry.setDescription(syndContent);
356 
357             entries.add(syndEntry);
358         }
359 
360         try {
361             return RSSUtil.export(syndFeed);
362         }
363         catch (FeedException fe) {
364             throw new SystemException(fe);
365         }
366     }
367 
368     private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
369         PropsUtil.get(PropsKeys.BLOGS_RSS_ABSTRACT_LENGTH));
370 
371 }