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