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