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