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