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