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