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