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