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