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