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.increment.BufferedIncrement;
020 import com.liferay.portal.kernel.increment.NumberIncrement;
021 import com.liferay.portal.kernel.json.JSONFactoryUtil;
022 import com.liferay.portal.kernel.json.JSONObject;
023 import com.liferay.portal.kernel.portletfilerepository.PortletFileRepositoryUtil;
024 import com.liferay.portal.kernel.repository.model.FileEntry;
025 import com.liferay.portal.kernel.repository.model.Folder;
026 import com.liferay.portal.kernel.search.Field;
027 import com.liferay.portal.kernel.search.Hits;
028 import com.liferay.portal.kernel.search.Indexer;
029 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030 import com.liferay.portal.kernel.search.SearchContext;
031 import com.liferay.portal.kernel.search.Sort;
032 import com.liferay.portal.kernel.social.SocialActivityManagerUtil;
033 import com.liferay.portal.kernel.systemevent.SystemEvent;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.kernel.workflow.WorkflowConstants;
037 import com.liferay.portal.model.Group;
038 import com.liferay.portal.model.ResourceConstants;
039 import com.liferay.portal.model.SystemEventConstants;
040 import com.liferay.portal.model.User;
041 import com.liferay.portal.service.ServiceContext;
042 import com.liferay.portlet.asset.model.AssetEntry;
043 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
044 import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
045 import com.liferay.portlet.messageboards.constants.MBConstants;
046 import com.liferay.portlet.messageboards.exception.NoSuchCategoryException;
047 import com.liferay.portlet.messageboards.exception.SplitThreadException;
048 import com.liferay.portlet.messageboards.model.MBCategory;
049 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
050 import com.liferay.portlet.messageboards.model.MBMessage;
051 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
052 import com.liferay.portlet.messageboards.model.MBThread;
053 import com.liferay.portlet.messageboards.model.MBThreadConstants;
054 import com.liferay.portlet.messageboards.model.MBTreeWalker;
055 import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
056 import com.liferay.portlet.messageboards.util.MBUtil;
057 import com.liferay.portlet.social.model.SocialActivityConstants;
058 import com.liferay.portlet.trash.model.TrashEntry;
059 import com.liferay.portlet.trash.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 MBThreadConstants.THREAD_VIEW_TREE, false);
1006
1007 MBTreeWalker treeWalker = messageDisplay.getTreeWalker();
1008
1009 List<MBMessage> messages = treeWalker.getMessages();
1010
1011 int[] range = treeWalker.getChildrenRange(message);
1012
1013 for (int i = range[0]; i < range[1]; i++) {
1014 MBMessage curMessage = messages.get(i);
1015
1016 String oldSubject = message.getSubject();
1017 String curSubject = curMessage.getSubject();
1018
1019 if (oldSubject.startsWith("RE: ")) {
1020 curSubject = StringUtil.replace(
1021 curSubject, rootMessage.getSubject(), subject);
1022 }
1023 else {
1024 curSubject = StringUtil.replace(
1025 curSubject, oldSubject, subject);
1026 }
1027
1028 curMessage.setSubject(curSubject);
1029
1030 mbMessagePersistence.update(curMessage);
1031 }
1032
1033 message.setSubject(subject);
1034 }
1035
1036 message.setThreadId(thread.getThreadId());
1037 message.setRootMessageId(thread.getRootMessageId());
1038 message.setParentMessageId(0);
1039
1040 mbMessagePersistence.update(message);
1041
1042
1043
1044 moveAttachmentsFolders(
1045 message, oldAttachmentsFolderId, oldThread, thread, serviceContext);
1046
1047
1048
1049 if (!message.isDiscussion()) {
1050 Indexer<MBMessage> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1051 MBMessage.class);
1052
1053 indexer.reindex(message);
1054 }
1055
1056
1057
1058 moveChildrenMessages(message, category, oldThread.getThreadId());
1059
1060
1061
1062 MBUtil.updateThreadMessageCount(thread.getThreadId());
1063
1064
1065
1066 MBUtil.updateThreadMessageCount(oldThread.getThreadId());
1067
1068
1069
1070 if ((message.getCategoryId() !=
1071 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1072 (message.getCategoryId() !=
1073 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1074
1075 MBUtil.updateCategoryThreadCount(category.getCategoryId());
1076 }
1077
1078
1079
1080 Indexer<MBThread> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1081 MBThread.class);
1082
1083 indexer.reindex(oldThread);
1084
1085 indexer.reindex(message.getThread());
1086
1087 return thread;
1088 }
1089
1090 @Override
1091 public MBThread updateMessageCount(long threadId) {
1092 MBThread mbThread = mbThreadPersistence.fetchByPrimaryKey(threadId);
1093
1094 if (mbThread == null) {
1095 return null;
1096 }
1097
1098 int messageCount = mbMessageLocalService.getThreadMessagesCount(
1099 threadId, WorkflowConstants.STATUS_APPROVED);
1100
1101 mbThread.setMessageCount(messageCount);
1102
1103 return mbThreadPersistence.update(mbThread);
1104 }
1105
1106 @Override
1107 public void updateQuestion(long threadId, boolean question)
1108 throws PortalException {
1109
1110 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1111
1112 if (thread.isQuestion() == question) {
1113 return;
1114 }
1115
1116 thread.setQuestion(question);
1117
1118 mbThreadPersistence.update(thread);
1119
1120 if (!question) {
1121 MBMessage message = mbMessagePersistence.findByPrimaryKey(
1122 thread.getRootMessageId());
1123
1124 mbMessageLocalService.updateAnswer(message, false, true);
1125 }
1126 }
1127
1128 @Override
1129 public MBThread updateStatus(long userId, long threadId, int status)
1130 throws PortalException {
1131
1132 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
1133
1134
1135
1136 User user = userPersistence.findByPrimaryKey(userId);
1137
1138 thread.setStatus(status);
1139 thread.setStatusByUserId(user.getUserId());
1140 thread.setStatusByUserName(user.getFullName());
1141 thread.setStatusDate(new Date());
1142
1143 mbThreadPersistence.update(thread);
1144
1145
1146
1147 if (thread.getCategoryId() !=
1148 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
1149
1150
1151
1152 MBCategory category = mbCategoryPersistence.fetchByPrimaryKey(
1153 thread.getCategoryId());
1154
1155 if (category != null) {
1156 MBUtil.updateCategoryStatistics(category.getCategoryId());
1157 }
1158 }
1159
1160
1161
1162 Indexer<MBThread> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1163 MBThread.class);
1164
1165 indexer.reindex(thread);
1166
1167 return thread;
1168 }
1169
1170 protected void moveAttachmentsFolders(
1171 MBMessage message, long oldAttachmentsFolderId, MBThread oldThread,
1172 MBThread newThread, ServiceContext serviceContext)
1173 throws PortalException {
1174
1175 if (oldAttachmentsFolderId !=
1176 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1177
1178 Folder newThreadFolder = newThread.addAttachmentsFolder();
1179
1180 PortletFileRepositoryUtil.movePortletFolder(
1181 message.getGroupId(), message.getUserId(),
1182 oldAttachmentsFolderId, newThreadFolder.getFolderId(),
1183 serviceContext);
1184 }
1185
1186 List<MBMessage> childMessages = mbMessagePersistence.findByT_P(
1187 oldThread.getThreadId(), message.getMessageId());
1188
1189 for (MBMessage childMessage : childMessages) {
1190 moveAttachmentsFolders(
1191 childMessage, childMessage.getAttachmentsFolderId(), oldThread,
1192 newThread, serviceContext);
1193 }
1194 }
1195
1196 protected void moveChildrenMessages(
1197 MBMessage parentMessage, MBCategory category, long oldThreadId)
1198 throws PortalException {
1199
1200 List<MBMessage> messages = mbMessagePersistence.findByT_P(
1201 oldThreadId, parentMessage.getMessageId());
1202
1203 for (MBMessage message : messages) {
1204 message.setCategoryId(parentMessage.getCategoryId());
1205 message.setThreadId(parentMessage.getThreadId());
1206 message.setRootMessageId(parentMessage.getRootMessageId());
1207
1208 mbMessagePersistence.update(message);
1209
1210 if (!message.isDiscussion()) {
1211 Indexer<MBMessage> indexer =
1212 IndexerRegistryUtil.nullSafeGetIndexer(MBMessage.class);
1213
1214 indexer.reindex(message);
1215 }
1216
1217 moveChildrenMessages(message, category, oldThreadId);
1218 }
1219 }
1220
1221 }