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