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