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