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