001
014
015 package com.liferay.portlet.messageboards.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.json.JSONFactoryUtil;
021 import com.liferay.portal.kernel.json.JSONObject;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.parsers.bbcode.BBCodeTranslatorUtil;
025 import com.liferay.portal.kernel.repository.model.FileEntry;
026 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
027 import com.liferay.portal.kernel.search.Indexable;
028 import com.liferay.portal.kernel.search.IndexableType;
029 import com.liferay.portal.kernel.search.Indexer;
030 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
031 import com.liferay.portal.kernel.util.Constants;
032 import com.liferay.portal.kernel.util.ContentTypes;
033 import com.liferay.portal.kernel.util.ListUtil;
034 import com.liferay.portal.kernel.util.ObjectValuePair;
035 import com.liferay.portal.kernel.util.OrderByComparator;
036 import com.liferay.portal.kernel.util.ParamUtil;
037 import com.liferay.portal.kernel.util.PropsKeys;
038 import com.liferay.portal.kernel.util.StringPool;
039 import com.liferay.portal.kernel.util.StringUtil;
040 import com.liferay.portal.kernel.util.Validator;
041 import com.liferay.portal.kernel.util.WebKeys;
042 import com.liferay.portal.kernel.workflow.WorkflowConstants;
043 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
044 import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
045 import com.liferay.portal.model.Company;
046 import com.liferay.portal.model.Group;
047 import com.liferay.portal.model.ModelHintsUtil;
048 import com.liferay.portal.model.ResourceConstants;
049 import com.liferay.portal.model.User;
050 import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
051 import com.liferay.portal.security.auth.PrincipalException;
052 import com.liferay.portal.service.ServiceContext;
053 import com.liferay.portal.service.ServiceContextUtil;
054 import com.liferay.portal.theme.ThemeDisplay;
055 import com.liferay.portal.util.Portal;
056 import com.liferay.portal.util.PortalUtil;
057 import com.liferay.portal.util.PortletKeys;
058 import com.liferay.portal.util.PrefsPropsUtil;
059 import com.liferay.portal.util.PropsValues;
060 import com.liferay.portal.util.SubscriptionSender;
061 import com.liferay.portlet.asset.model.AssetEntry;
062 import com.liferay.portlet.asset.model.AssetLinkConstants;
063 import com.liferay.portlet.blogs.model.BlogsEntry;
064 import com.liferay.portlet.blogs.util.LinkbackProducerUtil;
065 import com.liferay.portlet.expando.model.ExpandoBridge;
066 import com.liferay.portlet.messageboards.MessageBodyException;
067 import com.liferay.portlet.messageboards.MessageSubjectException;
068 import com.liferay.portlet.messageboards.NoSuchDiscussionException;
069 import com.liferay.portlet.messageboards.RequiredMessageException;
070 import com.liferay.portlet.messageboards.model.MBCategory;
071 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
072 import com.liferay.portlet.messageboards.model.MBDiscussion;
073 import com.liferay.portlet.messageboards.model.MBMessage;
074 import com.liferay.portlet.messageboards.model.MBMessageConstants;
075 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
076 import com.liferay.portlet.messageboards.model.MBThread;
077 import com.liferay.portlet.messageboards.model.MBThreadConstants;
078 import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
079 import com.liferay.portlet.messageboards.model.impl.MBMessageDisplayImpl;
080 import com.liferay.portlet.messageboards.service.base.MBMessageLocalServiceBaseImpl;
081 import com.liferay.portlet.messageboards.social.MBActivityKeys;
082 import com.liferay.portlet.messageboards.util.MBSubscriptionSender;
083 import com.liferay.portlet.messageboards.util.MBUtil;
084 import com.liferay.portlet.messageboards.util.MailingListThreadLocal;
085 import com.liferay.portlet.messageboards.util.comparator.MessageCreateDateComparator;
086 import com.liferay.portlet.messageboards.util.comparator.MessageThreadComparator;
087 import com.liferay.portlet.messageboards.util.comparator.ThreadLastPostDateComparator;
088 import com.liferay.portlet.social.model.SocialActivity;
089 import com.liferay.portlet.social.model.SocialActivityConstants;
090 import com.liferay.portlet.trash.util.TrashUtil;
091 import com.liferay.util.SerializableUtil;
092
093 import java.io.InputStream;
094
095 import java.util.ArrayList;
096 import java.util.Collections;
097 import java.util.Comparator;
098 import java.util.Date;
099 import java.util.List;
100
101 import javax.portlet.PortletPreferences;
102
103 import javax.servlet.http.HttpServletRequest;
104
105 import net.htmlparser.jericho.Source;
106 import net.htmlparser.jericho.StartTag;
107
108
116 public class MBMessageLocalServiceImpl extends MBMessageLocalServiceBaseImpl {
117
118 public MBMessage addDiscussionMessage(
119 long userId, String userName, long groupId, String className,
120 long classPK, int workflowAction)
121 throws PortalException, SystemException {
122
123 long threadId = 0;
124 long parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
125 String subject = String.valueOf(classPK);
126 String body = subject;
127
128 ServiceContext serviceContext = new ServiceContext();
129
130 serviceContext.setWorkflowAction(workflowAction);
131
132 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
133
134 WorkflowThreadLocal.setEnabled(false);
135
136 try {
137 return addDiscussionMessage(
138 userId, userName, groupId, className, classPK, threadId,
139 parentMessageId, subject, body, serviceContext);
140 }
141 finally {
142 WorkflowThreadLocal.setEnabled(workflowEnabled);
143 }
144 }
145
146 public MBMessage addDiscussionMessage(
147 long userId, String userName, long groupId, String className,
148 long classPK, long threadId, long parentMessageId, String subject,
149 String body, ServiceContext serviceContext)
150 throws PortalException, SystemException {
151
152
153
154 long categoryId = MBCategoryConstants.DISCUSSION_CATEGORY_ID;
155
156 if (Validator.isNull(subject)) {
157 if (Validator.isNotNull(body)) {
158 int pos = Math.min(body.length(), 50);
159
160 subject = body.substring(0, pos) + "...";
161 }
162 else {
163 throw new MessageBodyException();
164 }
165 }
166
167 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
168 Collections.emptyList();
169 boolean anonymous = false;
170 double priority = 0.0;
171 boolean allowPingbacks = false;
172
173 serviceContext.setAddGroupPermissions(true);
174 serviceContext.setAddGuestPermissions(true);
175 serviceContext.setAttribute("className", className);
176 serviceContext.setAttribute("classPK", String.valueOf(classPK));
177
178 MBMessage message = addMessage(
179 userId, userName, groupId, categoryId, threadId, parentMessageId,
180 subject, body, MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs,
181 anonymous, priority, allowPingbacks, serviceContext);
182
183
184
185 if (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
186 long classNameId = PortalUtil.getClassNameId(className);
187
188 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
189 classNameId, classPK);
190
191 if (discussion == null) {
192 mbDiscussionLocalService.addDiscussion(
193 classNameId, classPK, message.getThreadId());
194 }
195 }
196
197 return message;
198 }
199
200 public MBMessage addMessage(
201 long userId, String userName, long groupId, long categoryId,
202 long threadId, long parentMessageId, String subject, String body,
203 String format,
204 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
205 boolean anonymous, double priority, boolean allowPingbacks,
206 ServiceContext serviceContext)
207 throws PortalException, SystemException {
208
209
210
211 User user = userPersistence.findByPrimaryKey(userId);
212 userName = user.isDefaultUser() ? userName : user.getFullName();
213 subject = ModelHintsUtil.trimString(
214 MBMessage.class.getName(), "subject", subject);
215
216 PortletPreferences preferences =
217 ServiceContextUtil.getPortletPreferences(serviceContext);
218
219 if (preferences != null) {
220 if (!MBUtil.isAllowAnonymousPosting(preferences)) {
221 if (anonymous || user.isDefaultUser()) {
222 throw new PrincipalException();
223 }
224 }
225 }
226
227 if (user.isDefaultUser()) {
228 anonymous = true;
229 }
230
231 Date now = new Date();
232
233 long messageId = counterLocalService.increment();
234
235 body = SanitizerUtil.sanitize(
236 user.getCompanyId(), groupId, userId, MBMessage.class.getName(),
237 messageId, "text/" + format, body);
238
239 validate(subject, body);
240
241 subject = getSubject(subject, body);
242 body = getBody(subject, body);
243
244 MBMessage message = mbMessagePersistence.create(messageId);
245
246 message.setUuid(serviceContext.getUuid());
247 message.setGroupId(groupId);
248 message.setCompanyId(user.getCompanyId());
249 message.setUserId(user.getUserId());
250 message.setUserName(userName);
251 message.setCreateDate(serviceContext.getCreateDate(now));
252 message.setModifiedDate(serviceContext.getModifiedDate(now));
253
254 if (threadId > 0) {
255 message.setThreadId(threadId);
256 }
257
258 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
259 message.setPriority(priority);
260 }
261
262 message.setAllowPingbacks(allowPingbacks);
263 message.setStatus(WorkflowConstants.STATUS_DRAFT);
264 message.setStatusByUserId(user.getUserId());
265 message.setStatusByUserName(userName);
266 message.setStatusDate(serviceContext.getModifiedDate(now));
267
268
269
270 if (parentMessageId != MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
271 MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
272 parentMessageId);
273
274 if (parentMessage == null) {
275 parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
276 }
277 }
278
279 MBThread thread = null;
280
281 if (threadId > 0) {
282 thread = mbThreadPersistence.fetchByPrimaryKey(threadId);
283 }
284
285 if ((thread == null) ||
286 (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID)) {
287
288 thread = mbThreadLocalService.addThread(categoryId, message);
289 }
290
291 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
292 (thread.getPriority() != priority)) {
293
294 thread.setPriority(priority);
295
296 mbThreadPersistence.update(thread);
297
298 updatePriorities(thread.getThreadId(), priority);
299 }
300
301
302
303 message.setCategoryId(categoryId);
304 message.setThreadId(thread.getThreadId());
305 message.setRootMessageId(thread.getRootMessageId());
306 message.setParentMessageId(parentMessageId);
307 message.setSubject(subject);
308 message.setBody(body);
309 message.setFormat(format);
310 message.setAnonymous(anonymous);
311
312 if (message.isDiscussion()) {
313 long classNameId = PortalUtil.getClassNameId(
314 (String)serviceContext.getAttribute("className"));
315 long classPK = ParamUtil.getLong(serviceContext, "classPK");
316
317 message.setClassNameId(classNameId);
318 message.setClassPK(classPK);
319 }
320
321 mbMessagePersistence.update(message);
322
323
324
325 if (!inputStreamOVPs.isEmpty()) {
326 PortletFileRepositoryUtil.addPortletFileEntries(
327 message.getGroupId(), userId, PortletKeys.MESSAGE_BOARDS,
328 message.getAttachmentsFolderId(), inputStreamOVPs);
329 }
330
331
332
333 if (!message.isDiscussion()) {
334 if (user.isDefaultUser()) {
335 addMessageResources(message, true, true);
336 }
337 else if (serviceContext.isAddGroupPermissions() ||
338 serviceContext.isAddGuestPermissions()) {
339
340 addMessageResources(
341 message, serviceContext.isAddGroupPermissions(),
342 serviceContext.isAddGuestPermissions());
343 }
344 else {
345 addMessageResources(
346 message, serviceContext.getGroupPermissions(),
347 serviceContext.getGuestPermissions());
348 }
349 }
350
351
352
353 updateAsset(
354 userId, message, serviceContext.getAssetCategoryIds(),
355 serviceContext.getAssetTagNames(),
356 serviceContext.getAssetLinkEntryIds(),
357 serviceContext.isAssetEntryVisible());
358
359
360
361 ExpandoBridge expandoBridge = message.getExpandoBridge();
362
363 expandoBridge.setAttributes(serviceContext);
364
365
366
367 WorkflowHandlerRegistryUtil.startWorkflowInstance(
368 user.getCompanyId(), groupId, userId,
369 message.getWorkflowClassName(), message.getMessageId(), message,
370 serviceContext);
371
372
373
374
377
378 return message;
379 }
380
381 public MBMessage addMessage(
382 long userId, String userName, long groupId, long categoryId,
383 String subject, String body, String format,
384 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
385 boolean anonymous, double priority, boolean allowPingbacks,
386 ServiceContext serviceContext)
387 throws PortalException, SystemException {
388
389 long threadId = 0;
390 long parentMessageId = 0;
391
392 return addMessage(
393 userId, userName, groupId, categoryId, threadId, parentMessageId,
394 subject, body, format, inputStreamOVPs, anonymous, priority,
395 allowPingbacks, serviceContext);
396 }
397
398 public MBMessage addMessage(
399 long userId, String userName, long categoryId, String subject,
400 String body, ServiceContext serviceContext)
401 throws PortalException, SystemException {
402
403 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
404 categoryId);
405
406 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
407 Collections.emptyList();
408
409 return addMessage(
410 userId, userName, category.getGroupId(), categoryId, 0, 0, subject,
411 body, MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false,
412 0.0, false, serviceContext);
413 }
414
415 public void addMessageResources(
416 long messageId, boolean addGroupPermissions,
417 boolean addGuestPermissions)
418 throws PortalException, SystemException {
419
420 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
421
422 addMessageResources(message, addGroupPermissions, addGuestPermissions);
423 }
424
425 public void addMessageResources(
426 long messageId, String[] groupPermissions,
427 String[] guestPermissions)
428 throws PortalException, SystemException {
429
430 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
431
432 addMessageResources(message, groupPermissions, guestPermissions);
433 }
434
435 public void addMessageResources(
436 MBMessage message, boolean addGroupPermissions,
437 boolean addGuestPermissions)
438 throws PortalException, SystemException {
439
440 resourceLocalService.addResources(
441 message.getCompanyId(), message.getGroupId(), message.getUserId(),
442 MBMessage.class.getName(), message.getMessageId(), false,
443 addGroupPermissions, addGuestPermissions);
444 }
445
446 public void addMessageResources(
447 MBMessage message, String[] groupPermissions,
448 String[] guestPermissions)
449 throws PortalException, SystemException {
450
451 resourceLocalService.addModelResources(
452 message.getCompanyId(), message.getGroupId(), message.getUserId(),
453 MBMessage.class.getName(), message.getMessageId(), groupPermissions,
454 guestPermissions);
455 }
456
457 @Indexable(type = IndexableType.DELETE)
458 public MBMessage deleteDiscussionMessage(long messageId)
459 throws PortalException, SystemException {
460
461 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
462
463 deleteDiscussionSocialActivities(BlogsEntry.class.getName(), message);
464
465 return deleteMessage(message);
466 }
467
468 public void deleteDiscussionMessages(String className, long classPK)
469 throws PortalException, SystemException {
470
471 try {
472 long classNameId = PortalUtil.getClassNameId(className);
473
474 MBDiscussion discussion = mbDiscussionPersistence.findByC_C(
475 classNameId, classPK);
476
477 List<MBMessage> messages = mbMessagePersistence.findByT_P(
478 discussion.getThreadId(),
479 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, 0, 1);
480
481 if (!messages.isEmpty()) {
482 MBMessage message = messages.get(0);
483
484 deleteDiscussionSocialActivities(
485 BlogsEntry.class.getName(), message);
486
487 mbThreadLocalService.deleteThread(message.getThreadId());
488 }
489
490 mbDiscussionPersistence.remove(discussion);
491 }
492 catch (NoSuchDiscussionException nsde) {
493 if (_log.isDebugEnabled()) {
494 _log.debug(nsde.getMessage());
495 }
496 }
497 }
498
499 @Indexable(type = IndexableType.DELETE)
500 public MBMessage deleteMessage(long messageId)
501 throws PortalException, SystemException {
502
503 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
504
505 return deleteMessage(message);
506 }
507
508 @Indexable(type = IndexableType.DELETE)
509 public MBMessage deleteMessage(MBMessage message)
510 throws PortalException, SystemException {
511
512
513
514 PortletFileRepositoryUtil.deleteFolder(
515 message.getAttachmentsFolderId());
516
517
518
519 int count = mbMessagePersistence.countByThreadId(message.getThreadId());
520
521 if (count == 1) {
522
523
524
525 PortletFileRepositoryUtil.deleteFolder(
526 message.getThreadAttachmentsFolderId());
527
528
529
530 subscriptionLocalService.deleteSubscriptions(
531 message.getCompanyId(), MBThread.class.getName(),
532 message.getThreadId());
533
534
535
536 mbThreadPersistence.remove(message.getThreadId());
537
538
539
540 if ((message.getCategoryId() !=
541 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
542 (message.getCategoryId() !=
543 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
544
545 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
546 message.getCategoryId());
547
548 category.setThreadCount(category.getThreadCount() - 1);
549 category.setMessageCount(category.getMessageCount() - 1);
550
551 mbCategoryPersistence.update(category);
552 }
553 }
554 else {
555 MBThread thread = mbThreadPersistence.findByPrimaryKey(
556 message.getThreadId());
557
558
559
560 if (thread.getRootMessageId() == message.getMessageId()) {
561 List<MBMessage> childrenMessages =
562 mbMessagePersistence.findByT_P(
563 message.getThreadId(), message.getMessageId());
564
565 if (childrenMessages.size() > 1) {
566 throw new RequiredMessageException(
567 String.valueOf(message.getMessageId()));
568 }
569 else if (childrenMessages.size() == 1) {
570 MBMessage childMessage = childrenMessages.get(0);
571
572 childMessage.setRootMessageId(childMessage.getMessageId());
573 childMessage.setParentMessageId(
574 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
575
576 mbMessagePersistence.update(childMessage);
577
578 List<MBMessage> repliesMessages =
579 mbMessagePersistence.findByThreadReplies(
580 message.getThreadId());
581
582 for (MBMessage repliesMessage : repliesMessages) {
583 repliesMessage.setRootMessageId(
584 childMessage.getMessageId());
585
586 mbMessagePersistence.update(repliesMessage);
587 }
588
589 thread.setRootMessageId(childMessage.getMessageId());
590 thread.setRootMessageUserId(childMessage.getUserId());
591
592 mbThreadPersistence.update(thread);
593 }
594 }
595
596
597
598 else {
599 List<MBMessage> childrenMessages =
600 mbMessagePersistence.findByT_P(
601 message.getThreadId(), message.getMessageId());
602
603
604
605 if (!childrenMessages.isEmpty()) {
606 for (MBMessage childMessage : childrenMessages) {
607 childMessage.setParentMessageId(
608 message.getParentMessageId());
609
610 mbMessagePersistence.update(childMessage);
611 }
612 }
613 else {
614 MessageCreateDateComparator comparator =
615 new MessageCreateDateComparator(true);
616
617 MBMessage lastMessage =
618 mbMessagePersistence.fetchByT_S_Last(
619 thread.getThreadId(),
620 WorkflowConstants.STATUS_APPROVED, comparator);
621
622 if ((lastMessage != null) &&
623 (message.getMessageId() ==
624 lastMessage.getMessageId())) {
625
626 MBMessage parentMessage =
627 mbMessagePersistence.findByPrimaryKey(
628 message.getParentMessageId());
629
630 thread.setLastPostByUserId(parentMessage.getUserId());
631 thread.setLastPostDate(parentMessage.getModifiedDate());
632 }
633 }
634 }
635
636
637
638 if (message.isApproved()) {
639 int messageCount = mbMessagePersistence.countByT_S(
640 message.getThreadId(), WorkflowConstants.STATUS_APPROVED);
641
642 thread.setMessageCount(messageCount - 1);
643 }
644
645 mbThreadPersistence.update(thread);
646
647
648
649 if ((message.getCategoryId() !=
650 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
651 (message.getCategoryId() !=
652 MBCategoryConstants.DISCUSSION_CATEGORY_ID) &&
653 !message.isDraft()) {
654
655 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
656 message.getCategoryId());
657
658 category.setMessageCount(category.getMessageCount() - 1);
659
660 mbCategoryPersistence.update(category);
661 }
662 }
663
664
665
666 assetEntryLocalService.deleteEntry(
667 message.getWorkflowClassName(), message.getMessageId());
668
669
670
671 expandoValueLocalService.deleteValues(
672 message.getWorkflowClassName(), message.getMessageId());
673
674
675
676 ratingsStatsLocalService.deleteStats(
677 message.getWorkflowClassName(), message.getMessageId());
678
679
680
681 if (!message.isDiscussion()) {
682 resourceLocalService.deleteResource(
683 message.getCompanyId(), message.getWorkflowClassName(),
684 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
685 }
686
687
688
689 mbMessagePersistence.remove(message);
690
691
692
693 if (!message.isDiscussion()) {
694 mbStatsUserLocalService.updateStatsUser(
695 message.getGroupId(), message.getUserId());
696 }
697
698
699
700 workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
701 message.getCompanyId(), message.getGroupId(),
702 message.getWorkflowClassName(), message.getMessageId());
703
704 return message;
705 }
706
707 public void deleteMessageAttachment(long messageId, String fileName)
708 throws PortalException, SystemException {
709
710 MBMessage message = getMessage(messageId);
711
712 PortletFileRepositoryUtil.deletePortletFileEntry(
713 message.getGroupId(), message.getAttachmentsFolderId(), fileName);
714 }
715
716 public void deleteMessageAttachments(long messageId)
717 throws PortalException, SystemException {
718
719 MBMessage message = getMessage(messageId);
720
721 PortletFileRepositoryUtil.deletePortletFileEntries(
722 message.getGroupId(), message.getAttachmentsFolderId());
723 }
724
725 public List<MBMessage> getCategoryMessages(
726 long groupId, long categoryId, int status, int start, int end)
727 throws SystemException {
728
729 if (status == WorkflowConstants.STATUS_ANY) {
730 return mbMessagePersistence.findByG_C(
731 groupId, categoryId, start, end);
732 }
733 else {
734 return mbMessagePersistence.findByG_C_S(
735 groupId, categoryId, status, start, end);
736 }
737 }
738
739 public List<MBMessage> getCategoryMessages(
740 long groupId, long categoryId, int status, int start, int end,
741 OrderByComparator obc)
742 throws SystemException {
743
744 if (status == WorkflowConstants.STATUS_ANY) {
745 return mbMessagePersistence.findByG_C(
746 groupId, categoryId, start, end, obc);
747 }
748 else {
749 return mbMessagePersistence.findByG_C_S(
750 groupId, categoryId, status, start, end, obc);
751 }
752 }
753
754 public int getCategoryMessagesCount(
755 long groupId, long categoryId, int status)
756 throws SystemException {
757
758 if (status == WorkflowConstants.STATUS_ANY) {
759 return mbMessagePersistence.countByG_C(groupId, categoryId);
760 }
761 else {
762 return mbMessagePersistence.countByG_C_S(
763 groupId, categoryId, status);
764 }
765 }
766
767 public List<MBMessage> getCompanyMessages(
768 long companyId, int status, int start, int end)
769 throws SystemException {
770
771 if (status == WorkflowConstants.STATUS_ANY) {
772 return mbMessagePersistence.findByCompanyId(companyId, start, end);
773 }
774 else {
775 return mbMessagePersistence.findByC_S(
776 companyId, status, start, end);
777 }
778 }
779
780 public List<MBMessage> getCompanyMessages(
781 long companyId, int status, int start, int end,
782 OrderByComparator obc)
783 throws SystemException {
784
785 if (status == WorkflowConstants.STATUS_ANY) {
786 return mbMessagePersistence.findByCompanyId(
787 companyId, start, end, obc);
788 }
789 else {
790 return mbMessagePersistence.findByC_S(
791 companyId, status, start, end, obc);
792 }
793 }
794
795 public int getCompanyMessagesCount(long companyId, int status)
796 throws SystemException {
797
798 if (status == WorkflowConstants.STATUS_ANY) {
799 return mbMessagePersistence.countByCompanyId(companyId);
800 }
801 else {
802 return mbMessagePersistence.countByC_S(companyId, status);
803 }
804 }
805
806 public MBMessageDisplay getDiscussionMessageDisplay(
807 long userId, long groupId, String className, long classPK,
808 int status)
809 throws PortalException, SystemException {
810
811 return getDiscussionMessageDisplay(
812 userId, groupId, className, classPK, status,
813 MBThreadConstants.THREAD_VIEW_COMBINATION);
814 }
815
816 public MBMessageDisplay getDiscussionMessageDisplay(
817 long userId, long groupId, String className, long classPK,
818 int status, String threadView)
819 throws PortalException, SystemException {
820
821 long classNameId = PortalUtil.getClassNameId(className);
822
823 MBMessage message = null;
824
825 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
826 classNameId, classPK);
827
828 if (discussion != null) {
829 List<MBMessage> messages = mbMessagePersistence.findByT_P(
830 discussion.getThreadId(),
831 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
832
833 message = messages.get(0);
834 }
835 else {
836 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
837
838 WorkflowThreadLocal.setEnabled(false);
839
840 try {
841 String subject = String.valueOf(classPK);
842
843
844 message = addDiscussionMessage(
845 userId, null, groupId, className, classPK, 0,
846 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, subject,
847 subject, new ServiceContext());
848 }
849 catch (SystemException se) {
850 if (_log.isWarnEnabled()) {
851 _log.warn(
852 "Add failed, fetch {threadId=0, parentMessageId=" +
853 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID + "}");
854 }
855
856 List<MBMessage> messages = mbMessagePersistence.findByT_P(
857 0, MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
858
859 if (messages.isEmpty()) {
860 throw se;
861 }
862
863 message = messages.get(0);
864 }
865 finally {
866 WorkflowThreadLocal.setEnabled(workflowEnabled);
867 }
868 }
869
870 return getMessageDisplay(userId, message, status, threadView, false);
871 }
872
873 public int getDiscussionMessagesCount(
874 long classNameId, long classPK, int status)
875 throws SystemException {
876
877 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
878 classNameId, classPK);
879
880 if (discussion == null) {
881 return 0;
882 }
883
884 int count = 0;
885
886 if (status == WorkflowConstants.STATUS_ANY) {
887 count = mbMessagePersistence.countByThreadId(
888 discussion.getThreadId());
889 }
890 else {
891 count = mbMessagePersistence.countByT_S(
892 discussion.getThreadId(), status);
893 }
894
895 if (count >= 1) {
896 return count - 1;
897 }
898 else {
899 return 0;
900 }
901 }
902
903 public int getDiscussionMessagesCount(
904 String className, long classPK, int status)
905 throws SystemException {
906
907 long classNameId = PortalUtil.getClassNameId(className);
908
909 return getDiscussionMessagesCount(classNameId, classPK, status);
910 }
911
912 public List<MBDiscussion> getDiscussions(String className)
913 throws SystemException {
914
915 long classNameId = PortalUtil.getClassNameId(className);
916
917 return mbDiscussionPersistence.findByClassNameId(classNameId);
918 }
919
920 public List<MBMessage> getGroupMessages(
921 long groupId, int status, int start, int end)
922 throws SystemException {
923
924 if (status == WorkflowConstants.STATUS_ANY) {
925 return mbMessagePersistence.findByGroupId(groupId, start, end);
926 }
927 else {
928 return mbMessagePersistence.findByG_S(groupId, status, start, end);
929 }
930 }
931
932 public List<MBMessage> getGroupMessages(
933 long groupId, int status, int start, int end, OrderByComparator obc)
934 throws SystemException {
935
936 if (status == WorkflowConstants.STATUS_ANY) {
937 return mbMessagePersistence.findByGroupId(groupId, start, end, obc);
938 }
939 else {
940 return mbMessagePersistence.findByG_S(
941 groupId, status, start, end, obc);
942 }
943 }
944
945 public List<MBMessage> getGroupMessages(
946 long groupId, long userId, int status, int start, int end)
947 throws SystemException {
948
949 if (status == WorkflowConstants.STATUS_ANY) {
950 return mbMessagePersistence.findByG_U(groupId, userId, start, end);
951 }
952 else {
953 return mbMessagePersistence.findByG_U_S(
954 groupId, userId, status, start, end);
955 }
956 }
957
958 public List<MBMessage> getGroupMessages(
959 long groupId, long userId, int status, int start, int end,
960 OrderByComparator obc)
961 throws SystemException {
962
963 if (status == WorkflowConstants.STATUS_ANY) {
964 return mbMessagePersistence.findByG_U(
965 groupId, userId, start, end, obc);
966 }
967 else {
968 return mbMessagePersistence.findByG_U_S(
969 groupId, userId, status, start, end, obc);
970 }
971 }
972
973 public int getGroupMessagesCount(long groupId, int status)
974 throws SystemException {
975
976 if (status == WorkflowConstants.STATUS_ANY) {
977 return mbMessagePersistence.countByGroupId(groupId);
978 }
979 else {
980 return mbMessagePersistence.countByG_S(groupId, status);
981 }
982 }
983
984 public int getGroupMessagesCount(long groupId, long userId, int status)
985 throws SystemException {
986
987 if (status == WorkflowConstants.STATUS_ANY) {
988 return mbMessagePersistence.countByG_U(groupId, userId);
989 }
990 else {
991 return mbMessagePersistence.countByG_U_S(groupId, userId, status);
992 }
993 }
994
995 public MBMessage getMessage(long messageId)
996 throws PortalException, SystemException {
997
998 return mbMessagePersistence.findByPrimaryKey(messageId);
999 }
1000
1001 public MBMessageDisplay getMessageDisplay(
1002 long userId, long messageId, int status, String threadView,
1003 boolean includePrevAndNext)
1004 throws PortalException, SystemException {
1005
1006 MBMessage message = getMessage(messageId);
1007
1008 return getMessageDisplay(
1009 userId, message, status, threadView, includePrevAndNext);
1010 }
1011
1012 public MBMessageDisplay getMessageDisplay(
1013 long userId, MBMessage message, int status, String threadView,
1014 boolean includePrevAndNext)
1015 throws PortalException, SystemException {
1016
1017 MBCategory category = null;
1018
1019 if ((message.getCategoryId() !=
1020 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1021 (message.getCategoryId() !=
1022 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1023
1024 category = mbCategoryPersistence.findByPrimaryKey(
1025 message.getCategoryId());
1026 }
1027 else {
1028 category = new MBCategoryImpl();
1029
1030 category.setCategoryId(message.getCategoryId());
1031 category.setDisplayStyle(MBCategoryConstants.DEFAULT_DISPLAY_STYLE);
1032 }
1033
1034 MBMessage parentMessage = null;
1035
1036 if (message.isReply()) {
1037 parentMessage = mbMessagePersistence.findByPrimaryKey(
1038 message.getParentMessageId());
1039 }
1040
1041 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1042 message.getThreadId());
1043
1044 if (message.isApproved() && !message.isDiscussion()) {
1045 mbThreadLocalService.incrementViewCounter(thread.getThreadId(), 1);
1046
1047 if (thread.getRootMessageUserId() != userId) {
1048 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
1049 thread.getRootMessageId());
1050
1051 socialActivityLocalService.addActivity(
1052 userId, rootMessage.getGroupId(), MBMessage.class.getName(),
1053 rootMessage.getMessageId(),
1054 SocialActivityConstants.TYPE_VIEW, StringPool.BLANK, 0);
1055 }
1056 }
1057
1058 MBThread previousThread = null;
1059 MBThread nextThread = null;
1060
1061 if (message.isApproved() && includePrevAndNext) {
1062 ThreadLastPostDateComparator comparator =
1063 new ThreadLastPostDateComparator(false);
1064
1065 MBThread[] prevAndNextThreads =
1066 mbThreadPersistence.findByG_C_PrevAndNext(
1067 message.getThreadId(), message.getGroupId(),
1068 message.getCategoryId(), comparator);
1069
1070 previousThread = prevAndNextThreads[0];
1071 nextThread = prevAndNextThreads[2];
1072 }
1073
1074 return new MBMessageDisplayImpl(
1075 message, parentMessage, category, thread, previousThread,
1076 nextThread, status, threadView, this);
1077 }
1078
1079 public List<MBMessage> getMessages(
1080 String className, long classPK, int status)
1081 throws SystemException {
1082
1083 long classNameId = PortalUtil.getClassNameId(className);
1084
1085 if (status == WorkflowConstants.STATUS_ANY) {
1086 return mbMessagePersistence.findByC_C(classNameId, classPK);
1087 }
1088 else {
1089 return mbMessagePersistence.findByC_C_S(
1090 classNameId, classPK, status);
1091 }
1092 }
1093
1094 public List<MBMessage> getNoAssetMessages() throws SystemException {
1095 return mbMessageFinder.findByNoAssets();
1096 }
1097
1098 public int getPositionInThread(long messageId)
1099 throws PortalException, SystemException {
1100
1101 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1102
1103 return mbMessageFinder.countByC_T(
1104 message.getCreateDate(), message.getThreadId());
1105 }
1106
1107 public List<MBMessage> getThreadMessages(long threadId, int status)
1108 throws SystemException {
1109
1110 return getThreadMessages(
1111 threadId, status, new MessageThreadComparator());
1112 }
1113
1114 public List<MBMessage> getThreadMessages(
1115 long threadId, int status, Comparator<MBMessage> comparator)
1116 throws SystemException {
1117
1118 List<MBMessage> messages = null;
1119
1120 if (status == WorkflowConstants.STATUS_ANY) {
1121 messages = mbMessagePersistence.findByThreadId(threadId);
1122 }
1123 else {
1124 messages = mbMessagePersistence.findByT_S(threadId, status);
1125 }
1126
1127 return ListUtil.sort(messages, comparator);
1128 }
1129
1130 public List<MBMessage> getThreadMessages(
1131 long threadId, int status, int start, int end)
1132 throws SystemException {
1133
1134 if (status == WorkflowConstants.STATUS_ANY) {
1135 return mbMessagePersistence.findByThreadId(threadId, start, end);
1136 }
1137 else {
1138 return mbMessagePersistence.findByT_S(threadId, status, start, end);
1139 }
1140 }
1141
1142 public int getThreadMessagesCount(long threadId, int status)
1143 throws SystemException {
1144
1145 if (status == WorkflowConstants.STATUS_ANY) {
1146 return mbMessagePersistence.countByThreadId(threadId);
1147 }
1148 else {
1149 return mbMessagePersistence.countByT_S(threadId, status);
1150 }
1151 }
1152
1153 public List<MBMessage> getThreadRepliesMessages(
1154 long threadId, int status, int start, int end)
1155 throws SystemException {
1156
1157 if (status == WorkflowConstants.STATUS_ANY) {
1158 return mbMessagePersistence.findByThreadReplies(
1159 threadId, start, end);
1160 }
1161 else {
1162 return mbMessagePersistence.findByTR_S(
1163 threadId, status, start, end);
1164 }
1165 }
1166
1167 public List<MBMessage> getUserDiscussionMessages(
1168 long userId, long classNameId, long classPK, int status, int start,
1169 int end, OrderByComparator obc)
1170 throws SystemException {
1171
1172 if (status == WorkflowConstants.STATUS_ANY) {
1173 return mbMessagePersistence.findByU_C_C(
1174 userId, classNameId, classPK, start, end, obc);
1175 }
1176 else {
1177 return mbMessagePersistence.findByU_C_C_S(
1178 userId, classNameId, classPK, status, start, end, obc);
1179 }
1180 }
1181
1182 public List<MBMessage> getUserDiscussionMessages(
1183 long userId, long[] classNameIds, int status, int start, int end,
1184 OrderByComparator obc)
1185 throws SystemException {
1186
1187 if (status == WorkflowConstants.STATUS_ANY) {
1188 return mbMessagePersistence.findByU_C(
1189 userId, classNameIds, start, end, obc);
1190 }
1191 else {
1192 return mbMessagePersistence.findByU_C_S(
1193 userId, classNameIds, status, start, end, obc);
1194 }
1195 }
1196
1197 public List<MBMessage> getUserDiscussionMessages(
1198 long userId, String className, long classPK, int status, int start,
1199 int end, OrderByComparator obc)
1200 throws SystemException {
1201
1202 long classNameId = PortalUtil.getClassNameId(className);
1203
1204 return getUserDiscussionMessages(
1205 userId, classNameId, classPK, status, start, end, obc);
1206 }
1207
1208 public int getUserDiscussionMessagesCount(
1209 long userId, long classNameId, long classPK, int status)
1210 throws SystemException {
1211
1212 if (status == WorkflowConstants.STATUS_ANY) {
1213 return mbMessagePersistence.countByU_C_C(
1214 userId, classNameId, classPK);
1215 }
1216 else {
1217 return mbMessagePersistence.countByU_C_C_S(
1218 userId, classNameId, classPK, status);
1219 }
1220 }
1221
1222 public int getUserDiscussionMessagesCount(
1223 long userId, long[] classNameIds, int status)
1224 throws SystemException {
1225
1226 if (status == WorkflowConstants.STATUS_ANY) {
1227 return mbMessagePersistence.countByU_C(userId, classNameIds);
1228 }
1229 else {
1230 return mbMessagePersistence.countByU_C_S(
1231 userId, classNameIds, status);
1232 }
1233 }
1234
1235 public int getUserDiscussionMessagesCount(
1236 long userId, String className, long classPK, int status)
1237 throws SystemException {
1238
1239 long classNameId = PortalUtil.getClassNameId(className);
1240
1241 return getUserDiscussionMessagesCount(
1242 userId, classNameId, classPK, status);
1243 }
1244
1245 public long moveMessageAttachmentToTrash(
1246 long userId, long messageId, String fileName)
1247 throws PortalException, SystemException {
1248
1249 MBMessage message = getMessage(messageId);
1250
1251 FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
1252 message.getGroupId(), message.getAttachmentsFolderId(), fileName);
1253
1254 PortletFileRepositoryUtil.movePortletFileEntryToTrash(
1255 userId, fileEntry.getFileEntryId());
1256
1257 return fileEntry.getFileEntryId();
1258 }
1259
1260 public void restoreMessageAttachmentFromTrash(
1261 long userId, long messageId, String deletedFileName)
1262 throws PortalException, SystemException {
1263
1264 MBMessage message = getMessage(messageId);
1265
1266 PortletFileRepositoryUtil.restorePortletFileEntryFromTrash(
1267 message.getGroupId(), userId, message.getAttachmentsFolderId(),
1268 deletedFileName);
1269 }
1270
1271 public void subscribeMessage(long userId, long messageId)
1272 throws PortalException, SystemException {
1273
1274 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1275
1276 subscriptionLocalService.addSubscription(
1277 userId, message.getGroupId(), MBThread.class.getName(),
1278 message.getThreadId());
1279 }
1280
1281 public void unsubscribeMessage(long userId, long messageId)
1282 throws PortalException, SystemException {
1283
1284 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1285
1286 subscriptionLocalService.deleteSubscription(
1287 userId, MBThread.class.getName(), message.getThreadId());
1288 }
1289
1290 public void updateAnswer(long messageId, boolean answer, boolean cascade)
1291 throws PortalException, SystemException {
1292
1293 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1294
1295 updateAnswer(message, answer, cascade);
1296 }
1297
1298 public void updateAnswer(MBMessage message, boolean answer, boolean cascade)
1299 throws PortalException, SystemException {
1300
1301 if (message.isAnswer() != answer) {
1302 message.setAnswer(answer);
1303
1304 mbMessagePersistence.update(message);
1305 }
1306
1307 if (cascade) {
1308 List<MBMessage> messages = mbMessagePersistence.findByT_P(
1309 message.getThreadId(), message.getMessageId());
1310
1311 for (MBMessage curMessage : messages) {
1312 updateAnswer(curMessage, answer, cascade);
1313 }
1314 }
1315 }
1316
1317 public void updateAsset(
1318 long userId, MBMessage message, long[] assetCategoryIds,
1319 String[] assetTagNames, long[] assetLinkEntryIds)
1320 throws PortalException, SystemException {
1321
1322 updateAsset(
1323 userId, message, assetCategoryIds, assetTagNames, assetLinkEntryIds,
1324 true);
1325 }
1326
1327 public MBMessage updateDiscussionMessage(
1328 long userId, long messageId, String className, long classPK,
1329 String subject, String body, ServiceContext serviceContext)
1330 throws PortalException, SystemException {
1331
1332 if (Validator.isNull(subject)) {
1333 if (Validator.isNotNull(body)) {
1334 int pos = Math.min(body.length(), 50);
1335
1336 subject = body.substring(0, pos) + "...";
1337 }
1338 else {
1339 throw new MessageBodyException();
1340 }
1341 }
1342
1343 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
1344 Collections.emptyList();
1345 List<String> existingFiles = new ArrayList<String>();
1346 double priority = 0.0;
1347 boolean allowPingbacks = false;
1348
1349 serviceContext.setAttribute("className", className);
1350 serviceContext.setAttribute("classPK", String.valueOf(classPK));
1351
1352 return updateMessage(
1353 userId, messageId, subject, body, inputStreamOVPs, existingFiles,
1354 priority, allowPingbacks, serviceContext);
1355 }
1356
1357 public MBMessage updateMessage(
1358 long userId, long messageId, String subject, String body,
1359 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
1360 List<String> existingFiles, double priority, boolean allowPingbacks,
1361 ServiceContext serviceContext)
1362 throws PortalException, SystemException {
1363
1364
1365
1366 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1367
1368 int oldStatus = message.getStatus();
1369
1370 Date modifiedDate = serviceContext.getModifiedDate(new Date());
1371 subject = ModelHintsUtil.trimString(
1372 MBMessage.class.getName(), "subject", subject);
1373 body = SanitizerUtil.sanitize(
1374 message.getCompanyId(), message.getGroupId(), userId,
1375 MBMessage.class.getName(), messageId, "text/" + message.getFormat(),
1376 body);
1377
1378 validate(subject, body);
1379
1380 subject = getSubject(subject, body);
1381 body = getBody(subject, body);
1382
1383 message.setModifiedDate(modifiedDate);
1384 message.setSubject(subject);
1385 message.setBody(body);
1386 message.setAllowPingbacks(allowPingbacks);
1387
1388 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
1389 message.setPriority(priority);
1390 }
1391
1392 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1393 message.getThreadId());
1394
1395 if (serviceContext.getWorkflowAction() ==
1396 WorkflowConstants.ACTION_SAVE_DRAFT) {
1397
1398 if (!message.isDraft() && !message.isPending()) {
1399 message.setStatus(WorkflowConstants.STATUS_DRAFT);
1400
1401
1402
1403 User user = userPersistence.findByPrimaryKey(userId);
1404
1405 updateThreadStatus(
1406 thread, message, user, oldStatus, modifiedDate);
1407
1408
1409
1410 assetEntryLocalService.updateVisible(
1411 message.getWorkflowClassName(), message.getMessageId(),
1412 false);
1413
1414 if (!message.isDiscussion()) {
1415
1416
1417
1418 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1419 MBMessage.class);
1420
1421 indexer.delete(message);
1422 }
1423 }
1424 }
1425
1426
1427
1428 if (!inputStreamOVPs.isEmpty() || !existingFiles.isEmpty()) {
1429 List<FileEntry> fileEntries = message.getAttachmentsFileEntries();
1430
1431 for (FileEntry fileEntry : fileEntries) {
1432 if (!existingFiles.contains(fileEntry.getTitle())) {
1433 if (!TrashUtil.isTrashEnabled(message.getGroupId())) {
1434 deleteMessageAttachment(
1435 messageId, fileEntry.getTitle());
1436 }
1437 else {
1438 moveMessageAttachmentToTrash(
1439 userId, messageId, fileEntry.getTitle());
1440 }
1441 }
1442 }
1443
1444 PortletFileRepositoryUtil.addPortletFileEntries(
1445 message.getGroupId(), userId, PortletKeys.MESSAGE_BOARDS,
1446 message.getAttachmentsFolderId(), inputStreamOVPs);
1447 }
1448 else {
1449 if (TrashUtil.isTrashEnabled(message.getGroupId())) {
1450 List<FileEntry> fileEntries =
1451 message.getAttachmentsFileEntries();
1452
1453 for (FileEntry fileEntry : fileEntries) {
1454 moveMessageAttachmentToTrash(
1455 userId, messageId, fileEntry.getTitle());
1456 }
1457 }
1458 }
1459
1460 mbMessagePersistence.update(message);
1461
1462
1463
1464 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
1465 (thread.getPriority() != priority)) {
1466
1467 thread.setPriority(priority);
1468
1469 mbThreadPersistence.update(thread);
1470
1471 updatePriorities(thread.getThreadId(), priority);
1472 }
1473
1474
1475
1476 updateAsset(
1477 userId, message, serviceContext.getAssetCategoryIds(),
1478 serviceContext.getAssetTagNames(),
1479 serviceContext.getAssetLinkEntryIds());
1480
1481
1482
1483 ExpandoBridge expandoBridge = message.getExpandoBridge();
1484
1485 expandoBridge.setAttributes(serviceContext);
1486
1487
1488
1489 WorkflowHandlerRegistryUtil.startWorkflowInstance(
1490 message.getCompanyId(), message.getGroupId(), userId,
1491 message.getWorkflowClassName(), message.getMessageId(), message,
1492 serviceContext);
1493
1494 return message;
1495 }
1496
1497 public MBMessage updateMessage(long messageId, String body)
1498 throws PortalException, SystemException {
1499
1500 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1501
1502 message.setBody(body);
1503
1504 mbMessagePersistence.update(message);
1505
1506 return message;
1507 }
1508
1509 public MBMessage updateStatus(
1510 long userId, long messageId, int status,
1511 ServiceContext serviceContext)
1512 throws PortalException, SystemException {
1513
1514
1515
1516 MBMessage message = getMessage(messageId);
1517
1518 int oldStatus = message.getStatus();
1519
1520 User user = userPersistence.findByPrimaryKey(userId);
1521 Date now = new Date();
1522
1523 Date modifiedDate = serviceContext.getModifiedDate(now);
1524
1525 message.setStatus(status);
1526 message.setStatusByUserId(userId);
1527 message.setStatusByUserName(user.getFullName());
1528 message.setStatusDate(modifiedDate);
1529
1530 mbMessagePersistence.update(message);
1531
1532
1533
1534 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1535 message.getThreadId());
1536
1537 updateThreadStatus(thread, message, user, oldStatus, modifiedDate);
1538
1539 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1540 MBMessage.class);
1541
1542 if (status == WorkflowConstants.STATUS_APPROVED) {
1543 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
1544
1545
1546
1547 if (serviceContext.isAssetEntryVisible() &&
1548 ((message.getClassNameId() == 0) ||
1549 (message.getParentMessageId() != 0))) {
1550
1551 Date publishDate = null;
1552
1553 AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
1554 message.getWorkflowClassName(), message.getMessageId());
1555
1556 if ((assetEntry != null) &&
1557 (assetEntry.getPublishDate() != null)) {
1558
1559 publishDate = assetEntry.getPublishDate();
1560 }
1561 else {
1562 publishDate = now;
1563
1564 serviceContext.setCommand(Constants.ADD);
1565 }
1566
1567 assetEntryLocalService.updateEntry(
1568 message.getWorkflowClassName(), message.getMessageId(),
1569 publishDate, true);
1570 }
1571
1572 if (serviceContext.isCommandAdd()) {
1573
1574
1575
1576 JSONObject extraDataJSONObject =
1577 JSONFactoryUtil.createJSONObject();
1578
1579 extraDataJSONObject.put("title", message.getSubject());
1580
1581 if (!message.isDiscussion() ) {
1582 if (!message.isAnonymous() && !user.isDefaultUser()) {
1583 long receiverUserId = 0;
1584
1585 MBMessage parentMessage =
1586 mbMessagePersistence.fetchByPrimaryKey(
1587 message.getParentMessageId());
1588
1589 if (parentMessage != null) {
1590 receiverUserId = parentMessage.getUserId();
1591 }
1592
1593 socialActivityLocalService.addActivity(
1594 userId, message.getGroupId(),
1595 MBMessage.class.getName(),
1596 message.getMessageId(),
1597 MBActivityKeys.ADD_MESSAGE,
1598 extraDataJSONObject.toString(), receiverUserId);
1599
1600 if ((parentMessage != null) &&
1601 (receiverUserId != userId)) {
1602
1603 socialActivityLocalService.addActivity(
1604 userId, parentMessage.getGroupId(),
1605 MBMessage.class.getName(),
1606 parentMessage.getMessageId(),
1607 MBActivityKeys.REPLY_MESSAGE,
1608 extraDataJSONObject.toString(), 0);
1609 }
1610 }
1611 }
1612 else {
1613 String className = (String)serviceContext.getAttribute(
1614 "className");
1615 long classPK = ParamUtil.getLong(
1616 serviceContext, "classPK");
1617 long parentMessageId = message.getParentMessageId();
1618
1619 if (parentMessageId !=
1620 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
1621
1622 AssetEntry assetEntry =
1623 assetEntryLocalService.fetchEntry(
1624 className, classPK);
1625
1626 if (assetEntry != null) {
1627 extraDataJSONObject.put(
1628 "messageId", message.getMessageId());
1629
1630 socialActivityLocalService.addActivity(
1631 userId, assetEntry.getGroupId(), className,
1632 classPK,
1633 SocialActivityConstants.TYPE_ADD_COMMENT,
1634 extraDataJSONObject.toString(),
1635 assetEntry.getUserId());
1636 }
1637 }
1638 }
1639 }
1640 }
1641
1642
1643
1644 notifySubscribers((MBMessage)message.clone(), serviceContext);
1645
1646
1647
1648 if (!message.isDiscussion()) {
1649 indexer.reindex(message);
1650 }
1651
1652
1653
1654 pingPingback(message, serviceContext);
1655 }
1656 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
1657
1658
1659
1660 assetEntryLocalService.updateVisible(
1661 message.getWorkflowClassName(), message.getMessageId(), false);
1662
1663 if (!message.isDiscussion()) {
1664
1665
1666
1667 indexer.delete(message);
1668 }
1669 }
1670
1671
1672
1673 if (!message.isDiscussion()) {
1674 mbStatsUserLocalService.updateStatsUser(
1675 message.getGroupId(), userId,
1676 serviceContext.getModifiedDate(now));
1677 }
1678
1679 return message;
1680 }
1681
1682 public void updateUserName(long userId, String userName)
1683 throws SystemException {
1684
1685 List<MBMessage> messages = mbMessagePersistence.findByUserId(userId);
1686
1687 for (MBMessage message : messages) {
1688 message.setUserName(userName);
1689
1690 mbMessagePersistence.update(message);
1691 }
1692 }
1693
1694 protected void deleteDiscussionSocialActivities(
1695 String className, MBMessage message)
1696 throws PortalException, SystemException {
1697
1698 MBDiscussion discussion = mbDiscussionPersistence.findByThreadId(
1699 message.getThreadId());
1700
1701 long classNameId = PortalUtil.getClassNameId(className);
1702 long classPK = discussion.getClassPK();
1703
1704 if (discussion.getClassNameId() != classNameId) {
1705 return;
1706 }
1707
1708 List<SocialActivity> socialActivities =
1709 socialActivityLocalService.getActivities(
1710 0, className, classPK, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1711
1712 for (SocialActivity socialActivity : socialActivities) {
1713 if (Validator.isNull(socialActivity.getExtraData())) {
1714 continue;
1715 }
1716
1717 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
1718 socialActivity.getExtraData());
1719
1720 long extraDataMessageId = extraDataJSONObject.getLong("messageId");
1721
1722 if (message.getMessageId() == extraDataMessageId) {
1723 socialActivityLocalService.deleteActivity(
1724 socialActivity.getActivityId());
1725 }
1726 }
1727 }
1728
1729 protected String getBody(String subject, String body) {
1730 if (Validator.isNull(body)) {
1731 return subject;
1732 }
1733
1734 return body;
1735 }
1736
1737 protected String getSubject(String subject, String body) {
1738 if (Validator.isNull(subject)) {
1739 return StringUtil.shorten(body);
1740 }
1741
1742 return subject;
1743 }
1744
1745 protected void notifyDiscussionSubscribers(
1746 MBMessage message, ServiceContext serviceContext)
1747 throws SystemException {
1748
1749 if (!PrefsPropsUtil.getBoolean(
1750 message.getCompanyId(),
1751 PropsKeys.DISCUSSION_EMAIL_COMMENTS_ADDED_ENABLED)) {
1752
1753 return;
1754 }
1755
1756 String contentURL = (String)serviceContext.getAttribute("contentURL");
1757
1758 String userAddress = StringPool.BLANK;
1759 String userName = (String)serviceContext.getAttribute(
1760 "pingbackUserName");
1761
1762 if (Validator.isNull(userName)) {
1763 userAddress = PortalUtil.getUserEmailAddress(message.getUserId());
1764 userName = PortalUtil.getUserName(
1765 message.getUserId(), StringPool.BLANK);
1766 }
1767
1768 String fromName = PrefsPropsUtil.getString(
1769 message.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
1770 String fromAddress = PrefsPropsUtil.getString(
1771 message.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
1772
1773 String subject = PrefsPropsUtil.getContent(
1774 message.getCompanyId(), PropsKeys.DISCUSSION_EMAIL_SUBJECT);
1775 String body = PrefsPropsUtil.getContent(
1776 message.getCompanyId(), PropsKeys.DISCUSSION_EMAIL_BODY);
1777
1778 SubscriptionSender subscriptionSender = new SubscriptionSender();
1779
1780 subscriptionSender.setBody(body);
1781 subscriptionSender.setCompanyId(message.getCompanyId());
1782 subscriptionSender.setContextAttribute(
1783 "[$COMMENTS_BODY$]", message.getBody(true), false);
1784 subscriptionSender.setContextAttributes(
1785 "[$COMMENTS_USER_ADDRESS$]", userAddress, "[$COMMENTS_USER_NAME$]",
1786 userName, "[$CONTENT_URL$]", contentURL);
1787 subscriptionSender.setFrom(fromAddress, fromName);
1788 subscriptionSender.setHtmlFormat(true);
1789 subscriptionSender.setMailId(
1790 "mb_discussion", message.getCategoryId(), message.getMessageId());
1791 subscriptionSender.setScopeGroupId(message.getGroupId());
1792 subscriptionSender.setServiceContext(serviceContext);
1793 subscriptionSender.setSubject(subject);
1794 subscriptionSender.setUserId(message.getUserId());
1795
1796 String className = (String)serviceContext.getAttribute("className");
1797 long classPK = ParamUtil.getLong(serviceContext, "classPK");
1798
1799 subscriptionSender.addPersistedSubscribers(className, classPK);
1800
1801 subscriptionSender.flushNotificationsAsync();
1802 }
1803
1804 protected void notifySubscribers(
1805 MBMessage message, ServiceContext serviceContext)
1806 throws PortalException, SystemException {
1807
1808 String layoutFullURL = serviceContext.getLayoutFullURL();
1809
1810 if (!message.isApproved() || Validator.isNull(layoutFullURL)) {
1811 return;
1812 }
1813
1814 if (message.isDiscussion()) {
1815 try {
1816 notifyDiscussionSubscribers(message, serviceContext);
1817 }
1818 catch (Exception e) {
1819 _log.error(e, e);
1820 }
1821
1822 return;
1823 }
1824
1825 PortletPreferences preferences =
1826 ServiceContextUtil.getPortletPreferences(serviceContext);
1827
1828 if (preferences == null) {
1829 long ownerId = message.getGroupId();
1830 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1831 long plid = PortletKeys.PREFS_PLID_SHARED;
1832 String portletId = PortletKeys.MESSAGE_BOARDS;
1833 String defaultPreferences = null;
1834
1835 preferences = portletPreferencesLocalService.getPreferences(
1836 message.getCompanyId(), ownerId, ownerType, plid, portletId,
1837 defaultPreferences);
1838 }
1839
1840 if (serviceContext.isCommandAdd() &&
1841 MBUtil.getEmailMessageAddedEnabled(preferences)) {
1842 }
1843 else if (serviceContext.isCommandUpdate() &&
1844 MBUtil.getEmailMessageUpdatedEnabled(preferences)) {
1845 }
1846 else {
1847 return;
1848 }
1849
1850 Company company = companyPersistence.findByPrimaryKey(
1851 message.getCompanyId());
1852
1853 Group group = groupPersistence.findByPrimaryKey(message.getGroupId());
1854
1855 String emailAddress = PortalUtil.getUserEmailAddress(
1856 message.getUserId());
1857 String fullName = PortalUtil.getUserName(
1858 message.getUserId(), message.getUserName());
1859
1860 if (message.isAnonymous()) {
1861 emailAddress = StringPool.BLANK;
1862 fullName = serviceContext.translate("anonymous");
1863 }
1864
1865 MBCategory category = message.getCategory();
1866
1867 String categoryName = category.getName();
1868
1869 if (category.getCategoryId() ==
1870 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
1871
1872 categoryName = serviceContext.translate("message-boards-home");
1873
1874 categoryName += " - " + group.getDescriptiveName();
1875 }
1876
1877 List<Long> categoryIds = new ArrayList<Long>();
1878
1879 categoryIds.add(message.getCategoryId());
1880
1881 if (message.getCategoryId() !=
1882 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
1883
1884 categoryIds.addAll(category.getAncestorCategoryIds());
1885 }
1886
1887 String messageURL =
1888 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
1889 "message_boards/view_message/" + message.getMessageId();
1890
1891 String fromName = MBUtil.getEmailFromName(
1892 preferences, message.getCompanyId());
1893 String fromAddress = MBUtil.getEmailFromAddress(
1894 preferences, message.getCompanyId());
1895
1896 String mailingListAddress = StringPool.BLANK;
1897
1898 if (PropsValues.POP_SERVER_NOTIFICATIONS_ENABLED) {
1899 mailingListAddress = MBUtil.getMailingListAddress(
1900 message.getGroupId(), message.getCategoryId(),
1901 message.getMessageId(), company.getMx(), fromAddress);
1902 }
1903
1904 String subjectPrefix = null;
1905 String body = null;
1906 String signature = null;
1907
1908 if (serviceContext.isCommandUpdate()) {
1909 subjectPrefix = MBUtil.getEmailMessageUpdatedSubjectPrefix(
1910 preferences);
1911 body = MBUtil.getEmailMessageUpdatedBody(preferences);
1912 signature = MBUtil.getEmailMessageUpdatedSignature(preferences);
1913 }
1914 else {
1915 subjectPrefix = MBUtil.getEmailMessageAddedSubjectPrefix(
1916 preferences);
1917 body = MBUtil.getEmailMessageAddedBody(preferences);
1918 signature = MBUtil.getEmailMessageAddedSignature(preferences);
1919 }
1920
1921 if (!subjectPrefix.contains("[$MESSAGE_SUBJECT$]")) {
1922 String subject = message.getSubject();
1923
1924 subject = subjectPrefix.trim() + StringPool.SPACE + subject.trim();
1925
1926 message.setSubject(subject);
1927 }
1928
1929 boolean htmlFormat = MBUtil.getEmailHtmlFormat(preferences);
1930
1931 if (Validator.isNotNull(signature)) {
1932 String signatureSeparator = null;
1933
1934 if (htmlFormat) {
1935 signatureSeparator = "<br />--<br />";
1936 }
1937 else {
1938 signatureSeparator = "\n--\n";
1939 }
1940
1941 body += signatureSeparator + signature;
1942 }
1943
1944 String messageBody = message.getBody();
1945
1946 if (htmlFormat && message.isFormatBBCode()) {
1947 try {
1948 messageBody = BBCodeTranslatorUtil.getHTML(messageBody);
1949
1950 HttpServletRequest request = serviceContext.getRequest();
1951
1952 if (request != null) {
1953 ThemeDisplay themeDisplay =
1954 (ThemeDisplay)request.getAttribute(
1955 WebKeys.THEME_DISPLAY);
1956
1957 messageBody = MBUtil.replaceMessageBodyPaths(
1958 themeDisplay, messageBody);
1959 }
1960 }
1961 catch (Exception e) {
1962 _log.error(
1963 "Could not parse message " + message.getMessageId() +
1964 " " + e.getMessage());
1965 }
1966 }
1967
1968 String inReplyTo = null;
1969
1970 if (message.getParentMessageId() !=
1971 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
1972
1973 inReplyTo = PortalUtil.getMailId(
1974 company.getMx(), MBUtil.MESSAGE_POP_PORTLET_PREFIX,
1975 message.getCategoryId(), message.getParentMessageId());
1976 }
1977
1978 SubscriptionSender subscriptionSenderPrototype =
1979 new MBSubscriptionSender();
1980
1981 subscriptionSenderPrototype.setBody(body);
1982 subscriptionSenderPrototype.setBulk(
1983 PropsValues.MESSAGE_BOARDS_EMAIL_BULK);
1984 subscriptionSenderPrototype.setCompanyId(message.getCompanyId());
1985 subscriptionSenderPrototype.setContextAttribute(
1986 "[$MESSAGE_BODY$]", messageBody, false);
1987 subscriptionSenderPrototype.setContextAttributes(
1988 "[$CATEGORY_NAME$]", categoryName, "[$MAILING_LIST_ADDRESS$]",
1989 mailingListAddress, "[$MESSAGE_ID$]", message.getMessageId(),
1990 "[$MESSAGE_SUBJECT$]", message.getSubject(), "[$MESSAGE_URL$]",
1991 messageURL, "[$MESSAGE_USER_ADDRESS$]", emailAddress,
1992 "[$MESSAGE_USER_NAME$]", fullName);
1993 subscriptionSenderPrototype.setFrom(fromAddress, fromName);
1994 subscriptionSenderPrototype.setHtmlFormat(htmlFormat);
1995 subscriptionSenderPrototype.setInReplyTo(inReplyTo);
1996 subscriptionSenderPrototype.setMailId(
1997 MBUtil.MESSAGE_POP_PORTLET_PREFIX, message.getCategoryId(),
1998 message.getMessageId());
1999 subscriptionSenderPrototype.setPortletId(PortletKeys.MESSAGE_BOARDS);
2000 subscriptionSenderPrototype.setReplyToAddress(mailingListAddress);
2001 subscriptionSenderPrototype.setScopeGroupId(message.getGroupId());
2002 subscriptionSenderPrototype.setServiceContext(serviceContext);
2003 subscriptionSenderPrototype.setSubject(message.getSubject());
2004 subscriptionSenderPrototype.setUserId(message.getUserId());
2005
2006 SubscriptionSender subscriptionSender =
2007 (SubscriptionSender)SerializableUtil.clone(
2008 subscriptionSenderPrototype);
2009
2010 subscriptionSender.addPersistedSubscribers(
2011 MBCategory.class.getName(), message.getGroupId());
2012
2013 for (long categoryId : categoryIds) {
2014 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2015 subscriptionSender.addPersistedSubscribers(
2016 MBCategory.class.getName(), categoryId);
2017 }
2018 }
2019
2020 subscriptionSender.addPersistedSubscribers(
2021 MBThread.class.getName(), message.getThreadId());
2022
2023 subscriptionSender.flushNotificationsAsync();
2024
2025 if (!MailingListThreadLocal.isSourceMailingList()) {
2026 for (long categoryId : categoryIds) {
2027 MBSubscriptionSender sourceMailingListSubscriptionSender =
2028 (MBSubscriptionSender)SerializableUtil.clone(
2029 subscriptionSenderPrototype);
2030
2031 sourceMailingListSubscriptionSender.setBulk(false);
2032
2033 sourceMailingListSubscriptionSender.addMailingListSubscriber(
2034 message.getGroupId(), categoryId);
2035
2036 sourceMailingListSubscriptionSender.flushNotificationsAsync();
2037 }
2038 }
2039 }
2040
2041 protected void pingPingback(
2042 MBMessage message, ServiceContext serviceContext) {
2043
2044 if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
2045 !message.isAllowPingbacks() || !message.isApproved()) {
2046
2047 return;
2048 }
2049
2050 String layoutFullURL = serviceContext.getLayoutFullURL();
2051
2052 if (Validator.isNull(layoutFullURL)) {
2053 return;
2054 }
2055
2056 String sourceUri =
2057 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
2058 "message_boards/view_message/" + message.getMessageId();
2059
2060 Source source = new Source(message.getBody(true));
2061
2062 List<StartTag> startTags = source.getAllStartTags("a");
2063
2064 for (StartTag startTag : startTags) {
2065 String targetUri = startTag.getAttributeValue("href");
2066
2067 if (Validator.isNotNull(targetUri)) {
2068 try {
2069 LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
2070 }
2071 catch (Exception e) {
2072 _log.error("Error while sending pingback " + targetUri, e);
2073 }
2074 }
2075 }
2076 }
2077
2078 protected void updateAsset(
2079 long userId, MBMessage message, long[] assetCategoryIds,
2080 String[] assetTagNames, long[] assetLinkEntryIds,
2081 boolean assetEntryVisible)
2082 throws PortalException, SystemException {
2083
2084 boolean visible = false;
2085
2086 if (assetEntryVisible && message.isApproved() &&
2087 ((message.getClassNameId() == 0) ||
2088 (message.getParentMessageId() != 0))) {
2089
2090 visible = true;
2091 }
2092
2093 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
2094 userId, message.getGroupId(), message.getCreateDate(),
2095 message.getModifiedDate(), message.getWorkflowClassName(),
2096 message.getMessageId(), message.getUuid(), 0, assetCategoryIds,
2097 assetTagNames, visible, null, null, null, ContentTypes.TEXT_HTML,
2098 message.getSubject(), null, null, null, null, 0, 0, null, false);
2099
2100 assetLinkLocalService.updateLinks(
2101 userId, assetEntry.getEntryId(), assetLinkEntryIds,
2102 AssetLinkConstants.TYPE_RELATED);
2103 }
2104
2105 protected void updatePriorities(long threadId, double priority)
2106 throws SystemException {
2107
2108 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
2109 threadId);
2110
2111 for (MBMessage message : messages) {
2112 if (message.getPriority() != priority) {
2113 message.setPriority(priority);
2114
2115 mbMessagePersistence.update(message);
2116 }
2117 }
2118 }
2119
2120 protected void updateThreadStatus(
2121 MBThread thread, MBMessage message, User user, int oldStatus,
2122 Date modifiedDate)
2123 throws PortalException, SystemException {
2124
2125 MBCategory category = null;
2126
2127 int status = message.getStatus();
2128
2129 if ((thread.getCategoryId() !=
2130 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
2131 (thread.getCategoryId() !=
2132 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
2133
2134 category = mbCategoryPersistence.findByPrimaryKey(
2135 thread.getCategoryId());
2136 }
2137
2138 if ((thread.getRootMessageId() == message.getMessageId()) &&
2139 (oldStatus != status)) {
2140
2141 thread.setStatus(status);
2142 thread.setStatusByUserId(user.getUserId());
2143 thread.setStatusByUserName(user.getFullName());
2144 thread.setStatusDate(modifiedDate);
2145 }
2146
2147 if ((status == WorkflowConstants.STATUS_APPROVED) &&
2148 (oldStatus != WorkflowConstants.STATUS_APPROVED)) {
2149
2150
2151
2152 if ((category != null) &&
2153 (thread.getRootMessageId() == message.getMessageId())) {
2154
2155 category.setThreadCount(category.getThreadCount() + 1);
2156
2157 mbCategoryPersistence.update(category);
2158 }
2159
2160 thread.setMessageCount(thread.getMessageCount() + 1);
2161
2162 if (message.isAnonymous()) {
2163 thread.setLastPostByUserId(0);
2164 }
2165 else {
2166 thread.setLastPostByUserId(message.getUserId());
2167 }
2168
2169 thread.setLastPostDate(modifiedDate);
2170
2171
2172
2173 if (category != null) {
2174 category.setMessageCount(category.getMessageCount() + 1);
2175 category.setLastPostDate(modifiedDate);
2176
2177 mbCategoryPersistence.update(category);
2178 }
2179 }
2180 else if ((oldStatus == WorkflowConstants.STATUS_APPROVED) &&
2181 (status != WorkflowConstants.STATUS_APPROVED)) {
2182
2183
2184
2185 if ((category != null) &&
2186 (thread.getRootMessageId() == message.getMessageId())) {
2187
2188 category.setThreadCount(category.getThreadCount() - 1);
2189
2190 mbCategoryPersistence.update(category);
2191 }
2192
2193 thread.setMessageCount(thread.getMessageCount() - 1);
2194
2195
2196
2197 if (category != null) {
2198 category.setMessageCount(category.getMessageCount() - 1);
2199
2200 mbCategoryPersistence.update(category);
2201 }
2202 }
2203
2204 if (status != oldStatus) {
2205 mbThreadPersistence.update(thread);
2206 }
2207 }
2208
2209 protected void validate(String subject, String body)
2210 throws PortalException {
2211
2212 if (Validator.isNull(subject) && Validator.isNull(body)) {
2213 throw new MessageSubjectException();
2214 }
2215 }
2216
2217 private static Log _log = LogFactoryUtil.getLog(
2218 MBMessageLocalServiceImpl.class);
2219
2220 }