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