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