1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.messageboards.service.impl;
24  
25  import com.liferay.documentlibrary.DuplicateDirectoryException;
26  import com.liferay.documentlibrary.NoSuchDirectoryException;
27  import com.liferay.portal.PortalException;
28  import com.liferay.portal.SystemException;
29  import com.liferay.portal.kernel.log.Log;
30  import com.liferay.portal.kernel.log.LogFactoryUtil;
31  import com.liferay.portal.kernel.search.SearchException;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.StringUtil;
34  import com.liferay.portal.model.CompanyConstants;
35  import com.liferay.portal.model.GroupConstants;
36  import com.liferay.portal.model.ResourceConstants;
37  import com.liferay.portal.theme.ThemeDisplay;
38  import com.liferay.portlet.messageboards.model.MBCategory;
39  import com.liferay.portlet.messageboards.model.MBMessage;
40  import com.liferay.portlet.messageboards.model.MBThread;
41  import com.liferay.portlet.messageboards.model.impl.MBThreadImpl;
42  import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
43  import com.liferay.portlet.messageboards.util.Indexer;
44  
45  import java.rmi.RemoteException;
46  
47  import java.util.ArrayList;
48  import java.util.List;
49  
50  import javax.portlet.PortletPreferences;
51  
52  /**
53   * <a href="MBThreadLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Brian Wing Shun Chan
56   *
57   */
58  public class MBThreadLocalServiceImpl extends MBThreadLocalServiceBaseImpl {
59  
60      public void deleteThread(long threadId)
61          throws PortalException, SystemException {
62  
63          MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
64  
65          deleteThread(thread);
66      }
67  
68      public void deleteThread(MBThread thread)
69          throws PortalException, SystemException {
70  
71          MBCategory category = mbCategoryPersistence.findByPrimaryKey(
72              thread.getCategoryId());
73          MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
74              thread.getRootMessageId());
75  
76          // Indexer
77  
78          try {
79              Indexer.deleteMessages(
80                  rootMessage.getCompanyId(), thread.getThreadId());
81          }
82          catch (SearchException se) {
83              _log.error("Deleting index " + thread.getThreadId(), se);
84          }
85  
86          // Attachments
87  
88          long companyId = rootMessage.getCompanyId();
89          String portletId = CompanyConstants.SYSTEM_STRING;
90          long repositoryId = CompanyConstants.SYSTEM;
91          String dirName = thread.getAttachmentsDir();
92  
93          try {
94              dlService.deleteDirectory(
95                  companyId, portletId, repositoryId, dirName);
96          }
97          catch (NoSuchDirectoryException nsde) {
98          }
99          catch (RemoteException re) {
100             throw new SystemException(re);
101         }
102 
103         // Messages
104 
105         List<MBMessage> messages = mbMessagePersistence.findByThreadId(
106             thread.getThreadId());
107 
108         for (MBMessage message : messages) {
109 
110             // Tags
111 
112             tagsAssetLocalService.deleteAsset(
113                 MBMessage.class.getName(), message.getMessageId());
114 
115             // Social
116 
117             socialActivityLocalService.deleteActivities(
118                 MBMessage.class.getName(), message.getMessageId());
119 
120             // Ratings
121 
122             ratingsStatsLocalService.deleteStats(
123                 MBMessage.class.getName(), message.getMessageId());
124 
125             // Statistics
126 
127             if (!category.isDiscussion()) {
128                 mbStatsUserLocalService.updateStatsUser(
129                     message.getGroupId(), message.getUserId());
130             }
131 
132             // Message flags
133 
134             mbMessageFlagPersistence.removeByMessageId(message.getMessageId());
135 
136             // Resources
137 
138             if (!message.isDiscussion()) {
139                 resourceLocalService.deleteResource(
140                     message.getCompanyId(), MBMessage.class.getName(),
141                     ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
142             }
143 
144             // Message
145 
146             mbMessagePersistence.remove(message);
147         }
148 
149         // Category
150 
151         category.setThreadCount(category.getThreadCount() - 1);
152         category.setMessageCount(category.getMessageCount() - messages.size());
153 
154         mbCategoryPersistence.update(category, false);
155 
156         // Thread
157 
158         mbThreadPersistence.remove(thread);
159     }
160 
161     public void deleteThreads(long categoryId)
162         throws PortalException, SystemException {
163 
164         List<MBThread> threads = mbThreadPersistence.findByCategoryId(
165             categoryId);
166 
167         for (MBThread thread : threads) {
168             deleteThread(thread);
169         }
170     }
171 
172     /**
173      * @deprecated
174      */
175     public int getCategoriesThreadsCount(List<Long> categoryIds)
176         throws SystemException {
177 
178         return mbThreadFinder.countByCategoryIds(categoryIds);
179     }
180 
181     public int getCategoryThreadsCount(long categoryId) throws SystemException {
182         return mbThreadPersistence.countByCategoryId(categoryId);
183     }
184 
185     public List<MBThread> getGroupThreads(long groupId, int start, int end)
186         throws SystemException {
187 
188         return mbThreadPersistence.findByGroupId(groupId, start, end);
189     }
190 
191     public List<MBThread> getGroupThreads(
192             long groupId, long userId, int start, int end)
193         throws PortalException, SystemException {
194 
195         return getGroupThreads(groupId, userId, false, start, end);
196     }
197 
198     public List<MBThread> getGroupThreads(
199             long groupId, long userId, boolean subscribed, int start, int end)
200         throws PortalException, SystemException {
201 
202         return getGroupThreads(groupId, userId, subscribed, true, start, end);
203     }
204 
205     public List<MBThread> getGroupThreads(
206             long groupId, long userId, boolean subscribed,
207             boolean includeAnonymous, int start, int end)
208         throws PortalException, SystemException {
209 
210         if (userId <= 0) {
211             return mbThreadPersistence.findByGroupId(groupId, start, end);
212         }
213         else {
214             if (subscribed) {
215                 return mbThreadFinder.findByS_G_U(groupId, userId, start, end);
216             }
217             else {
218                 List<Long> threadIds = null;
219 
220                 if (includeAnonymous) {
221                     threadIds = mbMessageFinder.findByG_U(
222                         groupId, userId, start, end);
223                 }
224                 else {
225                     threadIds = mbMessageFinder.findByG_U_A(
226                         groupId, userId, false, start, end);
227                 }
228 
229                 List<MBThread> threads = new ArrayList<MBThread>(
230                     threadIds.size());
231 
232                 for (long threadId : threadIds) {
233                     MBThread thread = mbThreadPersistence.findByPrimaryKey(
234                         threadId);
235 
236                     threads.add(thread);
237                 }
238 
239                 return threads;
240             }
241         }
242     }
243 
244     public int getGroupThreadsCount(long groupId) throws SystemException {
245         return mbThreadPersistence.countByGroupId(groupId);
246     }
247 
248     public int getGroupThreadsCount(long groupId, long userId)
249         throws SystemException {
250 
251         return getGroupThreadsCount(groupId, userId, false);
252     }
253 
254     public int getGroupThreadsCount(
255             long groupId, long userId, boolean subscribed)
256         throws SystemException {
257 
258         return getGroupThreadsCount(groupId, userId, subscribed, true);
259     }
260 
261     public int getGroupThreadsCount(
262             long groupId, long userId, boolean subscribed,
263             boolean includeAnonymous)
264         throws SystemException {
265 
266         if (userId <= 0) {
267             return mbThreadPersistence.countByGroupId(groupId);
268         }
269         else {
270             if (subscribed) {
271                 return mbThreadFinder.countByS_G_U(groupId, userId);
272             }
273             else {
274                 if (includeAnonymous) {
275                     return mbMessageFinder.countByG_U(groupId, userId);
276                 }
277                 else {
278                     return mbMessageFinder.countByG_U_A(groupId, userId, false);
279                 }
280             }
281         }
282     }
283 
284     public MBThread getThread(long threadId)
285         throws PortalException, SystemException {
286 
287         return mbThreadPersistence.findByPrimaryKey(threadId);
288     }
289 
290     public List<MBThread> getThreads(long categoryId, int start, int end)
291         throws SystemException {
292 
293         return mbThreadPersistence.findByCategoryId(categoryId, start, end);
294     }
295 
296     public int getThreadsCount(long categoryId) throws SystemException {
297         return mbThreadPersistence.countByCategoryId(categoryId);
298     }
299 
300     /**
301      * @deprecated
302      */
303     public boolean hasReadThread(long userId, long threadId)
304         throws PortalException, SystemException {
305 
306         MBThread thread = mbThreadLocalService.getThread(threadId);
307 
308         return mbMessageFlagLocalService.hasReadFlag(userId, thread);
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.getModifiedDate(),
345                         message.getTagsEntries());
346                 }
347             }
348             catch (SearchException se) {
349                 _log.error("Indexing " + message.getMessageId(), se);
350             }
351         }
352 
353         // Thread
354 
355         thread.setCategoryId(category.getCategoryId());
356 
357         mbThreadPersistence.update(thread, false);
358 
359         // Category
360 
361         oldCategory.setThreadCount(oldCategory.getThreadCount() - 1);
362         oldCategory.setMessageCount(
363             oldCategory.getMessageCount() - messages.size());
364 
365         mbCategoryPersistence.update(oldCategory, false);
366 
367         category.setThreadCount(category.getThreadCount() + 1);
368         category.setMessageCount(category.getMessageCount() + messages.size());
369 
370         mbCategoryPersistence.update(category, false);
371 
372         return thread;
373     }
374 
375     public MBThread splitThread(
376             long messageId, PortletPreferences prefs, ThemeDisplay themeDisplay)
377         throws PortalException, SystemException {
378 
379         MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
380 
381         MBCategory category = message.getCategory();
382         long oldThreadId = message.getThreadId();
383         String oldAttachmentsDir = message.getAttachmentsDir();
384 
385         // Message flags
386 
387         mbMessageFlagLocalService.deleteThreadFlags(oldThreadId);
388 
389         // Create new thread
390 
391         MBThread thread = addThread(message.getCategoryId(), message);
392 
393         // Update message
394 
395         message.setThreadId(thread.getThreadId());
396         message.setParentMessageId(0);
397         message.setAttachmentsDir(null);
398 
399         mbMessagePersistence.update(message, false);
400 
401         // Attachments
402 
403         moveAttachmentsFromOldThread(message, oldAttachmentsDir);
404 
405         // Indexer
406 
407         try {
408             if (!category.isDiscussion()) {
409                 Indexer.updateMessage(
410                     message.getCompanyId(), message.getGroupId(),
411                     message.getUserId(), message.getUserName(),
412                     category.getCategoryId(), message.getThreadId(),
413                     message.getMessageId(), message.getSubject(),
414                     message.getBody(), message.getModifiedDate(),
415                     message.getTagsEntries());
416             }
417         }
418         catch (SearchException se) {
419             _log.error("Indexing " + message.getMessageId(), se);
420         }
421 
422         // Update children
423 
424         int messagesMoved = 1;
425 
426         messagesMoved += moveChildrenMessages(
427             message, category, oldThreadId);
428 
429         // Update new thread
430 
431         thread.setMessageCount(messagesMoved);
432 
433         mbThreadPersistence.update(thread, false);
434 
435         // Update old thread
436 
437         MBThread oldThread = mbThreadPersistence.findByPrimaryKey(oldThreadId);
438 
439         oldThread.setMessageCount(oldThread.getMessageCount() - messagesMoved);
440 
441         mbThreadPersistence.update(oldThread, false);
442 
443         return thread;
444     }
445 
446     public MBThread updateThread(long threadId, int viewCount)
447         throws PortalException, SystemException {
448 
449         MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
450 
451         thread.setViewCount(viewCount);
452 
453         mbThreadPersistence.update(thread, false);
454 
455         return thread;
456     }
457 
458     protected MBThread addThread(long categoryId, MBMessage message)
459         throws SystemException {
460 
461         long threadId = counterLocalService.increment();
462 
463         MBThread thread = mbThreadPersistence.create(threadId);
464 
465         thread.setGroupId(message.getGroupId());
466         thread.setCategoryId(categoryId);
467         thread.setRootMessageId(message.getMessageId());
468 
469         thread.setMessageCount(thread.getMessageCount() + 1);
470 
471         if (message.isAnonymous()) {
472             thread.setLastPostByUserId(0);
473         }
474         else {
475             thread.setLastPostByUserId(message.getUserId());
476         }
477 
478         thread.setLastPostDate(message.getCreateDate());
479 
480         if (message.getPriority() != MBThreadImpl.PRIORITY_NOT_GIVEN) {
481             thread.setPriority(message.getPriority());
482         }
483 
484         mbThreadPersistence.update(thread, false);
485 
486         return thread;
487     }
488 
489     protected void moveAttachmentsFromOldThread(
490             MBMessage message, String oldAttachmentsDir)
491         throws PortalException, SystemException {
492 
493         if (!message.getAttachments()) {
494             return;
495         }
496 
497         long companyId = message.getCompanyId();
498         String portletId = CompanyConstants.SYSTEM_STRING;
499         long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
500         long repositoryId = CompanyConstants.SYSTEM;
501         String newAttachmentsDir = message.getAttachmentsDir();
502 
503         try {
504             try {
505                 dlService.addDirectory(
506                     companyId, repositoryId, newAttachmentsDir);
507             }
508             catch (DuplicateDirectoryException dde) {
509             }
510 
511             String[] fileNames = dlService.getFileNames(
512                 companyId, repositoryId, oldAttachmentsDir);
513 
514             for (String fileName : fileNames) {
515                 String name = StringUtil.extractLast(
516                     fileName, StringPool.SLASH);
517                 byte[] fileBytes = dlService.getFile(
518                     companyId, repositoryId, fileName);
519 
520                 dlService.addFile(
521                     companyId, portletId, groupId, repositoryId,
522                     newAttachmentsDir + "/" + name, StringPool.BLANK,
523                     message.getModifiedDate(), new String[0], fileBytes);
524 
525                 dlService.deleteFile(
526                     companyId, portletId, repositoryId, fileName);
527             }
528 
529             try {
530                 dlService.deleteDirectory(
531                     companyId, portletId, repositoryId, oldAttachmentsDir);
532             }
533             catch (NoSuchDirectoryException nsde) {
534             }
535         }
536         catch (RemoteException re) {
537             throw new SystemException(re);
538         }
539     }
540 
541     protected int moveChildrenMessages(
542             MBMessage parentMessage, MBCategory category, long oldThreadId)
543         throws SystemException, PortalException {
544 
545         int messagesMoved = 0;
546 
547         List<MBMessage> messages = mbMessagePersistence.findByT_P(
548             oldThreadId, parentMessage.getMessageId());
549 
550         for (MBMessage message : messages) {
551             String oldAttachmentsDir = message.getAttachmentsDir();
552 
553             message.setCategoryId(parentMessage.getCategoryId());
554             message.setThreadId(parentMessage.getThreadId());
555             message.setAttachmentsDir(null);
556 
557             mbMessagePersistence.update(message, false);
558 
559             moveAttachmentsFromOldThread(message, oldAttachmentsDir);
560 
561             try {
562                 if (!category.isDiscussion()) {
563                     Indexer.updateMessage(
564                         message.getCompanyId(), message.getGroupId(),
565                         message.getUserId(), message.getUserName(),
566                         category.getCategoryId(), message.getThreadId(),
567                         message.getMessageId(), message.getSubject(),
568                         message.getBody(), message.getModifiedDate(),
569                         message.getTagsEntries());
570                 }
571             }
572             catch (SearchException se) {
573                 _log.error("Indexing " + message.getMessageId(), se);
574             }
575 
576             messagesMoved++;
577 
578             messagesMoved += moveChildrenMessages(
579                 message, category, oldThreadId);
580         }
581 
582         return messagesMoved;
583     }
584 
585     private static Log _log =
586         LogFactoryUtil.getLog(MBThreadLocalServiceImpl.class);
587 
588 }