1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.blogs.service.impl;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.HtmlUtil;
29  import com.liferay.portal.kernel.util.StringPool;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.model.Company;
32  import com.liferay.portal.model.Group;
33  import com.liferay.portal.model.Organization;
34  import com.liferay.portal.security.permission.ActionKeys;
35  import com.liferay.portal.service.ServiceContext;
36  import com.liferay.portal.theme.ThemeDisplay;
37  import com.liferay.portal.util.PortalUtil;
38  import com.liferay.portal.util.PropsKeys;
39  import com.liferay.portal.util.PropsUtil;
40  import com.liferay.portlet.blogs.model.BlogsEntry;
41  import com.liferay.portlet.blogs.service.base.BlogsEntryServiceBaseImpl;
42  import com.liferay.portlet.blogs.service.permission.BlogsEntryPermission;
43  import com.liferay.portlet.blogs.service.permission.BlogsPermission;
44  import com.liferay.portlet.blogs.util.comparator.EntryDisplayDateComparator;
45  import com.liferay.util.RSSUtil;
46  
47  import com.sun.syndication.feed.synd.SyndContent;
48  import com.sun.syndication.feed.synd.SyndContentImpl;
49  import com.sun.syndication.feed.synd.SyndEntry;
50  import com.sun.syndication.feed.synd.SyndEntryImpl;
51  import com.sun.syndication.feed.synd.SyndFeed;
52  import com.sun.syndication.feed.synd.SyndFeedImpl;
53  import com.sun.syndication.io.FeedException;
54  
55  import java.util.ArrayList;
56  import java.util.Date;
57  import java.util.Iterator;
58  import java.util.List;
59  
60  /**
61   * <a href="BlogsEntryServiceImpl.java.html"><b><i>View Source</i></b></a>
62   *
63   * @author Brian Wing Shun Chan
64   *
65   */
66  public class BlogsEntryServiceImpl extends BlogsEntryServiceBaseImpl {
67  
68      public BlogsEntry addEntry(
69              String title, String content, int displayDateMonth,
70              int displayDateDay, int displayDateYear, int displayDateHour,
71              int displayDateMinute, boolean draft, boolean allowTrackbacks,
72              String[] trackbacks, ServiceContext serviceContext)
73          throws PortalException, SystemException {
74  
75          BlogsPermission.check(
76              getPermissionChecker(), serviceContext.getScopeGroupId(),
77              ActionKeys.ADD_ENTRY);
78  
79          return blogsEntryLocalService.addEntry(
80              getUserId(), title, content, displayDateMonth, displayDateDay,
81              displayDateYear, displayDateHour, displayDateMinute, draft,
82              allowTrackbacks, trackbacks, serviceContext);
83      }
84  
85      public void deleteEntry(long entryId)
86          throws PortalException, SystemException {
87  
88          BlogsEntryPermission.check(
89              getPermissionChecker(), entryId, ActionKeys.DELETE);
90  
91          blogsEntryLocalService.deleteEntry(entryId);
92      }
93  
94      public List<BlogsEntry> getCompanyEntries(long companyId, int max)
95          throws PortalException, SystemException {
96  
97          List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
98  
99          int lastIntervalStart = 0;
100         boolean listNotExhausted = true;
101 
102         while ((entries.size() < max) && listNotExhausted) {
103             List<BlogsEntry> entryList =
104                 blogsEntryLocalService.getCompanyEntries(
105                     companyId, false, lastIntervalStart,
106                     lastIntervalStart + max, new EntryDisplayDateComparator());
107 
108             Iterator<BlogsEntry> itr = entryList.iterator();
109 
110             lastIntervalStart += max;
111             listNotExhausted = (entryList.size() == max);
112 
113             while (itr.hasNext() && (entries.size() < max)) {
114                 BlogsEntry entry = itr.next();
115 
116                 if (BlogsEntryPermission.contains(
117                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
118 
119                     entries.add(entry);
120                 }
121             }
122         }
123 
124         return entries;
125     }
126 
127     public String getCompanyEntriesRSS(
128             long companyId, int max, String type, double version,
129             String displayStyle, String feedURL, String entryURL,
130             ThemeDisplay themeDisplay)
131         throws PortalException, SystemException {
132 
133         Company company = companyPersistence.findByPrimaryKey(companyId);
134 
135         String name = company.getName();
136         String description = name;
137         List<BlogsEntry> blogsEntries = getCompanyEntries(companyId, max);
138 
139         return exportToRSS(
140             name, description, type, version, displayStyle, feedURL, entryURL,
141             blogsEntries, themeDisplay);
142     }
143 
144     public BlogsEntry getEntry(long entryId)
145         throws PortalException, SystemException {
146 
147         BlogsEntryPermission.check(
148             getPermissionChecker(), entryId, ActionKeys.VIEW);
149 
150         return blogsEntryLocalService.getEntry(entryId);
151     }
152 
153     public BlogsEntry getEntry(long groupId, String urlTitle)
154         throws PortalException, SystemException {
155 
156         BlogsEntry entry = blogsEntryLocalService.getEntry(groupId, urlTitle);
157 
158         BlogsEntryPermission.check(
159             getPermissionChecker(), entry.getEntryId(), ActionKeys.VIEW);
160 
161         return entry;
162     }
163 
164     public List<BlogsEntry> getGroupEntries(long groupId, int max)
165         throws PortalException, SystemException {
166 
167         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
168 
169         int lastIntervalStart = 0;
170         boolean listNotExhausted = true;
171 
172         while ((entries.size() < max) && listNotExhausted) {
173             List<BlogsEntry> entryList = blogsEntryLocalService.getGroupEntries(
174                 groupId, false, lastIntervalStart,
175                 lastIntervalStart + max);
176 
177             Iterator<BlogsEntry> itr = entryList.iterator();
178 
179             lastIntervalStart += max;
180             listNotExhausted = (entryList.size() == max);
181 
182             while (itr.hasNext() && (entries.size() < max)) {
183                 BlogsEntry entry = itr.next();
184 
185                 if (BlogsEntryPermission.contains(
186                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
187 
188                     entries.add(entry);
189                 }
190             }
191         }
192 
193         return entries;
194     }
195 
196     public String getGroupEntriesRSS(
197             long groupId, int max, String type, double version,
198             String displayStyle, String feedURL, String entryURL,
199             ThemeDisplay themeDisplay)
200         throws PortalException, SystemException {
201 
202         Group group = groupPersistence.findByPrimaryKey(groupId);
203 
204         String name = group.getDescriptiveName();
205         String description = name;
206         List<BlogsEntry> blogsEntries = getGroupEntries(groupId, max);
207 
208         return exportToRSS(
209             name, description, type, version, displayStyle, feedURL, entryURL,
210             blogsEntries, themeDisplay);
211     }
212 
213     public List<BlogsEntry> getOrganizationEntries(long organizationId, int max)
214         throws PortalException, SystemException {
215 
216         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
217 
218         Date displayDate = new Date();
219         boolean draft = false;
220         int lastIntervalStart = 0;
221         boolean listNotExhausted = true;
222 
223         while ((entries.size() < max) && listNotExhausted) {
224             List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
225                 organizationId, displayDate, draft, lastIntervalStart,
226                 lastIntervalStart + max);
227 
228             Iterator<BlogsEntry> itr = entryList.iterator();
229 
230             lastIntervalStart += max;
231             listNotExhausted = (entryList.size() == max);
232 
233             while (itr.hasNext() && (entries.size() < max)) {
234                 BlogsEntry entry = itr.next();
235 
236                 if (BlogsEntryPermission.contains(
237                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
238 
239                     entries.add(entry);
240                 }
241             }
242         }
243 
244         return entries;
245     }
246 
247     public String getOrganizationEntriesRSS(
248             long organizationId, int max, String type, double version,
249             String displayStyle, String feedURL, String entryURL,
250             ThemeDisplay themeDisplay)
251         throws PortalException, SystemException {
252 
253         Organization organization = organizationPersistence.findByPrimaryKey(
254             organizationId);
255 
256         String name = organization.getName();
257         String description = name;
258         List<BlogsEntry> blogsEntries = getOrganizationEntries(
259             organizationId, max);
260 
261         return exportToRSS(
262             name, description, type, version, displayStyle, feedURL, entryURL,
263             blogsEntries, themeDisplay);
264     }
265 
266     public BlogsEntry updateEntry(
267             long entryId, String title, String content, int displayDateMonth,
268             int displayDateDay, int displayDateYear, int displayDateHour,
269             int displayDateMinute, boolean draft, boolean allowTrackbacks,
270             String[] trackbacks, ServiceContext serviceContext)
271         throws PortalException, SystemException {
272 
273         BlogsEntryPermission.check(
274             getPermissionChecker(), entryId, ActionKeys.UPDATE);
275 
276         return blogsEntryLocalService.updateEntry(
277             getUserId(), entryId, title, content, displayDateMonth,
278             displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
279             draft, allowTrackbacks, trackbacks, serviceContext);
280     }
281 
282     protected String exportToRSS(
283             String name, String description, String type, double version,
284             String displayStyle, String feedURL, String entryURL,
285             List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay)
286         throws SystemException {
287 
288         SyndFeed syndFeed = new SyndFeedImpl();
289 
290         syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
291         syndFeed.setTitle(name);
292         syndFeed.setLink(feedURL);
293         syndFeed.setDescription(description);
294 
295         List<SyndEntry> entries = new ArrayList<SyndEntry>();
296 
297         syndFeed.setEntries(entries);
298 
299         for (BlogsEntry entry : blogsEntries) {
300             String author = PortalUtil.getUserName(
301                 entry.getUserId(), entry.getUserName());
302 
303             String link = entryURL;
304 
305             if (link.endsWith("/blogs/rss")) {
306                 link =
307                     link.substring(0, link.length() - 3) + entry.getUrlTitle();
308             }
309             else {
310                 if (!link.endsWith("?")) {
311                     link += "&";
312                 }
313 
314                 link += "entryId=" + 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);
346             syndEntry.setPublishedDate(entry.getCreateDate());
347 
348             SyndContent syndContent = new SyndContentImpl();
349 
350             syndContent.setType(RSSUtil.DEFAULT_ENTRY_TYPE);
351             syndContent.setValue(value);
352 
353             syndEntry.setDescription(syndContent);
354 
355             entries.add(syndEntry);
356         }
357 
358         try {
359             return RSSUtil.export(syndFeed);
360         }
361         catch (FeedException fe) {
362             throw new SystemException(fe);
363         }
364     }
365 
366     private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
367         PropsUtil.get(PropsKeys.BLOGS_RSS_ABSTRACT_LENGTH));
368 
369 }