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