001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.messageboards.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.parsers.bbcode.BBCodeTranslatorUtil;
020    import com.liferay.portal.kernel.util.HtmlUtil;
021    import com.liferay.portal.kernel.util.ObjectValuePair;
022    import com.liferay.portal.kernel.util.ParamUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.workflow.WorkflowConstants;
026    import com.liferay.portal.model.Company;
027    import com.liferay.portal.model.Group;
028    import com.liferay.portal.model.User;
029    import com.liferay.portal.security.auth.PrincipalException;
030    import com.liferay.portal.security.permission.ActionKeys;
031    import com.liferay.portal.service.ServiceContext;
032    import com.liferay.portal.theme.ThemeDisplay;
033    import com.liferay.portal.util.PortalUtil;
034    import com.liferay.portal.util.PropsValues;
035    import com.liferay.portlet.messageboards.LockedThreadException;
036    import com.liferay.portlet.messageboards.model.MBCategory;
037    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
038    import com.liferay.portlet.messageboards.model.MBMessage;
039    import com.liferay.portlet.messageboards.model.MBMessageConstants;
040    import com.liferay.portlet.messageboards.model.MBMessageDisplay;
041    import com.liferay.portlet.messageboards.model.MBThread;
042    import com.liferay.portlet.messageboards.model.MBThreadConstants;
043    import com.liferay.portlet.messageboards.service.base.MBMessageServiceBaseImpl;
044    import com.liferay.portlet.messageboards.service.permission.MBCategoryPermission;
045    import com.liferay.portlet.messageboards.service.permission.MBDiscussionPermission;
046    import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
047    import com.liferay.portlet.messageboards.util.MBUtil;
048    import com.liferay.portlet.messageboards.util.comparator.MessageCreateDateComparator;
049    import com.liferay.util.RSSUtil;
050    
051    import com.sun.syndication.feed.synd.SyndContent;
052    import com.sun.syndication.feed.synd.SyndContentImpl;
053    import com.sun.syndication.feed.synd.SyndEntry;
054    import com.sun.syndication.feed.synd.SyndEntryImpl;
055    import com.sun.syndication.feed.synd.SyndFeed;
056    import com.sun.syndication.feed.synd.SyndFeedImpl;
057    import com.sun.syndication.feed.synd.SyndLink;
058    import com.sun.syndication.feed.synd.SyndLinkImpl;
059    import com.sun.syndication.io.FeedException;
060    
061    import java.io.InputStream;
062    
063    import java.util.ArrayList;
064    import java.util.Collections;
065    import java.util.Date;
066    import java.util.List;
067    
068    /**
069     * @author Brian Wing Shun Chan
070     * @author Mika Koivisto
071     * @author Shuyang Zhou
072     */
073    public class MBMessageServiceImpl extends MBMessageServiceBaseImpl {
074    
075            @Override
076            public MBMessage addDiscussionMessage(
077                            long groupId, String className, long classPK,
078                            String permissionClassName, long permissionClassPK,
079                            long permissionOwnerId, long threadId, long parentMessageId,
080                            String subject, String body, ServiceContext serviceContext)
081                    throws PortalException, SystemException {
082    
083                    User user = getGuestOrUser();
084    
085                    MBDiscussionPermission.check(
086                            getPermissionChecker(), user.getCompanyId(),
087                            serviceContext.getScopeGroupId(), permissionClassName,
088                            permissionClassPK, permissionOwnerId, ActionKeys.ADD_DISCUSSION);
089    
090                    return mbMessageLocalService.addDiscussionMessage(
091                            user.getUserId(), null, groupId, className, classPK, threadId,
092                            parentMessageId, subject, body, serviceContext);
093            }
094    
095            /**
096             * @deprecated As of 6.2.0, replaced by {@link #addMessage(long, String,
097             *             String, String, java.util.List, boolean, double, boolean,
098             *             com.liferay.portal.service.ServiceContext)}
099             */
100            @Override
101            public MBMessage addMessage(
102                            long groupId, long categoryId, long threadId, long parentMessageId,
103                            String subject, String body, String format,
104                            List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
105                            boolean anonymous, double priority, boolean allowPingbacks,
106                            ServiceContext serviceContext)
107                    throws PortalException, SystemException {
108    
109                    return addMessage(
110                            parentMessageId, subject, body, format, inputStreamOVPs, anonymous,
111                            priority, allowPingbacks, serviceContext);
112            }
113    
114            @Override
115            public MBMessage addMessage(
116                            long groupId, long categoryId, String subject, String body,
117                            String format,
118                            List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
119                            boolean anonymous, double priority, boolean allowPingbacks,
120                            ServiceContext serviceContext)
121                    throws PortalException, SystemException {
122    
123                    MBCategoryPermission.check(
124                            getPermissionChecker(), groupId, categoryId,
125                            ActionKeys.ADD_MESSAGE);
126    
127                    if (!MBCategoryPermission.contains(
128                                    getPermissionChecker(), groupId, categoryId,
129                                    ActionKeys.ADD_FILE)) {
130    
131                            inputStreamOVPs = Collections.emptyList();
132                    }
133    
134                    if (!MBCategoryPermission.contains(
135                                    getPermissionChecker(), groupId, categoryId,
136                                    ActionKeys.UPDATE_THREAD_PRIORITY)) {
137    
138                            priority = MBThreadConstants.PRIORITY_NOT_GIVEN;
139                    }
140    
141                    return mbMessageLocalService.addMessage(
142                            getGuestOrUserId(), null, groupId, categoryId, subject, body,
143                            format, inputStreamOVPs, anonymous, priority, allowPingbacks,
144                            serviceContext);
145            }
146    
147            @Override
148            public MBMessage addMessage(
149                            long categoryId, String subject, String body,
150                            ServiceContext serviceContext)
151                    throws PortalException, SystemException {
152    
153                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
154                            categoryId);
155    
156                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
157                            Collections.emptyList();
158    
159                    return addMessage(
160                            category.getGroupId(), categoryId, subject, body,
161                            MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false, 0.0,
162                            false, serviceContext);
163            }
164    
165            @Override
166            public MBMessage addMessage(
167                            long parentMessageId, String subject, String body, String format,
168                            List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
169                            boolean anonymous, double priority, boolean allowPingbacks,
170                            ServiceContext serviceContext)
171                    throws PortalException, SystemException {
172    
173                    MBMessage parentMessage = mbMessagePersistence.findByPrimaryKey(
174                            parentMessageId);
175    
176                    checkReplyToPermission(
177                            parentMessage.getGroupId(), parentMessage.getCategoryId(),
178                            parentMessageId);
179    
180                    boolean preview = ParamUtil.getBoolean(serviceContext, "preview");
181    
182                    int workFlowAction = serviceContext.getWorkflowAction();
183    
184                    if ((workFlowAction == WorkflowConstants.STATUS_DRAFT) && !preview &&
185                            !serviceContext.isSignedIn()) {
186    
187                            MBMessagePermission.check(
188                                    getPermissionChecker(), parentMessageId, ActionKeys.UPDATE);
189                    }
190    
191                    if (lockLocalService.isLocked(
192                                    MBThread.class.getName(), parentMessage.getThreadId())) {
193    
194                            throw new LockedThreadException();
195                    }
196    
197                    if (!MBCategoryPermission.contains(
198                                    getPermissionChecker(), parentMessage.getGroupId(),
199                                    parentMessage.getCategoryId(), ActionKeys.ADD_FILE)) {
200    
201                            inputStreamOVPs = Collections.emptyList();
202                    }
203    
204                    if (!MBCategoryPermission.contains(
205                                    getPermissionChecker(), parentMessage.getGroupId(),
206                                    parentMessage.getCategoryId(),
207                                    ActionKeys.UPDATE_THREAD_PRIORITY)) {
208    
209                            priority = MBThreadConstants.PRIORITY_NOT_GIVEN;
210                    }
211    
212                    return mbMessageLocalService.addMessage(
213                            getGuestOrUserId(), null, parentMessage.getGroupId(),
214                            parentMessage.getCategoryId(), parentMessage.getThreadId(),
215                            parentMessageId, subject, body, format, inputStreamOVPs, anonymous,
216                            priority, allowPingbacks, serviceContext);
217            }
218    
219            @Override
220            public void deleteDiscussionMessage(
221                            long groupId, String className, long classPK,
222                            String permissionClassName, long permissionClassPK,
223                            long permissionOwnerId, long messageId)
224                    throws PortalException, SystemException {
225    
226                    User user = getUser();
227    
228                    MBDiscussionPermission.check(
229                            getPermissionChecker(), user.getCompanyId(), groupId,
230                            permissionClassName, permissionClassPK, messageId,
231                            permissionOwnerId, ActionKeys.DELETE_DISCUSSION);
232    
233                    mbMessageLocalService.deleteDiscussionMessage(messageId);
234            }
235    
236            @Override
237            public void deleteMessage(long messageId)
238                    throws PortalException, SystemException {
239    
240                    MBMessagePermission.check(
241                            getPermissionChecker(), messageId, ActionKeys.DELETE);
242    
243                    mbMessageLocalService.deleteMessage(messageId);
244            }
245    
246            @Override
247            public void deleteMessageAttachments(long messageId)
248                    throws PortalException, SystemException {
249    
250                    MBMessagePermission.check(
251                            getPermissionChecker(), messageId, ActionKeys.DELETE);
252    
253                    mbMessageLocalService.deleteMessageAttachments(messageId);
254            }
255    
256            @Override
257            public List<MBMessage> getCategoryMessages(
258                            long groupId, long categoryId, int status, int start, int end)
259                    throws PortalException, SystemException {
260    
261                    List<MBMessage> messages = new ArrayList<MBMessage>();
262    
263                    List<MBMessage> categoryMessages =
264                            mbMessageLocalService.getCategoryMessages(
265                                    groupId, categoryId, status, start, end);
266    
267                    for (MBMessage message : categoryMessages) {
268                            if (MBMessagePermission.contains(
269                                            getPermissionChecker(), message, ActionKeys.VIEW)) {
270    
271                                    messages.add(message);
272                            }
273                    }
274    
275                    return messages;
276            }
277    
278            @Override
279            public int getCategoryMessagesCount(
280                            long groupId, long categoryId, int status)
281                    throws SystemException {
282    
283                    return mbMessageLocalService.getCategoryMessagesCount(
284                            groupId, categoryId, status);
285            }
286    
287            @Override
288            public String getCategoryMessagesRSS(
289                            long groupId, long categoryId, int status, int max, String type,
290                            double version, String displayStyle, String feedURL,
291                            String entryURL, ThemeDisplay themeDisplay)
292                    throws PortalException, SystemException {
293    
294                    String name = StringPool.BLANK;
295                    String description = StringPool.BLANK;
296    
297                    MBCategory category = mbCategoryLocalService.fetchMBCategory(
298                            categoryId);
299    
300                    if (category == null) {
301                            Group group = groupLocalService.getGroup(categoryId);
302    
303                            groupId = group.getGroupId();
304                            categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
305                            name = group.getDescriptiveName();
306                            description = group.getDescription();
307                    }
308                    else {
309                            groupId = category.getGroupId();
310                            name = category.getName();
311                            description = category.getDescription();
312                    }
313    
314                    List<MBMessage> messages = new ArrayList<MBMessage>();
315    
316                    int lastIntervalStart = 0;
317                    boolean listNotExhausted = true;
318                    MessageCreateDateComparator comparator =
319                            new MessageCreateDateComparator(false);
320    
321                    while ((messages.size() < max) && listNotExhausted) {
322                            List<MBMessage> messageList =
323                                    mbMessageLocalService.getCategoryMessages(
324                                            groupId, categoryId, status, lastIntervalStart,
325                                            lastIntervalStart + max, comparator);
326    
327                            lastIntervalStart += max;
328                            listNotExhausted = (messageList.size() == max);
329    
330                            for (MBMessage message : messageList) {
331                                    if (messages.size() >= max) {
332                                            break;
333                                    }
334    
335                                    if (MBMessagePermission.contains(
336                                                    getPermissionChecker(), message, ActionKeys.VIEW)) {
337    
338                                            messages.add(message);
339                                    }
340                            }
341                    }
342    
343                    return exportToRSS(
344                            name, description, type, version, displayStyle, feedURL, entryURL,
345                            messages, themeDisplay);
346            }
347    
348            @Override
349            public String getCompanyMessagesRSS(
350                            long companyId, int status, int max, String type, double version,
351                            String displayStyle, String feedURL, String entryURL,
352                            ThemeDisplay themeDisplay)
353                    throws PortalException, SystemException {
354    
355                    Company company = companyPersistence.findByPrimaryKey(companyId);
356    
357                    String name = company.getName();
358                    String description = company.getName();
359    
360                    List<MBMessage> messages = new ArrayList<MBMessage>();
361    
362                    int lastIntervalStart = 0;
363                    boolean listNotExhausted = true;
364                    MessageCreateDateComparator comparator =
365                            new MessageCreateDateComparator(false);
366    
367                    while ((messages.size() < max) && listNotExhausted) {
368                            List<MBMessage> messageList =
369                                    mbMessageLocalService.getCompanyMessages(
370                                            companyId, status, lastIntervalStart,
371                                            lastIntervalStart + max, comparator);
372    
373                            lastIntervalStart += max;
374                            listNotExhausted = (messageList.size() == max);
375    
376                            for (MBMessage message : messageList) {
377                                    if (messages.size() >= max) {
378                                            break;
379                                    }
380    
381                                    if (MBMessagePermission.contains(
382                                                    getPermissionChecker(), message, ActionKeys.VIEW)) {
383    
384                                            messages.add(message);
385                                    }
386                            }
387                    }
388    
389                    return exportToRSS(
390                            name, description, type, version, displayStyle, feedURL, entryURL,
391                            messages, themeDisplay);
392            }
393    
394            @Override
395            public int getGroupMessagesCount(long groupId, int status)
396                    throws SystemException {
397    
398                    if (status == WorkflowConstants.STATUS_ANY) {
399                            return mbMessagePersistence.filterCountByGroupId(groupId);
400                    }
401                    else {
402                            return mbMessagePersistence.filterCountByG_S(groupId, status);
403                    }
404            }
405    
406            @Override
407            public String getGroupMessagesRSS(
408                            long groupId, int status, int max, String type, double version,
409                            String displayStyle, String feedURL, String entryURL,
410                            ThemeDisplay themeDisplay)
411                    throws PortalException, SystemException {
412    
413                    String name = StringPool.BLANK;
414                    String description = StringPool.BLANK;
415    
416                    List<MBMessage> messages = new ArrayList<MBMessage>();
417    
418                    int lastIntervalStart = 0;
419                    boolean listNotExhausted = true;
420                    MessageCreateDateComparator comparator =
421                            new MessageCreateDateComparator(false);
422    
423                    while ((messages.size() < max) && listNotExhausted) {
424                            List<MBMessage> messageList =
425                                    mbMessageLocalService.getGroupMessages(
426                                            groupId, status, lastIntervalStart, lastIntervalStart + max,
427                                            comparator);
428    
429                            lastIntervalStart += max;
430                            listNotExhausted = (messageList.size() == max);
431    
432                            for (MBMessage message : messageList) {
433                                    if (messages.size() >= max) {
434                                            break;
435                                    }
436    
437                                    if (MBMessagePermission.contains(
438                                                    getPermissionChecker(), message, ActionKeys.VIEW)) {
439    
440                                            messages.add(message);
441                                    }
442                            }
443                    }
444    
445                    if (messages.size() > 0) {
446                            MBMessage message = messages.get(messages.size() - 1);
447    
448                            name = message.getSubject();
449                            description = message.getSubject();
450                    }
451    
452                    return exportToRSS(
453                            name, description, type, version, displayStyle, feedURL, entryURL,
454                            messages, themeDisplay);
455            }
456    
457            @Override
458            public String getGroupMessagesRSS(
459                            long groupId, long userId, int status, int max, String type,
460                            double version, String displayStyle, String feedURL,
461                            String entryURL, ThemeDisplay themeDisplay)
462                    throws PortalException, SystemException {
463    
464                    String name = StringPool.BLANK;
465                    String description = StringPool.BLANK;
466    
467                    List<MBMessage> messages = new ArrayList<MBMessage>();
468    
469                    int lastIntervalStart = 0;
470                    boolean listNotExhausted = true;
471                    MessageCreateDateComparator comparator =
472                            new MessageCreateDateComparator(false);
473    
474                    while ((messages.size() < max) && listNotExhausted) {
475                            List<MBMessage> messageList =
476                                    mbMessageLocalService.getGroupMessages(
477                                            groupId, userId, status, lastIntervalStart,
478                                            lastIntervalStart + max, comparator);
479    
480                            lastIntervalStart += max;
481                            listNotExhausted = (messageList.size() == max);
482    
483                            for (MBMessage message : messageList) {
484                                    if (messages.size() >= max) {
485                                            break;
486                                    }
487    
488                                    if (MBMessagePermission.contains(
489                                                    getPermissionChecker(), message, ActionKeys.VIEW)) {
490    
491                                            messages.add(message);
492                                    }
493                            }
494                    }
495    
496                    if (messages.size() > 0) {
497                            MBMessage message = messages.get(messages.size() - 1);
498    
499                            name = message.getSubject();
500                            description = message.getSubject();
501                    }
502    
503                    return exportToRSS(
504                            name, description, type, version, displayStyle, feedURL, entryURL,
505                            messages, themeDisplay);
506            }
507    
508            @Override
509            public MBMessage getMessage(long messageId)
510                    throws PortalException, SystemException {
511    
512                    MBMessagePermission.check(
513                            getPermissionChecker(), messageId, ActionKeys.VIEW);
514    
515                    return mbMessageLocalService.getMessage(messageId);
516            }
517    
518            @Override
519            public MBMessageDisplay getMessageDisplay(
520                            long messageId, int status, String threadView,
521                            boolean includePrevAndNext)
522                    throws PortalException, SystemException {
523    
524                    MBMessagePermission.check(
525                            getPermissionChecker(), messageId, ActionKeys.VIEW);
526    
527                    return mbMessageLocalService.getMessageDisplay(
528                            getGuestOrUserId(), messageId, status, threadView,
529                            includePrevAndNext);
530            }
531    
532            @Override
533            public int getThreadAnswersCount(
534                            long groupId, long categoryId, long threadId)
535                    throws SystemException {
536    
537                    return mbMessagePersistence.filterCountByG_C_T_A(
538                            groupId, categoryId, threadId, true);
539            }
540    
541            @Override
542            public List<MBMessage> getThreadMessages(
543                            long groupId, long categoryId, long threadId, int status, int start,
544                            int end)
545                    throws SystemException {
546    
547                    if (status == WorkflowConstants.STATUS_ANY) {
548                            return mbMessagePersistence.filterFindByG_C_T(
549                                    groupId, categoryId, threadId, start, end);
550                    }
551                    else {
552                            return mbMessagePersistence.filterFindByG_C_T_S(
553                                    groupId, categoryId, threadId, status, start, end);
554                    }
555            }
556    
557            @Override
558            public int getThreadMessagesCount(
559                            long groupId, long categoryId, long threadId, int status)
560                    throws SystemException {
561    
562                    if (status == WorkflowConstants.STATUS_ANY) {
563                            return mbMessagePersistence.filterCountByG_C_T(
564                                    groupId, categoryId, threadId);
565                    }
566                    else {
567                            return mbMessagePersistence.filterCountByG_C_T_S(
568                                    groupId, categoryId, threadId, status);
569                    }
570            }
571    
572            @Override
573            public String getThreadMessagesRSS(
574                            long threadId, int status, int max, String type, double version,
575                            String displayStyle, String feedURL, String entryURL,
576                            ThemeDisplay themeDisplay)
577                    throws PortalException, SystemException {
578    
579                    String name = StringPool.BLANK;
580                    String description = StringPool.BLANK;
581    
582                    List<MBMessage> messages = new ArrayList<MBMessage>();
583    
584                    MBThread thread = mbThreadLocalService.getThread(threadId);
585    
586                    if (MBMessagePermission.contains(
587                                    getPermissionChecker(), thread.getRootMessageId(),
588                                    ActionKeys.VIEW)) {
589    
590                            MessageCreateDateComparator comparator =
591                                    new MessageCreateDateComparator(false);
592    
593                            List<MBMessage> threadMessages =
594                                    mbMessageLocalService.getThreadMessages(
595                                            threadId, status, comparator);
596    
597                            for (MBMessage message : threadMessages) {
598                                    if (messages.size() >= max) {
599                                            break;
600                                    }
601    
602                                    if (MBMessagePermission.contains(
603                                                    getPermissionChecker(), message, ActionKeys.VIEW)) {
604    
605                                            messages.add(message);
606                                    }
607                            }
608    
609                            if (messages.size() > 0) {
610                                    MBMessage message = messages.get(messages.size() - 1);
611    
612                                    name = message.getSubject();
613                                    description = message.getSubject();
614                            }
615                    }
616    
617                    return exportToRSS(
618                            name, description, type, version, displayStyle, feedURL, entryURL,
619                            messages, themeDisplay);
620            }
621    
622            @Override
623            public void restoreMessageAttachmentFromTrash(
624                            long messageId, String fileName)
625                    throws PortalException, SystemException {
626    
627                    MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
628    
629                    MBCategoryPermission.check(
630                            getPermissionChecker(), message.getGroupId(),
631                            message.getCategoryId(), ActionKeys.ADD_FILE);
632    
633                    mbMessageLocalService.restoreMessageAttachmentFromTrash(
634                            getUserId(), messageId, fileName);
635            }
636    
637            @Override
638            public void subscribeMessage(long messageId)
639                    throws PortalException, SystemException {
640    
641                    MBMessagePermission.check(
642                            getPermissionChecker(), messageId, ActionKeys.SUBSCRIBE);
643    
644                    mbMessageLocalService.subscribeMessage(getUserId(), messageId);
645            }
646    
647            @Override
648            public void unsubscribeMessage(long messageId)
649                    throws PortalException, SystemException {
650    
651                    MBMessagePermission.check(
652                            getPermissionChecker(), messageId, ActionKeys.SUBSCRIBE);
653    
654                    mbMessageLocalService.unsubscribeMessage(getUserId(), messageId);
655            }
656    
657            @Override
658            public void updateAnswer(long messageId, boolean answer, boolean cascade)
659                    throws PortalException, SystemException {
660    
661                    mbMessageLocalService.updateAnswer(messageId, answer, cascade);
662            }
663    
664            @Override
665            public MBMessage updateDiscussionMessage(
666                            String className, long classPK, String permissionClassName,
667                            long permissionClassPK, long permissionOwnerId, long messageId,
668                            String subject, String body, ServiceContext serviceContext)
669                    throws PortalException, SystemException {
670    
671                    User user = getUser();
672    
673                    MBDiscussionPermission.check(
674                            getPermissionChecker(), user.getCompanyId(),
675                            serviceContext.getScopeGroupId(), permissionClassName,
676                            permissionClassPK, messageId, permissionOwnerId,
677                            ActionKeys.UPDATE_DISCUSSION);
678    
679                    return mbMessageLocalService.updateDiscussionMessage(
680                            getUserId(), messageId, className, classPK, subject, body,
681                            serviceContext);
682            }
683    
684            @Override
685            public MBMessage updateMessage(
686                            long messageId, String subject, String body,
687                            List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
688                            List<String> existingFiles, double priority, boolean allowPingbacks,
689                            ServiceContext serviceContext)
690                    throws PortalException, SystemException {
691    
692                    MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
693    
694                    boolean preview = ParamUtil.getBoolean(serviceContext, "preview");
695    
696                    if (preview &&
697                            MBMessagePermission.contains(
698                                    getPermissionChecker(), message, ActionKeys.UPDATE)) {
699    
700                            checkReplyToPermission(
701                                    message.getGroupId(), message.getCategoryId(),
702                                    message.getParentMessageId());
703                    }
704                    else {
705                            MBMessagePermission.check(
706                                    getPermissionChecker(), messageId, ActionKeys.UPDATE);
707                    }
708    
709                    if (lockLocalService.isLocked(
710                                    MBThread.class.getName(), message.getThreadId())) {
711    
712                            throw new LockedThreadException();
713                    }
714    
715                    if (!MBCategoryPermission.contains(
716                                    getPermissionChecker(), message.getGroupId(),
717                                    message.getCategoryId(), ActionKeys.ADD_FILE)) {
718    
719                            inputStreamOVPs = Collections.emptyList();
720                    }
721    
722                    if (!MBCategoryPermission.contains(
723                                    getPermissionChecker(), message.getGroupId(),
724                                    message.getCategoryId(), ActionKeys.UPDATE_THREAD_PRIORITY)) {
725    
726                            MBThread thread = mbThreadLocalService.getThread(
727                                    message.getThreadId());
728    
729                            priority = thread.getPriority();
730                    }
731    
732                    return mbMessageLocalService.updateMessage(
733                            getGuestOrUserId(), messageId, subject, body, inputStreamOVPs,
734                            existingFiles, priority, allowPingbacks, serviceContext);
735            }
736    
737            protected void checkReplyToPermission(
738                            long groupId, long categoryId, long parentMessageId)
739                    throws PortalException, SystemException {
740    
741                    if (parentMessageId > 0) {
742                            if (MBCategoryPermission.contains(
743                                            getPermissionChecker(), groupId, categoryId,
744                                            ActionKeys.ADD_MESSAGE)) {
745    
746                                    return;
747                            }
748    
749                            if (!MBCategoryPermission.contains(
750                                            getPermissionChecker(), groupId, categoryId,
751                                            ActionKeys.REPLY_TO_MESSAGE)) {
752    
753                                    throw new PrincipalException();
754                            }
755                    }
756                    else {
757                            MBCategoryPermission.check(
758                                    getPermissionChecker(), groupId, categoryId,
759                                    ActionKeys.ADD_MESSAGE);
760                    }
761            }
762    
763            protected String exportToRSS(
764                            String name, String description, String type, double version,
765                            String displayStyle, String feedURL, String entryURL,
766                            List<MBMessage> messages, ThemeDisplay themeDisplay)
767                    throws SystemException {
768    
769                    SyndFeed syndFeed = new SyndFeedImpl();
770    
771                    syndFeed.setDescription(description);
772    
773                    List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
774    
775                    syndFeed.setEntries(syndEntries);
776    
777                    for (MBMessage message : messages) {
778                            SyndEntry syndEntry = new SyndEntryImpl();
779    
780                            if (!message.isAnonymous()) {
781                                    String author = PortalUtil.getUserName(message);
782    
783                                    syndEntry.setAuthor(author);
784                            }
785    
786                            SyndContent syndContent = new SyndContentImpl();
787    
788                            syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
789    
790                            String value = null;
791    
792                            if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
793                                    value = StringUtil.shorten(
794                                            HtmlUtil.extractText(message.getBody()),
795                                            PropsValues.MESSAGE_BOARDS_RSS_ABSTRACT_LENGTH,
796                                            StringPool.BLANK);
797                            }
798                            else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
799                                    value = StringPool.BLANK;
800                            }
801                            else if (message.isFormatBBCode()) {
802                                    value = BBCodeTranslatorUtil.getHTML(message.getBody());
803    
804                                    value = MBUtil.replaceMessageBodyPaths(themeDisplay, value);
805                            }
806                            else {
807                                    value = message.getBody();
808                            }
809    
810                            syndContent.setValue(value);
811    
812                            syndEntry.setDescription(syndContent);
813    
814                            syndEntry.setLink(
815                                    entryURL + "&messageId=" + message.getMessageId());
816                            syndEntry.setPublishedDate(message.getCreateDate());
817                            syndEntry.setTitle(message.getSubject());
818                            syndEntry.setUpdatedDate(message.getModifiedDate());
819                            syndEntry.setUri(syndEntry.getLink());
820    
821                            syndEntries.add(syndEntry);
822                    }
823    
824                    syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
825    
826                    List<SyndLink> syndLinks = new ArrayList<SyndLink>();
827    
828                    syndFeed.setLinks(syndLinks);
829    
830                    SyndLink selfSyndLink = new SyndLinkImpl();
831    
832                    syndLinks.add(selfSyndLink);
833    
834                    selfSyndLink.setHref(feedURL);
835                    selfSyndLink.setRel("self");
836    
837                    syndFeed.setPublishedDate(new Date());
838                    syndFeed.setTitle(name);
839                    syndFeed.setUri(feedURL);
840    
841                    try {
842                            return RSSUtil.export(syndFeed);
843                    }
844                    catch (FeedException fe) {
845                            throw new SystemException(fe);
846                    }
847            }
848    
849    }