1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.SplitThreadException;
39  import com.liferay.portlet.messageboards.model.MBCategory;
40  import com.liferay.portlet.messageboards.model.MBMessage;
41  import com.liferay.portlet.messageboards.model.MBThread;
42  import com.liferay.portlet.messageboards.model.impl.MBThreadImpl;
43  import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
44  import com.liferay.portlet.messageboards.util.Indexer;
45  
46  import java.util.ArrayList;
47  import java.util.List;
48  
49  /**
50   * <a href="MBThreadLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
51   *
52   * @author Brian Wing Shun Chan
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, boolean subscribed,
177             boolean includeAnonymous, int start, int end)
178         throws PortalException, SystemException {
179 
180         if (userId <= 0) {
181             return mbThreadPersistence.findByGroupId(groupId, start, end);
182         }
183         else {
184             if (subscribed) {
185                 return mbThreadFinder.findByS_G_U(groupId, userId, start, end);
186             }
187             else {
188                 List<Long> threadIds = null;
189 
190                 if (includeAnonymous) {
191                     threadIds = mbMessageFinder.findByG_U(
192                         groupId, userId, start, end);
193                 }
194                 else {
195                     threadIds = mbMessageFinder.findByG_U_A(
196                         groupId, userId, false, start, end);
197                 }
198 
199                 List<MBThread> threads = new ArrayList<MBThread>(
200                     threadIds.size());
201 
202                 for (long threadId : threadIds) {
203                     MBThread thread = mbThreadPersistence.findByPrimaryKey(
204                         threadId);
205 
206                     threads.add(thread);
207                 }
208 
209                 return threads;
210             }
211         }
212     }
213 
214     public List<MBThread> getGroupThreads(
215             long groupId, long userId, boolean subscribed, int start, int end)
216         throws PortalException, SystemException {
217 
218         return getGroupThreads(groupId, userId, subscribed, true, start, end);
219     }
220 
221     public List<MBThread> getGroupThreads(
222             long groupId, long userId, int start, int end)
223         throws PortalException, SystemException {
224 
225         return getGroupThreads(groupId, userId, false, start, end);
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         if (message.isRoot()) {
355             throw new SplitThreadException();
356         }
357 
358         MBCategory category = message.getCategory();
359         long oldThreadId = message.getThreadId();
360         String oldAttachmentsDir = message.getAttachmentsDir();
361 
362         // Message flags
363 
364         mbMessageFlagLocalService.deleteThreadFlags(oldThreadId);
365 
366         // Create new thread
367 
368         MBThread thread = addThread(message.getCategoryId(), message);
369 
370         // Update message
371 
372         message.setThreadId(thread.getThreadId());
373         message.setParentMessageId(0);
374         message.setAttachmentsDir(null);
375 
376         mbMessagePersistence.update(message, false);
377 
378         // Attachments
379 
380         moveAttachmentsFromOldThread(message, oldAttachmentsDir);
381 
382         // Indexer
383 
384         try {
385             if (!category.isDiscussion()) {
386                 Indexer.updateMessage(
387                     message.getCompanyId(), message.getGroupId(),
388                     message.getUserId(), message.getUserName(),
389                     category.getCategoryId(), message.getThreadId(),
390                     message.getMessageId(), message.getSubject(),
391                     message.getBody(), message.isAnonymous(),
392                     message.getModifiedDate(), message.getTagsEntries(),
393                     message.getExpandoBridge());
394             }
395         }
396         catch (SearchException se) {
397             _log.error("Indexing " + message.getMessageId(), se);
398         }
399 
400         // Update children
401 
402         int messagesMoved = 1;
403 
404         messagesMoved += moveChildrenMessages(
405             message, category, oldThreadId);
406 
407         // Update new thread
408 
409         thread.setMessageCount(messagesMoved);
410 
411         mbThreadPersistence.update(thread, false);
412 
413         // Update old thread
414 
415         MBThread oldThread = mbThreadPersistence.findByPrimaryKey(oldThreadId);
416 
417         oldThread.setMessageCount(oldThread.getMessageCount() - messagesMoved);
418 
419         mbThreadPersistence.update(oldThread, false);
420 
421         // Category
422 
423         category.setThreadCount(category.getThreadCount() + 1);
424 
425         mbCategoryPersistence.update(category, false);
426 
427         return thread;
428     }
429 
430     public MBThread updateThread(long threadId, int viewCount)
431         throws PortalException, SystemException {
432 
433         MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
434 
435         thread.setViewCount(viewCount);
436 
437         mbThreadPersistence.update(thread, false);
438 
439         return thread;
440     }
441 
442     protected MBThread addThread(long categoryId, MBMessage message)
443         throws SystemException {
444 
445         long threadId = counterLocalService.increment();
446 
447         MBThread thread = mbThreadPersistence.create(threadId);
448 
449         thread.setGroupId(message.getGroupId());
450         thread.setCategoryId(categoryId);
451         thread.setRootMessageId(message.getMessageId());
452 
453         thread.setMessageCount(thread.getMessageCount() + 1);
454 
455         if (message.isAnonymous()) {
456             thread.setLastPostByUserId(0);
457         }
458         else {
459             thread.setLastPostByUserId(message.getUserId());
460         }
461 
462         thread.setLastPostDate(message.getCreateDate());
463 
464         if (message.getPriority() != MBThreadImpl.PRIORITY_NOT_GIVEN) {
465             thread.setPriority(message.getPriority());
466         }
467 
468         mbThreadPersistence.update(thread, false);
469 
470         return thread;
471     }
472 
473     protected void moveAttachmentsFromOldThread(
474             MBMessage message, String oldAttachmentsDir)
475         throws PortalException, SystemException {
476 
477         if (!message.getAttachments()) {
478             return;
479         }
480 
481         long companyId = message.getCompanyId();
482         String portletId = CompanyConstants.SYSTEM_STRING;
483         long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
484         long repositoryId = CompanyConstants.SYSTEM;
485         String newAttachmentsDir = message.getAttachmentsDir();
486 
487         try {
488             dlService.addDirectory(companyId, repositoryId, newAttachmentsDir);
489         }
490         catch (DuplicateDirectoryException dde) {
491         }
492 
493         String[] fileNames = dlService.getFileNames(
494             companyId, repositoryId, oldAttachmentsDir);
495 
496         for (String fileName : fileNames) {
497             String name = StringUtil.extractLast(fileName, StringPool.SLASH);
498             byte[] fileBytes = dlService.getFile(
499                 companyId, repositoryId, fileName);
500 
501             dlService.addFile(
502                 companyId, portletId, groupId, repositoryId,
503                 newAttachmentsDir + "/" + name, 0, StringPool.BLANK,
504                 message.getModifiedDate(), new String[0], new String[0],
505                 fileBytes);
506 
507             dlService.deleteFile(companyId, portletId, repositoryId, fileName);
508         }
509 
510         try {
511             dlService.deleteDirectory(
512                 companyId, portletId, repositoryId, oldAttachmentsDir);
513         }
514         catch (NoSuchDirectoryException nsde) {
515         }
516     }
517 
518     protected int moveChildrenMessages(
519             MBMessage parentMessage, MBCategory category, long oldThreadId)
520         throws SystemException, PortalException {
521 
522         int messagesMoved = 0;
523 
524         List<MBMessage> messages = mbMessagePersistence.findByT_P(
525             oldThreadId, parentMessage.getMessageId());
526 
527         for (MBMessage message : messages) {
528             String oldAttachmentsDir = message.getAttachmentsDir();
529 
530             message.setCategoryId(parentMessage.getCategoryId());
531             message.setThreadId(parentMessage.getThreadId());
532             message.setAttachmentsDir(null);
533 
534             mbMessagePersistence.update(message, false);
535 
536             moveAttachmentsFromOldThread(message, oldAttachmentsDir);
537 
538             try {
539                 if (!category.isDiscussion()) {
540                     Indexer.updateMessage(
541                         message.getCompanyId(), message.getGroupId(),
542                         message.getUserId(), message.getUserName(),
543                         category.getCategoryId(), message.getThreadId(),
544                         message.getMessageId(), message.getSubject(),
545                         message.getBody(), message.isAnonymous(),
546                         message.getModifiedDate(), message.getTagsEntries(),
547                         message.getExpandoBridge());
548                 }
549             }
550             catch (SearchException se) {
551                 _log.error("Indexing " + message.getMessageId(), se);
552             }
553 
554             messagesMoved++;
555 
556             messagesMoved += moveChildrenMessages(
557                 message, category, oldThreadId);
558         }
559 
560         return messagesMoved;
561     }
562 
563     private static Log _log =
564         LogFactoryUtil.getLog(MBThreadLocalServiceImpl.class);
565 
566 }