001
014
015 package com.liferay.portlet.messageboards.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.increment.BufferedIncrement;
021 import com.liferay.portal.kernel.increment.NumberIncrement;
022 import com.liferay.portal.kernel.json.JSONFactoryUtil;
023 import com.liferay.portal.kernel.json.JSONObject;
024 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
025 import com.liferay.portal.kernel.search.Field;
026 import com.liferay.portal.kernel.search.Hits;
027 import com.liferay.portal.kernel.search.Indexer;
028 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
029 import com.liferay.portal.kernel.search.SearchContext;
030 import com.liferay.portal.kernel.search.Sort;
031 import com.liferay.portal.kernel.systemevent.SystemEvent;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.util.Validator;
034 import com.liferay.portal.kernel.workflow.WorkflowConstants;
035 import com.liferay.portal.model.Group;
036 import com.liferay.portal.model.ResourceConstants;
037 import com.liferay.portal.model.SystemEventConstants;
038 import com.liferay.portal.model.User;
039 import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
040 import com.liferay.portal.service.ServiceContext;
041 import com.liferay.portal.util.PortletKeys;
042 import com.liferay.portlet.asset.model.AssetEntry;
043 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
044 import com.liferay.portlet.messageboards.NoSuchCategoryException;
045 import com.liferay.portlet.messageboards.SplitThreadException;
046 import com.liferay.portlet.messageboards.model.MBCategory;
047 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
048 import com.liferay.portlet.messageboards.model.MBMessage;
049 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
050 import com.liferay.portlet.messageboards.model.MBThread;
051 import com.liferay.portlet.messageboards.model.MBThreadConstants;
052 import com.liferay.portlet.messageboards.model.MBTreeWalker;
053 import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
054 import com.liferay.portlet.messageboards.util.MBUtil;
055 import com.liferay.portlet.social.model.SocialActivityConstants;
056 import com.liferay.portlet.trash.model.TrashEntry;
057 import com.liferay.portlet.trash.model.TrashVersion;
058
059 import java.util.ArrayList;
060 import java.util.Date;
061 import java.util.HashSet;
062 import java.util.List;
063 import java.util.Set;
064
065
069 public class MBThreadLocalServiceImpl extends MBThreadLocalServiceBaseImpl {
070
071 @Override
072 public MBThread addThread(
073 long categoryId, MBMessage message, ServiceContext serviceContext)
074 throws PortalException, SystemException {
075
076
077
078 Date now = new Date();
079
080 long threadId = message.getThreadId();
081
082 if (!message.isRoot() || (threadId <= 0)) {
083 threadId = counterLocalService.increment();
084 }
085
086 MBThread thread = mbThreadPersistence.create(threadId);
087
088 thread.setUuid(serviceContext.getUuid());
089 thread.setGroupId(message.getGroupId());
090 thread.setCompanyId(message.getCompanyId());
091 thread.setUserId(message.getUserId());
092 thread.setUserName(message.getUserName());
093 thread.setCreateDate(serviceContext.getCreateDate(now));
094 thread.setModifiedDate(serviceContext.getModifiedDate(now));
095 thread.setCategoryId(categoryId);
096 thread.setRootMessageId(message.getMessageId());
097 thread.setRootMessageUserId(message.getUserId());
098
099 if (message.isAnonymous()) {
100 thread.setLastPostByUserId(0);
101 }
102 else {
103 thread.setLastPostByUserId(message.getUserId());
104 }
105
106 thread.setLastPostDate(message.getCreateDate());
107
108 if (message.getPriority() != MBThreadConstants.PRIORITY_NOT_GIVEN) {
109 thread.setPriority(message.getPriority());
110 }
111
112 thread.setStatus(message.getStatus());
113 thread.setStatusByUserId(message.getStatusByUserId());
114 thread.setStatusByUserName(message.getStatusByUserName());
115 thread.setStatusDate(message.getStatusDate());
116
117 mbThreadPersistence.update(thread);
118
119
120
121 if (categoryId >= 0) {
122 assetEntryLocalService.updateEntry(
123 message.getUserId(), message.getGroupId(),
124 thread.getStatusDate(), thread.getLastPostDate(),
125 MBThread.class.getName(), thread.getThreadId(),
126 thread.getUuid(), 0, new long[0], new String[0], false, null,
127 null, null, null, String.valueOf(thread.getRootMessageId()),
128 null, null, null, null, 0, 0, null, false);
129 }
130
131 return thread;
132 }
133
134 @Override
135 public void deleteThread(long threadId)
136 throws PortalException, SystemException {
137
138 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
139
140 mbThreadLocalService.deleteThread(thread);
141 }
142
143 @Override
144 @SystemEvent(
145 action = SystemEventConstants.ACTION_SKIP, send = false,
146 type = SystemEventConstants.TYPE_DELETE)
147 public void deleteThread(MBThread thread)
148 throws PortalException, SystemException {
149
150 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
151 thread.getRootMessageId());
152
153
154
155 Indexer messageIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
156 MBMessage.class);
157
158
159
160 long folderId = thread.getAttachmentsFolderId();
161
162 if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
163 PortletFileRepositoryUtil.deleteFolder(folderId);
164 }
165
166
167
168 subscriptionLocalService.deleteSubscriptions(
169 thread.getCompanyId(), MBThread.class.getName(),
170 thread.getThreadId());
171
172
173
174 mbThreadFlagPersistence.removeByThreadId(thread.getThreadId());
175
176
177
178 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
179 thread.getThreadId());
180
181 for (MBMessage message : messages) {
182
183
184
185 ratingsStatsLocalService.deleteStats(
186 message.getWorkflowClassName(), message.getMessageId());
187
188
189
190 assetEntryLocalService.deleteEntry(
191 message.getWorkflowClassName(), message.getMessageId());
192
193
194
195 if (!message.isDiscussion()) {
196 resourceLocalService.deleteResource(
197 message.getCompanyId(), message.getWorkflowClassName(),
198 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
199 }
200
201
202
203 mbMessagePersistence.remove(message);
204
205
206
207 messageIndexer.delete(message);
208
209
210
211 if (!message.isDiscussion()) {
212 mbStatsUserLocalService.updateStatsUser(
213 message.getGroupId(), message.getUserId());
214 }
215
216
217
218 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
219 message.getCompanyId(), message.getGroupId(),
220 message.getWorkflowClassName(), message.getMessageId());
221 }
222
223
224
225 if ((rootMessage.getCategoryId() !=
226 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
227 (rootMessage.getCategoryId() !=
228 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
229
230 try {
231 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
232 thread.getCategoryId());
233
234 MBUtil.updateCategoryStatistics(
235 category.getCompanyId(), category.getCategoryId());
236 }
237 catch (NoSuchCategoryException nsce) {
238 if (!thread.isInTrash()) {
239 throw nsce;
240 }
241 }
242 }
243
244
245
246 AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
247 MBThread.class.getName(), thread.getThreadId());
248
249 if (assetEntry != null) {
250 assetEntry.setTitle(rootMessage.getSubject());
251
252 assetEntryLocalService.updateAssetEntry(assetEntry);
253 }
254
255 assetEntryLocalService.deleteEntry(
256 MBThread.class.getName(), thread.getThreadId());
257
258
259
260 trashEntryLocalService.deleteEntry(
261 MBThread.class.getName(), thread.getThreadId());
262
263
264
265 Indexer threadIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
266 MBThread.class);
267
268 threadIndexer.delete(thread);
269
270
271
272 mbThreadPersistence.remove(thread);
273 }
274
275 @Override
276 public void deleteThreads(long groupId, long categoryId)
277 throws PortalException, SystemException {
278
279 deleteThreads(groupId, categoryId, true);
280 }
281
282 @Override
283 public void deleteThreads(
284 long groupId, long categoryId, boolean includeTrashedEntries)
285 throws PortalException, SystemException {
286
287 List<MBThread> threads = mbThreadPersistence.findByG_C(
288 groupId, categoryId);
289
290 for (MBThread thread : threads) {
291 if (includeTrashedEntries || !thread.isInTrashExplicitly()) {
292 mbThreadLocalService.deleteThread(thread);
293 }
294 }
295
296 if (mbThreadPersistence.countByGroupId(groupId) == 0) {
297 PortletFileRepositoryUtil.deletePortletRepository(
298 groupId, PortletKeys.MESSAGE_BOARDS);
299 }
300 }
301
302 @Override
303 public MBThread fetchThread(long threadId) throws SystemException {
304 return mbThreadPersistence.fetchByPrimaryKey(threadId);
305 }
306
307 @Override
308 public int getCategoryThreadsCount(
309 long groupId, long categoryId, int status)
310 throws SystemException {
311
312 if (status == WorkflowConstants.STATUS_ANY) {
313 return mbThreadPersistence.countByG_C(groupId, categoryId);
314 }
315 else {
316 return mbThreadPersistence.countByG_C_S(
317 groupId, categoryId, status);
318 }
319 }
320
321
325 @Override
326 public List<MBThread> getGroupThreads(
327 long groupId, int status, int start, int end)
328 throws SystemException {
329
330 QueryDefinition queryDefinition = new QueryDefinition(
331 status, start, end, null);
332
333 return getGroupThreads(groupId, queryDefinition);
334 }
335
336 @Override
337 public List<MBThread> getGroupThreads(
338 long groupId, long userId, boolean subscribed,
339 boolean includeAnonymous, QueryDefinition queryDefinition)
340 throws SystemException {
341
342 if (userId <= 0) {
343 return getGroupThreads(groupId, queryDefinition);
344 }
345
346 if (subscribed) {
347 return mbThreadFinder.findByS_G_U_C(
348 groupId, userId, null, queryDefinition);
349 }
350 else {
351 if (includeAnonymous) {
352 return mbThreadFinder.findByG_U_C(
353 groupId, userId, null, queryDefinition);
354 }
355 else {
356 return mbThreadFinder.findByG_U_C_A(
357 groupId, userId, null, false, queryDefinition);
358 }
359 }
360 }
361
362 @Override
363 public List<MBThread> getGroupThreads(
364 long groupId, long userId, boolean subscribed,
365 QueryDefinition queryDefinition)
366 throws SystemException {
367
368 return getGroupThreads(
369 groupId, userId, subscribed, true, queryDefinition);
370 }
371
372
376 @Override
377 public List<MBThread> getGroupThreads(
378 long groupId, long userId, int status, boolean subscribed,
379 boolean includeAnonymous, int start, int end)
380 throws SystemException {
381
382 QueryDefinition queryDefinition = new QueryDefinition(
383 status, start, end, null);
384
385 return getGroupThreads(
386 groupId, userId, subscribed, includeAnonymous, queryDefinition);
387 }
388
389
393 @Override
394 public List<MBThread> getGroupThreads(
395 long groupId, long userId, int status, boolean subscribed,
396 int start, int end)
397 throws SystemException {
398
399 QueryDefinition queryDefinition = new QueryDefinition(
400 status, start, end, null);
401
402 return getGroupThreads(groupId, userId, subscribed, queryDefinition);
403 }
404
405
409 @Override
410 public List<MBThread> getGroupThreads(
411 long groupId, long userId, int status, int start, int end)
412 throws SystemException {
413
414 QueryDefinition queryDefinition = new QueryDefinition(
415 status, start, end, null);
416
417 return getGroupThreads(groupId, userId, false, queryDefinition);
418 }
419
420 @Override
421 public List<MBThread> getGroupThreads(
422 long groupId, long userId, QueryDefinition queryDefinition)
423 throws SystemException {
424
425 return getGroupThreads(groupId, userId, false, queryDefinition);
426 }
427
428 @Override
429 public List<MBThread> getGroupThreads(
430 long groupId, QueryDefinition queryDefinition)
431 throws SystemException {
432
433 if (queryDefinition.isExcludeStatus()) {
434 return mbThreadPersistence.findByG_NotC_NotS(
435 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
436 queryDefinition.getStatus(), queryDefinition.getStart(),
437 queryDefinition.getEnd());
438 }
439 else {
440 return mbThreadPersistence.findByG_NotC_S(
441 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
442 queryDefinition.getStatus(), queryDefinition.getStart(),
443 queryDefinition.getEnd());
444 }
445 }
446
447
451 @Override
452 public int getGroupThreadsCount(long groupId, int status)
453 throws SystemException {
454
455 QueryDefinition queryDefinition = new QueryDefinition(status);
456
457 return getGroupThreadsCount(groupId, queryDefinition);
458 }
459
460 @Override
461 public int getGroupThreadsCount(
462 long groupId, long userId, boolean subscribed,
463 boolean includeAnonymous, QueryDefinition queryDefinition)
464 throws SystemException {
465
466 if (userId <= 0) {
467 return getGroupThreadsCount(groupId, queryDefinition);
468 }
469
470 if (subscribed) {
471 return mbThreadFinder.countByS_G_U_C(
472 groupId, userId, null, queryDefinition);
473 }
474 else {
475 if (includeAnonymous) {
476 return mbThreadFinder.countByG_U_C(
477 groupId, userId, null, queryDefinition);
478 }
479 else {
480 return mbThreadFinder.countByG_U_C_A(
481 groupId, userId, null, false, queryDefinition);
482 }
483 }
484 }
485
486 @Override
487 public int getGroupThreadsCount(
488 long groupId, long userId, boolean subscribed,
489 QueryDefinition queryDefinition)
490 throws SystemException {
491
492 return getGroupThreadsCount(
493 groupId, userId, subscribed, true, queryDefinition);
494 }
495
496
500 @Override
501 public int getGroupThreadsCount(long groupId, long userId, int status)
502 throws SystemException {
503
504 QueryDefinition queryDefinition = new QueryDefinition(status);
505
506 return getGroupThreadsCount(groupId, userId, false, queryDefinition);
507 }
508
509
513 @Override
514 public int getGroupThreadsCount(
515 long groupId, long userId, int status, boolean subscribed)
516 throws SystemException {
517
518 QueryDefinition queryDefinition = new QueryDefinition(status);
519
520 return getGroupThreadsCount(
521 groupId, userId, subscribed, true, queryDefinition);
522 }
523
524
528 @Override
529 public int getGroupThreadsCount(
530 long groupId, long userId, int status, boolean subscribed,
531 boolean includeAnonymous)
532 throws SystemException {
533
534 QueryDefinition queryDefinition = new QueryDefinition(status);
535
536 return getGroupThreadsCount(
537 groupId, userId, subscribed, includeAnonymous, queryDefinition);
538 }
539
540 @Override
541 public int getGroupThreadsCount(
542 long groupId, long userId, QueryDefinition queryDefinition)
543 throws SystemException {
544
545 return getGroupThreadsCount(groupId, userId, false, queryDefinition);
546 }
547
548 @Override
549 public int getGroupThreadsCount(
550 long groupId, QueryDefinition queryDefinition)
551 throws SystemException {
552
553 if (queryDefinition.isExcludeStatus()) {
554 return mbThreadPersistence.countByG_NotC_NotS(
555 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
556 queryDefinition.getStatus());
557 }
558 else {
559 return mbThreadPersistence.countByG_NotC_S(
560 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
561 queryDefinition.getStatus());
562 }
563 }
564
565 @Override
566 public List<MBThread> getNoAssetThreads() throws SystemException {
567 return mbThreadFinder.findByNoAssets();
568 }
569
570 @Override
571 public List<MBThread> getPriorityThreads(long categoryId, double priority)
572 throws PortalException, SystemException {
573
574 return getPriorityThreads(categoryId, priority, false);
575 }
576
577 @Override
578 public List<MBThread> getPriorityThreads(
579 long categoryId, double priority, boolean inherit)
580 throws PortalException, SystemException {
581
582 if (!inherit) {
583 return mbThreadPersistence.findByC_P(categoryId, priority);
584 }
585
586 List<MBThread> threads = new ArrayList<MBThread>();
587
588 while ((categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
589 (categoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
590
591 threads.addAll(
592 0, mbThreadPersistence.findByC_P(categoryId, priority));
593
594 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
595 categoryId);
596
597 categoryId = category.getParentCategoryId();
598 }
599
600 return threads;
601 }
602
603 @Override
604 public MBThread getThread(long threadId)
605 throws PortalException, SystemException {
606
607 return mbThreadPersistence.findByPrimaryKey(threadId);
608 }
609
610 @Override
611 public List<MBThread> getThreads(
612 long groupId, long categoryId, int status, int start, int end)
613 throws SystemException {
614
615 if (status == WorkflowConstants.STATUS_ANY) {
616 return mbThreadPersistence.findByG_C(
617 groupId, categoryId, start, end);
618 }
619 else {
620 return mbThreadPersistence.findByG_C_S(
621 groupId, categoryId, status, start, end);
622 }
623 }
624
625 @Override
626 public int getThreadsCount(long groupId, long categoryId, int status)
627 throws SystemException {
628
629 if (status == WorkflowConstants.STATUS_ANY) {
630 return mbThreadPersistence.countByG_C(groupId, categoryId);
631 }
632 else {
633 return mbThreadPersistence.countByG_C_S(
634 groupId, categoryId, status);
635 }
636 }
637
638 @Override
639 public boolean hasAnswerMessage(long threadId) throws SystemException {
640 int count = mbMessagePersistence.countByT_A(threadId, true);
641
642 if (count > 0) {
643 return true;
644 }
645 else {
646 return false;
647 }
648 }
649
650 @BufferedIncrement(
651 configuration = "MBThread", incrementClass = NumberIncrement.class)
652 @Override
653 public MBThread incrementViewCounter(long threadId, int increment)
654 throws PortalException, SystemException {
655
656 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
657
658 if (ExportImportThreadLocal.isImportInProcess()) {
659 return thread;
660 }
661
662 thread.setViewCount(thread.getViewCount() + increment);
663
664 mbThreadPersistence.update(thread);
665
666 return thread;
667 }
668
669 @Override
670 public void moveDependentsToTrash(
671 long groupId, long threadId, long trashEntryId)
672 throws PortalException, SystemException {
673
674 Set<Long> userIds = new HashSet<Long>();
675
676 List<MBMessage> messages = mbMessageLocalService.getThreadMessages(
677 threadId, WorkflowConstants.STATUS_ANY);
678
679 for (MBMessage message : messages) {
680
681
682
683 if (message.isDiscussion()) {
684 continue;
685 }
686
687 int oldStatus = message.getStatus();
688
689 message.setStatus(WorkflowConstants.STATUS_IN_TRASH);
690
691 mbMessagePersistence.update(message);
692
693 userIds.add(message.getUserId());
694
695
696
697 int status = oldStatus;
698
699 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
700 status = WorkflowConstants.STATUS_DRAFT;
701 }
702
703 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
704 trashVersionLocalService.addTrashVersion(
705 trashEntryId, MBMessage.class.getName(),
706 message.getMessageId(), status, null);
707 }
708
709
710
711 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
712 assetEntryLocalService.updateVisible(
713 MBMessage.class.getName(), message.getMessageId(), false);
714 }
715
716
717
718 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
719 MBMessage.class);
720
721 indexer.reindex(message);
722
723
724
725 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
726 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
727 message.getCompanyId(), message.getGroupId(),
728 MBMessage.class.getName(), message.getMessageId());
729 }
730 }
731
732
733
734 for (long userId : userIds) {
735 mbStatsUserLocalService.updateStatsUser(groupId, userId);
736 }
737 }
738
739 @Override
740 public MBThread moveThread(long groupId, long categoryId, long threadId)
741 throws PortalException, SystemException {
742
743 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
744
745 long oldCategoryId = thread.getCategoryId();
746
747 MBCategory oldCategory = null;
748
749 if (oldCategoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
750 oldCategory = mbCategoryPersistence.fetchByPrimaryKey(
751 oldCategoryId);
752 }
753
754 MBCategory category = null;
755
756 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
757 category = mbCategoryPersistence.fetchByPrimaryKey(categoryId);
758 }
759
760
761
762 thread.setModifiedDate(new Date());
763 thread.setCategoryId(categoryId);
764
765 mbThreadPersistence.update(thread);
766
767
768
769 List<MBMessage> messages = mbMessagePersistence.findByG_C_T(
770 groupId, oldCategoryId, thread.getThreadId());
771
772 for (MBMessage message : messages) {
773 message.setCategoryId(categoryId);
774
775 mbMessagePersistence.update(message);
776
777
778
779 if (!message.isDiscussion()) {
780 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
781 MBMessage.class);
782
783 indexer.reindex(message);
784 }
785 }
786
787
788
789 if ((oldCategory != null) && (categoryId != oldCategoryId)) {
790 MBUtil.updateCategoryStatistics(
791 oldCategory.getCompanyId(), oldCategory.getCategoryId());
792 }
793
794 if ((category != null) && (categoryId != oldCategoryId)) {
795 MBUtil.updateCategoryStatistics(
796 category.getCompanyId(), category.getCategoryId());
797 }
798
799
800
801 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
802 MBThread.class);
803
804 indexer.reindex(thread);
805
806 return thread;
807 }
808
809 @Override
810 public MBThread moveThreadFromTrash(
811 long userId, long categoryId, long threadId)
812 throws PortalException, SystemException {
813
814 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
815
816 if (thread.isInTrashExplicitly()) {
817 restoreThreadFromTrash(userId, threadId);
818 }
819 else {
820
821
822
823 TrashEntry trashEntry = thread.getTrashEntry();
824
825 TrashVersion trashVersion =
826 trashVersionLocalService.fetchVersion(
827 trashEntry.getEntryId(), MBThread.class.getName(),
828 thread.getThreadId());
829
830 int status = WorkflowConstants.STATUS_APPROVED;
831
832 if (trashVersion != null) {
833 status = trashVersion.getStatus();
834 }
835
836 updateStatus(userId, threadId, status);
837
838
839
840 if (trashVersion != null) {
841 trashVersionLocalService.deleteTrashVersion(trashVersion);
842 }
843
844
845
846 restoreDependentsFromTrash(
847 thread.getGroupId(), threadId, trashEntry.getEntryId());
848 }
849
850 return moveThread(thread.getGroupId(), categoryId, threadId);
851 }
852
853 @Override
854 public void moveThreadsToTrash(long groupId, long userId)
855 throws PortalException, SystemException {
856
857 List<MBThread> threads = mbThreadPersistence.findByGroupId(groupId);
858
859 for (MBThread thread : threads) {
860 moveThreadToTrash(userId, thread);
861 }
862 }
863
864 @Override
865 public MBThread moveThreadToTrash(long userId, long threadId)
866 throws PortalException, SystemException {
867
868 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
869
870 return moveThreadToTrash(userId, thread);
871 }
872
873 @Override
874 public MBThread moveThreadToTrash(long userId, MBThread thread)
875 throws PortalException, SystemException {
876
877
878
879 if (thread.getCategoryId() ==
880 MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
881
882 return thread;
883 }
884
885 int oldStatus = thread.getStatus();
886
887 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
888 thread.setStatus(WorkflowConstants.STATUS_DRAFT);
889
890 mbThreadPersistence.update(thread);
891 }
892
893 thread = updateStatus(
894 userId, thread.getThreadId(), WorkflowConstants.STATUS_IN_TRASH);
895
896
897
898 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
899 userId, thread.getGroupId(), MBThread.class.getName(),
900 thread.getThreadId(), thread.getUuid(), null, oldStatus, null,
901 null);
902
903
904
905 moveDependentsToTrash(
906 thread.getGroupId(), thread.getThreadId(), trashEntry.getEntryId());
907
908
909
910 MBMessage message = mbMessageLocalService.getMBMessage(
911 thread.getRootMessageId());
912
913 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
914
915 extraDataJSONObject.put("rootMessageId", thread.getRootMessageId());
916 extraDataJSONObject.put("title", message.getSubject());
917
918 socialActivityLocalService.addActivity(
919 userId, thread.getGroupId(), MBThread.class.getName(),
920 thread.getThreadId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
921 extraDataJSONObject.toString(), 0);
922
923 return thread;
924 }
925
926 @Override
927 public void restoreDependentsFromTrash(
928 long groupId, long threadId, long trashEntryId)
929 throws PortalException, SystemException {
930
931 Set<Long> userIds = new HashSet<Long>();
932
933 List<MBMessage> messages = mbMessageLocalService.getThreadMessages(
934 threadId, WorkflowConstants.STATUS_ANY);
935
936 for (MBMessage message : messages) {
937
938
939
940 if (message.isDiscussion()) {
941 continue;
942 }
943
944 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
945 trashEntryId, MBMessage.class.getName(),
946 message.getMessageId());
947
948 int oldStatus = WorkflowConstants.STATUS_APPROVED;
949
950 if (trashVersion != null) {
951 oldStatus = trashVersion.getStatus();
952 }
953
954 message.setStatus(oldStatus);
955
956 mbMessagePersistence.update(message);
957
958 userIds.add(message.getUserId());
959
960
961
962 if (trashVersion != null) {
963 trashVersionLocalService.deleteTrashVersion(trashVersion);
964 }
965
966
967
968 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
969 assetEntryLocalService.updateVisible(
970 MBMessage.class.getName(), message.getMessageId(), true);
971 }
972
973
974
975 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
976 MBMessage.class);
977
978 indexer.reindex(message);
979 }
980
981
982
983 for (long userId : userIds) {
984 mbStatsUserLocalService.updateStatsUser(groupId, userId);
985 }
986 }
987
988 @Override
989 public void restoreThreadFromTrash(long userId, long threadId)
990 throws PortalException, SystemException {
991
992
993
994 MBThread thread = getThread(threadId);
995
996 if (thread.getCategoryId() ==
997 MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
998
999 return;
1000 }
1001
1002 TrashEntry trashEntry = trashEntryLocalService.getEntry(
1003 MBThread.class.getName(), threadId);
1004
1005 updateStatus(userId, threadId, trashEntry.getStatus());
1006
1007
1008
1009 restoreDependentsFromTrash(
1010 thread.getGroupId(), threadId, trashEntry.getEntryId());
1011
1012
1013
1014 trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
1015
1016
1017
1018 MBMessage message = mbMessageLocalService.getMBMessage(
1019 thread.getRootMessageId());
1020
1021 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1022
1023 extraDataJSONObject.put("rootMessageId", thread.getRootMessageId());
1024 extraDataJSONObject.put("title", message.getSubject());
1025
1026 socialActivityLocalService.addActivity(
1027 userId, thread.getGroupId(), MBThread.class.getName(),
1028 thread.getThreadId(),
1029 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1030 extraDataJSONObject.toString(), 0);
1031 }
1032
1033 @Override
1034 public Hits search(
1035 long groupId, long userId, long creatorUserId, int status,
1036 int start, int end)
1037 throws PortalException, SystemException {
1038
1039 return search(groupId, userId, creatorUserId, 0, 0, status, start, end);
1040 }
1041
1042 @Override
1043 public Hits search(
1044 long groupId, long userId, long creatorUserId, long startDate,
1045 long endDate, int status, int start, int end)
1046 throws PortalException, SystemException {
1047
1048 Indexer indexer = IndexerRegistryUtil.getIndexer(
1049 MBThread.class.getName());
1050
1051 SearchContext searchContext = new SearchContext();
1052
1053 searchContext.setAttribute(Field.STATUS, status);
1054
1055 if (endDate > 0) {
1056 searchContext.setAttribute("endDate", endDate);
1057 }
1058
1059 searchContext.setAttribute("paginationType", "none");
1060
1061 if (creatorUserId > 0) {
1062 searchContext.setAttribute(
1063 "participantUserId", String.valueOf(creatorUserId));
1064 }
1065
1066 if (startDate > 0) {
1067 searchContext.setAttribute("startDate", startDate);
1068 }
1069
1070 Group group = groupLocalService.getGroup(groupId);
1071
1072 searchContext.setCompanyId(group.getCompanyId());
1073
1074 searchContext.setEnd(end);
1075 searchContext.setGroupIds(new long[] {groupId});
1076 searchContext.setSorts(new Sort("lastPostDate", true));
1077 searchContext.setStart(start);
1078 searchContext.setUserId(userId);
1079
1080 return indexer.search(searchContext);
1081 }
1082
1083 @Override
1084 public MBThread splitThread(
1085 long messageId, String subject, ServiceContext serviceContext)
1086 throws PortalException, SystemException {
1087
1088 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1089
1090 if (message.isRoot()) {
1091 throw new SplitThreadException();
1092 }
1093
1094 MBCategory category = message.getCategory();
1095 MBThread oldThread = message.getThread();
1096 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
1097 oldThread.getRootMessageId());
1098
1099
1100
1101 mbMessageLocalService.updateAnswer(message, false, true);
1102
1103
1104
1105 MBThread thread = addThread(
1106 message.getCategoryId(), message, serviceContext);
1107
1108 oldThread.setModifiedDate(serviceContext.getModifiedDate(new Date()));
1109
1110 mbThreadPersistence.update(oldThread);
1111
1112
1113
1114 if (Validator.isNotNull(subject)) {
1115 MBMessageDisplay messageDisplay =
1116 mbMessageService.getMessageDisplay(
1117 messageId, WorkflowConstants.STATUS_ANY,
1118 MBThreadConstants.THREAD_VIEW_TREE, false);
1119
1120 MBTreeWalker treeWalker = messageDisplay.getTreeWalker();
1121
1122 List<MBMessage> messages = treeWalker.getMessages();
1123
1124 int[] range = treeWalker.getChildrenRange(message);
1125
1126 for (int i = range[0]; i < range[1]; i++) {
1127 MBMessage curMessage = messages.get(i);
1128
1129 String oldSubject = message.getSubject();
1130 String curSubject = curMessage.getSubject();
1131
1132 if (oldSubject.startsWith("RE: ")) {
1133 curSubject = StringUtil.replace(
1134 curSubject, rootMessage.getSubject(), subject);
1135 }
1136 else {
1137 curSubject = StringUtil.replace(
1138 curSubject, oldSubject, subject);
1139 }
1140
1141 curMessage.setSubject(curSubject);
1142
1143 mbMessagePersistence.update(curMessage);
1144 }
1145
1146 message.setSubject(subject);
1147 }
1148
1149 message.setThreadId(thread.getThreadId());
1150 message.setRootMessageId(thread.getRootMessageId());
1151 message.setParentMessageId(0);
1152
1153 mbMessagePersistence.update(message);
1154
1155
1156
1157 if (!message.isDiscussion()) {
1158 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1159 MBMessage.class);
1160
1161 indexer.reindex(message);
1162 }
1163
1164
1165
1166 moveChildrenMessages(message, category, oldThread.getThreadId());
1167
1168
1169
1170 MBUtil.updateThreadMessageCount(
1171 thread.getCompanyId(), thread.getThreadId());
1172
1173
1174
1175 MBUtil.updateThreadMessageCount(
1176 oldThread.getCompanyId(), oldThread.getThreadId());
1177
1178
1179
1180 if ((message.getCategoryId() !=
1181 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1182 (message.getCategoryId() !=
1183 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1184
1185 MBUtil.updateCategoryThreadCount(
1186 category.getCompanyId(), category.getCategoryId());
1187 }
1188
1189
1190
1191 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1192 MBThread.class);
1193
1194 indexer.reindex(oldThread);
1195 indexer.reindex(message.getThread());
1196
1197 return thread;
1198 }
1199
1200 @Override
1201 public void updateQuestion(long threadId, boolean question)
1202 throws PortalException, SystemException {
1203
1204 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1205
1206 if (thread.isQuestion() == question) {
1207 return;
1208 }
1209
1210 thread.setQuestion(question);
1211
1212 mbThreadPersistence.update(thread);
1213
1214 if (!question) {
1215 MBMessage message = mbMessagePersistence.findByPrimaryKey(
1216 thread.getRootMessageId());
1217
1218 mbMessageLocalService.updateAnswer(message, false, true);
1219 }
1220 }
1221
1222 @Override
1223 public MBThread updateStatus(long userId, long threadId, int status)
1224 throws PortalException, SystemException {
1225
1226 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1227
1228
1229
1230 User user = userPersistence.findByPrimaryKey(userId);
1231
1232 Date now = new Date();
1233
1234 thread.setModifiedDate(now);
1235 thread.setStatus(status);
1236 thread.setStatusByUserId(user.getUserId());
1237 thread.setStatusByUserName(user.getFullName());
1238 thread.setStatusDate(now);
1239
1240 mbThreadPersistence.update(thread);
1241
1242
1243
1244 if (thread.getCategoryId() !=
1245 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
1246
1247
1248
1249 MBCategory category = mbCategoryPersistence.fetchByPrimaryKey(
1250 thread.getCategoryId());
1251
1252 if (category != null) {
1253 MBUtil.updateCategoryStatistics(
1254 category.getCompanyId(), category.getCategoryId());
1255 }
1256 }
1257
1258
1259
1260 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1261 MBThread.class);
1262
1263 indexer.reindex(thread);
1264
1265 return thread;
1266 }
1267
1268
1272 @Override
1273 public MBThread updateThread(long threadId, int viewCount)
1274 throws PortalException, SystemException {
1275
1276 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1277
1278 thread.setViewCount(viewCount);
1279
1280 mbThreadPersistence.update(thread);
1281
1282 return thread;
1283 }
1284
1285 protected void moveChildrenMessages(
1286 MBMessage parentMessage, MBCategory category, long oldThreadId)
1287 throws PortalException, SystemException {
1288
1289 List<MBMessage> messages = mbMessagePersistence.findByT_P(
1290 oldThreadId, parentMessage.getMessageId());
1291
1292 for (MBMessage message : messages) {
1293 message.setCategoryId(parentMessage.getCategoryId());
1294 message.setThreadId(parentMessage.getThreadId());
1295 message.setRootMessageId(parentMessage.getRootMessageId());
1296
1297 mbMessagePersistence.update(message);
1298
1299 if (!message.isDiscussion()) {
1300 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1301 MBMessage.class);
1302
1303 indexer.reindex(message);
1304 }
1305
1306 moveChildrenMessages(message, category, oldThreadId);
1307 }
1308 }
1309
1310 }