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