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