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