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