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 (!MBUtil.isDefaultParentCategoryId(message.getCategoryId()) &&
589 !MBUtil.isDiscussionCategoryId(message.getCategoryId())) {
590
591 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
592 message.getCategoryId());
593
594 category.setThreadCount(category.getThreadCount() - 1);
595 category.setMessageCount(category.getMessageCount() - 1);
596
597 mbCategoryPersistence.update(category, false);
598 }
599 }
600 else if (count > 1) {
601 MBThread thread = mbThreadPersistence.findByPrimaryKey(
602 message.getThreadId());
603
604
605
606 if (thread.getRootMessageId() == message.getMessageId()) {
607 List<MBMessage> childrenMessages =
608 mbMessagePersistence.findByT_P(
609 message.getThreadId(), message.getMessageId());
610
611 if (childrenMessages.size() > 1) {
612 throw new RequiredMessageException(
613 String.valueOf(message.getMessageId()));
614 }
615 else if (childrenMessages.size() == 1) {
616 MBMessage childMessage = childrenMessages.get(0);
617
618 childMessage.setRootMessageId(childMessage.getMessageId());
619 childMessage.setParentMessageId(
620 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
621
622 mbMessagePersistence.update(childMessage, false);
623
624 thread.setRootMessageId(childMessage.getMessageId());
625
626 mbThreadPersistence.update(thread, false);
627 }
628 }
629
630
631
632 else {
633 List<MBMessage> childrenMessages =
634 mbMessagePersistence.findByT_P(
635 message.getThreadId(), message.getMessageId());
636
637
638
639 if (childrenMessages.size() > 0) {
640 Iterator<MBMessage> itr = childrenMessages.iterator();
641
642 while (itr.hasNext()) {
643 MBMessage childMessage = itr.next();
644
645 childMessage.setParentMessageId(
646 message.getParentMessageId());
647
648 mbMessagePersistence.update(childMessage, false);
649 }
650 }
651 }
652
653
654
655 thread.setMessageCount(count - 1);
656
657 mbThreadPersistence.update(thread, false);
658
659
660
661 if (!MBUtil.isDefaultParentCategoryId(message.getCategoryId()) &&
662 !MBUtil.isDiscussionCategoryId(message.getCategoryId())) {
663
664 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
665 message.getCategoryId());
666
667 category.setMessageCount(category.getMessageCount() - 1);
668
669 mbCategoryPersistence.update(category, false);
670 }
671 }
672
673
674
675 assetEntryLocalService.deleteEntry(
676 MBMessage.class.getName(), message.getMessageId());
677
678
679
680 expandoValueLocalService.deleteValues(
681 MBMessage.class.getName(), message.getMessageId());
682
683
684
685 socialActivityLocalService.deleteActivities(
686 MBMessage.class.getName(), message.getMessageId());
687
688
689
690 ratingsStatsLocalService.deleteStats(
691 MBMessage.class.getName(), message.getMessageId());
692
693
694
695 if (!message.isDiscussion()) {
696 mbStatsUserLocalService.updateStatsUser(
697 message.getGroupId(), message.getUserId());
698 }
699
700
701
702 mbMessageFlagPersistence.removeByMessageId(message.getMessageId());
703
704
705
706 if (!message.isDiscussion()) {
707 resourceLocalService.deleteResource(
708 message.getCompanyId(), MBMessage.class.getName(),
709 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
710 }
711
712
713
714 mbMessagePersistence.remove(message);
715
716
717
718 workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
719 message.getCompanyId(), message.getGroupId(),
720 message.getWorkflowClassName(), message.getMessageId());
721 }
722
723 public List<MBMessage> getCategoryMessages(
724 long groupId, long categoryId, int status, int start, int end)
725 throws SystemException {
726
727 if (status == WorkflowConstants.STATUS_ANY) {
728 return mbMessagePersistence.findByG_C(
729 groupId, categoryId, start, end);
730 }
731 else {
732 return mbMessagePersistence.findByG_C_S(
733 groupId, categoryId, status, start, end);
734 }
735 }
736
737 public List<MBMessage> getCategoryMessages(
738 long groupId, long categoryId, int status, int start, int end,
739 OrderByComparator obc)
740 throws SystemException {
741
742 if (status == WorkflowConstants.STATUS_ANY) {
743 return mbMessagePersistence.findByG_C(
744 groupId, categoryId, start, end, obc);
745 }
746 else {
747 return mbMessagePersistence.findByG_C_S(
748 groupId, categoryId, status, start, end, obc);
749 }
750 }
751
752 public int getCategoryMessagesCount(
753 long groupId, long categoryId, int status)
754 throws SystemException {
755
756 if (status == WorkflowConstants.STATUS_ANY) {
757 return mbMessagePersistence.countByG_C(groupId, categoryId);
758 }
759 else {
760 return mbMessagePersistence.countByG_C_S(
761 groupId, categoryId, status);
762 }
763 }
764
765 public List<MBMessage> getCompanyMessages(
766 long companyId, int status, int start, int end)
767 throws SystemException {
768
769 if (status == WorkflowConstants.STATUS_ANY) {
770 return mbMessagePersistence.findByCompanyId(companyId, start, end);
771 }
772 else {
773 return mbMessagePersistence.findByC_S(
774 companyId, status, start, end);
775 }
776 }
777
778 public List<MBMessage> getCompanyMessages(
779 long companyId, int status, int start, int end,
780 OrderByComparator obc)
781 throws SystemException {
782
783 if (status == WorkflowConstants.STATUS_ANY) {
784 return mbMessagePersistence.findByCompanyId(
785 companyId, start, end, obc);
786 }
787 else {
788 return mbMessagePersistence.findByC_S(
789 companyId, status, start, end, obc);
790 }
791 }
792
793 public int getCompanyMessagesCount(long companyId, int status)
794 throws SystemException {
795
796 if (status == WorkflowConstants.STATUS_ANY) {
797 return mbMessagePersistence.countByCompanyId(companyId);
798 }
799 else {
800 return mbMessagePersistence.countByC_S(companyId, status);
801 }
802 }
803
804 public MBMessageDisplay getDiscussionMessageDisplay(
805 long userId, long groupId, String className, long classPK,
806 int status)
807 throws PortalException, SystemException {
808
809 return getDiscussionMessageDisplay(
810 userId, groupId, className, classPK, status,
811 MBThreadConstants.THREAD_VIEW_COMBINATION);
812 }
813
814 public MBMessageDisplay getDiscussionMessageDisplay(
815 long userId, long groupId, String className, long classPK,
816 int status, String threadView)
817 throws PortalException, SystemException {
818
819 long classNameId = PortalUtil.getClassNameId(className);
820
821 MBMessage message = null;
822
823 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
824 classNameId, classPK);
825
826 if (discussion != null) {
827 List<MBMessage> messages = mbMessagePersistence.findByT_P(
828 discussion.getThreadId(),
829 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
830
831 message = messages.get(0);
832 }
833 else {
834 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
835
836 WorkflowThreadLocal.setEnabled(false);
837
838 try {
839 String subject = String.valueOf(classPK);
840
841
842 message = addDiscussionMessage(
843 userId, null, groupId, className, classPK, 0,
844 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, subject,
845 subject, new ServiceContext());
846 }
847 catch (SystemException se) {
848 if (_log.isWarnEnabled()) {
849 _log.warn(
850 "Add failed, fetch {threadId=0, parentMessageId=" +
851 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID + "}");
852 }
853
854 List<MBMessage> messages = mbMessagePersistence.findByT_P(
855 0, MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
856
857 if (messages.isEmpty()) {
858 throw se;
859 }
860
861 message = messages.get(0);
862 }
863 finally {
864 WorkflowThreadLocal.setEnabled(workflowEnabled);
865 }
866 }
867
868 return getMessageDisplay(message, status, threadView, false);
869 }
870
871 public int getDiscussionMessagesCount(
872 long classNameId, long classPK, int status)
873 throws SystemException {
874
875 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
876 classNameId, classPK);
877
878 if (discussion == null) {
879 return 0;
880 }
881
882 int count = 0;
883
884 if (status == WorkflowConstants.STATUS_ANY) {
885 count = mbMessagePersistence.countByThreadId(
886 discussion.getThreadId());
887 }
888 else {
889 count = mbMessagePersistence.countByT_S(
890 discussion.getThreadId(), status);
891 }
892
893 if (count >= 1) {
894 return count - 1;
895 }
896 else {
897 return 0;
898 }
899 }
900
901 public int getDiscussionMessagesCount(
902 String className, long classPK, int status)
903 throws SystemException {
904
905 long classNameId = PortalUtil.getClassNameId(className);
906
907 return getDiscussionMessagesCount(classNameId, classPK, status);
908 }
909
910 public List<MBDiscussion> getDiscussions(String className)
911 throws SystemException {
912
913 long classNameId = PortalUtil.getClassNameId(className);
914
915 return mbDiscussionPersistence.findByClassNameId(classNameId);
916 }
917
918 public List<MBMessage> getGroupMessages(
919 long groupId, int status, int start, int end)
920 throws SystemException {
921
922 if (status == WorkflowConstants.STATUS_ANY) {
923 return mbMessagePersistence.findByGroupId(groupId, start, end);
924 }
925 else {
926 return mbMessagePersistence.findByG_S(groupId, status, start, end);
927 }
928 }
929
930 public List<MBMessage> getGroupMessages(
931 long groupId, int status, int start, int end, OrderByComparator obc)
932 throws SystemException {
933
934 if (status == WorkflowConstants.STATUS_ANY) {
935 return mbMessagePersistence.findByGroupId(groupId, start, end, obc);
936 }
937 else {
938 return mbMessagePersistence.findByG_S(
939 groupId, status, start, end, obc);
940 }
941 }
942
943 public List<MBMessage> getGroupMessages(
944 long groupId, long userId, int status, int start, int end)
945 throws SystemException {
946
947 if (status == WorkflowConstants.STATUS_ANY) {
948 return mbMessagePersistence.findByG_U(groupId, userId, start, end);
949 }
950 else {
951 return mbMessagePersistence.findByG_U_S(
952 groupId, userId, status, start, end);
953 }
954 }
955
956 public List<MBMessage> getGroupMessages(
957 long groupId, long userId, int status, int start, int end,
958 OrderByComparator obc)
959 throws SystemException {
960
961 if (status == WorkflowConstants.STATUS_ANY) {
962 return mbMessagePersistence.findByG_U(
963 groupId, userId, start, end, obc);
964 }
965 else {
966 return mbMessagePersistence.findByG_U_S(
967 groupId, userId, status, start, end, obc);
968 }
969 }
970
971 public int getGroupMessagesCount(long groupId, int status)
972 throws SystemException {
973
974 if (status == WorkflowConstants.STATUS_ANY) {
975 return mbMessagePersistence.countByGroupId(groupId);
976 }
977 else {
978 return mbMessagePersistence.countByG_S(groupId, status);
979 }
980 }
981
982 public int getGroupMessagesCount(long groupId, long userId, int status)
983 throws SystemException {
984
985 if (status == WorkflowConstants.STATUS_ANY) {
986 return mbMessagePersistence.countByG_U(groupId, userId);
987 }
988 else {
989 return mbMessagePersistence.countByG_U_S(groupId, userId, status);
990 }
991 }
992
993 public MBMessage getMessage(long messageId)
994 throws PortalException, SystemException {
995
996 return mbMessagePersistence.findByPrimaryKey(messageId);
997 }
998
999 public MBMessageDisplay getMessageDisplay(
1000 long messageId, int status, String threadView,
1001 boolean includePrevAndNext)
1002 throws PortalException, SystemException {
1003
1004 MBMessage message = getMessage(messageId);
1005
1006 return getMessageDisplay(
1007 message, status, threadView, includePrevAndNext);
1008 }
1009
1010 public MBMessageDisplay getMessageDisplay(
1011 MBMessage message, int status, String threadView,
1012 boolean includePrevAndNext)
1013 throws PortalException, SystemException {
1014
1015 MBCategory category = null;
1016
1017 if (!MBUtil.isDefaultParentCategoryId(message.getCategoryId()) &&
1018 !MBUtil.isDiscussionCategoryId(message.getCategoryId())) {
1019
1020 category = mbCategoryPersistence.findByPrimaryKey(
1021 message.getCategoryId());
1022 }
1023 else {
1024 category = new MBCategoryImpl();
1025
1026 category.setCategoryId(message.getCategoryId());
1027 }
1028
1029 MBMessage parentMessage = null;
1030
1031 if (message.isReply()) {
1032 parentMessage = mbMessagePersistence.findByPrimaryKey(
1033 message.getParentMessageId());
1034 }
1035
1036 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1037 message.getThreadId());
1038
1039 if (!message.isDiscussion() &&
1040 (message.getStatus() == WorkflowConstants.STATUS_APPROVED)) {
1041
1042 mbThreadLocalService.updateThread(
1043 thread.getThreadId(), thread.getViewCount() + 1);
1044 }
1045
1046 MBThread previousThread = null;
1047 MBThread nextThread = null;
1048
1049 if ((message.getStatus() == WorkflowConstants.STATUS_APPROVED) &&
1050 includePrevAndNext) {
1051
1052 ThreadLastPostDateComparator comparator =
1053 new ThreadLastPostDateComparator(false);
1054
1055 MBThread[] prevAndNextThreads =
1056 mbThreadPersistence.findByG_C_PrevAndNext(
1057 message.getThreadId(), message.getGroupId(),
1058 message.getCategoryId(), comparator);
1059
1060 previousThread = prevAndNextThreads[0];
1061 nextThread = prevAndNextThreads[2];
1062 }
1063
1064 return new MBMessageDisplayImpl(
1065 message, parentMessage, category, thread,
1066 previousThread, nextThread, status, threadView);
1067 }
1068
1069 public List<MBMessage> getMessages(
1070 String className, long classPK, int status)
1071 throws SystemException {
1072
1073 long classNameId = PortalUtil.getClassNameId(className);
1074
1075 if (status == WorkflowConstants.STATUS_ANY) {
1076 return mbMessagePersistence.findByC_C(classNameId, classPK);
1077 }
1078 else {
1079 return mbMessagePersistence.findByC_C_S(
1080 classNameId, classPK, status);
1081 }
1082 }
1083
1084 public List<MBMessage> getNoAssetMessages() throws SystemException {
1085 return mbMessageFinder.findByNoAssets();
1086 }
1087
1088 public int getPositionInThread(long messageId)
1089 throws PortalException, SystemException {
1090
1091 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1092
1093 return mbMessageFinder.countByC_T(
1094 message.getCreateDate(), message.getThreadId());
1095 }
1096
1097 public List<MBMessage> getThreadMessages(long threadId, int status)
1098 throws SystemException {
1099
1100 return getThreadMessages(
1101 threadId, status, new MessageThreadComparator());
1102 }
1103
1104 public List<MBMessage> getThreadMessages(
1105 long threadId, int status, Comparator<MBMessage> comparator)
1106 throws SystemException {
1107
1108 List<MBMessage> messages = null;
1109
1110 if (status == WorkflowConstants.STATUS_ANY) {
1111 messages = mbMessagePersistence.findByThreadId(threadId);
1112 }
1113 else {
1114 messages = mbMessagePersistence.findByT_S(threadId, status);
1115 }
1116
1117 return ListUtil.sort(messages, comparator);
1118 }
1119
1120 public List<MBMessage> getThreadMessages(
1121 long threadId, int status, int start, int end)
1122 throws SystemException {
1123
1124 if (status == WorkflowConstants.STATUS_ANY) {
1125 return mbMessagePersistence.findByThreadId(threadId, start, end);
1126 }
1127 else {
1128 return mbMessagePersistence.findByT_S(threadId, status, start, end);
1129 }
1130 }
1131
1132 public int getThreadMessagesCount(long threadId, int status)
1133 throws SystemException {
1134
1135 if (status == WorkflowConstants.STATUS_ANY) {
1136 return mbMessagePersistence.countByThreadId(threadId);
1137 }
1138 else {
1139 return mbMessagePersistence.countByT_S(threadId, status);
1140 }
1141 }
1142
1143 public List<MBMessage> getThreadRepliesMessages(
1144 long threadId, int status, int start, int end)
1145 throws SystemException {
1146
1147 if (status == WorkflowConstants.STATUS_ANY) {
1148 return mbMessagePersistence.findByThreadReplies(
1149 threadId, start, end);
1150 }
1151 else {
1152 return mbMessagePersistence.findByTR_S(
1153 threadId, status, start, end);
1154 }
1155 }
1156
1157 public void subscribeMessage(long userId, long messageId)
1158 throws PortalException, SystemException {
1159
1160 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1161
1162 subscriptionLocalService.addSubscription(
1163 userId, MBThread.class.getName(), message.getThreadId());
1164 }
1165
1166 public void unsubscribeMessage(long userId, long messageId)
1167 throws PortalException, SystemException {
1168
1169 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1170
1171 subscriptionLocalService.deleteSubscription(
1172 userId, MBThread.class.getName(), message.getThreadId());
1173 }
1174
1175 public void updateAsset(
1176 long userId, MBMessage message, long[] assetCategoryIds,
1177 String[] assetTagNames)
1178 throws PortalException, SystemException {
1179
1180 boolean visible = false;
1181
1182 if ((message.getStatus() == WorkflowConstants.STATUS_APPROVED) &&
1183 ((message.getClassNameId() == 0) ||
1184 (message.getParentMessageId() != 0))) {
1185
1186 visible = true;
1187 }
1188
1189 assetEntryLocalService.updateEntry(
1190 userId, message.getGroupId(), message.getWorkflowClassName(),
1191 message.getMessageId(), message.getUuid(), assetCategoryIds,
1192 assetTagNames, visible, null, null, null, null,
1193 ContentTypes.TEXT_HTML, message.getSubject(), null, null, null, 0,
1194 0, null, false);
1195 }
1196
1197 public MBMessage updateDiscussionMessage(
1198 long userId, long messageId, String subject, String body,
1199 int workflowAction)
1200 throws PortalException, SystemException {
1201
1202 if (Validator.isNull(subject)) {
1203 subject = body.substring(0, Math.min(body.length(), 50)) + "...";
1204 }
1205
1206 List<ObjectValuePair<String, byte[]>> files =
1207 new ArrayList<ObjectValuePair<String, byte[]>>();
1208 List<String> existingFiles = new ArrayList<String>();
1209 double priority = 0.0;
1210 boolean allowPingbacks = false;
1211
1212 ServiceContext serviceContext = new ServiceContext();
1213
1214 serviceContext.setWorkflowAction(workflowAction);
1215
1216 return updateMessage(
1217 userId, messageId, subject, body, files, existingFiles, priority,
1218 allowPingbacks, serviceContext);
1219 }
1220
1221 public MBMessage updateMessage(
1222 long userId, long messageId, String subject, String body,
1223 List<ObjectValuePair<String, byte[]>> files,
1224 List<String> existingFiles, double priority, boolean allowPingbacks,
1225 ServiceContext serviceContext)
1226 throws PortalException, SystemException {
1227
1228
1229
1230 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1231
1232 subject = ModelHintsUtil.trimString(
1233 MBMessage.class.getName(), "subject", subject);
1234 Date now = new Date();
1235
1236 validate(subject, body);
1237
1238 message.setModifiedDate(serviceContext.getModifiedDate(now));
1239 message.setSubject(subject);
1240 message.setBody(body);
1241 message.setAttachments(!files.isEmpty() || !existingFiles.isEmpty());
1242 message.setAllowPingbacks(allowPingbacks);
1243
1244 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
1245 message.setPriority(priority);
1246 }
1247
1248
1249
1250 long companyId = message.getCompanyId();
1251 String portletId = CompanyConstants.SYSTEM_STRING;
1252 long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
1253 long repositoryId = CompanyConstants.SYSTEM;
1254 String dirName = message.getAttachmentsDir();
1255
1256 if (!files.isEmpty() || !existingFiles.isEmpty()) {
1257 try {
1258 dlService.addDirectory(companyId, repositoryId, dirName);
1259 }
1260 catch (DuplicateDirectoryException dde) {
1261 }
1262
1263 String[] fileNames = dlService.getFileNames(
1264 companyId, repositoryId, dirName);
1265
1266 for (String fileName: fileNames) {
1267 if (!existingFiles.contains(fileName)) {
1268 dlService.deleteFile(
1269 companyId, portletId, repositoryId, fileName);
1270 }
1271 }
1272
1273 for (int i = 0; i < files.size(); i++) {
1274 ObjectValuePair<String, byte[]> ovp = files.get(i);
1275
1276 String fileName = ovp.getKey();
1277 byte[] bytes = ovp.getValue();
1278
1279 try {
1280 dlService.addFile(
1281 companyId, portletId, groupId, repositoryId,
1282 dirName + "/" + fileName, 0, StringPool.BLANK,
1283 message.getModifiedDate(), new ServiceContext(), bytes);
1284 }
1285 catch (DuplicateFileException dfe) {
1286 }
1287 }
1288 }
1289 else {
1290 try {
1291 dlService.deleteDirectory(
1292 companyId, portletId, repositoryId, dirName);
1293 }
1294 catch (NoSuchDirectoryException nsde) {
1295 }
1296 }
1297
1298 mbMessagePersistence.update(message, false);
1299
1300
1301
1302 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1303 message.getThreadId());
1304
1305 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
1306 (thread.getPriority() != priority)) {
1307
1308 thread.setPriority(priority);
1309
1310 mbThreadPersistence.update(thread, false);
1311
1312 updatePriorities(thread.getThreadId(), priority);
1313 }
1314
1315
1316
1317 updateAsset(
1318 userId, message, serviceContext.getAssetCategoryIds(),
1319 serviceContext.getAssetTagNames());
1320
1321
1322
1323 ExpandoBridge expandoBridge = message.getExpandoBridge();
1324
1325 expandoBridge.setAttributes(serviceContext);
1326
1327
1328
1329 serviceContext.setAttribute("update", Boolean.TRUE.toString());
1330
1331 WorkflowHandlerRegistryUtil.startWorkflowInstance(
1332 companyId, message.getGroupId(), userId,
1333 message.getWorkflowClassName(), message.getMessageId(), message,
1334 serviceContext);
1335
1336 return message;
1337 }
1338
1339 public MBMessage updateMessage(long messageId, String body)
1340 throws PortalException, SystemException {
1341
1342 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1343
1344 message.setBody(body);
1345
1346 mbMessagePersistence.update(message, false);
1347
1348 return message;
1349 }
1350
1351 public MBMessage updateStatus(
1352 long userId, long messageId, int status,
1353 ServiceContext serviceContext)
1354 throws PortalException, SystemException {
1355
1356 MBMessage message = getMessage(messageId);
1357
1358 int oldStatus = message.getStatus();
1359
1360 User user = userPersistence.findByPrimaryKey(userId);
1361 Date now = new Date();
1362
1363 message.setStatus(status);
1364 message.setStatusByUserId(userId);
1365 message.setStatusByUserName(user.getFullName());
1366 message.setStatusDate(serviceContext.getModifiedDate(now));
1367
1368 mbMessagePersistence.update(message, false);
1369
1370
1371
1372 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1373 message.getThreadId());
1374
1375 MBCategory category = null;
1376
1377 if (!MBUtil.isDefaultParentCategoryId(thread.getCategoryId()) &&
1378 !MBUtil.isDiscussionCategoryId(thread.getCategoryId())) {
1379
1380 category = mbCategoryPersistence.findByPrimaryKey(
1381 thread.getCategoryId());
1382 }
1383
1384 if ((thread.getRootMessageId() == message.getMessageId()) &&
1385 (oldStatus != status)) {
1386
1387 thread.setStatus(status);
1388 thread.setStatusByUserId(userId);
1389 thread.setStatusByUserName(user.getFullName());
1390 thread.setStatusDate(serviceContext.getModifiedDate(now));
1391 }
1392
1393 Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
1394
1395 if (status == WorkflowConstants.STATUS_APPROVED) {
1396 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
1397
1398
1399
1400 if ((category != null) &&
1401 (thread.getRootMessageId() == message.getMessageId())) {
1402
1403 category.setThreadCount(category.getThreadCount() + 1);
1404
1405 mbCategoryPersistence.update(category, false);
1406 }
1407
1408 thread.setMessageCount(thread.getMessageCount() + 1);
1409
1410 if (message.isAnonymous()) {
1411 thread.setLastPostByUserId(0);
1412 }
1413 else {
1414 thread.setLastPostByUserId(message.getUserId());
1415 }
1416
1417 thread.setLastPostDate(serviceContext.getModifiedDate(now));
1418
1419
1420
1421 if (category != null) {
1422 category.setMessageCount(category.getMessageCount() + 1);
1423 category.setLastPostDate(
1424 serviceContext.getModifiedDate(now));
1425
1426 mbCategoryPersistence.update(category, false);
1427
1428 }
1429
1430
1431
1432 if ((message.getClassNameId() == 0) ||
1433 (message.getParentMessageId() != 0)) {
1434
1435 assetEntryLocalService.updateVisible(
1436 message.getWorkflowClassName(), message.getMessageId(),
1437 true);
1438 }
1439
1440 if (!message.isDiscussion()) {
1441
1442
1443
1444 if (!message.isAnonymous() && !user.isDefaultUser()) {
1445 int activityType = MBActivityKeys.ADD_MESSAGE;
1446 long receiverUserId = 0;
1447 String actionId = ActionKeys.ADD_MESSAGE;
1448
1449 MBMessage parentMessage =
1450 mbMessagePersistence.fetchByPrimaryKey(
1451 message.getParentMessageId());
1452
1453 if (parentMessage != null) {
1454 activityType = MBActivityKeys.REPLY_MESSAGE;
1455 receiverUserId = parentMessage.getUserId();
1456
1457 if (receiverUserId != userId) {
1458 actionId = ActionKeys.REPLY_TO_MESSAGE;
1459 }
1460 }
1461
1462 socialActivityLocalService.addActivity(
1463 userId, message.getGroupId(),
1464 MBMessage.class.getName(), message.getMessageId(),
1465 activityType, StringPool.BLANK, receiverUserId);
1466
1467 socialEquityLogLocalService.addEquityLogs(
1468 userId, MBMessage.class.getName(), messageId,
1469 actionId);
1470 }
1471 }
1472 else {
1473 String className = (String)serviceContext.getAttribute(
1474 "className");
1475 long classPK = GetterUtil.getLong(
1476 (String)serviceContext.getAttribute("classPK"));
1477
1478
1479
1480 if (!message.isRoot()) {
1481 socialEquityLogLocalService.addEquityLogs(
1482 userId, className, classPK,
1483 ActionKeys.ADD_DISCUSSION);
1484 }
1485
1486 long parentMessageId = message.getParentMessageId();
1487
1488 if (className.equals(BlogsEntry.class.getName()) &&
1489 (parentMessageId !=
1490 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID)) {
1491
1492
1493
1494 BlogsEntry entry =
1495 blogsEntryPersistence.findByPrimaryKey(classPK);
1496
1497 JSONObject extraData =
1498 JSONFactoryUtil.createJSONObject();
1499
1500 extraData.put("messageId", message.getMessageId());
1501
1502 socialActivityLocalService.addActivity(
1503 userId, entry.getGroupId(),
1504 BlogsEntry.class.getName(), classPK,
1505 BlogsActivityKeys.ADD_COMMENT, extraData.toString(),
1506 entry.getUserId());
1507
1508
1509
1510 try {
1511 sendBlogsCommentsEmail(
1512 userId, entry, message, serviceContext);
1513 }
1514 catch (Exception e) {
1515 _log.error(e, e);
1516 }
1517 }
1518 }
1519
1520
1521
1522 notifySubscribers(message, serviceContext);
1523 }
1524
1525
1526
1527 if (!message.isDiscussion()) {
1528 indexer.reindex(message);
1529 }
1530
1531
1532
1533 pingPingback(message, serviceContext);
1534 }
1535 else if ((oldStatus == WorkflowConstants.STATUS_APPROVED) &&
1536 (status != WorkflowConstants.STATUS_APPROVED)) {
1537
1538
1539
1540 if ((category != null) &&
1541 (thread.getRootMessageId() == message.getMessageId())) {
1542
1543 category.setThreadCount(category.getThreadCount() - 1);
1544
1545 mbCategoryPersistence.update(category, false);
1546 }
1547
1548 thread.setMessageCount(thread.getMessageCount() - 1);
1549
1550
1551
1552 if (category != null) {
1553 category.setMessageCount(category.getMessageCount() - 1);
1554
1555 mbCategoryPersistence.update(category, false);
1556 }
1557
1558
1559
1560 assetEntryLocalService.updateVisible(
1561 message.getWorkflowClassName(), message.getMessageId(), false);
1562
1563 if (!message.isDiscussion()) {
1564
1565
1566
1567 indexer.delete(message);
1568 }
1569 }
1570
1571 if (status != oldStatus) {
1572 mbThreadPersistence.update(thread, false);
1573 }
1574
1575
1576
1577 if (!message.isDiscussion()) {
1578 mbStatsUserLocalService.updateStatsUser(
1579 message.getGroupId(), userId,
1580 serviceContext.getModifiedDate(now));
1581 }
1582
1583 return message;
1584 }
1585
1586 public void updateUserName(long userId, String userName)
1587 throws SystemException {
1588
1589 List<MBMessage> messages = mbMessagePersistence.findByUserId(userId);
1590
1591 for (MBMessage message : messages) {
1592 message.setUserName(userName);
1593
1594 mbMessagePersistence.update(message, false);
1595 }
1596 }
1597
1598 protected void deleteDiscussionSocialActivities(
1599 String className, List<MBMessage> messages)
1600 throws PortalException, SystemException {
1601
1602 if (messages.size() == 0) {
1603 return;
1604 }
1605
1606 MBMessage message = messages.get(0);
1607
1608 MBDiscussion discussion = mbDiscussionPersistence.findByThreadId(
1609 message.getThreadId());
1610
1611 long classNameId = PortalUtil.getClassNameId(className);
1612 long classPK = discussion.getClassPK();
1613
1614 if (discussion.getClassNameId() != classNameId) {
1615 return;
1616 }
1617
1618 Set<Long> messageIds = new HashSet<Long>();
1619
1620 for (MBMessage curMessage : messages) {
1621 messageIds.add(curMessage.getMessageId());
1622 }
1623
1624 List<SocialActivity> socialActivities =
1625 socialActivityLocalService.getActivities(
1626 0, className, classPK, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1627
1628 for (SocialActivity socialActivity : socialActivities) {
1629 if (Validator.isNull(socialActivity.getExtraData())) {
1630 continue;
1631 }
1632
1633 JSONObject extraData = JSONFactoryUtil.createJSONObject(
1634 socialActivity.getExtraData());
1635
1636 long extraDataMessageId = extraData.getLong("messageId");
1637
1638 if (messageIds.contains(extraDataMessageId)) {
1639 socialActivityLocalService.deleteActivity(
1640 socialActivity.getActivityId());
1641 }
1642 }
1643 }
1644
1645 protected void notifySubscribers(
1646 MBMessage message, ServiceContext serviceContext)
1647 throws PortalException, SystemException {
1648
1649 if (message.getStatus() != WorkflowConstants.STATUS_APPROVED) {
1650 return;
1651 }
1652
1653 String layoutFullURL = serviceContext.getLayoutFullURL();
1654
1655 if (Validator.isNull(layoutFullURL) || message.isDiscussion()) {
1656 return;
1657 }
1658
1659 PortletPreferences preferences =
1660 ServiceContextUtil.getPortletPreferences(serviceContext);
1661
1662 if (preferences == null) {
1663 long ownerId = message.getGroupId();
1664 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1665 long plid = PortletKeys.PREFS_PLID_SHARED;
1666 String portletId = PortletKeys.MESSAGE_BOARDS;
1667 String defaultPreferences = null;
1668
1669 preferences = portletPreferencesLocalService.getPreferences(
1670 message.getCompanyId(), ownerId, ownerType, plid, portletId,
1671 defaultPreferences);
1672 }
1673
1674 boolean update = GetterUtil.getBoolean(
1675 (String)serviceContext.getAttribute("update"));
1676
1677 if (!update && MBUtil.getEmailMessageAddedEnabled(preferences)) {
1678 }
1679 else if (update && MBUtil.getEmailMessageUpdatedEnabled(preferences)) {
1680 }
1681 else {
1682 return;
1683 }
1684
1685 Company company = companyPersistence.findByPrimaryKey(
1686 message.getCompanyId());
1687
1688 Group group = groupPersistence.findByPrimaryKey(message.getGroupId());
1689
1690 String emailAddress = StringPool.BLANK;
1691 String fullName = message.getUserName();
1692
1693 try {
1694 User user = userPersistence.findByPrimaryKey(message.getUserId());
1695
1696 emailAddress = user.getEmailAddress();
1697 fullName = user.getFullName();
1698 }
1699 catch (NoSuchUserException nsue) {
1700 }
1701
1702 MBCategory category = message.getCategory();
1703
1704 if (message.isAnonymous()) {
1705 emailAddress = StringPool.BLANK;
1706 fullName = LanguageUtil.get(
1707 ServiceContextUtil.getLocale(serviceContext), "anonymous");
1708 }
1709
1710 String categoryName = category.getName();
1711
1712 if (category.getCategoryId() ==
1713 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
1714
1715 categoryName = LanguageUtil.get(
1716 ServiceContextUtil.getLocale(serviceContext),
1717 "message-boards-home") + StringPool.SPACE + StringPool.DASH +
1718 StringPool.SPACE + group.getName();
1719 }
1720
1721 List<Long> categoryIds = new ArrayList<Long>();
1722
1723 categoryIds.add(message.getCategoryId());
1724
1725 if (!MBUtil.isDefaultParentCategoryId(message.getCategoryId()) &&
1726 !MBUtil.isDiscussionCategoryId(message.getCategoryId())) {
1727
1728 categoryIds.addAll(category.getAncestorCategoryIds());
1729 }
1730
1731 String messageURL =
1732 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
1733 "message_boards/view_message/" + message.getMessageId();
1734
1735 String portletName = PortalUtil.getPortletTitle(
1736 PortletKeys.MESSAGE_BOARDS, LocaleUtil.getDefault());
1737
1738 String fromName = MBUtil.getEmailFromName(preferences);
1739 String fromAddress = MBUtil.getEmailFromAddress(preferences);
1740
1741 String mailingListAddress = StringPool.BLANK;
1742
1743 if (PropsValues.POP_SERVER_NOTIFICATIONS_ENABLED) {
1744 mailingListAddress = MBUtil.getMailingListAddress(
1745 message.getGroupId(), message.getCategoryId(),
1746 message.getMessageId(), company.getMx(), fromAddress);
1747 }
1748
1749 String replyToAddress = mailingListAddress;
1750 String mailId = MBUtil.getMailId(
1751 company.getMx(), message.getCategoryId(), message.getMessageId());
1752
1753 fromName = StringUtil.replace(
1754 fromName,
1755 new String[] {
1756 "[$COMPANY_ID$]",
1757 "[$COMPANY_MX$]",
1758 "[$COMPANY_NAME$]",
1759 "[$COMMUNITY_NAME$]",
1760 "[$MAILING_LIST_ADDRESS$]",
1761 "[$MESSAGE_USER_ADDRESS$]",
1762 "[$MESSAGE_USER_NAME$]",
1763 "[$PORTLET_NAME$]"
1764 },
1765 new String[] {
1766 String.valueOf(company.getCompanyId()),
1767 company.getMx(),
1768 company.getName(),
1769 group.getName(),
1770 mailingListAddress,
1771 emailAddress,
1772 fullName,
1773 portletName
1774 });
1775
1776 fromAddress = StringUtil.replace(
1777 fromAddress,
1778 new String[] {
1779 "[$COMPANY_ID$]",
1780 "[$COMPANY_MX$]",
1781 "[$COMPANY_NAME$]",
1782 "[$COMMUNITY_NAME$]",
1783 "[$MAILING_LIST_ADDRESS$]",
1784 "[$MESSAGE_USER_ADDRESS$]",
1785 "[$MESSAGE_USER_NAME$]",
1786 "[$PORTLET_NAME$]"
1787 },
1788 new String[] {
1789 String.valueOf(company.getCompanyId()),
1790 company.getMx(),
1791 company.getName(),
1792 group.getName(),
1793 mailingListAddress,
1794 emailAddress,
1795 fullName,
1796 portletName
1797 });
1798
1799 String subjectPrefix = null;
1800 String body = null;
1801 String signature = null;
1802 boolean htmlFormat = MBUtil.getEmailHtmlFormat(preferences);
1803
1804 if (update) {
1805 subjectPrefix = MBUtil.getEmailMessageUpdatedSubjectPrefix(
1806 preferences);
1807 body = MBUtil.getEmailMessageUpdatedBody(preferences);
1808 signature = MBUtil.getEmailMessageUpdatedSignature(preferences);
1809 }
1810 else {
1811 subjectPrefix = MBUtil.getEmailMessageAddedSubjectPrefix(
1812 preferences);
1813 body = MBUtil.getEmailMessageAddedBody(preferences);
1814 signature = MBUtil.getEmailMessageAddedSignature(preferences);
1815 }
1816
1817 if (Validator.isNotNull(signature)) {
1818 body += "\n--\n" + signature;
1819 }
1820
1821 subjectPrefix = StringUtil.replace(
1822 subjectPrefix,
1823 new String[] {
1824 "[$CATEGORY_NAME$]",
1825 "[$COMPANY_ID$]",
1826 "[$COMPANY_MX$]",
1827 "[$COMPANY_NAME$]",
1828 "[$COMMUNITY_NAME$]",
1829 "[$FROM_ADDRESS$]",
1830 "[$FROM_NAME$]",
1831 "[$MAILING_LIST_ADDRESS$]",
1832 "[$MESSAGE_BODY$]",
1833 "[$MESSAGE_ID$]",
1834 "[$MESSAGE_SUBJECT$]",
1835 "[$MESSAGE_USER_ADDRESS$]",
1836 "[$MESSAGE_USER_NAME$]",
1837 "[$PORTAL_URL$]",
1838 "[$PORTLET_NAME$]"
1839 },
1840 new String[] {
1841 categoryName,
1842 String.valueOf(company.getCompanyId()),
1843 company.getMx(),
1844 company.getName(),
1845 group.getName(),
1846 fromAddress,
1847 fromName,
1848 mailingListAddress,
1849 message.getBody(),
1850 String.valueOf(message.getMessageId()),
1851 message.getSubject(),
1852 emailAddress,
1853 fullName,
1854 company.getVirtualHost(),
1855 portletName
1856 });
1857
1858 body = StringUtil.replace(
1859 body,
1860 new String[] {
1861 "[$CATEGORY_NAME$]",
1862 "[$COMPANY_ID$]",
1863 "[$COMPANY_MX$]",
1864 "[$COMPANY_NAME$]",
1865 "[$COMMUNITY_NAME$]",
1866 "[$FROM_ADDRESS$]",
1867 "[$FROM_NAME$]",
1868 "[$MAILING_LIST_ADDRESS$]",
1869 "[$MESSAGE_BODY$]",
1870 "[$MESSAGE_ID$]",
1871 "[$MESSAGE_SUBJECT$]",
1872 "[$MESSAGE_URL$]",
1873 "[$MESSAGE_USER_ADDRESS$]",
1874 "[$MESSAGE_USER_NAME$]",
1875 "[$PORTAL_URL$]",
1876 "[$PORTLET_NAME$]"
1877 },
1878 new String[] {
1879 categoryName,
1880 String.valueOf(company.getCompanyId()),
1881 company.getMx(),
1882 company.getName(),
1883 group.getName(),
1884 fromAddress,
1885 fromName,
1886 mailingListAddress,
1887 message.getBody(),
1888 String.valueOf(message.getMessageId()),
1889 message.getSubject(),
1890 messageURL,
1891 emailAddress,
1892 fullName,
1893 company.getVirtualHost(),
1894 portletName
1895 });
1896
1897 String subject = message.getSubject();
1898
1899 if (subject.indexOf(subjectPrefix) == -1) {
1900 subject = subjectPrefix.trim() + " " + subject.trim();
1901 }
1902
1903 String inReplyTo = null;
1904
1905 if (message.getParentMessageId() !=
1906 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
1907
1908 inReplyTo = MBUtil.getMailId(
1909 company.getMx(), message.getCategoryId(),
1910 message.getParentMessageId());
1911 }
1912
1913 com.liferay.portal.kernel.messaging.Message messagingObj =
1914 new com.liferay.portal.kernel.messaging.Message();
1915
1916 messagingObj.put("companyId", message.getCompanyId());
1917 messagingObj.put("userId", message.getUserId());
1918 messagingObj.put("groupId", message.getGroupId());
1919 messagingObj.put("categoryIds", StringUtil.merge(categoryIds));
1920 messagingObj.put("threadId", message.getThreadId());
1921 messagingObj.put("fromName", fromName);
1922 messagingObj.put("fromAddress", fromAddress);
1923 messagingObj.put("subject", subject);
1924 messagingObj.put("body", body);
1925 messagingObj.put("replyToAddress", replyToAddress);
1926 messagingObj.put("mailId", mailId);
1927 messagingObj.put("inReplyTo", inReplyTo);
1928 messagingObj.put("htmlFormat", htmlFormat);
1929 messagingObj.put(
1930 "sourceMailingList", MailingListThreadLocal.isSourceMailingList());
1931
1932 MessageBusUtil.sendMessage(
1933 DestinationNames.MESSAGE_BOARDS, messagingObj);
1934 }
1935
1936 protected void pingPingback(
1937 MBMessage message, ServiceContext serviceContext) {
1938
1939 if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
1940 !message.isAllowPingbacks() ||
1941 (message.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
1942
1943 return;
1944 }
1945
1946 String layoutFullURL = serviceContext.getLayoutFullURL();
1947
1948 if (Validator.isNull(layoutFullURL)) {
1949 return;
1950 }
1951
1952 String sourceUri =
1953 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
1954 "message_boards/view_message/" + message.getMessageId();
1955
1956 Source source = new Source(message.getBody(true));
1957
1958 List<StartTag> startTags = source.getAllStartTags("a");
1959
1960 for (StartTag startTag : startTags) {
1961 String targetUri = startTag.getAttributeValue("href");
1962
1963 if (Validator.isNotNull(targetUri)) {
1964 try {
1965 LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
1966 }
1967 catch (Exception e) {
1968 _log.error("Error while sending pingback " + targetUri, e);
1969 }
1970 }
1971 }
1972 }
1973
1974 protected void sendBlogsCommentsEmail(
1975 long userId, BlogsEntry entry, MBMessage message,
1976 ServiceContext serviceContext)
1977 throws IOException, PortalException, SystemException {
1978
1979 long companyId = message.getCompanyId();
1980
1981 if (!PrefsPropsUtil.getBoolean(
1982 companyId, PropsKeys.BLOGS_EMAIL_COMMENTS_ADDED_ENABLED)) {
1983
1984 return;
1985 }
1986
1987 String layoutFullURL = serviceContext.getLayoutFullURL();
1988
1989 String blogsEntryURL =
1990 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "blogs/" +
1991 entry.getUrlTitle();
1992
1993 User user = userPersistence.findByPrimaryKey(userId);
1994
1995 String fromName = PrefsPropsUtil.getString(
1996 companyId, PropsKeys.ADMIN_EMAIL_FROM_NAME);
1997 String fromAddress = PrefsPropsUtil.getString(
1998 companyId, PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
1999
2000 String subject = PrefsPropsUtil.getContent(
2001 companyId, PropsKeys.BLOGS_EMAIL_COMMENTS_ADDED_SUBJECT);
2002 String body = PrefsPropsUtil.getContent(
2003 companyId, PropsKeys.BLOGS_EMAIL_COMMENTS_ADDED_BODY);
2004
2005 subject = StringUtil.replace(
2006 subject,
2007 new String[] {
2008 "[$BLOGS_COMMENTS_BODY$]",
2009 "[$BLOGS_COMMENTS_USER_ADDRESS$]",
2010 "[$BLOGS_COMMENTS_USER_NAME$]",
2011 "[$BLOGS_ENTRY_URL$]",
2012 "[$FROM_ADDRESS$]",
2013 "[$FROM_NAME$]"
2014 },
2015 new String[] {
2016 message.getBody(),
2017 user.getEmailAddress(),
2018 user.getFullName(),
2019 blogsEntryURL,
2020 fromAddress,
2021 fromName
2022 });
2023
2024 body = StringUtil.replace(
2025 body,
2026 new String[] {
2027 "[$BLOGS_COMMENTS_BODY$]",
2028 "[$BLOGS_COMMENTS_USER_ADDRESS$]",
2029 "[$BLOGS_COMMENTS_USER_NAME$]",
2030 "[$BLOGS_ENTRY_URL$]",
2031 "[$FROM_ADDRESS$]",
2032 "[$FROM_NAME$]"
2033 },
2034 new String[] {
2035 message.getBody(),
2036 user.getEmailAddress(),
2037 user.getFullName(),
2038 blogsEntryURL,
2039 fromAddress,
2040 fromName
2041 });
2042
2043 Set<Long> sent = new HashSet<Long>();
2044
2045 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
2046 message.getThreadId());
2047
2048 for (MBMessage curMessage : messages) {
2049 long curMessageUserId = curMessage.getUserId();
2050
2051 if (curMessageUserId == userId) {
2052 continue;
2053 }
2054
2055 if (sent.contains(curMessageUserId)) {
2056 if (_log.isDebugEnabled()) {
2057 _log.debug(
2058 "Do not send a duplicate email to user " +
2059 curMessageUserId);
2060 }
2061
2062 continue;
2063 }
2064 else {
2065 if (_log.isDebugEnabled()) {
2066 _log.debug(
2067 "Add user " + curMessageUserId +
2068 " to the list of users who have received an email");
2069 }
2070
2071 sent.add(curMessageUserId);
2072 }
2073
2074 User curMessageUser = null;
2075
2076 try {
2077 curMessageUser = userLocalService.getUserById(curMessageUserId);
2078 }
2079 catch (NoSuchUserException nsue) {
2080 continue;
2081 }
2082
2083 if (!curMessageUser.isActive()) {
2084 continue;
2085 }
2086
2087 InternetAddress from = new InternetAddress(fromAddress, fromName);
2088
2089 InternetAddress to = new InternetAddress(
2090 curMessageUser.getEmailAddress(), curMessageUser.getFullName());
2091
2092 String curSubject = StringUtil.replace(
2093 subject,
2094 new String[] {
2095 "[$TO_ADDRESS$]",
2096 "[$TO_NAME$]"
2097 },
2098 new String[] {
2099 curMessageUser.getFullName(),
2100 curMessageUser.getEmailAddress()
2101 });
2102
2103 String curBody = StringUtil.replace(
2104 body,
2105 new String[] {
2106 "[$TO_ADDRESS$]",
2107 "[$TO_NAME$]"
2108 },
2109 new String[] {
2110 curMessageUser.getFullName(),
2111 curMessageUser.getEmailAddress()
2112 });
2113
2114 MailMessage mailMessage = new MailMessage(
2115 from, to, curSubject, curBody, true);
2116
2117 mailService.sendEmail(mailMessage);
2118 }
2119 }
2120
2121 protected void updatePriorities(long threadId, double priority)
2122 throws SystemException {
2123
2124 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
2125 threadId);
2126
2127 for (MBMessage message : messages) {
2128 if (message.getPriority() != priority) {
2129 message.setPriority(priority);
2130
2131 mbMessagePersistence.update(message, false);
2132 }
2133 }
2134 }
2135
2136 protected void validate(String subject, String body)
2137 throws PortalException {
2138
2139 if (Validator.isNull(subject)) {
2140 throw new MessageSubjectException();
2141 }
2142
2143 if (Validator.isNull(body)) {
2144 throw new MessageBodyException();
2145 }
2146 }
2147
2148 private static Log _log = LogFactoryUtil.getLog(
2149 MBMessageLocalServiceImpl.class);
2150
2151 }