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.messageboards.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.ObjectValuePair;
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.security.auth.PrincipalException;
34  import com.liferay.portal.security.permission.ActionKeys;
35  import com.liferay.portal.theme.ThemeDisplay;
36  import com.liferay.portal.util.PortalUtil;
37  import com.liferay.portal.util.PropsUtil;
38  import com.liferay.portlet.messageboards.model.MBCategory;
39  import com.liferay.portlet.messageboards.model.MBMessage;
40  import com.liferay.portlet.messageboards.model.MBMessageDisplay;
41  import com.liferay.portlet.messageboards.model.MBThread;
42  import com.liferay.portlet.messageboards.model.impl.MBThreadImpl;
43  import com.liferay.portlet.messageboards.service.base.MBMessageServiceBaseImpl;
44  import com.liferay.portlet.messageboards.service.permission.MBCategoryPermission;
45  import com.liferay.portlet.messageboards.service.permission.MBDiscussionPermission;
46  import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
47  import com.liferay.portlet.messageboards.util.comparator.MessageCreateDateComparator;
48  import com.liferay.util.RSSUtil;
49  
50  import com.sun.syndication.feed.synd.SyndContent;
51  import com.sun.syndication.feed.synd.SyndContentImpl;
52  import com.sun.syndication.feed.synd.SyndEntry;
53  import com.sun.syndication.feed.synd.SyndEntryImpl;
54  import com.sun.syndication.feed.synd.SyndFeed;
55  import com.sun.syndication.feed.synd.SyndFeedImpl;
56  import com.sun.syndication.io.FeedException;
57  
58  import java.io.IOException;
59  
60  import java.util.ArrayList;
61  import java.util.Iterator;
62  import java.util.List;
63  
64  import javax.portlet.PortletPreferences;
65  
66  /**
67   * <a href="MBMessageServiceImpl.java.html"><b><i>View Source</i></b></a>
68   *
69   * @author Brian Wing Shun Chan
70   *
71   */
72  public class MBMessageServiceImpl extends MBMessageServiceBaseImpl {
73  
74      public MBMessage addDiscussionMessage(
75              long groupId, String className, long classPK, long threadId,
76              long parentMessageId, String subject, String body,
77              ThemeDisplay themeDisplay)
78          throws PortalException, SystemException {
79  
80          MBDiscussionPermission.check(
81              getPermissionChecker(), groupId, className, classPK,
82              ActionKeys.ADD_DISCUSSION);
83  
84          return mbMessageLocalService.addDiscussionMessage(
85              getUserId(), groupId, className, classPK, threadId, parentMessageId,
86              subject, body, themeDisplay);
87      }
88  
89      public MBMessage addMessage(
90              long categoryId, String subject, String body,
91              List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
92              double priority, String[] tagsEntries,
93              boolean addCommunityPermissions, boolean addGuestPermissions)
94          throws PortalException, SystemException {
95  
96          MBCategoryPermission.check(
97              getPermissionChecker(), categoryId, ActionKeys.ADD_MESSAGE);
98  
99          if (!MBCategoryPermission.contains(
100                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
101 
102             files.clear();
103         }
104 
105         if (!MBCategoryPermission.contains(
106                 getPermissionChecker(), categoryId,
107                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
108 
109             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
110         }
111 
112         return mbMessageLocalService.addMessage(
113             getGuestOrUserId(), categoryId, subject, body, files, anonymous,
114             priority, tagsEntries, null, addCommunityPermissions,
115             addGuestPermissions, null);
116     }
117 
118     public MBMessage addMessage(
119             long categoryId, String subject, String body,
120             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
121             double priority, String[] tagsEntries,
122             String[] communityPermissions, String[] guestPermissions)
123         throws PortalException, SystemException {
124 
125         MBCategoryPermission.check(
126             getPermissionChecker(), categoryId, ActionKeys.ADD_MESSAGE);
127 
128         if (!MBCategoryPermission.contains(
129                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
130 
131             files.clear();
132         }
133 
134         if (!MBCategoryPermission.contains(
135                 getPermissionChecker(), categoryId,
136                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
137 
138             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
139         }
140 
141         return mbMessageLocalService.addMessage(
142             getGuestOrUserId(), categoryId, subject, body, files, anonymous,
143             priority, tagsEntries, null, communityPermissions, guestPermissions,
144             null);
145     }
146 
147     public MBMessage addMessage(
148             long categoryId, String subject, String body,
149             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
150             double priority, String[] tagsEntries, PortletPreferences prefs,
151             boolean addCommunityPermissions, boolean addGuestPermissions,
152             ThemeDisplay themeDisplay)
153         throws PortalException, SystemException {
154 
155         MBCategoryPermission.check(
156             getPermissionChecker(), categoryId, ActionKeys.ADD_MESSAGE);
157 
158         if (!MBCategoryPermission.contains(
159                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
160 
161             files.clear();
162         }
163 
164         if (!MBCategoryPermission.contains(
165                 getPermissionChecker(), categoryId,
166                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
167 
168             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
169         }
170 
171         return mbMessageLocalService.addMessage(
172             getGuestOrUserId(), categoryId, subject, body, files, anonymous,
173             priority, tagsEntries, prefs, addCommunityPermissions,
174             addGuestPermissions, themeDisplay);
175     }
176 
177     public MBMessage addMessage(
178             long categoryId, String subject, String body,
179             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
180             double priority, String[] tagsEntries, PortletPreferences prefs,
181             String[] communityPermissions, String[] guestPermissions,
182             ThemeDisplay themeDisplay)
183         throws PortalException, SystemException {
184 
185         MBCategoryPermission.check(
186             getPermissionChecker(), categoryId, ActionKeys.ADD_MESSAGE);
187 
188         if (!MBCategoryPermission.contains(
189                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
190 
191             files.clear();
192         }
193 
194         if (!MBCategoryPermission.contains(
195                 getPermissionChecker(), categoryId,
196                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
197 
198             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
199         }
200 
201         return mbMessageLocalService.addMessage(
202             getGuestOrUserId(), categoryId, subject, body, files, anonymous,
203             priority, tagsEntries, prefs, communityPermissions,
204             guestPermissions, themeDisplay);
205     }
206 
207     public MBMessage addMessage(
208             long categoryId, long threadId, long parentMessageId,
209             String subject, String body,
210             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
211             double priority, String[] tagsEntries,
212             boolean addCommunityPermissions, boolean addGuestPermissions)
213         throws PortalException, SystemException {
214 
215         checkReplyToPermission(categoryId, parentMessageId);
216 
217         if (!MBCategoryPermission.contains(
218                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
219 
220             files.clear();
221         }
222 
223         if (!MBCategoryPermission.contains(
224                 getPermissionChecker(), categoryId,
225                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
226 
227             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
228         }
229 
230         return mbMessageLocalService.addMessage(
231             getGuestOrUserId(), categoryId, threadId, parentMessageId, subject,
232             body, files, anonymous, priority, tagsEntries, null,
233             addCommunityPermissions, addGuestPermissions, null);
234     }
235 
236     public MBMessage addMessage(
237             long categoryId, long threadId, long parentMessageId,
238             String subject, String body,
239             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
240             double priority, String[] tagsEntries,
241             String[] communityPermissions, String[] guestPermissions)
242         throws PortalException, SystemException {
243 
244         checkReplyToPermission(categoryId, parentMessageId);
245 
246         if (!MBCategoryPermission.contains(
247                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
248 
249             files.clear();
250         }
251 
252         if (!MBCategoryPermission.contains(
253                 getPermissionChecker(), categoryId,
254                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
255 
256             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
257         }
258 
259         return mbMessageLocalService.addMessage(
260             getGuestOrUserId(), categoryId, threadId, parentMessageId, subject,
261             body, files, anonymous, priority, tagsEntries, null,
262             communityPermissions, guestPermissions, null);
263     }
264 
265     public MBMessage addMessage(
266             long categoryId, long threadId, long parentMessageId,
267             String subject, String body,
268             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
269             double priority, String[] tagsEntries, PortletPreferences prefs,
270             boolean addCommunityPermissions, boolean addGuestPermissions,
271             ThemeDisplay themeDisplay)
272         throws PortalException, SystemException {
273 
274         checkReplyToPermission(categoryId, parentMessageId);
275 
276         if (!MBCategoryPermission.contains(
277                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
278 
279             files.clear();
280         }
281 
282         if (!MBCategoryPermission.contains(
283                 getPermissionChecker(), categoryId,
284                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
285 
286             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
287         }
288 
289         return mbMessageLocalService.addMessage(
290             getGuestOrUserId(), categoryId, threadId, parentMessageId, subject,
291             body, files, anonymous, priority, tagsEntries, prefs,
292             addCommunityPermissions, addGuestPermissions, themeDisplay);
293     }
294 
295     public MBMessage addMessage(
296             long categoryId, long threadId, long parentMessageId,
297             String subject, String body,
298             List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
299             double priority, String[] tagsEntries, PortletPreferences prefs,
300             String[] communityPermissions, String[] guestPermissions,
301             ThemeDisplay themeDisplay)
302         throws PortalException, SystemException {
303 
304         checkReplyToPermission(categoryId, parentMessageId);
305 
306         if (!MBCategoryPermission.contains(
307                 getPermissionChecker(), categoryId, ActionKeys.ADD_FILE)) {
308 
309             files.clear();
310         }
311 
312         if (!MBCategoryPermission.contains(
313                 getPermissionChecker(), categoryId,
314                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
315 
316             priority = MBThreadImpl.PRIORITY_NOT_GIVEN;
317         }
318 
319         return mbMessageLocalService.addMessage(
320             getGuestOrUserId(), categoryId, threadId, parentMessageId, subject,
321             body, files, anonymous, priority, tagsEntries, prefs,
322             communityPermissions, guestPermissions, themeDisplay);
323     }
324 
325     public void deleteDiscussionMessage(
326             long groupId, String className, long classPK, long messageId)
327         throws PortalException, SystemException {
328 
329         MBDiscussionPermission.check(
330             getPermissionChecker(), groupId, className, classPK,
331             ActionKeys.DELETE_DISCUSSION);
332 
333         mbMessageLocalService.deleteDiscussionMessage(messageId);
334     }
335 
336     public void deleteMessage(long messageId)
337         throws PortalException, SystemException {
338 
339         MBMessagePermission.check(
340             getPermissionChecker(), messageId, ActionKeys.DELETE);
341 
342         mbMessageLocalService.deleteMessage(messageId);
343     }
344 
345     public List<MBMessage> getCategoryMessages(
346             long categoryId, int begin, int end)
347         throws PortalException, SystemException {
348 
349         List<MBMessage> messages = new ArrayList<MBMessage>();
350 
351         Iterator<MBMessage> itr = mbMessageLocalService.getCategoryMessages(
352             categoryId, begin, end).iterator();
353 
354         while (itr.hasNext()) {
355             MBMessage message = itr.next();
356 
357             if (MBMessagePermission.contains(
358                     getPermissionChecker(), message, ActionKeys.VIEW)) {
359 
360                 messages.add(message);
361             }
362         }
363 
364         return messages;
365     }
366 
367     public int getCategoryMessagesCount(long categoryId)
368         throws PortalException, SystemException {
369 
370         return mbMessageLocalService.getCategoryMessagesCount(categoryId);
371     }
372 
373     public String getCategoryMessagesRSS(
374             long categoryId, int max, String type, double version,
375             String displayStyle, String feedURL, String entryURL)
376         throws PortalException, SystemException {
377 
378         MBCategory category = mbCategoryLocalService.getCategory(
379             categoryId);
380 
381         String name = category.getName();
382         String description = category.getDescription();
383 
384         List<MBMessage> messages = new ArrayList<MBMessage>();
385 
386         MessageCreateDateComparator comparator =
387             new MessageCreateDateComparator(false, false);
388 
389         Iterator<MBMessage> itr = mbMessageLocalService.getCategoryMessages(
390             categoryId, 0, _MAX_END, comparator).iterator();
391 
392         while (itr.hasNext() && (messages.size() < max)) {
393             MBMessage message = itr.next();
394 
395             if (MBMessagePermission.contains(
396                     getPermissionChecker(), message, ActionKeys.VIEW)) {
397 
398                 messages.add(message);
399             }
400         }
401 
402         return exportToRSS(
403             name, description, type, version, displayStyle, feedURL, entryURL,
404             messages);
405     }
406 
407     public String getCompanyMessagesRSS(
408             long companyId, int max, String type, double version,
409             String displayStyle, String feedURL, String entryURL)
410         throws PortalException, SystemException {
411 
412         Company company = companyPersistence.findByPrimaryKey(companyId);
413 
414         String name = company.getName();
415         String description = company.getName();
416 
417         List<MBMessage> messages = new ArrayList<MBMessage>();
418 
419         MessageCreateDateComparator comparator =
420             new MessageCreateDateComparator(false, false);
421 
422         Iterator<MBMessage> itr = mbMessageLocalService.getCompanyMessages(
423             companyId, 0, _MAX_END, comparator).iterator();
424 
425         while (itr.hasNext() && (messages.size() < max)) {
426             MBMessage message = itr.next();
427 
428             if (MBMessagePermission.contains(
429                     getPermissionChecker(), message, ActionKeys.VIEW)) {
430 
431                 messages.add(message);
432             }
433         }
434 
435         return exportToRSS(
436             name, description, type, version, displayStyle, feedURL, entryURL,
437             messages);
438     }
439 
440     public String getGroupMessagesRSS(
441             long groupId, int max, String type, double version,
442             String displayStyle, String feedURL, String entryURL)
443         throws PortalException, SystemException {
444 
445         String name = StringPool.BLANK;
446         String description = StringPool.BLANK;
447 
448         List<MBMessage> messages = new ArrayList<MBMessage>();
449 
450         MessageCreateDateComparator comparator =
451             new MessageCreateDateComparator(false, true);
452 
453         Iterator<MBMessage> itr = mbMessageLocalService.getGroupMessages(
454             groupId, 0, _MAX_END, comparator).iterator();
455 
456         while (itr.hasNext() && (messages.size() < max)) {
457             MBMessage message = itr.next();
458 
459             if (MBMessagePermission.contains(
460                     getPermissionChecker(), message, ActionKeys.VIEW)) {
461 
462                 messages.add(message);
463             }
464         }
465 
466         if (messages.size() > 0) {
467             MBMessage message = messages.get(messages.size() - 1);
468 
469             name = message.getSubject();
470             description = message.getSubject();
471         }
472 
473         return exportToRSS(
474             name, description, type, version, displayStyle, feedURL, entryURL,
475             messages);
476     }
477 
478     public String getGroupMessagesRSS(
479             long groupId, long userId, int max, String type, double version,
480             String displayStyle, String feedURL, String entryURL)
481         throws PortalException, SystemException {
482 
483         String name = StringPool.BLANK;
484         String description = StringPool.BLANK;
485 
486         List<MBMessage> messages = new ArrayList<MBMessage>();
487 
488         MessageCreateDateComparator comparator =
489             new MessageCreateDateComparator(false, true);
490 
491         Iterator<MBMessage> itr = mbMessageLocalService.getGroupMessages(
492             groupId, userId, 0, _MAX_END, comparator).iterator();
493 
494         while (itr.hasNext() && (messages.size() < max)) {
495             MBMessage message = itr.next();
496 
497             if (MBMessagePermission.contains(
498                     getPermissionChecker(), message, ActionKeys.VIEW)) {
499 
500                 messages.add(message);
501             }
502         }
503 
504         if (messages.size() > 0) {
505             MBMessage message = messages.get(messages.size() - 1);
506 
507             name = message.getSubject();
508             description = message.getSubject();
509         }
510 
511         return exportToRSS(
512             name, description, type, version, displayStyle, feedURL, entryURL,
513             messages);
514     }
515 
516     public MBMessage getMessage(long messageId)
517         throws PortalException, SystemException {
518 
519         MBMessagePermission.check(
520             getPermissionChecker(), messageId, ActionKeys.VIEW);
521 
522         return mbMessageLocalService.getMessage(messageId);
523     }
524 
525     public MBMessageDisplay getMessageDisplay(long messageId)
526         throws PortalException, SystemException {
527 
528         MBMessagePermission.check(
529             getPermissionChecker(), messageId, ActionKeys.VIEW);
530 
531         return mbMessageLocalService.getMessageDisplay(messageId);
532     }
533 
534     public String getThreadMessagesRSS(
535             long threadId, int max, String type, double version,
536             String displayStyle, String feedURL, String entryURL)
537         throws PortalException, SystemException {
538 
539         String name = StringPool.BLANK;
540         String description = StringPool.BLANK;
541 
542         List<MBMessage> messages = new ArrayList<MBMessage>();
543 
544         MessageCreateDateComparator comparator =
545             new MessageCreateDateComparator(false, true);
546 
547         Iterator<MBMessage> itr = mbMessageLocalService.getThreadMessages(
548             threadId, comparator).iterator();
549 
550         while (itr.hasNext() && (messages.size() < max)) {
551             MBMessage message = itr.next();
552 
553             if (MBMessagePermission.contains(
554                     getPermissionChecker(), message, ActionKeys.VIEW)) {
555 
556                 messages.add(message);
557             }
558         }
559 
560         if (messages.size() > 0) {
561             MBMessage message = messages.get(messages.size() - 1);
562 
563             name = message.getSubject();
564             description = message.getSubject();
565         }
566 
567         return exportToRSS(
568             name, description, type, version, displayStyle, feedURL, entryURL,
569             messages);
570     }
571 
572     public void subscribeMessage(long messageId)
573         throws PortalException, SystemException {
574 
575         MBMessagePermission.check(
576             getPermissionChecker(), messageId, ActionKeys.SUBSCRIBE);
577 
578         mbMessageLocalService.subscribeMessage(getUserId(), messageId);
579     }
580 
581     public void unsubscribeMessage(long messageId)
582         throws PortalException, SystemException {
583 
584         MBMessagePermission.check(
585             getPermissionChecker(), messageId, ActionKeys.SUBSCRIBE);
586 
587         mbMessageLocalService.unsubscribeMessage(getUserId(), messageId);
588     }
589 
590     public MBMessage updateDiscussionMessage(
591             long groupId, String className, long classPK, long messageId,
592             String subject, String body)
593         throws PortalException, SystemException {
594 
595         MBDiscussionPermission.check(
596             getPermissionChecker(), groupId, className, classPK,
597             ActionKeys.UPDATE_DISCUSSION);
598 
599         return mbMessageLocalService.updateDiscussionMessage(
600             getUserId(), messageId, subject, body);
601     }
602 
603     public MBMessage updateMessage(
604             long messageId, String subject, String body,
605             List<ObjectValuePair<String, byte[]>> files,
606             List<String> existingFiles, double priority, String[] tagsEntries)
607         throws PortalException, SystemException {
608 
609         MBMessage message = mbMessageLocalService.getMessage(messageId);
610 
611         MBMessagePermission.check(
612             getPermissionChecker(), messageId, ActionKeys.UPDATE);
613 
614         if (!MBCategoryPermission.contains(
615                 getPermissionChecker(), message.getCategoryId(),
616                 ActionKeys.ADD_FILE)) {
617 
618             files.clear();
619         }
620 
621         if (!MBCategoryPermission.contains(
622                 getPermissionChecker(), message.getCategoryId(),
623                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
624 
625             MBThread thread = mbThreadLocalService.getThread(
626                 message.getThreadId());
627 
628             priority = thread.getPriority();
629         }
630 
631         return mbMessageLocalService.updateMessage(
632             getUserId(), messageId, subject, body, files, existingFiles,
633             priority, tagsEntries, null, null);
634     }
635 
636     public MBMessage updateMessage(
637             long messageId, String subject, String body,
638             List<ObjectValuePair<String, byte[]>> files,
639             List<String> existingFiles, double priority, String[] tagsEntries,
640             PortletPreferences prefs, ThemeDisplay themeDisplay)
641         throws PortalException, SystemException {
642 
643         MBMessage message = mbMessageLocalService.getMessage(messageId);
644 
645         MBMessagePermission.check(
646             getPermissionChecker(), messageId, ActionKeys.UPDATE);
647 
648         if (!MBCategoryPermission.contains(
649                 getPermissionChecker(), message.getCategoryId(),
650                 ActionKeys.ADD_FILE)) {
651 
652             files.clear();
653         }
654 
655         if (!MBCategoryPermission.contains(
656                 getPermissionChecker(), message.getCategoryId(),
657                 ActionKeys.UPDATE_THREAD_PRIORITY)) {
658 
659             MBThread thread = mbThreadLocalService.getThread(
660                 message.getThreadId());
661 
662             priority = thread.getPriority();
663         }
664 
665         return mbMessageLocalService.updateMessage(
666             getUserId(), messageId, subject, body, files, existingFiles,
667             priority, tagsEntries, prefs, themeDisplay);
668     }
669 
670     protected void checkReplyToPermission(long categoryId, long parentMessageId)
671         throws PortalException, SystemException {
672 
673         if (parentMessageId > 0) {
674             if (MBCategoryPermission.contains(
675                     getPermissionChecker(), categoryId,
676                     ActionKeys.ADD_MESSAGE)) {
677 
678                 return;
679             }
680 
681             MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
682                 parentMessageId);
683 
684             if ((parentMessage == null) ||
685                 !MBCategoryPermission.contains(
686                     getPermissionChecker(), categoryId,
687                     ActionKeys.REPLY_TO_MESSAGE)) {
688 
689                 throw new PrincipalException();
690             }
691         }
692         else {
693             MBCategoryPermission.check(
694                 getPermissionChecker(), categoryId, ActionKeys.ADD_MESSAGE);
695         }
696     }
697 
698     protected String exportToRSS(
699             String name, String description, String type, double version,
700             String displayStyle, String feedURL, String entryURL,
701             List<MBMessage> messages)
702         throws SystemException {
703 
704         SyndFeed syndFeed = new SyndFeedImpl();
705 
706         syndFeed.setFeedType(type + "_" + version);
707         syndFeed.setTitle(name);
708         syndFeed.setLink(feedURL);
709         syndFeed.setDescription(description);
710 
711         List<SyndEntry> entries = new ArrayList<SyndEntry>();
712 
713         syndFeed.setEntries(entries);
714 
715         Iterator<MBMessage> itr = messages.iterator();
716 
717         while (itr.hasNext()) {
718             MBMessage message = itr.next();
719 
720             String author = PortalUtil.getUserName(
721                 message.getUserId(), message.getUserName());
722 
723             String value = null;
724 
725             if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
726                 value = StringUtil.shorten(
727                     HtmlUtil.extractText(message.getBody()),
728                     _RSS_ABSTRACT_LENGTH, StringPool.BLANK);
729             }
730             else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
731                 value = StringPool.BLANK;
732             }
733             else {
734                 value = message.getBody();
735             }
736 
737             SyndEntry syndEntry = new SyndEntryImpl();
738 
739             if (!message.isAnonymous()) {
740                 syndEntry.setAuthor(author);
741             }
742 
743             syndEntry.setTitle(message.getSubject());
744             syndEntry.setLink(
745                 entryURL + "&messageId=" + message.getMessageId());
746             syndEntry.setPublishedDate(message.getCreateDate());
747 
748             SyndContent syndContent = new SyndContentImpl();
749 
750             syndContent.setType("html");
751             syndContent.setValue(value);
752 
753             syndEntry.setDescription(syndContent);
754 
755             entries.add(syndEntry);
756         }
757 
758         try {
759             return RSSUtil.export(syndFeed);
760         }
761         catch (FeedException fe) {
762             throw new SystemException(fe);
763         }
764         catch (IOException ioe) {
765             throw new SystemException(ioe);
766         }
767     }
768 
769     private static final int _MAX_END = 200;
770 
771     private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
772         PropsUtil.get(PropsUtil.MESSAGE_BOARDS_RSS_ABSTRACT_LENGTH));
773 
774 }