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