1
14
15 package com.liferay.portlet.messageboards.service.impl;
16
17 import com.liferay.documentlibrary.DuplicateDirectoryException;
18 import com.liferay.documentlibrary.DuplicateFileException;
19 import com.liferay.documentlibrary.NoSuchDirectoryException;
20 import com.liferay.portal.NoSuchUserException;
21 import com.liferay.portal.kernel.dao.orm.QueryUtil;
22 import com.liferay.portal.kernel.exception.PortalException;
23 import com.liferay.portal.kernel.exception.SystemException;
24 import com.liferay.portal.kernel.json.JSONFactoryUtil;
25 import com.liferay.portal.kernel.json.JSONObject;
26 import com.liferay.portal.kernel.language.LanguageUtil;
27 import com.liferay.portal.kernel.log.Log;
28 import com.liferay.portal.kernel.log.LogFactoryUtil;
29 import com.liferay.portal.kernel.mail.MailMessage;
30 import com.liferay.portal.kernel.messaging.DestinationNames;
31 import com.liferay.portal.kernel.messaging.MessageBusUtil;
32 import com.liferay.portal.kernel.search.Indexer;
33 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
34 import com.liferay.portal.kernel.util.ContentTypes;
35 import com.liferay.portal.kernel.util.GetterUtil;
36 import com.liferay.portal.kernel.util.ListUtil;
37 import com.liferay.portal.kernel.util.LocaleUtil;
38 import com.liferay.portal.kernel.util.ObjectValuePair;
39 import com.liferay.portal.kernel.util.OrderByComparator;
40 import com.liferay.portal.kernel.util.PropsKeys;
41 import com.liferay.portal.kernel.util.StringPool;
42 import com.liferay.portal.kernel.util.StringUtil;
43 import com.liferay.portal.kernel.util.Validator;
44 import com.liferay.portal.kernel.workflow.WorkflowConstants;
45 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
46 import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
47 import com.liferay.portal.model.Company;
48 import com.liferay.portal.model.CompanyConstants;
49 import com.liferay.portal.model.Group;
50 import com.liferay.portal.model.GroupConstants;
51 import com.liferay.portal.model.ModelHintsUtil;
52 import com.liferay.portal.model.ResourceConstants;
53 import com.liferay.portal.model.User;
54 import com.liferay.portal.security.auth.PrincipalException;
55 import com.liferay.portal.security.permission.ActionKeys;
56 import com.liferay.portal.service.ServiceContext;
57 import com.liferay.portal.service.ServiceContextUtil;
58 import com.liferay.portal.util.Portal;
59 import com.liferay.portal.util.PortalUtil;
60 import com.liferay.portal.util.PortletKeys;
61 import com.liferay.portal.util.PrefsPropsUtil;
62 import com.liferay.portal.util.PropsValues;
63 import com.liferay.portlet.blogs.model.BlogsEntry;
64 import com.liferay.portlet.blogs.social.BlogsActivityKeys;
65 import com.liferay.portlet.blogs.util.LinkbackProducerUtil;
66 import com.liferay.portlet.expando.model.ExpandoBridge;
67 import com.liferay.portlet.messageboards.MessageBodyException;
68 import com.liferay.portlet.messageboards.MessageSubjectException;
69 import com.liferay.portlet.messageboards.NoSuchDiscussionException;
70 import com.liferay.portlet.messageboards.RequiredMessageException;
71 import com.liferay.portlet.messageboards.model.MBCategory;
72 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
73 import com.liferay.portlet.messageboards.model.MBDiscussion;
74 import com.liferay.portlet.messageboards.model.MBMessage;
75 import com.liferay.portlet.messageboards.model.MBMessageConstants;
76 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
77 import com.liferay.portlet.messageboards.model.MBThread;
78 import com.liferay.portlet.messageboards.model.MBThreadConstants;
79 import com.liferay.portlet.messageboards.model.impl.MBMessageDisplayImpl;
80 import com.liferay.portlet.messageboards.service.base.MBMessageLocalServiceBaseImpl;
81 import com.liferay.portlet.messageboards.social.MBActivityKeys;
82 import com.liferay.portlet.messageboards.util.MBUtil;
83 import com.liferay.portlet.messageboards.util.MailingListThreadLocal;
84 import com.liferay.portlet.messageboards.util.comparator.MessageThreadComparator;
85 import com.liferay.portlet.messageboards.util.comparator.ThreadLastPostDateComparator;
86 import com.liferay.portlet.social.model.SocialActivity;
87
88 import java.io.IOException;
89
90 import java.util.ArrayList;
91 import java.util.Comparator;
92 import java.util.Date;
93 import java.util.HashSet;
94 import java.util.Iterator;
95 import java.util.List;
96 import java.util.Set;
97
98 import javax.mail.internet.InternetAddress;
99
100 import javax.portlet.PortletPreferences;
101
102 import net.htmlparser.jericho.Source;
103 import net.htmlparser.jericho.StartTag;
104
105
113 public class MBMessageLocalServiceImpl extends MBMessageLocalServiceBaseImpl {
114
115 public MBMessage addDiscussionMessage(
116 long userId, String userName, long groupId, String className,
117 long classPK, int workflowAction)
118 throws PortalException, SystemException {
119
120 long threadId = 0;
121 long parentMessageId = 0;
122 String subject = String.valueOf(classPK);
123 String body = subject;
124
125 ServiceContext serviceContext = new ServiceContext();
126
127 serviceContext.setWorkflowAction(workflowAction);
128
129 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
130
131 WorkflowThreadLocal.setEnabled(workflowEnabled);
132
133 try {
134 return addDiscussionMessage(
135 null, userId, userName, groupId, className, classPK, threadId,
136 parentMessageId, subject, body, serviceContext);
137 }
138 finally {
139 WorkflowThreadLocal.setEnabled(workflowEnabled);
140 }
141 }
142
143 public MBMessage addDiscussionMessage(
144 String uuid, long userId, String userName, long groupId,
145 String className, long classPK, long threadId, long parentMessageId,
146 String subject, String body, ServiceContext serviceContext)
147 throws PortalException, SystemException {
148
149
151 long categoryId = MBCategoryConstants.DISCUSSION_CATEGORY_ID;
152
153 if (Validator.isNull(subject)) {
154 subject = body.substring(0, Math.min(body.length(), 50)) + "...";
155 }
156
157 List<ObjectValuePair<String, byte[]>> files =
158 new ArrayList<ObjectValuePair<String, byte[]>>();
159 boolean anonymous = false;
160 double priority = 0.0;
161 boolean allowPingbacks = false;
162
163 serviceContext.setAddCommunityPermissions(true);
164 serviceContext.setAddGuestPermissions(true);
165 serviceContext.setAttribute("className", className);
166 serviceContext.setAttribute("classPK", String.valueOf(classPK));
167
168 MBMessage message = addMessage(
169 uuid, userId, userName, groupId, categoryId, threadId,
170 parentMessageId, subject, body, files, anonymous, priority,
171 allowPingbacks, serviceContext);
172
173
175 if (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
176 long classNameId = PortalUtil.getClassNameId(className);
177
178 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
179 classNameId, classPK);
180
181 if (discussion == null) {
182 discussion = mbDiscussionLocalService.addDiscussion(
183 classNameId, classPK, message.getThreadId());
184 }
185 }
186
187 return message;
188 }
189
190 public MBMessage addMessage(
191 long userId, String userName, long groupId, long categoryId,
192 String subject, String body,
193 List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
194 double priority, boolean allowPingbacks,
195 ServiceContext serviceContext)
196 throws PortalException, SystemException {
197
198 long threadId = 0;
199 long parentMessageId = 0;
200
201 return addMessage(
202 null, userId, userName, groupId, categoryId, threadId,
203 parentMessageId, subject, body, files, anonymous, priority,
204 allowPingbacks, serviceContext);
205 }
206
207 public MBMessage addMessage(
208 long userId, String userName, long groupId, long categoryId,
209 long threadId, long parentMessageId, String subject, String body,
210 List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
211 double priority, boolean allowPingbacks,
212 ServiceContext serviceContext)
213 throws PortalException, SystemException {
214
215 return addMessage(
216 null, userId, userName, groupId, categoryId, threadId,
217 parentMessageId, subject, body, files, anonymous, priority,
218 allowPingbacks, serviceContext);
219 }
220
221 public MBMessage addMessage(
222 String uuid, long userId, String userName, long groupId,
223 long categoryId, long threadId, long parentMessageId,
224 String subject, String body,
225 List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
226 double priority, boolean allowPingbacks,
227 ServiceContext serviceContext)
228 throws PortalException, SystemException {
229
230
232 User user = userPersistence.findByPrimaryKey(userId);
233 userName = user.isDefaultUser() ? userName : user.getFullName();
234 subject = ModelHintsUtil.trimString(
235 MBMessage.class.getName(), "subject", subject);
236
237 PortletPreferences preferences =
238 ServiceContextUtil.getPortletPreferences(serviceContext);
239
240 if (preferences != null) {
241 if (!MBUtil.isAllowAnonymousPosting(preferences)) {
242 if (anonymous || user.isDefaultUser()) {
243 throw new PrincipalException();
244 }
245 }
246 }
247
248 if (user.isDefaultUser()) {
249 anonymous = true;
250 }
251
252 Date now = new Date();
253
254 validate(subject, body);
255
256 long messageId = counterLocalService.increment();
257
258 MBMessage message = mbMessagePersistence.create(messageId);
259
260 message.setUuid(uuid);
261 message.setGroupId(groupId);
262 message.setCompanyId(user.getCompanyId());
263 message.setUserId(user.getUserId());
264 message.setUserName(userName);
265 message.setCreateDate(serviceContext.getCreateDate(now));
266 message.setModifiedDate(serviceContext.getModifiedDate(now));
267 message.setAllowPingbacks(allowPingbacks);
268 message.setStatus(WorkflowConstants.STATUS_DRAFT);
269 message.setStatusByUserId(user.getUserId());
270 message.setStatusByUserName(userName);
271 message.setStatusDate(serviceContext.getModifiedDate(now));
272
273
275 if (parentMessageId != MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
276 MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
277 parentMessageId);
278
279 if (parentMessage == null) {
280 parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
281 }
282 }
283
284 MBThread thread = null;
285
286 if (threadId > 0) {
287 thread = mbThreadPersistence.fetchByPrimaryKey(threadId);
288 }
289
290 if ((thread == null) ||
291 (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID)) {
292
293 threadId = counterLocalService.increment();
294
295 thread = mbThreadPersistence.create(threadId);
296
297 thread.setGroupId(groupId);
298 thread.setCategoryId(categoryId);
299 thread.setRootMessageId(messageId);
300 thread.setStatus(WorkflowConstants.STATUS_DRAFT);
301 thread.setStatusByUserId(user.getUserId());
302 thread.setStatusByUserName(userName);
303 thread.setStatusDate(serviceContext.getModifiedDate(now));
304 }
305
306 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
307 (thread.getPriority() != priority)) {
308
309 thread.setPriority(priority);
310
311 updatePriorities(thread.getThreadId(), priority);
312 }
313
314
316 message.setCategoryId(categoryId);
317 message.setThreadId(threadId);
318 message.setParentMessageId(parentMessageId);
319 message.setSubject(subject);
320 message.setBody(body);
321 message.setAttachments(!files.isEmpty());
322 message.setAnonymous(anonymous);
323
324 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
325 message.setPriority(priority);
326 }
327
328 if (message.isDiscussion()) {
329 long classNameId = PortalUtil.getClassNameId(
330 (String)serviceContext.getAttribute("className"));
331 long classPK = GetterUtil.getLong(
332 (String)serviceContext.getAttribute("classPK"));
333
334 message.setClassNameId(classNameId);
335 message.setClassPK(classPK);
336 }
337
338
340 if (files.size() > 0) {
341 long companyId = message.getCompanyId();
342 String portletId = CompanyConstants.SYSTEM_STRING;
343 long dlGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
344 long repositoryId = CompanyConstants.SYSTEM;
345 String dirName = message.getAttachmentsDir();
346
347 try {
348 dlService.deleteDirectory(
349 companyId, portletId, repositoryId, dirName);
350 }
351 catch (NoSuchDirectoryException nsde) {
352 if (_log.isDebugEnabled()) {
353 _log.debug(nsde.getMessage());
354 }
355 }
356
357 dlService.addDirectory(companyId, repositoryId, dirName);
358
359 for (int i = 0; i < files.size(); i++) {
360 ObjectValuePair<String, byte[]> ovp = files.get(i);
361
362 String fileName = ovp.getKey();
363 byte[] bytes = ovp.getValue();
364
365 try {
366 dlService.addFile(
367 companyId, portletId, dlGroupId, repositoryId,
368 dirName + "/" + fileName, 0, StringPool.BLANK,
369 message.getModifiedDate(), new ServiceContext(), bytes);
370 }
371 catch (DuplicateFileException dfe) {
372 if (_log.isDebugEnabled()) {
373 _log.debug(dfe.getMessage());
374 }
375 }
376 }
377 }
378
379
381 mbThreadPersistence.update(thread, false);
382 mbMessagePersistence.update(message, false);
383
384
386 if (!message.isDiscussion()) {
387 if (user.isDefaultUser()) {
388 addMessageResources(message, true, true);
389 }
390 if (serviceContext.getAddCommunityPermissions() ||
391 serviceContext.getAddGuestPermissions()) {
392
393 addMessageResources(
394 message, serviceContext.getAddCommunityPermissions(),
395 serviceContext.getAddGuestPermissions());
396 }
397 else {
398 addMessageResources(
399 message, serviceContext.getCommunityPermissions(),
400 serviceContext.getGuestPermissions());
401 }
402 }
403
404
406 updateAsset(
407 userId, message, serviceContext.getAssetCategoryIds(),
408 serviceContext.getAssetTagNames());
409
410
412 ExpandoBridge expandoBridge = message.getExpandoBridge();
413
414 expandoBridge.setAttributes(serviceContext);
415
416
418 String className = MBMessage.class.getName();
419
420 if (message.isDiscussion()) {
421 className = MBDiscussion.class.getName();
422 }
423
424 WorkflowHandlerRegistryUtil.startWorkflowInstance(
425 user.getCompanyId(), groupId, userId, className,
426 message.getMessageId(), message, serviceContext);
427
428
430
433
434 return message;
435 }
436
437 public void addMessageResources(
438 long messageId, boolean addCommunityPermissions,
439 boolean addGuestPermissions)
440 throws PortalException, SystemException {
441
442 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
443
444 addMessageResources(
445 message, addCommunityPermissions, addGuestPermissions);
446 }
447
448 public void addMessageResources(
449 MBMessage message, boolean addCommunityPermissions,
450 boolean addGuestPermissions)
451 throws PortalException, SystemException {
452
453 resourceLocalService.addResources(
454 message.getCompanyId(), message.getGroupId(), message.getUserId(),
455 MBMessage.class.getName(), message.getMessageId(),
456 false, addCommunityPermissions, addGuestPermissions);
457 }
458
459 public void addMessageResources(
460 long messageId, String[] communityPermissions,
461 String[] guestPermissions)
462 throws PortalException, SystemException {
463
464 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
465
466 addMessageResources(message, communityPermissions, guestPermissions);
467 }
468
469 public void addMessageResources(
470 MBMessage message, String[] communityPermissions,
471 String[] guestPermissions)
472 throws PortalException, SystemException {
473
474 resourceLocalService.addModelResources(
475 message.getCompanyId(), message.getGroupId(), message.getUserId(),
476 MBMessage.class.getName(), message.getMessageId(),
477 communityPermissions, guestPermissions);
478 }
479
480 public void deleteDiscussionMessage(long messageId)
481 throws PortalException, SystemException {
482
483 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
484
485 List<MBMessage> messages = new ArrayList<MBMessage>();
486
487 messages.add(message);
488
489 deleteDiscussionSocialActivities(BlogsEntry.class.getName(), messages);
490
491 deleteMessage(message);
492 }
493
494 public void deleteDiscussionMessages(String className, long classPK)
495 throws PortalException, SystemException {
496
497 try {
498 long classNameId = PortalUtil.getClassNameId(className);
499
500 MBDiscussion discussion = mbDiscussionPersistence.findByC_C(
501 classNameId, classPK);
502
503 List<MBMessage> messages = mbMessagePersistence.findByT_P(
504 discussion.getThreadId(),
505 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, 0, 1);
506
507 deleteDiscussionSocialActivities(
508 BlogsEntry.class.getName(), messages);
509
510 if (messages.size() > 0) {
511 MBMessage message = messages.get(0);
512
513 mbThreadLocalService.deleteThread(message.getThreadId());
514 }
515
516 mbDiscussionPersistence.remove(discussion);
517 }
518 catch (NoSuchDiscussionException nsde) {
519 if (_log.isDebugEnabled()) {
520 _log.debug(nsde.getMessage());
521 }
522 }
523 }
524
525 public void deleteMessage(long messageId)
526 throws PortalException, SystemException {
527
528 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
529
530 deleteMessage(message);
531 }
532
533 public void deleteMessage(MBMessage message)
534 throws PortalException, SystemException {
535
536
538 Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
539
540 indexer.delete(message);
541
542
544 if (message.isAttachments()) {
545 long companyId = message.getCompanyId();
546 String portletId = CompanyConstants.SYSTEM_STRING;
547 long repositoryId = CompanyConstants.SYSTEM;
548 String dirName = message.getAttachmentsDir();
549
550 try {
551 dlService.deleteDirectory(
552 companyId, portletId, repositoryId, dirName);
553 }
554 catch (NoSuchDirectoryException nsde) {
555 if (_log.isDebugEnabled()) {
556 _log.debug(nsde.getMessage());
557 }
558 }
559 }
560
561
563 int count = mbMessagePersistence.countByThreadId(message.getThreadId());
564
565
567 if (message.isRoot()) {
568 mbMessageFlagLocalService.deleteQuestionAndAnswerFlags(
569 message.getThreadId());
570 }
571 else if (mbMessageFlagLocalService.hasAnswerFlag(
572 message.getMessageId())) {
573
574 mbMessageFlagService.deleteAnswerFlag(message.getMessageId());
575 }
576
577 if (count == 1) {
578
579
581 long companyId = message.getCompanyId();
582 String portletId = CompanyConstants.SYSTEM_STRING;
583 long repositoryId = CompanyConstants.SYSTEM;
584 String dirName = message.getThreadAttachmentsDir();
585
586 try {
587 dlService.deleteDirectory(
588 companyId, portletId, repositoryId, dirName);
589 }
590 catch (NoSuchDirectoryException nsde) {
591 if (_log.isDebugEnabled()) {
592 _log.debug(nsde.getMessage());
593 }
594 }
595
596
598 subscriptionLocalService.deleteSubscriptions(
599 message.getCompanyId(), MBThread.class.getName(),
600 message.getThreadId());
601
602
604 mbThreadPersistence.remove(message.getThreadId());
605
606
608 if (!message.isDiscussion()) {
609 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
610 message.getCategoryId());
611
612 category.setThreadCount(category.getThreadCount() - 1);
613 category.setMessageCount(category.getMessageCount() - 1);
614
615 mbCategoryPersistence.update(category, false);
616 }
617 }
618 else if (count > 1) {
619 MBThread thread = mbThreadPersistence.findByPrimaryKey(
620 message.getThreadId());
621
622
624 if (thread.getRootMessageId() == message.getMessageId()) {
625 List<MBMessage> childrenMessages =
626 mbMessagePersistence.findByT_P(
627 message.getThreadId(), message.getMessageId());
628
629 if (childrenMessages.size() > 1) {
630 throw new RequiredMessageException(
631 String.valueOf(message.getMessageId()));
632 }
633 else if (childrenMessages.size() == 1) {
634 MBMessage childMessage = childrenMessages.get(0);
635
636 childMessage.setParentMessageId(
637 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
638
639 mbMessagePersistence.update(childMessage, false);
640
641 thread.setRootMessageId(childMessage.getMessageId());
642
643 mbThreadPersistence.update(thread, false);
644 }
645 }
646
647
649 else {
650 List<MBMessage> childrenMessages =
651 mbMessagePersistence.findByT_P(
652 message.getThreadId(), message.getMessageId());
653
654
656 if (childrenMessages.size() > 0) {
657 Iterator<MBMessage> itr = childrenMessages.iterator();
658
659 while (itr.hasNext()) {
660 MBMessage childMessage = itr.next();
661
662 childMessage.setParentMessageId(
663 message.getParentMessageId());
664
665 mbMessagePersistence.update(childMessage, false);
666 }
667 }
668 }
669
670
672 thread.setMessageCount(count - 1);
673
674 mbThreadPersistence.update(thread, false);
675
676
678 if (!message.isDiscussion()) {
679 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
680 message.getCategoryId());
681
682 category.setMessageCount(category.getMessageCount() - 1);
683
684 mbCategoryPersistence.update(category, false);
685 }
686 }
687
688
690 assetEntryLocalService.deleteEntry(
691 MBMessage.class.getName(), message.getMessageId());
692
693
695 expandoValueLocalService.deleteValues(
696 MBMessage.class.getName(), message.getMessageId());
697
698
700 socialActivityLocalService.deleteActivities(
701 MBMessage.class.getName(), message.getMessageId());
702
703
705 ratingsStatsLocalService.deleteStats(
706 MBMessage.class.getName(), message.getMessageId());
707
708
710 if (!message.isDiscussion()) {
711 mbStatsUserLocalService.updateStatsUser(
712 message.getGroupId(), message.getUserId());
713 }
714
715
717 mbMessageFlagPersistence.removeByMessageId(message.getMessageId());
718
719
721 if (!message.isDiscussion()) {
722 resourceLocalService.deleteResource(
723 message.getCompanyId(), MBMessage.class.getName(),
724 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
725 }
726
727
729 mbMessagePersistence.remove(message);
730
731
733 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
734 message.getCompanyId(), message.getGroupId(),
735 MBMessage.class.getName(), message.getMessageId());
736 }
737
738 public List<MBMessage> getCategoryMessages(
739 long groupId, long categoryId, int status, int start, int end)
740 throws SystemException {
741
742 if (status == WorkflowConstants.STATUS_ANY) {
743 return mbMessagePersistence.findByG_C(
744 groupId, categoryId, start, end);
745 }
746 else {
747 return mbMessagePersistence.findByG_C_S(
748 groupId, categoryId, status, start, end);
749 }
750 }
751
752 public List<MBMessage> getCategoryMessages(
753 long groupId, long categoryId, int status, int start, int end,
754 OrderByComparator obc)
755 throws SystemException {
756
757 if (status == WorkflowConstants.STATUS_ANY) {
758 return mbMessagePersistence.findByG_C(
759 groupId, categoryId, start, end, obc);
760 }
761 else {
762 return mbMessagePersistence.findByG_C_S(
763 groupId, categoryId, status, start, end, obc);
764 }
765 }
766
767 public int getCategoryMessagesCount(
768 long groupId, long categoryId, int status)
769 throws SystemException {
770
771 if (status == WorkflowConstants.STATUS_ANY) {
772 return mbMessagePersistence.countByG_C(groupId, categoryId);
773 }
774 else {
775 return mbMessagePersistence.countByG_C_S(
776 groupId, categoryId, status);
777 }
778 }
779
780 public List<MBMessage> getCompanyMessages(
781 long companyId, int status, int start, int end)
782 throws SystemException {
783
784 if (status == WorkflowConstants.STATUS_ANY) {
785 return mbMessagePersistence.findByCompanyId(companyId, start, end);
786 }
787 else {
788 return mbMessagePersistence.findByC_S(
789 companyId, status, start, end);
790 }
791 }
792
793 public List<MBMessage> getCompanyMessages(
794 long companyId, int status, int start, int end,
795 OrderByComparator obc)
796 throws SystemException {
797
798 if (status == WorkflowConstants.STATUS_ANY) {
799 return mbMessagePersistence.findByCompanyId(
800 companyId, start, end, obc);
801 }
802 else {
803 return mbMessagePersistence.findByC_S(
804 companyId, status, start, end, obc);
805 }
806 }
807
808 public int getCompanyMessagesCount(long companyId, int status)
809 throws SystemException {
810
811 if (status == WorkflowConstants.STATUS_ANY) {
812 return mbMessagePersistence.countByCompanyId(companyId);
813 }
814 else {
815 return mbMessagePersistence.countByC_S(companyId, status);
816 }
817 }
818
819 public MBMessageDisplay getDiscussionMessageDisplay(
820 long userId, long groupId, String className, long classPK,
821 int status)
822 throws PortalException, SystemException {
823
824 return getDiscussionMessageDisplay(
825 userId, groupId, className, classPK, status,
826 MBThreadConstants.THREAD_VIEW_COMBINATION);
827 }
828
829 public MBMessageDisplay getDiscussionMessageDisplay(
830 long userId, long groupId, String className, long classPK,
831 int status, String threadView)
832 throws PortalException, SystemException {
833
834 long classNameId = PortalUtil.getClassNameId(className);
835
836 MBMessage message = null;
837
838 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
839 classNameId, classPK);
840
841 if (discussion != null) {
842 List<MBMessage> messages = mbMessagePersistence.findByT_P(
843 discussion.getThreadId(),
844 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
845
846 message = messages.get(0);
847 }
848 else {
849 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
850
851 WorkflowThreadLocal.setEnabled(false);
852
853 try {
854 String subject = String.valueOf(classPK);
855
857 message = addDiscussionMessage(
858 null, userId, null, groupId, className, classPK, 0,
859 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, subject,
860 subject, new ServiceContext());
861 }
862 catch (SystemException se) {
863 if (_log.isWarnEnabled()) {
864 _log.warn(
865 "Add failed, fetch {threadId=0, parentMessageId=" +
866 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID + "}");
867 }
868
869 List<MBMessage> messages = mbMessagePersistence.findByT_P(
870 0, MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
871
872 if (messages.isEmpty()) {
873 throw se;
874 }
875
876 message = messages.get(0);
877 }
878 finally {
879 WorkflowThreadLocal.setEnabled(workflowEnabled);
880 }
881 }
882
883 return getMessageDisplay(message, status, threadView, false);
884 }
885
886 public int getDiscussionMessagesCount(
887 long classNameId, long classPK, int status)
888 throws SystemException {
889
890 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
891 classNameId, classPK);
892
893 if (discussion == null) {
894 return 0;
895 }
896
897 int count = 0;
898
899 if (status == WorkflowConstants.STATUS_ANY) {
900 count = mbMessagePersistence.countByThreadId(
901 discussion.getThreadId());
902 }
903 else {
904 count = mbMessagePersistence.countByT_S(
905 discussion.getThreadId(), status);
906 }
907
908 if (count >= 1) {
909 return count - 1;
910 }
911 else {
912 return 0;
913 }
914 }
915
916 public int getDiscussionMessagesCount(
917 String className, long classPK, int status)
918 throws SystemException {
919
920 long classNameId = PortalUtil.getClassNameId(className);
921
922 return getDiscussionMessagesCount(classNameId, classPK, status);
923 }
924
925 public List<MBDiscussion> getDiscussions(String className)
926 throws SystemException {
927
928 long classNameId = PortalUtil.getClassNameId(className);
929
930 return mbDiscussionPersistence.findByClassNameId(classNameId);
931 }
932
933 public List<MBMessage> getGroupMessages(
934 long groupId, int status, int start, int end)
935 throws SystemException {
936
937 if (status == WorkflowConstants.STATUS_ANY) {
938 return mbMessagePersistence.findByGroupId(groupId, start, end);
939 }
940 else {
941 return mbMessagePersistence.findByG_S(groupId, status, start, end);
942 }
943 }
944
945 public List<MBMessage> getGroupMessages(
946 long groupId, int status, int start, int end, OrderByComparator obc)
947 throws SystemException {
948
949 if (status == WorkflowConstants.STATUS_ANY) {
950 return mbMessagePersistence.findByGroupId(groupId, start, end, obc);
951 }
952 else {
953 return mbMessagePersistence.findByG_S(
954 groupId, status, start, end, obc);
955 }
956 }
957
958 public List<MBMessage> getGroupMessages(
959 long groupId, long userId, int status, int start, int end)
960 throws SystemException {
961
962 if (status == WorkflowConstants.STATUS_ANY) {
963 return mbMessagePersistence.findByG_U(groupId, userId, start, end);
964 }
965 else {
966 return mbMessagePersistence.findByG_U_S(
967 groupId, userId, status, start, end);
968 }
969 }
970
971 public List<MBMessage> getGroupMessages(
972 long groupId, long userId, int status, int start, int end,
973 OrderByComparator obc)
974 throws SystemException {
975
976 if (status == WorkflowConstants.STATUS_ANY) {
977 return mbMessagePersistence.findByG_U(
978 groupId, userId, start, end, obc);
979 }
980 else {
981 return mbMessagePersistence.findByG_U_S(
982 groupId, userId, status, start, end, obc);
983 }
984 }
985
986 public int getGroupMessagesCount(long groupId, int status)
987 throws SystemException {
988
989 if (status == WorkflowConstants.STATUS_ANY) {
990 return mbMessagePersistence.countByGroupId(groupId);
991 }
992 else {
993 return mbMessagePersistence.countByG_S(groupId, status);
994 }
995 }
996
997 public int getGroupMessagesCount(long groupId, long userId, int status)
998 throws SystemException {
999
1000 if (status == WorkflowConstants.STATUS_ANY) {
1001 return mbMessagePersistence.countByG_U(groupId, userId);
1002 }
1003 else {
1004 return mbMessagePersistence.countByG_U_S(groupId, userId, status);
1005 }
1006 }
1007
1008 public MBMessage getMessage(long messageId)
1009 throws PortalException, SystemException {
1010
1011 return mbMessagePersistence.findByPrimaryKey(messageId);
1012 }
1013
1014 public List<MBMessage> getMessages(
1015 String className, long classPK, int status)
1016 throws SystemException {
1017
1018 long classNameId = PortalUtil.getClassNameId(className);
1019
1020 if (status == WorkflowConstants.STATUS_ANY) {
1021 return mbMessagePersistence.findByC_C(classNameId, classPK);
1022 }
1023 else {
1024 return mbMessagePersistence.findByC_C_S(
1025 classNameId, classPK, status);
1026 }
1027 }
1028
1029 public MBMessageDisplay getMessageDisplay(
1030 long messageId, int status, String threadView,
1031 boolean includePrevAndNext)
1032 throws PortalException, SystemException {
1033
1034 MBMessage message = getMessage(messageId);
1035
1036 return getMessageDisplay(
1037 message, status, threadView, includePrevAndNext);
1038 }
1039
1040 public MBMessageDisplay getMessageDisplay(
1041 MBMessage message, int status, String threadView,
1042 boolean includePrevAndNext)
1043 throws PortalException, SystemException {
1044
1045 MBCategory category = null;
1046
1047 if ((message.getCategoryId() !=
1048 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1049 (message.getCategoryId() !=
1050 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1051
1052 category = mbCategoryPersistence.findByPrimaryKey(
1053 message.getCategoryId());
1054 }
1055
1056 MBMessage parentMessage = null;
1057
1058 if (message.isReply()) {
1059 parentMessage = mbMessagePersistence.findByPrimaryKey(
1060 message.getParentMessageId());
1061 }
1062
1063 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1064 message.getThreadId());
1065
1066 if (!message.isDiscussion() &&
1067 (message.getStatus() == WorkflowConstants.STATUS_APPROVED)) {
1068
1069 mbThreadLocalService.updateThread(
1070 thread.getThreadId(), thread.getViewCount() + 1);
1071 }
1072
1073 MBThread previousThread = null;
1074 MBThread nextThread = null;
1075
1076 if ((message.getStatus() == WorkflowConstants.STATUS_APPROVED) &&
1077 includePrevAndNext) {
1078
1079 ThreadLastPostDateComparator comparator =
1080 new ThreadLastPostDateComparator(false);
1081
1082 MBThread[] prevAndNextThreads =
1083 mbThreadPersistence.findByG_C_PrevAndNext(
1084 message.getThreadId(), message.getGroupId(),
1085 message.getCategoryId(), comparator);
1086
1087 previousThread = prevAndNextThreads[0];
1088 nextThread = prevAndNextThreads[2];
1089 }
1090
1091 return new MBMessageDisplayImpl(
1092 message, parentMessage, category, thread,
1093 previousThread, nextThread, status, threadView);
1094 }
1095
1096 public List<MBMessage> getNoAssetMessages() throws SystemException {
1097 return mbMessageFinder.findByNoAssets();
1098 }
1099
1100 public int getPositionInThread(long messageId)
1101 throws PortalException, SystemException {
1102
1103 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1104
1105 return mbMessageFinder.countByC_T(
1106 message.getCreateDate(), message.getThreadId());
1107 }
1108
1109 public List<MBMessage> getThreadMessages(long threadId, int status)
1110 throws SystemException {
1111
1112 return getThreadMessages(
1113 threadId, status, new MessageThreadComparator());
1114 }
1115
1116 public List<MBMessage> getThreadMessages(
1117 long threadId, int status, Comparator<MBMessage> comparator)
1118 throws SystemException {
1119
1120 List<MBMessage> messages = null;
1121
1122 if (status == WorkflowConstants.STATUS_ANY) {
1123 messages = mbMessagePersistence.findByThreadId(threadId);
1124 }
1125 else {
1126 messages = mbMessagePersistence.findByT_S(threadId, status);
1127 }
1128
1129 return ListUtil.sort(messages, comparator);
1130 }
1131
1132 public List<MBMessage> getThreadMessages(
1133 long threadId, int status, int start, int end)
1134 throws SystemException {
1135
1136 if (status == WorkflowConstants.STATUS_ANY) {
1137 return mbMessagePersistence.findByThreadId(threadId, start, end);
1138 }
1139 else {
1140 return mbMessagePersistence.findByT_S(threadId, status, start, end);
1141 }
1142 }
1143
1144 public int getThreadMessagesCount(long threadId, int status)
1145 throws SystemException {
1146
1147 if (status == WorkflowConstants.STATUS_ANY) {
1148 return mbMessagePersistence.countByThreadId(threadId);
1149 }
1150 else {
1151 return mbMessagePersistence.countByT_S(threadId, status);
1152 }
1153 }
1154
1155 public List<MBMessage> getThreadRepliesMessages(
1156 long threadId, int status, int start, int end)
1157 throws SystemException {
1158
1159 if (status == WorkflowConstants.STATUS_ANY) {
1160 return mbMessagePersistence.findByThreadReplies(
1161 threadId, start, end);
1162 }
1163 else {
1164 return mbMessagePersistence.findByTR_S(
1165 threadId, status, start, end);
1166 }
1167 }
1168
1169 public void subscribeMessage(long userId, long messageId)
1170 throws PortalException, SystemException {
1171
1172 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1173
1174 subscriptionLocalService.addSubscription(
1175 userId, MBThread.class.getName(), message.getThreadId());
1176 }
1177
1178 public void unsubscribeMessage(long userId, long messageId)
1179 throws PortalException, SystemException {
1180
1181 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1182
1183 subscriptionLocalService.deleteSubscription(
1184 userId, MBThread.class.getName(), message.getThreadId());
1185 }
1186
1187 public void updateAsset(
1188 long userId, MBMessage message, long[] assetCategoryIds,
1189 String[] assetTagNames)
1190 throws PortalException, SystemException {
1191
1192 if (message.isDiscussion()) {
1193 return;
1194 }
1195
1196 boolean visible = false;
1197
1198 if (message.getStatus() == WorkflowConstants.STATUS_APPROVED) {
1199 visible = true;
1200 }
1201
1202 assetEntryLocalService.updateEntry(
1203 userId, message.getGroupId(), MBMessage.class.getName(),
1204 message.getMessageId(), assetCategoryIds, assetTagNames, visible,
1205 null, null, null, null, ContentTypes.TEXT_HTML,
1206 message.getSubject(), null, null, null, 0, 0, null, false);
1207 }
1208
1209 public MBMessage updateDiscussionMessage(
1210 long userId, long messageId, String subject, String body,
1211 int workflowAction)
1212 throws PortalException, SystemException {
1213
1214 if (Validator.isNull(subject)) {
1215 subject = "N/A";
1216 }
1217
1218 List<ObjectValuePair<String, byte[]>> files =
1219 new ArrayList<ObjectValuePair<String, byte[]>>();
1220 List<String> existingFiles = new ArrayList<String>();
1221 double priority = 0.0;
1222 boolean allowPingbacks = false;
1223
1224 ServiceContext serviceContext = new ServiceContext();
1225
1226 serviceContext.setWorkflowAction(workflowAction);
1227
1228 return updateMessage(
1229 userId, messageId, subject, body, files, existingFiles, priority,
1230 allowPingbacks, serviceContext);
1231 }
1232
1233 public MBMessage updateMessage(
1234 long userId, long messageId, String subject, String body,
1235 List<ObjectValuePair<String, byte[]>> files,
1236 List<String> existingFiles, double priority, boolean allowPingbacks,
1237 ServiceContext serviceContext)
1238 throws PortalException, SystemException {
1239
1240
1242 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1243
1244 subject = ModelHintsUtil.trimString(
1245 MBMessage.class.getName(), "subject", subject);
1246 Date now = new Date();
1247
1248 validate(subject, body);
1249
1250 message.setModifiedDate(serviceContext.getModifiedDate(now));
1251 message.setSubject(subject);
1252 message.setBody(body);
1253 message.setAttachments(!files.isEmpty() || !existingFiles.isEmpty());
1254 message.setAllowPingbacks(allowPingbacks);
1255
1256 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
1257 message.setPriority(priority);
1258 }
1259
1260
1262 long companyId = message.getCompanyId();
1263 String portletId = CompanyConstants.SYSTEM_STRING;
1264 long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
1265 long repositoryId = CompanyConstants.SYSTEM;
1266 String dirName = message.getAttachmentsDir();
1267
1268 if (!files.isEmpty() || !existingFiles.isEmpty()) {
1269 try {
1270 dlService.addDirectory(companyId, repositoryId, dirName);
1271 }
1272 catch (DuplicateDirectoryException dde) {
1273 }
1274
1275 String[] fileNames = dlService.getFileNames(
1276 companyId, repositoryId, dirName);
1277
1278 for (String fileName: fileNames) {
1279 if (!existingFiles.contains(fileName)) {
1280 dlService.deleteFile(
1281 companyId, portletId, repositoryId, fileName);
1282 }
1283 }
1284
1285 for (int i = 0; i < files.size(); i++) {
1286 ObjectValuePair<String, byte[]> ovp = files.get(i);
1287
1288 String fileName = ovp.getKey();
1289 byte[] bytes = ovp.getValue();
1290
1291 try {
1292 dlService.addFile(
1293 companyId, portletId, groupId, repositoryId,
1294 dirName + "/" + fileName, 0, StringPool.BLANK,
1295 message.getModifiedDate(), new ServiceContext(), bytes);
1296 }
1297 catch (DuplicateFileException dfe) {
1298 }
1299 }
1300 }
1301 else {
1302 try {
1303 dlService.deleteDirectory(
1304 companyId, portletId, repositoryId, dirName);
1305 }
1306 catch (NoSuchDirectoryException nsde) {
1307 }
1308 }
1309
1310 mbMessagePersistence.update(message, false);
1311
1312
1314 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1315 message.getThreadId());
1316
1317 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
1318 (thread.getPriority() != priority)) {
1319
1320 thread.setPriority(priority);
1321
1322 mbThreadPersistence.update(thread, false);
1323
1324 updatePriorities(thread.getThreadId(), priority);
1325 }
1326
1327
1329 updateAsset(
1330 userId, message, serviceContext.getAssetCategoryIds(),
1331 serviceContext.getAssetTagNames());
1332
1333
1335 ExpandoBridge expandoBridge = message.getExpandoBridge();
1336
1337 expandoBridge.setAttributes(serviceContext);
1338
1339
1341 serviceContext.setAttribute("update", Boolean.TRUE.toString());
1342
1343 WorkflowHandlerRegistryUtil.startWorkflowInstance(
1344 companyId, message.getGroupId(), userId, MBMessage.class.getName(),
1345 message.getMessageId(), message, serviceContext);
1346
1347 return message;
1348 }
1349
1350 public MBMessage updateMessage(long messageId, String body)
1351 throws PortalException, SystemException {
1352
1353 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1354
1355 message.setBody(body);
1356
1357 mbMessagePersistence.update(message, false);
1358
1359 return message;
1360 }
1361
1362 public void updateUserName(long userId, String userName)
1363 throws SystemException {
1364
1365 List<MBMessage> messages = mbMessagePersistence.findByUserId(userId);
1366
1367 for (MBMessage message : messages) {
1368 message.setUserName(userName);
1369
1370 mbMessagePersistence.update(message, false);
1371 }
1372 }
1373
1374 public MBMessage updateStatus(
1375 long userId, long messageId, int status,
1376 ServiceContext serviceContext)
1377 throws PortalException, SystemException {
1378
1379 MBMessage message = getMessage(messageId);
1380
1381 int oldStatus = message.getStatus();
1382
1383 User user = userPersistence.findByPrimaryKey(userId);
1384 Date now = new Date();
1385
1386 message.setStatus(status);
1387 message.setStatusByUserId(userId);
1388 message.setStatusByUserName(user.getFullName());
1389 message.setStatusDate(serviceContext.getModifiedDate(now));
1390
1391 mbMessagePersistence.update(message, false);
1392
1393
1395 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1396 message.getThreadId());
1397
1398 MBCategory category = null;
1399
1400 if ((thread.getCategoryId() !=
1401 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1402 (thread.getCategoryId() !=
1403 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1404
1405 category = mbCategoryPersistence.findByPrimaryKey(
1406 thread.getCategoryId());
1407 }
1408
1409 if ((thread.getRootMessageId() == message.getMessageId()) &&
1410 (oldStatus != status)) {
1411
1412 thread.setStatus(status);
1413 thread.setStatusByUserId(userId);
1414 thread.setStatusByUserName(user.getFullName());
1415 thread.setStatusDate(serviceContext.getModifiedDate(now));
1416 }
1417
1418 Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
1419
1420 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
1421 (status == WorkflowConstants.STATUS_APPROVED)) {
1422
1423
1425 if ((category != null) &&
1426 (thread.getRootMessageId() == message.getMessageId())) {
1427
1428 category.setThreadCount(category.getThreadCount() + 1);
1429
1430 mbCategoryPersistence.update(category, false);
1431 }
1432
1433 thread.setMessageCount(thread.getMessageCount() + 1);
1434
1435 if (message.isAnonymous()) {
1436 thread.setLastPostByUserId(0);
1437 }
1438 else {
1439 thread.setLastPostByUserId(message.getUserId());
1440 }
1441
1442 thread.setLastPostDate(serviceContext.getModifiedDate(now));
1443
1444
1446 if (category != null) {
1447 category.setMessageCount(category.getMessageCount() + 1);
1448 category.setLastPostDate(serviceContext.getModifiedDate(now));
1449
1450 mbCategoryPersistence.update(category, false);
1451
1452 }
1453
1454 if (!message.isDiscussion()) {
1455
1456
1458 assetEntryLocalService.updateVisible(
1459 MBMessage.class.getName(), message.getMessageId(), true);
1460
1461
1463 indexer.reindex(message);
1464
1465
1467 if (!message.isAnonymous() && !user.isDefaultUser()) {
1468
1469 int activityType = MBActivityKeys.ADD_MESSAGE;
1470 long receiverUserId = 0;
1471
1472 MBMessage parentMessage =
1473 mbMessagePersistence.fetchByPrimaryKey(
1474 message.getParentMessageId());
1475
1476 if (parentMessage != null) {
1477 activityType = MBActivityKeys.REPLY_MESSAGE;
1478 receiverUserId = parentMessage.getUserId();
1479 }
1480
1481 socialActivityLocalService.addActivity(
1482 userId, message.getGroupId(), MBMessage.class.getName(),
1483 message.getMessageId(), activityType, StringPool.BLANK,
1484 receiverUserId);
1485 }
1486
1487 }
1488
1489
1491 notifySubscribers(message, serviceContext);
1492
1493
1495 pingPingback(message, serviceContext);
1496
1497
1499 if (message.isDiscussion()) {
1500 updateDiscussionMessageStatus(
1501 userId, messageId, status, serviceContext);
1502 }
1503 }
1504 else if ((oldStatus == WorkflowConstants.STATUS_APPROVED) &&
1505 (status != WorkflowConstants.STATUS_APPROVED)) {
1506
1507
1509 if ((category != null) &&
1510 (thread.getRootMessageId() == message.getMessageId())) {
1511
1512 category.setThreadCount(category.getThreadCount() - 1);
1513
1514 mbCategoryPersistence.update(category, false);
1515 }
1516
1517 thread.setMessageCount(thread.getMessageCount() - 1);
1518
1519
1521 if (category != null) {
1522 category.setMessageCount(category.getMessageCount() - 1);
1523
1524 mbCategoryPersistence.update(category, false);
1525 }
1526
1527 if (!message.isDiscussion()) {
1528
1529
1531 assetEntryLocalService.updateVisible(
1532 MBMessage.class.getName(), message.getMessageId(), false);
1533
1534
1536 indexer.delete(message);
1537 }
1538
1539 }
1540
1541 if (status != oldStatus) {
1542 mbThreadPersistence.update(thread, false);
1543 }
1544
1545
1547 if (!message.isDiscussion()) {
1548 mbStatsUserLocalService.updateStatsUser(
1549 message.getGroupId(), userId,
1550 serviceContext.getModifiedDate(now));
1551 }
1552
1553 return message;
1554 }
1555
1556 protected void deleteDiscussionSocialActivities(
1557 String className, List<MBMessage> messages)
1558 throws PortalException, SystemException {
1559
1560 if (messages.size() == 0) {
1561 return;
1562 }
1563
1564 MBMessage message = messages.get(0);
1565
1566 MBDiscussion discussion = mbDiscussionPersistence.findByThreadId(
1567 message.getThreadId());
1568
1569 long classNameId = PortalUtil.getClassNameId(className);
1570 long classPK = discussion.getClassPK();
1571
1572 if (discussion.getClassNameId() != classNameId) {
1573 return;
1574 }
1575
1576 Set<Long> messageIds = new HashSet<Long>();
1577
1578 for (MBMessage curMessage : messages) {
1579 messageIds.add(curMessage.getMessageId());
1580 }
1581
1582 List<SocialActivity> socialActivities =
1583 socialActivityLocalService.getActivities(
1584 0, className, classPK, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1585
1586 for (SocialActivity socialActivity : socialActivities) {
1587 if (Validator.isNull(socialActivity.getExtraData())) {
1588 continue;
1589 }
1590
1591 JSONObject extraData = JSONFactoryUtil.createJSONObject(
1592 socialActivity.getExtraData());
1593
1594 long extraDataMessageId = extraData.getLong("messageId");
1595
1596 if (messageIds.contains(extraDataMessageId)) {
1597 socialActivityLocalService.deleteActivity(
1598 socialActivity.getActivityId());
1599 }
1600 }
1601 }
1602
1603 protected void notifySubscribers(
1604 MBMessage message, ServiceContext serviceContext)
1605 throws PortalException, SystemException {
1606
1607 if (message.getStatus() != WorkflowConstants.STATUS_APPROVED) {
1608 return;
1609 }
1610
1611 String layoutFullURL = serviceContext.getLayoutFullURL();
1612
1613 if (Validator.isNull(layoutFullURL) || message.isDiscussion()) {
1614 return;
1615 }
1616
1617 PortletPreferences preferences =
1618 ServiceContextUtil.getPortletPreferences(serviceContext);
1619
1620 if (preferences == null) {
1621 long ownerId = message.getGroupId();
1622 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1623 long plid = PortletKeys.PREFS_PLID_SHARED;
1624 String portletId = PortletKeys.MESSAGE_BOARDS;
1625 String defaultPreferences = null;
1626
1627 preferences = portletPreferencesLocalService.getPreferences(
1628 message.getCompanyId(), ownerId, ownerType, plid, portletId,
1629 defaultPreferences);
1630 }
1631
1632 boolean update = GetterUtil.getBoolean(
1633 (String)serviceContext.getAttribute("update"));
1634
1635 if (!update && MBUtil.getEmailMessageAddedEnabled(preferences)) {
1636 }
1637 else if (update && MBUtil.getEmailMessageUpdatedEnabled(preferences)) {
1638 }
1639 else {
1640 return;
1641 }
1642
1643 Company company = companyPersistence.findByPrimaryKey(
1644 message.getCompanyId());
1645
1646 Group group = groupPersistence.findByPrimaryKey(message.getGroupId());
1647
1648 String emailAddress = StringPool.BLANK;
1649 String fullName = message.getUserName();
1650
1651 try {
1652 User user = userPersistence.findByPrimaryKey(message.getUserId());
1653
1654 emailAddress = user.getEmailAddress();
1655 fullName = user.getFullName();
1656 }
1657 catch (NoSuchUserException nsue) {
1658 }
1659
1660 MBCategory category = message.getCategory();
1661
1662 if (message.isAnonymous()) {
1663 emailAddress = StringPool.BLANK;
1664 fullName = LanguageUtil.get(
1665 ServiceContextUtil.getLocale(serviceContext), "anonymous");
1666 }
1667
1668 List<Long> categoryIds = new ArrayList<Long>();
1669
1670 categoryIds.add(message.getCategoryId());
1671 categoryIds.addAll(category.getAncestorCategoryIds());
1672
1673 String messageURL =
1674 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
1675 "message_boards/message/" + message.getMessageId();
1676
1677 String portletName = PortalUtil.getPortletTitle(
1678 PortletKeys.MESSAGE_BOARDS, LocaleUtil.getDefault());
1679
1680 String fromName = MBUtil.getEmailFromName(preferences);
1681 String fromAddress = MBUtil.getEmailFromAddress(preferences);
1682
1683 String mailingListAddress = StringPool.BLANK;
1684
1685 if (PropsValues.POP_SERVER_NOTIFICATIONS_ENABLED) {
1686 mailingListAddress = MBUtil.getMailingListAddress(
1687 message.getGroupId(), message.getCategoryId(),
1688 message.getMessageId(), company.getMx(), fromAddress);
1689 }
1690
1691 String replyToAddress = mailingListAddress;
1692 String mailId = MBUtil.getMailId(
1693 company.getMx(), message.getCategoryId(), message.getMessageId());
1694
1695 fromName = StringUtil.replace(
1696 fromName,
1697 new String[] {
1698 "[$COMPANY_ID$]",
1699 "[$COMPANY_MX$]",
1700 "[$COMPANY_NAME$]",
1701 "[$COMMUNITY_NAME$]",
1702 "[$MAILING_LIST_ADDRESS$]",
1703 "[$MESSAGE_USER_ADDRESS$]",
1704 "[$MESSAGE_USER_NAME$]",
1705 "[$PORTLET_NAME$]"
1706 },
1707 new String[] {
1708 String.valueOf(company.getCompanyId()),
1709 company.getMx(),
1710 company.getName(),
1711 group.getName(),
1712 mailingListAddress,
1713 emailAddress,
1714 fullName,
1715 portletName
1716 });
1717
1718 fromAddress = StringUtil.replace(
1719 fromAddress,
1720 new String[] {
1721 "[$COMPANY_ID$]",
1722 "[$COMPANY_MX$]",
1723 "[$COMPANY_NAME$]",
1724 "[$COMMUNITY_NAME$]",
1725 "[$MAILING_LIST_ADDRESS$]",
1726 "[$MESSAGE_USER_ADDRESS$]",
1727 "[$MESSAGE_USER_NAME$]",
1728 "[$PORTLET_NAME$]"
1729 },
1730 new String[] {
1731 String.valueOf(company.getCompanyId()),
1732 company.getMx(),
1733 company.getName(),
1734 group.getName(),
1735 mailingListAddress,
1736 emailAddress,
1737 fullName,
1738 portletName
1739 });
1740
1741 String subjectPrefix = null;
1742 String body = null;
1743 String signature = null;
1744 boolean htmlFormat = MBUtil.getEmailHtmlFormat(preferences);
1745
1746 if (update) {
1747 subjectPrefix = MBUtil.getEmailMessageUpdatedSubjectPrefix(
1748 preferences);
1749 body = MBUtil.getEmailMessageUpdatedBody(preferences);
1750 signature = MBUtil.getEmailMessageUpdatedSignature(preferences);
1751 }
1752 else {
1753 subjectPrefix = MBUtil.getEmailMessageAddedSubjectPrefix(
1754 preferences);
1755 body = MBUtil.getEmailMessageAddedBody(preferences);
1756 signature = MBUtil.getEmailMessageAddedSignature(preferences);
1757 }
1758
1759 if (Validator.isNotNull(signature)) {
1760 body += "\n--\n" + signature;
1761 }
1762
1763 subjectPrefix = StringUtil.replace(
1764 subjectPrefix,
1765 new String[] {
1766 "[$CATEGORY_NAME$]",
1767 "[$COMPANY_ID$]",
1768 "[$COMPANY_MX$]",
1769 "[$COMPANY_NAME$]",
1770 "[$COMMUNITY_NAME$]",
1771 "[$FROM_ADDRESS$]",
1772 "[$FROM_NAME$]",
1773 "[$MAILING_LIST_ADDRESS$]",
1774 "[$MESSAGE_BODY$]",
1775 "[$MESSAGE_ID$]",
1776 "[$MESSAGE_SUBJECT$]",
1777 "[$MESSAGE_USER_ADDRESS$]",
1778 "[$MESSAGE_USER_NAME$]",
1779 "[$PORTAL_URL$]",
1780 "[$PORTLET_NAME$]"
1781 },
1782 new String[] {
1783 category.getName(),
1784 String.valueOf(company.getCompanyId()),
1785 company.getMx(),
1786 company.getName(),
1787 group.getName(),
1788 fromAddress,
1789 fromName,
1790 mailingListAddress,
1791 message.getBody(),
1792 String.valueOf(message.getMessageId()),
1793 message.getSubject(),
1794 emailAddress,
1795 fullName,
1796 company.getVirtualHost(),
1797 portletName
1798 });
1799
1800 body = StringUtil.replace(
1801 body,
1802 new String[] {
1803 "[$CATEGORY_NAME$]",
1804 "[$COMPANY_ID$]",
1805 "[$COMPANY_MX$]",
1806 "[$COMPANY_NAME$]",
1807 "[$COMMUNITY_NAME$]",
1808 "[$FROM_ADDRESS$]",
1809 "[$FROM_NAME$]",
1810 "[$MAILING_LIST_ADDRESS$]",
1811 "[$MESSAGE_BODY$]",
1812 "[$MESSAGE_ID$]",
1813 "[$MESSAGE_SUBJECT$]",
1814 "[$MESSAGE_URL$]",
1815 "[$MESSAGE_USER_ADDRESS$]",
1816 "[$MESSAGE_USER_NAME$]",
1817 "[$PORTAL_URL$]",
1818 "[$PORTLET_NAME$]"
1819 },
1820 new String[] {
1821 category.getName(),
1822 String.valueOf(company.getCompanyId()),
1823 company.getMx(),
1824 company.getName(),
1825 group.getName(),
1826 fromAddress,
1827 fromName,
1828 mailingListAddress,
1829 message.getBody(),
1830 String.valueOf(message.getMessageId()),
1831 message.getSubject(),
1832 messageURL,
1833 emailAddress,
1834 fullName,
1835 company.getVirtualHost(),
1836 portletName
1837 });
1838
1839 String subject = message.getSubject();
1840
1841 if (subject.indexOf(subjectPrefix) == -1) {
1842 subject = subjectPrefix.trim() + " " + subject.trim();
1843 }
1844
1845 String inReplyTo = null;
1846
1847 if (message.getParentMessageId() !=
1848 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
1849
1850 inReplyTo = MBUtil.getMailId(
1851 company.getMx(), message.getCategoryId(),
1852 message.getParentMessageId());
1853 }
1854
1855 com.liferay.portal.kernel.messaging.Message messagingObj =
1856 new com.liferay.portal.kernel.messaging.Message();
1857
1858 messagingObj.put("companyId", message.getCompanyId());
1859 messagingObj.put("userId", message.getUserId());
1860 messagingObj.put("groupId", message.getGroupId());
1861 messagingObj.put("categoryIds", StringUtil.merge(categoryIds));
1862 messagingObj.put("threadId", message.getThreadId());
1863 messagingObj.put("fromName", fromName);
1864 messagingObj.put("fromAddress", fromAddress);
1865 messagingObj.put("subject", subject);
1866 messagingObj.put("body", body);
1867 messagingObj.put("replyToAddress", replyToAddress);
1868 messagingObj.put("mailId", mailId);
1869 messagingObj.put("inReplyTo", inReplyTo);
1870 messagingObj.put("htmlFormat", htmlFormat);
1871 messagingObj.put(
1872 "sourceMailingList", MailingListThreadLocal.isSourceMailingList());
1873
1874 MessageBusUtil.sendMessage(
1875 DestinationNames.MESSAGE_BOARDS, messagingObj);
1876 }
1877
1878 protected void pingPingback(
1879 MBMessage message, ServiceContext serviceContext) {
1880
1881 if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
1882 !message.isAllowPingbacks() ||
1883 (message.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
1884
1885 return;
1886 }
1887
1888 String layoutFullURL = serviceContext.getLayoutFullURL();
1889
1890 if (Validator.isNull(layoutFullURL)) {
1891 return;
1892 }
1893
1894 String sourceUri =
1895 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
1896 "message_boards/message/" + message.getMessageId();
1897
1898 Source source = new Source(message.getBody(true));
1899
1900 List<StartTag> startTags = source.getAllStartTags("a");
1901
1902 for (StartTag startTag : startTags) {
1903 String targetUri = startTag.getAttributeValue("href");
1904
1905 if (Validator.isNotNull(targetUri)) {
1906 try {
1907 LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
1908 }
1909 catch (Exception e) {
1910 _log.error("Error while sending pingback " + targetUri, e);
1911 }
1912 }
1913 }
1914 }
1915
1916 protected void sendBlogsCommentsEmail(
1917 long userId, BlogsEntry entry, MBMessage message,
1918 ServiceContext serviceContext)
1919 throws IOException, PortalException, SystemException {
1920
1921 long companyId = message.getCompanyId();
1922
1923 if (!PrefsPropsUtil.getBoolean(
1924 companyId, PropsKeys.BLOGS_EMAIL_COMMENTS_ADDED_ENABLED)) {
1925
1926 return;
1927 }
1928
1929 String layoutFullURL = serviceContext.getLayoutFullURL();
1930
1931 String blogsEntryURL =
1932 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs/" +
1933 entry.getUrlTitle();
1934
1935 User user = userPersistence.findByPrimaryKey(userId);
1936
1937 String fromName = PrefsPropsUtil.getString(
1938 companyId, PropsKeys.ADMIN_EMAIL_FROM_NAME);
1939 String fromAddress = PrefsPropsUtil.getString(
1940 companyId, PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
1941
1942 String subject = PrefsPropsUtil.getContent(
1943 companyId, PropsKeys.BLOGS_EMAIL_COMMENTS_ADDED_SUBJECT);
1944 String body = PrefsPropsUtil.getContent(
1945 companyId, PropsKeys.BLOGS_EMAIL_COMMENTS_ADDED_BODY);
1946
1947 subject = StringUtil.replace(
1948 subject,
1949 new String[] {
1950 "[$BLOGS_COMMENTS_BODY$]",
1951 "[$BLOGS_COMMENTS_USER_ADDRESS$]",
1952 "[$BLOGS_COMMENTS_USER_NAME$]",
1953 "[$BLOGS_ENTRY_URL$]",
1954 "[$FROM_ADDRESS$]",
1955 "[$FROM_NAME$]"
1956 },
1957 new String[] {
1958 message.getBody(),
1959 user.getEmailAddress(),
1960 user.getFullName(),
1961 blogsEntryURL,
1962 fromAddress,
1963 fromName
1964 });
1965
1966 body = StringUtil.replace(
1967 body,
1968 new String[] {
1969 "[$BLOGS_COMMENTS_BODY$]",
1970 "[$BLOGS_COMMENTS_USER_ADDRESS$]",
1971 "[$BLOGS_COMMENTS_USER_NAME$]",
1972 "[$BLOGS_ENTRY_URL$]",
1973 "[$FROM_ADDRESS$]",
1974 "[$FROM_NAME$]"
1975 },
1976 new String[] {
1977 message.getBody(),
1978 user.getEmailAddress(),
1979 user.getFullName(),
1980 blogsEntryURL,
1981 fromAddress,
1982 fromName
1983 });
1984
1985 Set<Long> sent = new HashSet<Long>();
1986
1987 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
1988 message.getThreadId());
1989
1990 for (MBMessage curMessage : messages) {
1991 long curMessageUserId = curMessage.getUserId();
1992
1993 if (curMessageUserId == userId) {
1994 continue;
1995 }
1996
1997 if (sent.contains(curMessageUserId)) {
1998 if (_log.isDebugEnabled()) {
1999 _log.debug(
2000 "Do not send a duplicate email to user " +
2001 curMessageUserId);
2002 }
2003
2004 continue;
2005 }
2006 else {
2007 if (_log.isDebugEnabled()) {
2008 _log.debug(
2009 "Add user " + curMessageUserId +
2010 " to the list of users who have received an email");
2011 }
2012
2013 sent.add(curMessageUserId);
2014 }
2015
2016 User curMessageUser = null;
2017
2018 try {
2019 curMessageUser = userLocalService.getUserById(curMessageUserId);
2020 }
2021 catch (NoSuchUserException nsue) {
2022 continue;
2023 }
2024
2025 if (!curMessageUser.isActive()) {
2026 continue;
2027 }
2028
2029 InternetAddress from = new InternetAddress(fromAddress, fromName);
2030
2031 InternetAddress to = new InternetAddress(
2032 curMessageUser.getEmailAddress(), curMessageUser.getFullName());
2033
2034 String curSubject = StringUtil.replace(
2035 subject,
2036 new String[] {
2037 "[$TO_ADDRESS$]",
2038 "[$TO_NAME$]"
2039 },
2040 new String[] {
2041 curMessageUser.getFullName(),
2042 curMessageUser.getEmailAddress()
2043 });
2044
2045 String curBody = StringUtil.replace(
2046 body,
2047 new String[] {
2048 "[$TO_ADDRESS$]",
2049 "[$TO_NAME$]"
2050 },
2051 new String[] {
2052 curMessageUser.getFullName(),
2053 curMessageUser.getEmailAddress()
2054 });
2055
2056 MailMessage mailMessage = new MailMessage(
2057 from, to, curSubject, curBody, true);
2058
2059 mailService.sendEmail(mailMessage);
2060 }
2061 }
2062
2063 protected void updateDiscussionMessageStatus(
2064 long userId, long messageId, int status,
2065 ServiceContext serviceContext)
2066 throws PortalException, SystemException {
2067
2068 String className = (String)serviceContext.getAttribute("className");
2069 long classPK = GetterUtil.getLong(
2070 (String)serviceContext.getAttribute("classPK"));
2071
2072 MBMessage message = getMessage(messageId);
2073
2074 int oldStatus = message.getStatus();
2075
2076 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
2077 (status == WorkflowConstants.STATUS_APPROVED)) {
2078
2079
2081 if (!message.isRoot()) {
2082 socialEquityLogLocalService.addEquityLogs(
2083 userId, className, classPK, ActionKeys.ADD_DISCUSSION);
2084 }
2085
2086 long parentMessageId = message.getParentMessageId();
2087
2088 if (className.equals(BlogsEntry.class.getName()) &&
2089 (parentMessageId !=
2090 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID)) {
2091
2092
2094 BlogsEntry entry = blogsEntryPersistence.findByPrimaryKey(
2095 classPK);
2096
2097 JSONObject extraData = JSONFactoryUtil.createJSONObject();
2098
2099 extraData.put("messageId", message.getMessageId());
2100
2101 socialActivityLocalService.addActivity(
2102 userId, entry.getGroupId(), BlogsEntry.class.getName(),
2103 classPK, BlogsActivityKeys.ADD_COMMENT,
2104 extraData.toString(), entry.getUserId());
2105
2106
2108 try {
2109 sendBlogsCommentsEmail(
2110 userId, entry, message, serviceContext);
2111 }
2112 catch (Exception e) {
2113 _log.error(e, e);
2114 }
2115 }
2116 }
2117 }
2118
2119 protected void updatePriorities(long threadId, double priority)
2120 throws SystemException {
2121
2122 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
2123 threadId);
2124
2125 for (MBMessage message : messages) {
2126 if (message.getPriority() != priority) {
2127 message.setPriority(priority);
2128
2129 mbMessagePersistence.update(message, false);
2130 }
2131 }
2132 }
2133
2134 protected void validate(String subject, String body)
2135 throws PortalException {
2136
2137 if (Validator.isNull(subject)) {
2138 throw new MessageSubjectException();
2139 }
2140
2141 if (Validator.isNull(body)) {
2142 throw new MessageBodyException();
2143 }
2144 }
2145
2146 private static Log _log = LogFactoryUtil.getLog(
2147 MBMessageLocalServiceImpl.class);
2148
2149}