1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.messageboards.service.impl;
16  
17  import com.liferay.documentlibrary.DuplicateDirectoryException;
18  import com.liferay.documentlibrary.NoSuchDirectoryException;
19  import com.liferay.portal.kernel.exception.PortalException;
20  import com.liferay.portal.kernel.exception.SystemException;
21  import com.liferay.portal.kernel.search.Indexer;
22  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
23  import com.liferay.portal.kernel.util.StringPool;
24  import com.liferay.portal.kernel.util.StringUtil;
25  import com.liferay.portal.kernel.workflow.StatusConstants;
26  import com.liferay.portal.model.CompanyConstants;
27  import com.liferay.portal.model.GroupConstants;
28  import com.liferay.portal.model.ResourceConstants;
29  import com.liferay.portal.service.ServiceContext;
30  import com.liferay.portlet.messageboards.SplitThreadException;
31  import com.liferay.portlet.messageboards.model.MBCategory;
32  import com.liferay.portlet.messageboards.model.MBCategoryConstants;
33  import com.liferay.portlet.messageboards.model.MBMessage;
34  import com.liferay.portlet.messageboards.model.MBThread;
35  import com.liferay.portlet.messageboards.model.MBThreadConstants;
36  import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
37  
38  import java.util.ArrayList;
39  import java.util.List;
40  
41  /**
42   * <a href="MBThreadLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
43   *
44   * @author Brian Wing Shun Chan
45   */
46  public class MBThreadLocalServiceImpl extends MBThreadLocalServiceBaseImpl {
47  
48      public void deleteThread(long threadId)
49          throws PortalException, SystemException {
50  
51          MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
52  
53          deleteThread(thread);
54      }
55  
56      public void deleteThread(MBThread thread)
57          throws PortalException, SystemException {
58  
59          MBCategory category = mbCategoryPersistence.findByPrimaryKey(
60              thread.getCategoryId());
61          MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
62              thread.getRootMessageId());
63  
64          // Indexer
65  
66          Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
67  
68          indexer.delete(thread);
69  
70          // Attachments
71  
72          long companyId = rootMessage.getCompanyId();
73          String portletId = CompanyConstants.SYSTEM_STRING;
74          long repositoryId = CompanyConstants.SYSTEM;
75          String dirName = thread.getAttachmentsDir();
76  
77          try {
78              dlService.deleteDirectory(
79                  companyId, portletId, repositoryId, dirName);
80          }
81          catch (NoSuchDirectoryException nsde) {
82          }
83  
84          // Messages
85  
86          List<MBMessage> messages = mbMessagePersistence.findByThreadId(
87              thread.getThreadId());
88  
89          for (MBMessage message : messages) {
90  
91              // Social
92  
93              socialActivityLocalService.deleteActivities(
94                  MBMessage.class.getName(), message.getMessageId());
95  
96              // Ratings
97  
98              ratingsStatsLocalService.deleteStats(
99                  MBMessage.class.getName(), message.getMessageId());
100 
101             // Asset
102 
103             assetEntryLocalService.deleteEntry(
104                 MBMessage.class.getName(), message.getMessageId());
105 
106             // Statistics
107 
108             if (!message.isDiscussion()) {
109                 mbStatsUserLocalService.updateStatsUser(
110                     message.getGroupId(), message.getUserId());
111             }
112 
113             // Message flags
114 
115             mbMessageFlagPersistence.removeByMessageId(message.getMessageId());
116 
117             // Resources
118 
119             if (!message.isDiscussion()) {
120                 resourceLocalService.deleteResource(
121                     message.getCompanyId(), MBMessage.class.getName(),
122                     ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
123             }
124 
125             // Message
126 
127             mbMessagePersistence.remove(message);
128         }
129 
130         // Category
131 
132         if (!rootMessage.isDiscussion()) {
133             category.setThreadCount(category.getThreadCount() - 1);
134             category.setMessageCount(
135                 category.getMessageCount() - messages.size());
136 
137             mbCategoryPersistence.update(category, false);
138         }
139 
140         // Thread
141 
142         mbThreadPersistence.remove(thread);
143     }
144 
145     public void deleteThreads(long groupId, long categoryId)
146         throws PortalException, SystemException {
147 
148         List<MBThread> threads = mbThreadPersistence.findByG_C(
149             groupId, categoryId);
150 
151         for (MBThread thread : threads) {
152             deleteThread(thread);
153         }
154     }
155 
156     public int getCategoryThreadsCount(
157             long groupId, long categoryId, int status)
158         throws SystemException {
159 
160         if (status == StatusConstants.ANY) {
161             return mbThreadPersistence.countByG_C(groupId, categoryId);
162         }
163         else {
164             return mbThreadPersistence.countByG_C_S(
165                 groupId, categoryId, status);
166         }
167     }
168 
169     public List<MBThread> getGroupThreads(
170             long groupId, int status, int start, int end)
171         throws SystemException {
172 
173         if (status == StatusConstants.ANY) {
174             return mbThreadPersistence.findByGroupId(groupId, start, end);
175         }
176         else {
177             return mbThreadPersistence.findByG_S(groupId, status, start, end);
178         }
179     }
180 
181     public List<MBThread> getGroupThreads(
182             long groupId, long userId, int status, int start, int end)
183         throws PortalException, SystemException {
184 
185         return getGroupThreads(groupId, userId, status, false, start, end);
186     }
187 
188     public List<MBThread> getGroupThreads(
189             long groupId, long userId, int status, boolean subscribed,
190             int start, int end)
191         throws PortalException, SystemException {
192 
193         return getGroupThreads(
194             groupId, userId, status, subscribed, true, start, end);
195     }
196 
197     public List<MBThread> getGroupThreads(
198             long groupId, long userId, int status, boolean subscribed,
199             boolean includeAnonymous, int start, int end)
200         throws PortalException, SystemException {
201 
202         if (userId <= 0) {
203             if (status == StatusConstants.ANY) {
204                 return mbThreadPersistence.findByGroupId(groupId, start, end);
205             }
206             else {
207                 return mbThreadPersistence.findByG_S(
208                     groupId, status, start, end);
209             }
210         }
211         else {
212             if (subscribed) {
213                 return mbThreadFinder.findByS_G_U_S(
214                     groupId, userId, status, start, end);
215             }
216             else {
217                 List<Long> threadIds = null;
218 
219                 if (includeAnonymous) {
220                     threadIds = mbMessageFinder.findByG_U_S(
221                         groupId, userId, status, start, end);
222                 }
223                 else {
224                     threadIds = mbMessageFinder.findByG_U_A_S(
225                         groupId, userId, false, status, start, end);
226                 }
227 
228                 List<MBThread> threads = new ArrayList<MBThread>(
229                     threadIds.size());
230 
231                 for (long threadId : threadIds) {
232                     MBThread thread = mbThreadPersistence.findByPrimaryKey(
233                         threadId);
234 
235                     threads.add(thread);
236                 }
237 
238                 return threads;
239             }
240         }
241     }
242 
243     public int getGroupThreadsCount(long groupId, int status)
244         throws SystemException {
245 
246         if (status == StatusConstants.ANY) {
247             return mbThreadPersistence.countByGroupId(groupId);
248         }
249         else {
250             return mbThreadPersistence.countByG_S(groupId, status);
251         }
252     }
253 
254     public int getGroupThreadsCount(long groupId, long userId, int status)
255         throws SystemException {
256 
257         return getGroupThreadsCount(groupId, userId, status, false);
258     }
259 
260     public int getGroupThreadsCount(
261             long groupId, long userId, int status, boolean subscribed)
262         throws SystemException {
263 
264         return getGroupThreadsCount(groupId, userId, status, subscribed, true);
265     }
266 
267     public int getGroupThreadsCount(
268             long groupId, long userId, int status, boolean subscribed,
269             boolean includeAnonymous)
270         throws SystemException {
271 
272         if (userId <= 0) {
273             if (status == StatusConstants.ANY) {
274                 return mbThreadPersistence.countByGroupId(groupId);
275             }
276             else {
277                 return mbThreadPersistence.countByG_S(groupId, status);
278             }
279         }
280         else {
281             if (subscribed) {
282                 return mbThreadFinder.countByS_G_U_S(groupId, userId, status);
283             }
284             else {
285                 if (includeAnonymous) {
286                     return mbMessageFinder.countByG_U_S(
287                         groupId, userId, status);
288                 }
289                 else {
290                     return mbMessageFinder.countByG_U_A_S(
291                         groupId, userId, false, status);
292                 }
293             }
294         }
295     }
296 
297     public List<MBThread> getPriorityThreads(long categoryId, double priority)
298         throws PortalException, SystemException {
299 
300         return getPriorityThreads(categoryId, priority, false);
301     }
302 
303     public List<MBThread> getPriorityThreads(
304             long categoryId, double priority, boolean inherit)
305         throws PortalException, SystemException {
306 
307         if (!inherit) {
308             return mbThreadPersistence.findByC_P(categoryId, priority);
309         }
310 
311         List<MBThread> threads = new ArrayList<MBThread>();
312 
313         while (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
314             threads.addAll(
315                 0, mbThreadPersistence.findByC_P(categoryId, priority));
316 
317             MBCategory category = mbCategoryPersistence.findByPrimaryKey(
318                 categoryId);
319 
320             categoryId = category.getParentCategoryId();
321         }
322 
323         return threads;
324     }
325 
326     public MBThread getThread(long threadId)
327         throws PortalException, SystemException {
328 
329         return mbThreadPersistence.findByPrimaryKey(threadId);
330     }
331 
332     public List<MBThread> getThreads(
333             long groupId, long categoryId, int status, int start, int end)
334         throws SystemException {
335 
336         if (status == StatusConstants.ANY) {
337             return mbThreadPersistence.findByG_C(
338                 groupId, categoryId, start, end);
339         }
340         else {
341             return mbThreadPersistence.findByG_C_S(
342                 groupId, categoryId, status, start, end);
343         }
344     }
345 
346     public int getThreadsCount(long groupId, long categoryId, int status)
347         throws SystemException {
348 
349         if (status == StatusConstants.ANY) {
350             return mbThreadPersistence.countByG_C(groupId, categoryId);
351         }
352         else {
353             return mbThreadPersistence.countByG_C_S(
354                 groupId, categoryId, status);
355         }
356     }
357 
358     public MBThread moveThread(long groupId, long categoryId, long threadId)
359         throws PortalException, SystemException {
360 
361         MBThread thread = mbThreadPersistence.findByPrimaryKey(
362             threadId);
363 
364         long oldCategoryId = thread.getCategoryId();
365 
366         MBCategory oldCategory = mbCategoryPersistence.findByPrimaryKey(
367             oldCategoryId);
368 
369         MBCategory category = mbCategoryPersistence.findByPrimaryKey(
370             categoryId);
371 
372         // Messages
373 
374         List<MBMessage> messages = mbMessagePersistence.findByG_C_T(
375             groupId, oldCategoryId, thread.getThreadId());
376 
377         for (MBMessage message : messages) {
378             message.setCategoryId(category.getCategoryId());
379 
380             mbMessagePersistence.update(message, false);
381 
382             // Indexer
383 
384             if (!message.isDiscussion()) {
385                 Indexer indexer = IndexerRegistryUtil.getIndexer(
386                     MBMessage.class);
387 
388                 indexer.reindex(message);
389             }
390         }
391 
392         // Thread
393 
394         thread.setCategoryId(category.getCategoryId());
395 
396         mbThreadPersistence.update(thread, false);
397 
398         // Category
399 
400         oldCategory.setThreadCount(oldCategory.getThreadCount() - 1);
401         oldCategory.setMessageCount(
402             oldCategory.getMessageCount() - messages.size());
403 
404         mbCategoryPersistence.update(oldCategory, false);
405 
406         category.setThreadCount(category.getThreadCount() + 1);
407         category.setMessageCount(category.getMessageCount() + messages.size());
408 
409         mbCategoryPersistence.update(category, false);
410 
411         return thread;
412     }
413 
414     public MBThread splitThread(long messageId, ServiceContext serviceContext)
415         throws PortalException, SystemException {
416 
417         MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
418 
419         if (message.isRoot()) {
420             throw new SplitThreadException();
421         }
422 
423         MBCategory category = message.getCategory();
424         long oldThreadId = message.getThreadId();
425         String oldAttachmentsDir = message.getAttachmentsDir();
426 
427         // Message flags
428 
429         mbMessageFlagLocalService.deleteThreadFlags(oldThreadId);
430 
431         // Create new thread
432 
433         MBThread thread = addThread(message.getCategoryId(), message);
434 
435         // Update message
436 
437         message.setThreadId(thread.getThreadId());
438         message.setParentMessageId(0);
439         message.setAttachmentsDir(null);
440 
441         mbMessagePersistence.update(message, false);
442 
443         // Attachments
444 
445         moveAttachmentsFromOldThread(message, oldAttachmentsDir);
446 
447         // Indexer
448 
449         if (!message.isDiscussion()) {
450             Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
451 
452             indexer.reindex(message);
453         }
454 
455         // Update children
456 
457         int messagesMoved = 1;
458 
459         messagesMoved += moveChildrenMessages(
460             message, category, oldThreadId);
461 
462         // Update new thread
463 
464         thread.setMessageCount(messagesMoved);
465 
466         mbThreadPersistence.update(thread, false);
467 
468         // Update old thread
469 
470         MBThread oldThread = mbThreadPersistence.findByPrimaryKey(oldThreadId);
471 
472         oldThread.setMessageCount(oldThread.getMessageCount() - messagesMoved);
473 
474         mbThreadPersistence.update(oldThread, false);
475 
476         // Category
477 
478         category.setThreadCount(category.getThreadCount() + 1);
479 
480         mbCategoryPersistence.update(category, false);
481 
482         return thread;
483     }
484 
485     public MBThread updateThread(long threadId, int viewCount)
486         throws PortalException, SystemException {
487 
488         MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
489 
490         thread.setViewCount(viewCount);
491 
492         mbThreadPersistence.update(thread, false);
493 
494         return thread;
495     }
496 
497     protected MBThread addThread(long categoryId, MBMessage message)
498         throws SystemException {
499 
500         long threadId = counterLocalService.increment();
501 
502         MBThread thread = mbThreadPersistence.create(threadId);
503 
504         thread.setGroupId(message.getGroupId());
505         thread.setCategoryId(categoryId);
506         thread.setRootMessageId(message.getMessageId());
507         thread.setStatus(message.getStatus());
508         thread.setStatusByUserId(message.getStatusByUserId());
509         thread.setStatusByUserName(message.getStatusByUserName());
510         thread.setStatusDate(message.getStatusDate());
511 
512         thread.setMessageCount(thread.getMessageCount() + 1);
513 
514         if (message.isAnonymous()) {
515             thread.setLastPostByUserId(0);
516         }
517         else {
518             thread.setLastPostByUserId(message.getUserId());
519         }
520 
521         thread.setLastPostDate(message.getCreateDate());
522 
523         if (message.getPriority() != MBThreadConstants.PRIORITY_NOT_GIVEN) {
524             thread.setPriority(message.getPriority());
525         }
526 
527         mbThreadPersistence.update(thread, false);
528 
529         return thread;
530     }
531 
532     protected void moveAttachmentsFromOldThread(
533             MBMessage message, String oldAttachmentsDir)
534         throws PortalException, SystemException {
535 
536         if (!message.getAttachments()) {
537             return;
538         }
539 
540         long companyId = message.getCompanyId();
541         String portletId = CompanyConstants.SYSTEM_STRING;
542         long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
543         long repositoryId = CompanyConstants.SYSTEM;
544         String newAttachmentsDir = message.getAttachmentsDir();
545 
546         try {
547             dlService.addDirectory(companyId, repositoryId, newAttachmentsDir);
548         }
549         catch (DuplicateDirectoryException dde) {
550         }
551 
552         String[] fileNames = dlService.getFileNames(
553             companyId, repositoryId, oldAttachmentsDir);
554 
555         for (String fileName : fileNames) {
556             String name = StringUtil.extractLast(fileName, StringPool.SLASH);
557             byte[] fileBytes = dlService.getFile(
558                 companyId, repositoryId, fileName);
559 
560             dlService.addFile(
561                 companyId, portletId, groupId, repositoryId,
562                 newAttachmentsDir + "/" + name, 0, StringPool.BLANK,
563                 message.getModifiedDate(), new ServiceContext(), fileBytes);
564 
565             dlService.deleteFile(companyId, portletId, repositoryId, fileName);
566         }
567 
568         try {
569             dlService.deleteDirectory(
570                 companyId, portletId, repositoryId, oldAttachmentsDir);
571         }
572         catch (NoSuchDirectoryException nsde) {
573         }
574     }
575 
576     protected int moveChildrenMessages(
577             MBMessage parentMessage, MBCategory category, long oldThreadId)
578         throws SystemException, PortalException {
579 
580         int messagesMoved = 0;
581 
582         List<MBMessage> messages = mbMessagePersistence.findByT_P(
583             oldThreadId, parentMessage.getMessageId());
584 
585         for (MBMessage message : messages) {
586             String oldAttachmentsDir = message.getAttachmentsDir();
587 
588             message.setCategoryId(parentMessage.getCategoryId());
589             message.setThreadId(parentMessage.getThreadId());
590             message.setAttachmentsDir(null);
591 
592             mbMessagePersistence.update(message, false);
593 
594             moveAttachmentsFromOldThread(message, oldAttachmentsDir);
595 
596             if (!message.isDiscussion()) {
597                 Indexer indexer = IndexerRegistryUtil.getIndexer(
598                     MBMessage.class);
599 
600                 indexer.reindex(message);
601             }
602 
603             messagesMoved++;
604 
605             messagesMoved += moveChildrenMessages(
606                 message, category, oldThreadId);
607         }
608 
609         return messagesMoved;
610     }
611 
612 }