1   /**
2    * Copyright (c) 2000-2008 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.permission.PortletPermissionUtil;
36  import com.liferay.portal.theme.ThemeDisplay;
37  import com.liferay.portal.util.PortalUtil;
38  import com.liferay.portal.util.PortletKeys;
39  import com.liferay.portal.util.PropsKeys;
40  import com.liferay.portal.util.PropsUtil;
41  import com.liferay.portlet.blogs.model.BlogsEntry;
42  import com.liferay.portlet.blogs.service.base.BlogsEntryServiceBaseImpl;
43  import com.liferay.portlet.blogs.service.permission.BlogsEntryPermission;
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.io.IOException;
56  
57  import java.util.ArrayList;
58  import java.util.Iterator;
59  import java.util.List;
60  
61  /**
62   * <a href="BlogsEntryServiceImpl.java.html"><b><i>View Source</i></b></a>
63   *
64   * @author Brian Wing Shun Chan
65   *
66   */
67  public class BlogsEntryServiceImpl extends BlogsEntryServiceBaseImpl {
68  
69      public BlogsEntry addEntry(
70              long plid, String title, String content, int displayDateMonth,
71              int displayDateDay, int displayDateYear, int displayDateHour,
72              int displayDateMinute, boolean draft, boolean allowTrackbacks,
73              String[] trackbacks, String[] tagsEntries,
74              boolean addCommunityPermissions, boolean addGuestPermissions,
75              ThemeDisplay themeDisplay)
76          throws PortalException, SystemException {
77  
78          PortletPermissionUtil.check(
79              getPermissionChecker(), plid, PortletKeys.BLOGS,
80              ActionKeys.ADD_ENTRY);
81  
82          return blogsEntryLocalService.addEntry(
83              getUserId(), plid, title, content, displayDateMonth, displayDateDay,
84              displayDateYear, displayDateHour, displayDateMinute, draft,
85              allowTrackbacks, trackbacks, tagsEntries, addCommunityPermissions,
86              addGuestPermissions, themeDisplay);
87      }
88  
89      public BlogsEntry addEntry(
90              long plid, String title, String content, int displayDateMonth,
91              int displayDateDay, int displayDateYear, int displayDateHour,
92              int displayDateMinute, boolean draft, boolean allowTrackbacks,
93              String[] trackbacks, String[] tagsEntries,
94              String[] communityPermissions, String[] guestPermissions,
95              ThemeDisplay themeDisplay)
96          throws PortalException, SystemException {
97  
98          PortletPermissionUtil.check(
99              getPermissionChecker(), plid, PortletKeys.BLOGS,
100             ActionKeys.ADD_ENTRY);
101 
102         return blogsEntryLocalService.addEntry(
103             getUserId(), plid, title, content, displayDateMonth, displayDateDay,
104             displayDateYear, displayDateHour, displayDateMinute, draft,
105             allowTrackbacks, trackbacks, tagsEntries, communityPermissions,
106             guestPermissions, themeDisplay);
107     }
108 
109     public void deleteEntry(long entryId)
110         throws PortalException, SystemException {
111 
112         BlogsEntryPermission.check(
113             getPermissionChecker(), entryId, ActionKeys.DELETE);
114 
115         blogsEntryLocalService.deleteEntry(entryId);
116     }
117 
118     public List<BlogsEntry> getCompanyEntries(long companyId, int max)
119         throws PortalException, SystemException {
120 
121         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
122 
123         int lastIntervalStart = 0;
124         boolean listNotExhausted = true;
125 
126         while ((entries.size() < max) && listNotExhausted) {
127             List<BlogsEntry> entryList =
128                 blogsEntryLocalService.getCompanyEntries(
129                     companyId, false, lastIntervalStart,
130                     lastIntervalStart + max, new EntryDisplayDateComparator());
131 
132             Iterator<BlogsEntry> itr = entryList.iterator();
133 
134             lastIntervalStart += max;
135             listNotExhausted = (entryList.size() == max);
136 
137             while (itr.hasNext() && (entries.size() < max)) {
138                 BlogsEntry entry = itr.next();
139 
140                 if (BlogsEntryPermission.contains(
141                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
142 
143                     entries.add(entry);
144                 }
145             }
146         }
147 
148         return entries;
149     }
150 
151     public String getCompanyEntriesRSS(
152             long companyId, int max, String type, double version,
153             String displayStyle, String feedURL, String entryURL,
154             ThemeDisplay themeDisplay)
155         throws PortalException, SystemException {
156 
157         Company company = companyPersistence.findByPrimaryKey(companyId);
158 
159         String name = company.getName();
160         String description = name;
161         List<BlogsEntry> blogsEntries = getCompanyEntries(companyId, max);
162 
163         return exportToRSS(
164             name, description, type, version, displayStyle, feedURL, entryURL,
165             blogsEntries, themeDisplay);
166     }
167 
168     public BlogsEntry getEntry(long entryId)
169         throws PortalException, SystemException {
170 
171         BlogsEntryPermission.check(
172             getPermissionChecker(), entryId, ActionKeys.VIEW);
173 
174         return blogsEntryLocalService.getEntry(entryId);
175     }
176 
177     public BlogsEntry getEntry(long groupId, String urlTitle)
178         throws PortalException, SystemException {
179 
180         BlogsEntry entry = blogsEntryLocalService.getEntry(groupId, urlTitle);
181 
182         BlogsEntryPermission.check(
183             getPermissionChecker(), entry.getEntryId(), ActionKeys.VIEW);
184 
185         return entry;
186     }
187 
188     public List<BlogsEntry> getGroupEntries(long groupId, int max)
189         throws PortalException, SystemException {
190 
191         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
192 
193         int lastIntervalStart = 0;
194         boolean listNotExhausted = true;
195 
196         while ((entries.size() < max) && listNotExhausted) {
197             List<BlogsEntry> entryList = blogsEntryLocalService.getGroupEntries(
198                 groupId, false, lastIntervalStart,
199                 lastIntervalStart + max);
200 
201             Iterator<BlogsEntry> itr = entryList.iterator();
202 
203             lastIntervalStart += max;
204             listNotExhausted = (entryList.size() == max);
205 
206             while (itr.hasNext() && (entries.size() < max)) {
207                 BlogsEntry entry = itr.next();
208 
209                 if (BlogsEntryPermission.contains(
210                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
211 
212                     entries.add(entry);
213                 }
214             }
215         }
216 
217         return entries;
218     }
219 
220     public String getGroupEntriesRSS(
221             long groupId, int max, String type, double version,
222             String displayStyle, String feedURL, String entryURL,
223             ThemeDisplay themeDisplay)
224         throws PortalException, SystemException {
225 
226         Group group = groupPersistence.findByPrimaryKey(groupId);
227 
228         String name = group.getDescriptiveName();
229         String description = name;
230         List<BlogsEntry> blogsEntries = getGroupEntries(groupId, max);
231 
232         return exportToRSS(
233             name, description, type, version, displayStyle, feedURL, entryURL,
234             blogsEntries, themeDisplay);
235     }
236 
237     public List<BlogsEntry> getOrganizationEntries(long organizationId, int max)
238         throws PortalException, SystemException {
239 
240         List<BlogsEntry> entries = new ArrayList<BlogsEntry>();
241 
242         int lastIntervalStart = 0;
243         boolean listNotExhausted = true;
244 
245         while ((entries.size() < max) && listNotExhausted) {
246             List<BlogsEntry> entryList = blogsEntryFinder.findByOrganizationId(
247                 organizationId, false, lastIntervalStart,
248                 lastIntervalStart + max);
249 
250             Iterator<BlogsEntry> itr = entryList.iterator();
251 
252             lastIntervalStart += max;
253             listNotExhausted = (entryList.size() == max);
254 
255             while (itr.hasNext() && (entries.size() < max)) {
256                 BlogsEntry entry = itr.next();
257 
258                 if (BlogsEntryPermission.contains(
259                         getPermissionChecker(), entry, ActionKeys.VIEW)) {
260 
261                     entries.add(entry);
262                 }
263             }
264         }
265 
266         return entries;
267     }
268 
269     public String getOrganizationEntriesRSS(
270             long organizationId, int max, String type, double version,
271             String displayStyle, String feedURL, String entryURL,
272             ThemeDisplay themeDisplay)
273         throws PortalException, SystemException {
274 
275         Organization organization = organizationPersistence.findByPrimaryKey(
276             organizationId);
277 
278         String name = organization.getName();
279         String description = name;
280         List<BlogsEntry> blogsEntries = getOrganizationEntries(
281             organizationId, max);
282 
283         return exportToRSS(
284             name, description, type, version, displayStyle, feedURL, entryURL,
285             blogsEntries, themeDisplay);
286     }
287 
288     public BlogsEntry updateEntry(
289             long entryId, String title, String content, int displayDateMonth,
290             int displayDateDay, int displayDateYear, int displayDateHour,
291             int displayDateMinute, boolean draft, boolean allowTrackbacks,
292             String[] trackbacks, String[] tagsEntries,
293             ThemeDisplay themeDisplay)
294         throws PortalException, SystemException {
295 
296         BlogsEntryPermission.check(
297             getPermissionChecker(), entryId, ActionKeys.UPDATE);
298 
299         return blogsEntryLocalService.updateEntry(
300             getUserId(), entryId, title, content, displayDateMonth,
301             displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
302             draft, allowTrackbacks, trackbacks, tagsEntries, themeDisplay);
303     }
304 
305     protected String exportToRSS(
306             String name, String description, String type, double version,
307             String displayStyle, String feedURL, String entryURL,
308             List<BlogsEntry> blogsEntries, ThemeDisplay themeDisplay)
309         throws SystemException {
310 
311         SyndFeed syndFeed = new SyndFeedImpl();
312 
313         syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
314         syndFeed.setTitle(name);
315         syndFeed.setLink(feedURL);
316         syndFeed.setDescription(description);
317 
318         List<SyndEntry> entries = new ArrayList<SyndEntry>();
319 
320         syndFeed.setEntries(entries);
321 
322         for (BlogsEntry entry : blogsEntries) {
323             String author = PortalUtil.getUserName(
324                 entry.getUserId(), entry.getUserName());
325 
326             String link = entryURL;
327 
328             if (link.endsWith("/blogs/rss")) {
329                 link =
330                     link.substring(0, link.length() - 3) + entry.getUrlTitle();
331             }
332             else {
333                 if (!link.endsWith("?")) {
334                     link += "&";
335                 }
336 
337                 link += "entryId=" + entry.getEntryId();
338             }
339 
340             String value = null;
341 
342             if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
343                 value = StringUtil.shorten(
344                     HtmlUtil.extractText(entry.getContent()),
345                     _RSS_ABSTRACT_LENGTH, StringPool.BLANK);
346             }
347             else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
348                 value = StringPool.BLANK;
349             }
350             else {
351                 value = StringUtil.replace(
352                     entry.getContent(),
353                     new String[] {
354                         "href=\"/",
355                         "src=\"/"
356                     },
357                     new String[] {
358                         "href=\"" + themeDisplay.getURLPortal() + "/",
359                         "src=\"" + themeDisplay.getURLPortal() + "/"
360                     }
361                 );
362             }
363 
364             SyndEntry syndEntry = new SyndEntryImpl();
365 
366             syndEntry.setAuthor(author);
367             syndEntry.setTitle(entry.getTitle());
368             syndEntry.setLink(link);
369             syndEntry.setPublishedDate(entry.getCreateDate());
370 
371             SyndContent syndContent = new SyndContentImpl();
372 
373             syndContent.setType(RSSUtil.DEFAULT_ENTRY_TYPE);
374             syndContent.setValue(value);
375 
376             syndEntry.setDescription(syndContent);
377 
378             entries.add(syndEntry);
379         }
380 
381         try {
382             return RSSUtil.export(syndFeed);
383         }
384         catch (FeedException fe) {
385             throw new SystemException(fe);
386         }
387         catch (IOException ioe) {
388             throw new SystemException(ioe);
389         }
390     }
391 
392     private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
393         PropsUtil.get(PropsKeys.BLOGS_RSS_ABSTRACT_LENGTH));
394 
395 }