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