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.model.User;
35  import com.liferay.portal.theme.ThemeDisplay;
36  import com.liferay.portlet.messageboards.model.MBCategory;
37  import com.liferay.portlet.messageboards.model.MBMessage;
38  import com.liferay.portlet.messageboards.model.MBThread;
39  import com.liferay.portlet.messageboards.model.impl.MBThreadImpl;
40  import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
41  import com.liferay.portlet.messageboards.util.Indexer;
42  
43  import java.rmi.RemoteException;
44  
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          MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
69              thread.getRootMessageId());
70  
71          // Indexer
72  
73          try {
74              Indexer.deleteMessages(
75                  rootMessage.getCompanyId(), thread.getThreadId());
76          }
77          catch (SearchException se) {
78              _log.error("Deleting index " + thread.getThreadId(), se);
79          }
80  
81          // Attachments
82  
83          long companyId = rootMessage.getCompanyId();
84          String portletId = CompanyConstants.SYSTEM_STRING;
85          long repositoryId = CompanyConstants.SYSTEM;
86          String dirName = thread.getAttachmentsDir();
87  
88          try {
89              dlService.deleteDirectory(
90                  companyId, portletId, repositoryId, dirName);
91          }
92          catch (NoSuchDirectoryException nsde) {
93          }
94          catch (RemoteException re) {
95              throw new SystemException(re);
96          }
97  
98          // Messages
99  
100         List<MBMessage> messages = mbMessagePersistence.findByThreadId(
101             thread.getThreadId());
102 
103         for (MBMessage message : messages) {
104 
105             // Tags
106 
107             tagsAssetLocalService.deleteAsset(
108                 MBMessage.class.getName(), message.getMessageId());
109 
110             // Social
111 
112             socialActivityLocalService.deleteActivities(
113                 MBMessage.class.getName(), message.getMessageId());
114 
115             // Ratings
116 
117             ratingsStatsLocalService.deleteStats(
118                 MBMessage.class.getName(), message.getMessageId());
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         // Thread
138 
139         mbThreadPersistence.remove(thread);
140     }
141 
142     public void deleteThreads(long categoryId)
143         throws PortalException, SystemException {
144 
145         List<MBThread> threads = mbThreadPersistence.findByCategoryId(
146             categoryId);
147 
148         for (MBThread thread : threads) {
149             deleteThread(thread);
150         }
151     }
152 
153     public int getCategoriesThreadsCount(List<Long> categoryIds)
154         throws SystemException {
155 
156         return mbThreadFinder.countByCategoryIds(categoryIds);
157     }
158 
159     public List<MBThread> getGroupThreads(long groupId, int start, int end)
160         throws SystemException {
161 
162         return mbThreadFinder.findByGroupId(groupId, start, end);
163     }
164 
165     public List<MBThread> getGroupThreads(
166             long groupId, long userId, int start, int end)
167         throws SystemException {
168 
169         return getGroupThreads(groupId, userId, false, start, end);
170     }
171 
172     public List<MBThread> getGroupThreads(
173             long groupId, long userId, boolean subscribed, int start, int end)
174         throws SystemException {
175 
176         if (userId <= 0) {
177             return mbThreadFinder.findByGroupId(groupId, start, end);
178         }
179         else {
180             if (subscribed) {
181                 return mbThreadFinder.findByS_G_U(groupId, userId, start, end);
182             }
183             else {
184                 return mbThreadFinder.findByG_U(groupId, userId, start, end);
185             }
186         }
187     }
188 
189     public int getGroupThreadsCount(long groupId) throws SystemException {
190         return mbThreadFinder.countByGroupId(groupId);
191     }
192 
193     public int getGroupThreadsCount(long groupId, long userId)
194         throws SystemException {
195 
196         return getGroupThreadsCount(groupId, userId, false);
197     }
198 
199     public int getGroupThreadsCount(
200             long groupId, long userId, boolean subscribed)
201         throws SystemException {
202 
203         if (userId <= 0) {
204             return mbThreadFinder.countByGroupId(groupId);
205         }
206         else {
207             if (subscribed) {
208                 return mbThreadFinder.countByS_G_U(groupId, userId);
209             }
210             else {
211                 return mbThreadFinder.countByG_U(groupId, userId);
212             }
213         }
214     }
215 
216     public MBThread getThread(long threadId)
217         throws PortalException, SystemException {
218 
219         return mbThreadPersistence.findByPrimaryKey(threadId);
220     }
221 
222     public List<MBThread> getThreads(long categoryId, int start, int end)
223         throws SystemException {
224 
225         return mbThreadPersistence.findByCategoryId(categoryId, start, end);
226     }
227 
228     public int getThreadsCount(long categoryId) throws SystemException {
229         return mbThreadPersistence.countByCategoryId(categoryId);
230     }
231 
232     public boolean hasReadThread(long userId, long threadId)
233         throws PortalException, SystemException {
234 
235         User user = userPersistence.findByPrimaryKey(userId);
236 
237         if (user.isDefaultUser()) {
238             return true;
239         }
240 
241         int total = mbMessagePersistence.countByThreadId(threadId);
242         int read = mbMessageFlagFinder.countByU_T(userId, threadId);
243 
244         if (total != read) {
245             return false;
246         }
247         else {
248             return true;
249         }
250     }
251 
252     public MBThread moveThread(long categoryId, long threadId)
253         throws PortalException, SystemException {
254 
255         MBThread thread = mbThreadPersistence.findByPrimaryKey(
256             threadId);
257 
258         long oldCategoryId = thread.getCategoryId();
259 
260         MBCategory category = mbCategoryPersistence.findByPrimaryKey(
261             categoryId);
262 
263         // Messages
264 
265         List<MBMessage> messages = mbMessagePersistence.findByC_T(
266             oldCategoryId, thread.getThreadId());
267 
268         for (MBMessage message : messages) {
269             message.setCategoryId(category.getCategoryId());
270 
271             mbMessagePersistence.update(message, false);
272 
273             // Indexer
274 
275             try {
276                 if (!category.isDiscussion()) {
277                     Indexer.updateMessage(
278                         message.getCompanyId(), category.getGroupId(),
279                         message.getUserId(), message.getUserName(),
280                         category.getCategoryId(), message.getThreadId(),
281                         message.getMessageId(), message.getSubject(),
282                         message.getBody(), message.getModifiedDate(),
283                         message.getTagsEntries());
284                 }
285             }
286             catch (SearchException se) {
287                 _log.error("Indexing " + message.getMessageId(), se);
288             }
289         }
290 
291         // Thread
292 
293         thread.setCategoryId(category.getCategoryId());
294 
295         mbThreadPersistence.update(thread, false);
296 
297         return thread;
298     }
299 
300     public MBThread splitThread(
301             long messageId, PortletPreferences prefs, ThemeDisplay themeDisplay)
302         throws PortalException, SystemException {
303 
304         MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
305 
306         MBCategory category = message.getCategory();
307         long oldThreadId = message.getThreadId();
308         String oldAttachmentsDir = message.getAttachmentsDir();
309 
310         // Create new thread
311 
312         MBThread thread = addThread(message.getCategoryId(), message);
313 
314         // Update message
315 
316         message.setThreadId(thread.getThreadId());
317         message.setParentMessageId(0);
318         message.setAttachmentsDir(null);
319 
320         mbMessagePersistence.update(message, false);
321 
322         // Attachments
323 
324         moveAttachmentsFromOldThread(message, oldAttachmentsDir);
325 
326         // Indexer
327 
328         try {
329             if (!category.isDiscussion()) {
330                 Indexer.updateMessage(
331                     message.getCompanyId(), category.getGroupId(),
332                     message.getUserId(), message.getUserName(),
333                     category.getCategoryId(), message.getThreadId(),
334                     message.getMessageId(), message.getSubject(),
335                     message.getBody(), message.getModifiedDate(),
336                     message.getTagsEntries());
337             }
338         }
339         catch (SearchException se) {
340             _log.error("Indexing " + message.getMessageId(), se);
341         }
342 
343         // Update children
344 
345         int messagesMoved = 1;
346 
347         messagesMoved += moveChildrenMessages(
348             message, category, oldThreadId);
349 
350         // Update new thread
351 
352         thread.setMessageCount(messagesMoved);
353 
354         mbThreadPersistence.update(thread, false);
355 
356         // Update old thread
357 
358         MBThread oldThread = mbThreadPersistence.findByPrimaryKey(oldThreadId);
359 
360         oldThread.setMessageCount(oldThread.getMessageCount() - messagesMoved);
361 
362         mbThreadPersistence.update(oldThread, false);
363 
364         return thread;
365     }
366 
367     public MBThread updateThread(long threadId, int viewCount)
368         throws PortalException, SystemException {
369 
370         MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
371 
372         thread.setViewCount(viewCount);
373 
374         mbThreadPersistence.update(thread, false);
375 
376         return thread;
377     }
378 
379     protected MBThread addThread(long categoryId, MBMessage message)
380         throws SystemException, PortalException {
381 
382         long threadId = counterLocalService.increment();
383 
384         MBThread thread = mbThreadPersistence.create(threadId);
385 
386         thread.setCategoryId(categoryId);
387         thread.setRootMessageId(message.getMessageId());
388 
389         thread.setMessageCount(thread.getMessageCount() + 1);
390 
391         if (message.isAnonymous()) {
392             thread.setLastPostByUserId(0);
393         }
394         else {
395             thread.setLastPostByUserId(message.getUserId());
396         }
397 
398         thread.setLastPostDate(message.getCreateDate());
399 
400         if (message.getPriority() != MBThreadImpl.PRIORITY_NOT_GIVEN) {
401             thread.setPriority(message.getPriority());
402         }
403 
404         mbThreadPersistence.update(thread, false);
405 
406         return thread;
407     }
408 
409     protected void moveAttachmentsFromOldThread(
410             MBMessage message, String oldAttachmentsDir)
411         throws PortalException, SystemException {
412 
413         if (!message.getAttachments()) {
414             return;
415         }
416 
417         long companyId = message.getCompanyId();
418         String portletId = CompanyConstants.SYSTEM_STRING;
419         long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
420         long repositoryId = CompanyConstants.SYSTEM;
421         String newAttachmentsDir = message.getAttachmentsDir();
422 
423         try {
424             try {
425                 dlService.addDirectory(
426                     companyId, repositoryId, newAttachmentsDir);
427             }
428             catch (DuplicateDirectoryException dde) {
429             }
430 
431             String[] fileNames = dlService.getFileNames(
432                 companyId, repositoryId, oldAttachmentsDir);
433 
434             for (String fileName : fileNames) {
435                 String name = StringUtil.extractLast(
436                     fileName, StringPool.SLASH);
437                 byte[] fileBytes = dlService.getFile(
438                     companyId, repositoryId, fileName);
439 
440                 dlService.addFile(
441                     companyId, portletId, groupId, repositoryId,
442                     newAttachmentsDir + "/" + name, StringPool.BLANK,
443                     message.getModifiedDate(), new String[0], fileBytes);
444 
445                 dlService.deleteFile(
446                     companyId, portletId, repositoryId, fileName);
447             }
448 
449             try {
450                 dlService.deleteDirectory(
451                     companyId, portletId, repositoryId, oldAttachmentsDir);
452             }
453             catch (NoSuchDirectoryException nsde) {
454             }
455         }
456         catch (RemoteException re) {
457             throw new SystemException(re);
458         }
459     }
460 
461     protected int moveChildrenMessages(
462             MBMessage parentMessage, MBCategory category, long oldThreadId)
463         throws SystemException, PortalException {
464 
465         int messagesMoved = 0;
466 
467         List<MBMessage> messages = mbMessagePersistence.findByT_P(
468             oldThreadId, parentMessage.getMessageId());
469 
470         for (MBMessage message : messages) {
471             String oldAttachmentsDir = message.getAttachmentsDir();
472 
473             message.setCategoryId(parentMessage.getCategoryId());
474             message.setThreadId(parentMessage.getThreadId());
475             message.setAttachmentsDir(null);
476 
477             mbMessagePersistence.update(message, false);
478 
479             moveAttachmentsFromOldThread(message, oldAttachmentsDir);
480 
481             try {
482                 if (!category.isDiscussion()) {
483                     Indexer.updateMessage(
484                         message.getCompanyId(), category.getGroupId(),
485                         message.getUserId(), message.getUserName(),
486                         category.getCategoryId(), message.getThreadId(),
487                         message.getMessageId(), message.getSubject(),
488                         message.getBody(), message.getModifiedDate(),
489                         message.getTagsEntries());
490                 }
491             }
492             catch (SearchException se) {
493                 _log.error("Indexing " + message.getMessageId(), se);
494             }
495 
496             messagesMoved++;
497 
498             messagesMoved += moveChildrenMessages(
499                 message, category, oldThreadId);
500         }
501 
502         return messagesMoved;
503     }
504 
505     private static Log _log =
506          LogFactoryUtil.getLog(MBThreadLocalServiceImpl.class);
507 
508 }