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