001
014
015 package com.liferay.portlet.messageboards.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.increment.BufferedIncrement;
020 import com.liferay.portal.kernel.increment.NumberIncrement;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.search.Indexer;
024 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
025 import com.liferay.portal.kernel.util.CharPool;
026 import com.liferay.portal.kernel.util.StringBundler;
027 import com.liferay.portal.kernel.util.StringPool;
028 import com.liferay.portal.kernel.util.StringUtil;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.kernel.workflow.WorkflowConstants;
031 import com.liferay.portal.model.CompanyConstants;
032 import com.liferay.portal.model.ResourceConstants;
033 import com.liferay.portal.service.ServiceContext;
034 import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
035 import com.liferay.portlet.documentlibrary.NoSuchDirectoryException;
036 import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
037 import com.liferay.portlet.messageboards.SplitThreadException;
038 import com.liferay.portlet.messageboards.model.MBCategory;
039 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
040 import com.liferay.portlet.messageboards.model.MBMessage;
041 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
042 import com.liferay.portlet.messageboards.model.MBThread;
043 import com.liferay.portlet.messageboards.model.MBThreadConstants;
044 import com.liferay.portlet.messageboards.model.MBTreeWalker;
045 import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
046 import com.liferay.portlet.messageboards.util.MBUtil;
047
048 import java.io.File;
049 import java.io.IOException;
050 import java.io.InputStream;
051
052 import java.util.ArrayList;
053 import java.util.List;
054
055
059 public class MBThreadLocalServiceImpl extends MBThreadLocalServiceBaseImpl {
060
061 @Override
062 public MBThread addThread(long categoryId, MBMessage message)
063 throws PortalException, SystemException {
064
065
066
067 long threadId = message.getThreadId();
068
069 if (!message.isRoot() || (threadId <= 0)) {
070 threadId = counterLocalService.increment();
071 }
072
073 MBThread thread = mbThreadPersistence.create(threadId);
074
075 thread.setGroupId(message.getGroupId());
076 thread.setCompanyId(message.getCompanyId());
077 thread.setCategoryId(categoryId);
078 thread.setRootMessageId(message.getMessageId());
079 thread.setRootMessageUserId(message.getUserId());
080
081 if (message.isAnonymous()) {
082 thread.setLastPostByUserId(0);
083 }
084 else {
085 thread.setLastPostByUserId(message.getUserId());
086 }
087
088 thread.setLastPostDate(message.getCreateDate());
089
090 if (message.getPriority() != MBThreadConstants.PRIORITY_NOT_GIVEN) {
091 thread.setPriority(message.getPriority());
092 }
093
094 thread.setStatus(message.getStatus());
095 thread.setStatusByUserId(message.getStatusByUserId());
096 thread.setStatusByUserName(message.getStatusByUserName());
097 thread.setStatusDate(message.getStatusDate());
098
099 mbThreadPersistence.update(thread, false);
100
101
102
103 if (categoryId >= 0) {
104 assetEntryLocalService.updateEntry(
105 message.getUserId(), message.getGroupId(),
106 thread.getStatusDate(), thread.getLastPostDate(),
107 MBThread.class.getName(), thread.getThreadId(), null, 0,
108 new long[0], new String[0], false, null, null, null, null, null,
109 String.valueOf(thread.getRootMessageId()), null, null, null,
110 null, 0, 0, null, false);
111 }
112
113 return thread;
114 }
115
116 @Override
117 public void deleteThread(long threadId)
118 throws PortalException, SystemException {
119
120 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
121
122 deleteThread(thread);
123 }
124
125 @Override
126 public void deleteThread(MBThread thread)
127 throws PortalException, SystemException {
128
129 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
130 thread.getRootMessageId());
131
132
133
134 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
135 MBMessage.class);
136
137 indexer.delete(thread);
138
139
140
141 long companyId = rootMessage.getCompanyId();
142 long repositoryId = CompanyConstants.SYSTEM;
143 String dirName = thread.getAttachmentsDir();
144
145 try {
146 DLStoreUtil.deleteDirectory(companyId, repositoryId, dirName);
147 }
148 catch (NoSuchDirectoryException nsde) {
149 }
150
151
152
153 subscriptionLocalService.deleteSubscriptions(
154 thread.getCompanyId(), MBThread.class.getName(),
155 thread.getThreadId());
156
157
158
159 mbThreadFlagPersistence.removeByThreadId(thread.getThreadId());
160
161
162
163 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
164 thread.getThreadId());
165
166 for (MBMessage message : messages) {
167
168
169
170 ratingsStatsLocalService.deleteStats(
171 message.getWorkflowClassName(), message.getMessageId());
172
173
174
175 assetEntryLocalService.deleteEntry(
176 message.getWorkflowClassName(), message.getMessageId());
177
178
179
180 if (!message.isDiscussion()) {
181 resourceLocalService.deleteResource(
182 message.getCompanyId(), message.getWorkflowClassName(),
183 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
184 }
185
186
187
188 mbMessagePersistence.remove(message);
189
190
191
192 if (!message.isDiscussion()) {
193 mbStatsUserLocalService.updateStatsUser(
194 message.getGroupId(), message.getUserId());
195 }
196
197
198
199 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
200 message.getCompanyId(), message.getGroupId(),
201 message.getWorkflowClassName(), message.getMessageId());
202 }
203
204
205
206 if ((rootMessage.getCategoryId() !=
207 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
208 (rootMessage.getCategoryId() !=
209 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
210
211 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
212 thread.getCategoryId());
213
214 MBUtil.updateCategoryStatistics(
215 category.getCompanyId(), category.getCategoryId());
216 }
217
218
219
220 assetEntryLocalService.deleteEntry(
221 MBThread.class.getName(), thread.getThreadId());
222
223
224
225 mbThreadPersistence.remove(thread);
226 }
227
228 @Override
229 public void deleteThreads(long groupId, long categoryId)
230 throws PortalException, SystemException {
231
232 List<MBThread> threads = mbThreadPersistence.findByG_C(
233 groupId, categoryId);
234
235 for (MBThread thread : threads) {
236 deleteThread(thread);
237 }
238 }
239
240 @Override
241 public MBThread fetchThread(long threadId) throws SystemException {
242 return mbThreadPersistence.fetchByPrimaryKey(threadId);
243 }
244
245 @Override
246 public int getCategoryThreadsCount(
247 long groupId, long categoryId, int status)
248 throws SystemException {
249
250 if (status == WorkflowConstants.STATUS_ANY) {
251 return mbThreadPersistence.countByG_C(groupId, categoryId);
252 }
253 else {
254 return mbThreadPersistence.countByG_C_S(
255 groupId, categoryId, status);
256 }
257 }
258
259 @Override
260 public List<MBThread> getGroupThreads(
261 long groupId, int status, int start, int end)
262 throws SystemException {
263
264 if (status == WorkflowConstants.STATUS_ANY) {
265 return mbThreadPersistence.findByG_NotC(
266 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, start,
267 end);
268 }
269 else {
270 return mbThreadPersistence.findByG_NotC_S(
271 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, status,
272 start, end);
273 }
274 }
275
276 @Override
277 public List<MBThread> getGroupThreads(
278 long groupId, long userId, int status, boolean subscribed,
279 boolean includeAnonymous, int start, int end)
280 throws PortalException, SystemException {
281
282 if (userId <= 0) {
283 if (status == WorkflowConstants.STATUS_ANY) {
284 return mbThreadPersistence.findByG_NotC(
285 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, start,
286 end);
287 }
288 else {
289 return mbThreadPersistence.findByG_NotC_S(
290 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, status,
291 start, end);
292 }
293 }
294 else {
295 if (subscribed) {
296 return mbThreadFinder.findByS_G_U_C_S(
297 groupId, userId, null, status, start, end);
298 }
299 else {
300 List<Long> threadIds = null;
301
302 if (includeAnonymous) {
303 threadIds = mbMessageFinder.findByG_U_C_S(
304 groupId, userId, null, status, start, end);
305 }
306 else {
307 threadIds = mbMessageFinder.findByG_U_C_A_S(
308 groupId, userId, null, false, status, start, end);
309 }
310
311 List<MBThread> threads = new ArrayList<MBThread>(
312 threadIds.size());
313
314 for (long threadId : threadIds) {
315 MBThread thread = mbThreadPersistence.findByPrimaryKey(
316 threadId);
317
318 threads.add(thread);
319 }
320
321 return threads;
322 }
323 }
324 }
325
326 @Override
327 public List<MBThread> getGroupThreads(
328 long groupId, long userId, int status, boolean subscribed,
329 int start, int end)
330 throws PortalException, SystemException {
331
332 return getGroupThreads(
333 groupId, userId, status, subscribed, true, start, end);
334 }
335
336 @Override
337 public List<MBThread> getGroupThreads(
338 long groupId, long userId, int status, int start, int end)
339 throws PortalException, SystemException {
340
341 return getGroupThreads(groupId, userId, status, false, start, end);
342 }
343
344 @Override
345 public int getGroupThreadsCount(long groupId, int status)
346 throws SystemException {
347
348 if (status == WorkflowConstants.STATUS_ANY) {
349 return mbThreadPersistence.countByG_NotC(
350 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID);
351 }
352 else {
353 return mbThreadPersistence.countByG_NotC_S(
354 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, status);
355 }
356 }
357
358 @Override
359 public int getGroupThreadsCount(long groupId, long userId, int status)
360 throws SystemException {
361
362 return getGroupThreadsCount(groupId, userId, status, false);
363 }
364
365 @Override
366 public int getGroupThreadsCount(
367 long groupId, long userId, int status, boolean subscribed)
368 throws SystemException {
369
370 return getGroupThreadsCount(groupId, userId, status, subscribed, true);
371 }
372
373 @Override
374 public int getGroupThreadsCount(
375 long groupId, long userId, int status, boolean subscribed,
376 boolean includeAnonymous)
377 throws SystemException {
378
379 if (userId <= 0) {
380 if (status == WorkflowConstants.STATUS_ANY) {
381 return mbThreadPersistence.countByG_NotC(
382 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID);
383 }
384 else {
385 return mbThreadPersistence.countByG_NotC_S(
386 groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
387 status);
388 }
389 }
390 else {
391 if (subscribed) {
392 return mbThreadFinder.countByS_G_U_C_S(
393 groupId, userId, null, status);
394 }
395 else {
396 if (includeAnonymous) {
397 return mbMessageFinder.countByG_U_C_S(
398 groupId, userId, null, status);
399 }
400 else {
401 return mbMessageFinder.countByG_U_C_A_S(
402 groupId, userId, null, false, status);
403 }
404 }
405 }
406 }
407
408 @Override
409 public List<MBThread> getNoAssetThreads() throws SystemException {
410 return mbThreadFinder.findByNoAssets();
411 }
412
413 @Override
414 public List<MBThread> getPriorityThreads(long categoryId, double priority)
415 throws PortalException, SystemException {
416
417 return getPriorityThreads(categoryId, priority, false);
418 }
419
420 @Override
421 public List<MBThread> getPriorityThreads(
422 long categoryId, double priority, boolean inherit)
423 throws PortalException, SystemException {
424
425 if (!inherit) {
426 return mbThreadPersistence.findByC_P(categoryId, priority);
427 }
428
429 List<MBThread> threads = new ArrayList<MBThread>();
430
431 while ((categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
432 (categoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
433
434 threads.addAll(
435 0, mbThreadPersistence.findByC_P(categoryId, priority));
436
437 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
438 categoryId);
439
440 categoryId = category.getParentCategoryId();
441 }
442
443 return threads;
444 }
445
446 @Override
447 public MBThread getThread(long threadId)
448 throws PortalException, SystemException {
449
450 return mbThreadPersistence.findByPrimaryKey(threadId);
451 }
452
453 @Override
454 public List<MBThread> getThreads(
455 long groupId, long categoryId, int status, int start, int end)
456 throws SystemException {
457
458 if (status == WorkflowConstants.STATUS_ANY) {
459 return mbThreadPersistence.findByG_C(
460 groupId, categoryId, start, end);
461 }
462 else {
463 return mbThreadPersistence.findByG_C_S(
464 groupId, categoryId, status, start, end);
465 }
466 }
467
468 @Override
469 public int getThreadsCount(long groupId, long categoryId, int status)
470 throws SystemException {
471
472 if (status == WorkflowConstants.STATUS_ANY) {
473 return mbThreadPersistence.countByG_C(groupId, categoryId);
474 }
475 else {
476 return mbThreadPersistence.countByG_C_S(
477 groupId, categoryId, status);
478 }
479 }
480
481 @Override
482 public boolean hasAnswerMessage(long threadId) throws SystemException {
483 int count = mbMessagePersistence.countByT_A(threadId, true);
484
485 if (count > 0) {
486 return true;
487 }
488 else {
489 return false;
490 }
491 }
492
493 @BufferedIncrement(incrementClass = NumberIncrement.class)
494 @Override
495 public MBThread incrementViewCounter(long threadId, int increment)
496 throws PortalException, SystemException {
497
498 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
499
500 thread.setViewCount(thread.getViewCount() + increment);
501
502 mbThreadPersistence.update(thread, false);
503
504 return thread;
505 }
506
507 @Override
508 public MBThread moveThread(long groupId, long categoryId, long threadId)
509 throws PortalException, SystemException {
510
511 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
512
513 long oldCategoryId = thread.getCategoryId();
514
515 MBCategory oldCategory = null;
516
517 if (oldCategoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
518 oldCategory = mbCategoryPersistence.findByPrimaryKey(oldCategoryId);
519 }
520
521 MBCategory category = null;
522
523 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
524 category = mbCategoryPersistence.findByPrimaryKey(categoryId);
525 }
526
527
528
529 List<MBMessage> messages = mbMessagePersistence.findByG_C_T(
530 groupId, oldCategoryId, thread.getThreadId());
531
532 for (MBMessage message : messages) {
533 message.setCategoryId(categoryId);
534
535 mbMessagePersistence.update(message, false);
536
537
538
539 if (!message.isDiscussion()) {
540 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
541 MBMessage.class);
542
543 indexer.reindex(message);
544 }
545 }
546
547
548
549 thread.setCategoryId(categoryId);
550
551 mbThreadPersistence.update(thread, false);
552
553
554
555 if ((oldCategory != null) && (categoryId != oldCategoryId)) {
556 MBUtil.updateCategoryStatistics(
557 oldCategory.getCompanyId(), oldCategory.getCategoryId());
558 }
559
560 if ((category != null) && (categoryId != oldCategoryId)) {
561 MBUtil.updateCategoryStatistics(
562 category.getCompanyId(), category.getCategoryId());
563 }
564
565 return thread;
566 }
567
568 @Override
569 public MBThread splitThread(
570 long messageId, String subject, ServiceContext serviceContext)
571 throws PortalException, SystemException {
572
573 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
574
575 if (message.isRoot()) {
576 throw new SplitThreadException();
577 }
578
579 MBCategory category = message.getCategory();
580 MBThread oldThread = message.getThread();
581 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
582 oldThread.getRootMessageId());
583 String oldAttachmentsDir = message.getAttachmentsDir();
584
585
586
587 mbMessageLocalService.updateAnswer(message, false, true);
588
589
590
591 MBThread thread = addThread(message.getCategoryId(), message);
592
593
594
595 if (Validator.isNotNull(subject)) {
596 MBMessageDisplay messageDisplay =
597 mbMessageService.getMessageDisplay(
598 messageId, WorkflowConstants.STATUS_ANY,
599 MBThreadConstants.THREAD_VIEW_TREE, false);
600
601 MBTreeWalker treeWalker = messageDisplay.getTreeWalker();
602
603 List<MBMessage> messages = treeWalker.getMessages();
604
605 int[] range = treeWalker.getChildrenRange(message);
606
607 for (int i = range[0]; i < range[1]; i++) {
608 MBMessage curMessage = messages.get(i);
609
610 String oldSubject = message.getSubject();
611 String curSubject = curMessage.getSubject();
612
613 if (oldSubject.startsWith("RE: ")) {
614 curSubject = StringUtil.replace(
615 curSubject, rootMessage.getSubject(), subject);
616 }
617 else {
618 curSubject = StringUtil.replace(
619 curSubject, oldSubject, subject);
620 }
621
622 curMessage.setSubject(curSubject);
623
624 mbMessagePersistence.update(curMessage, false);
625 }
626
627 message.setSubject(subject);
628 }
629
630 message.setThreadId(thread.getThreadId());
631 message.setRootMessageId(thread.getRootMessageId());
632 message.setParentMessageId(0);
633 message.setAttachmentsDir(null);
634
635 mbMessagePersistence.update(message, false);
636
637
638
639 moveAttachmentsFromOldThread(message, oldAttachmentsDir);
640
641
642
643 if (!message.isDiscussion()) {
644 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
645 MBMessage.class);
646
647 indexer.reindex(message);
648 }
649
650
651
652 moveChildrenMessages(message, category, oldThread.getThreadId());
653
654
655
656 MBUtil.updateThreadMessageCount(
657 thread.getCompanyId(), thread.getThreadId());
658
659
660
661 MBUtil.updateThreadMessageCount(
662 oldThread.getCompanyId(), oldThread.getThreadId());
663
664
665
666 if ((message.getCategoryId() !=
667 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
668 (message.getCategoryId() !=
669 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
670
671 MBUtil.updateCategoryThreadCount(
672 category.getCompanyId(), category.getCategoryId());
673 }
674
675 return thread;
676 }
677
678 @Override
679 public void updateQuestion(long threadId, boolean question)
680 throws PortalException, SystemException {
681
682 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
683
684 if (thread.isQuestion() == question) {
685 return;
686 }
687
688 thread.setQuestion(question);
689
690 mbThreadPersistence.update(thread, false);
691
692 if (!question) {
693 MBMessage message = mbMessagePersistence.findByPrimaryKey(
694 thread.getRootMessageId());
695
696 mbMessageLocalService.updateAnswer(message, false, true);
697 }
698 }
699
700
703 @Override
704 public MBThread updateThread(long threadId, int viewCount)
705 throws PortalException, SystemException {
706
707 MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
708
709 thread.setViewCount(viewCount);
710
711 mbThreadPersistence.update(thread, false);
712
713 return thread;
714 }
715
716 protected void moveAttachmentFromOldThread(
717 long companyId, String fileName, String newAttachmentsDir)
718 throws PortalException, SystemException {
719
720 long repositoryId = CompanyConstants.SYSTEM;
721
722 StringBundler sb = new StringBundler(4);
723
724 sb.append(newAttachmentsDir);
725 sb.append(StringPool.SLASH);
726 sb.append(StringUtil.extractLast(fileName, CharPool.SLASH));
727
728 String newFileName = sb.toString();
729
730 try {
731 File file = DLStoreUtil.getFile(companyId, repositoryId, fileName);
732
733 DLStoreUtil.addFile(
734 companyId, repositoryId, newFileName, false, file);
735 }
736 catch (UnsupportedOperationException uoe) {
737 InputStream is = DLStoreUtil.getFileAsStream(
738 companyId, repositoryId, fileName);
739
740 try {
741 DLStoreUtil.addFile(
742 companyId, repositoryId, newFileName, false, is);
743 }
744 finally {
745 try {
746 is.close();
747 }
748 catch (IOException ioe) {
749 _log.error(ioe);
750 }
751 }
752 }
753
754 DLStoreUtil.deleteFile(companyId, repositoryId, fileName);
755 }
756
757 protected void moveAttachmentsFromOldThread(
758 MBMessage message, String oldAttachmentsDir)
759 throws PortalException, SystemException {
760
761 if (!message.getAttachments()) {
762 return;
763 }
764
765 long companyId = message.getCompanyId();
766 long repositoryId = CompanyConstants.SYSTEM;
767 String newAttachmentsDir = message.getAttachmentsDir();
768
769 try {
770 DLStoreUtil.addDirectory(
771 companyId, repositoryId, newAttachmentsDir);
772 }
773 catch (DuplicateDirectoryException dde) {
774 }
775
776 String[] fileNames = DLStoreUtil.getFileNames(
777 companyId, repositoryId, oldAttachmentsDir);
778
779 for (String fileName : fileNames) {
780 moveAttachmentFromOldThread(companyId, fileName, newAttachmentsDir);
781 }
782
783 try {
784 DLStoreUtil.deleteDirectory(
785 companyId, repositoryId, oldAttachmentsDir);
786 }
787 catch (NoSuchDirectoryException nsde) {
788 }
789 }
790
791 protected void moveChildrenMessages(
792 MBMessage parentMessage, MBCategory category, long oldThreadId)
793 throws PortalException, SystemException {
794
795 List<MBMessage> messages = mbMessagePersistence.findByT_P(
796 oldThreadId, parentMessage.getMessageId());
797
798 for (MBMessage message : messages) {
799 String oldAttachmentsDir = message.getAttachmentsDir();
800
801 message.setCategoryId(parentMessage.getCategoryId());
802 message.setThreadId(parentMessage.getThreadId());
803 message.setRootMessageId(parentMessage.getRootMessageId());
804 message.setAttachmentsDir(null);
805
806 mbMessagePersistence.update(message, false);
807
808 moveAttachmentsFromOldThread(message, oldAttachmentsDir);
809
810 if (!message.isDiscussion()) {
811 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
812 MBMessage.class);
813
814 indexer.reindex(message);
815 }
816
817 moveChildrenMessages(message, category, oldThreadId);
818 }
819 }
820
821 private static Log _log = LogFactoryUtil.getLog(
822 MBThreadLocalServiceImpl.class);
823
824 }