001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.messageboards.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.increment.BufferedIncrement;
020    import com.liferay.portal.kernel.increment.NumberIncrement;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.search.Indexer;
024    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
025    import com.liferay.portal.kernel.util.CharPool;
026    import com.liferay.portal.kernel.util.StringBundler;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.kernel.workflow.WorkflowConstants;
031    import com.liferay.portal.model.CompanyConstants;
032    import com.liferay.portal.model.ResourceConstants;
033    import com.liferay.portal.service.ServiceContext;
034    import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
035    import com.liferay.portlet.documentlibrary.NoSuchDirectoryException;
036    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
037    import com.liferay.portlet.messageboards.SplitThreadException;
038    import com.liferay.portlet.messageboards.model.MBCategory;
039    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
040    import com.liferay.portlet.messageboards.model.MBMessage;
041    import com.liferay.portlet.messageboards.model.MBMessageDisplay;
042    import com.liferay.portlet.messageboards.model.MBThread;
043    import com.liferay.portlet.messageboards.model.MBThreadConstants;
044    import com.liferay.portlet.messageboards.model.MBTreeWalker;
045    import com.liferay.portlet.messageboards.service.base.MBThreadLocalServiceBaseImpl;
046    
047    import java.io.File;
048    import java.io.IOException;
049    import java.io.InputStream;
050    
051    import java.util.ArrayList;
052    import java.util.List;
053    
054    /**
055     * @author Brian Wing Shun Chan
056     * @author Shuyang Zhou
057     */
058    public class MBThreadLocalServiceImpl extends MBThreadLocalServiceBaseImpl {
059    
060            public MBThread addThread(long categoryId, MBMessage message)
061                    throws PortalException, SystemException {
062    
063                    // Thread
064    
065                    long threadId = message.getThreadId();
066    
067                    if (!message.isRoot() || (threadId <= 0)) {
068                            threadId = counterLocalService.increment();
069                    }
070    
071                    MBThread thread = mbThreadPersistence.create(threadId);
072    
073                    thread.setGroupId(message.getGroupId());
074                    thread.setCompanyId(message.getCompanyId());
075                    thread.setCategoryId(categoryId);
076                    thread.setRootMessageId(message.getMessageId());
077                    thread.setRootMessageUserId(message.getUserId());
078    
079                    if (message.isAnonymous()) {
080                            thread.setLastPostByUserId(0);
081                    }
082                    else {
083                            thread.setLastPostByUserId(message.getUserId());
084                    }
085    
086                    thread.setLastPostDate(message.getCreateDate());
087    
088                    if (message.getPriority() != MBThreadConstants.PRIORITY_NOT_GIVEN) {
089                            thread.setPriority(message.getPriority());
090                    }
091    
092                    thread.setStatus(message.getStatus());
093                    thread.setStatusByUserId(message.getStatusByUserId());
094                    thread.setStatusByUserName(message.getStatusByUserName());
095                    thread.setStatusDate(message.getStatusDate());
096    
097                    mbThreadPersistence.update(thread, false);
098    
099                    // Asset
100    
101                    if (categoryId >= 0) {
102                            assetEntryLocalService.updateEntry(
103                                    message.getUserId(), message.getGroupId(),
104                                    MBThread.class.getName(), thread.getThreadId(), null, 0,
105                                    new long[0], new String[0], false, null, null, null, null, null,
106                                    String.valueOf(thread.getRootMessageId()), null, null, null,
107                                    null, 0, 0, null, false);
108                    }
109    
110                    return thread;
111            }
112    
113            public void deleteThread(long threadId)
114                    throws PortalException, SystemException {
115    
116                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
117    
118                    deleteThread(thread);
119            }
120    
121            public void deleteThread(MBThread thread)
122                    throws PortalException, SystemException {
123    
124                    MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
125                            thread.getRootMessageId());
126    
127                    // Indexer
128    
129                    Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
130    
131                    indexer.delete(thread);
132    
133                    // Attachments
134    
135                    long companyId = rootMessage.getCompanyId();
136                    long repositoryId = CompanyConstants.SYSTEM;
137                    String dirName = thread.getAttachmentsDir();
138    
139                    try {
140                            DLStoreUtil.deleteDirectory(companyId, repositoryId, dirName);
141                    }
142                    catch (NoSuchDirectoryException nsde) {
143                    }
144    
145                    // Thread flags
146    
147                    mbThreadFlagPersistence.removeByThreadId(thread.getThreadId());
148    
149                    // Messages
150    
151                    List<MBMessage> messages = mbMessagePersistence.findByThreadId(
152                            thread.getThreadId());
153    
154                    for (MBMessage message : messages) {
155    
156                            // Ratings
157    
158                            ratingsStatsLocalService.deleteStats(
159                                    MBMessage.class.getName(), message.getMessageId());
160    
161                            // Asset
162    
163                            assetEntryLocalService.deleteEntry(
164                                    MBMessage.class.getName(), message.getMessageId());
165    
166                            // Resources
167    
168                            if (!message.isDiscussion()) {
169                                    resourceLocalService.deleteResource(
170                                            message.getCompanyId(), MBMessage.class.getName(),
171                                            ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
172                            }
173    
174                            // Message
175    
176                            mbMessagePersistence.remove(message);
177    
178                            // Statistics
179    
180                            if (!message.isDiscussion()) {
181                                    mbStatsUserLocalService.updateStatsUser(
182                                            message.getGroupId(), message.getUserId());
183                            }
184    
185                            // Workflow
186    
187                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
188                                    message.getCompanyId(), message.getGroupId(),
189                                    message.getWorkflowClassName(), message.getMessageId());
190                    }
191    
192                    // Category
193    
194                    if ((rootMessage.getCategoryId() !=
195                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
196                            (rootMessage.getCategoryId() !=
197                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
198    
199                            MBCategory category = mbCategoryPersistence.findByPrimaryKey(
200                                    thread.getCategoryId());
201    
202                            category.setThreadCount(category.getThreadCount() - 1);
203                            category.setMessageCount(
204                                    category.getMessageCount() - thread.getMessageCount());
205    
206                            mbCategoryPersistence.update(category, false);
207                    }
208    
209                    // Thread Asset
210    
211                    assetEntryLocalService.deleteEntry(
212                            MBThread.class.getName(), thread.getThreadId());
213    
214                    // Thread
215    
216                    mbThreadPersistence.remove(thread);
217            }
218    
219            public void deleteThreads(long groupId, long categoryId)
220                    throws PortalException, SystemException {
221    
222                    List<MBThread> threads = mbThreadPersistence.findByG_C(
223                            groupId, categoryId);
224    
225                    for (MBThread thread : threads) {
226                            deleteThread(thread);
227                    }
228            }
229    
230            public MBThread fetchThread(long threadId) throws SystemException {
231                    return mbThreadPersistence.fetchByPrimaryKey(threadId);
232            }
233    
234            public int getCategoryThreadsCount(
235                            long groupId, long categoryId, int status)
236                    throws SystemException {
237    
238                    if (status == WorkflowConstants.STATUS_ANY) {
239                            return mbThreadPersistence.countByG_C(groupId, categoryId);
240                    }
241                    else {
242                            return mbThreadPersistence.countByG_C_S(
243                                    groupId, categoryId, status);
244                    }
245            }
246    
247            public List<MBThread> getGroupThreads(
248                            long groupId, int status, int start, int end)
249                    throws SystemException {
250    
251                    if (status == WorkflowConstants.STATUS_ANY) {
252                            return mbThreadPersistence.findByG_NotC(
253                                    groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, start,
254                                    end);
255                    }
256                    else {
257                            return mbThreadPersistence.findByG_NotC_S(
258                                    groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, status,
259                                    start, end);
260                    }
261            }
262    
263            public List<MBThread> getGroupThreads(
264                            long groupId, long userId, int status, boolean subscribed,
265                            boolean includeAnonymous, int start, int end)
266                    throws PortalException, SystemException {
267    
268                    if (userId <= 0) {
269                            if (status == WorkflowConstants.STATUS_ANY) {
270                                    return mbThreadPersistence.findByG_NotC(
271                                            groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, start,
272                                            end);
273                            }
274                            else {
275                                    return mbThreadPersistence.findByG_NotC_S(
276                                            groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, status,
277                                            start, end);
278                            }
279                    }
280                    else {
281                            if (subscribed) {
282                                    return mbThreadFinder.findByS_G_U_C_S(
283                                            groupId, userId, null, status, start, end);
284                            }
285                            else {
286                                    List<Long> threadIds = null;
287    
288                                    if (includeAnonymous) {
289                                            threadIds = mbMessageFinder.findByG_U_C_S(
290                                                    groupId, userId, null, status, start, end);
291                                    }
292                                    else {
293                                            threadIds = mbMessageFinder.findByG_U_C_A_S(
294                                                    groupId, userId, null, false, status, start, end);
295                                    }
296    
297                                    List<MBThread> threads = new ArrayList<MBThread>(
298                                            threadIds.size());
299    
300                                    for (long threadId : threadIds) {
301                                            MBThread thread = mbThreadPersistence.findByPrimaryKey(
302                                                    threadId);
303    
304                                            threads.add(thread);
305                                    }
306    
307                                    return threads;
308                            }
309                    }
310            }
311    
312            public List<MBThread> getGroupThreads(
313                            long groupId, long userId, int status, boolean subscribed,
314                            int start, int end)
315                    throws PortalException, SystemException {
316    
317                    return getGroupThreads(
318                            groupId, userId, status, subscribed, true, start, end);
319            }
320    
321            public List<MBThread> getGroupThreads(
322                            long groupId, long userId, int status, int start, int end)
323                    throws PortalException, SystemException {
324    
325                    return getGroupThreads(groupId, userId, status, false, start, end);
326            }
327    
328            public int getGroupThreadsCount(long groupId, int status)
329                    throws SystemException {
330    
331                    if (status == WorkflowConstants.STATUS_ANY) {
332                            return mbThreadPersistence.countByG_NotC(
333                                    groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID);
334                    }
335                    else {
336                            return mbThreadPersistence.countByG_NotC_S(
337                                    groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID, status);
338                    }
339            }
340    
341            public int getGroupThreadsCount(long groupId, long userId, int status)
342                    throws SystemException {
343    
344                    return getGroupThreadsCount(groupId, userId, status, false);
345            }
346    
347            public int getGroupThreadsCount(
348                            long groupId, long userId, int status, boolean subscribed)
349                    throws SystemException {
350    
351                    return getGroupThreadsCount(groupId, userId, status, subscribed, true);
352            }
353    
354            public int getGroupThreadsCount(
355                            long groupId, long userId, int status, boolean subscribed,
356                            boolean includeAnonymous)
357                    throws SystemException {
358    
359                    if (userId <= 0) {
360                            if (status == WorkflowConstants.STATUS_ANY) {
361                                    return mbThreadPersistence.countByG_NotC(
362                                            groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID);
363                            }
364                            else {
365                                    return mbThreadPersistence.countByG_NotC_S(
366                                            groupId, MBCategoryConstants.DISCUSSION_CATEGORY_ID,
367                                            status);
368                            }
369                    }
370                    else {
371                            if (subscribed) {
372                                    return mbThreadFinder.countByS_G_U_C_S(
373                                            groupId, userId, null, status);
374                            }
375                            else {
376                                    if (includeAnonymous) {
377                                            return mbMessageFinder.countByG_U_C_S(
378                                                    groupId, userId, null, status);
379                                    }
380                                    else {
381                                            return mbMessageFinder.countByG_U_C_A_S(
382                                                    groupId, userId, null, false, status);
383                                    }
384                            }
385                    }
386            }
387    
388            public List<MBThread> getNoAssetThreads() throws SystemException {
389                    return mbThreadFinder.findByNoAssets();
390            }
391    
392            public List<MBThread> getPriorityThreads(long categoryId, double priority)
393                    throws PortalException, SystemException {
394    
395                    return getPriorityThreads(categoryId, priority, false);
396            }
397    
398            public List<MBThread> getPriorityThreads(
399                            long categoryId, double priority, boolean inherit)
400                    throws PortalException, SystemException {
401    
402                    if (!inherit) {
403                            return mbThreadPersistence.findByC_P(categoryId, priority);
404                    }
405    
406                    List<MBThread> threads = new ArrayList<MBThread>();
407    
408                    while ((categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
409                               (categoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
410    
411                            threads.addAll(
412                                    0, mbThreadPersistence.findByC_P(categoryId, priority));
413    
414                            MBCategory category = mbCategoryPersistence.findByPrimaryKey(
415                                    categoryId);
416    
417                            categoryId = category.getParentCategoryId();
418                    }
419    
420                    return threads;
421            }
422    
423            public MBThread getThread(long threadId)
424                    throws PortalException, SystemException {
425    
426                    return mbThreadPersistence.findByPrimaryKey(threadId);
427            }
428    
429            public List<MBThread> getThreads(
430                            long groupId, long categoryId, int status, int start, int end)
431                    throws SystemException {
432    
433                    if (status == WorkflowConstants.STATUS_ANY) {
434                            return mbThreadPersistence.findByG_C(
435                                    groupId, categoryId, start, end);
436                    }
437                    else {
438                            return mbThreadPersistence.findByG_C_S(
439                                    groupId, categoryId, status, start, end);
440                    }
441            }
442    
443            public int getThreadsCount(long groupId, long categoryId, int status)
444                    throws SystemException {
445    
446                    if (status == WorkflowConstants.STATUS_ANY) {
447                            return mbThreadPersistence.countByG_C(groupId, categoryId);
448                    }
449                    else {
450                            return mbThreadPersistence.countByG_C_S(
451                                    groupId, categoryId, status);
452                    }
453            }
454    
455            public boolean hasAnswerMessage(long threadId) throws SystemException {
456                    int count = mbMessagePersistence.countByT_A(threadId, true);
457    
458                    if (count > 0) {
459                            return true;
460                    }
461                    else {
462                            return false;
463                    }
464            }
465    
466            @BufferedIncrement(incrementClass = NumberIncrement.class)
467            public MBThread incrementViewCounter(long threadId, int increment)
468                    throws PortalException, SystemException {
469    
470                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
471    
472                    thread.setViewCount(thread.getViewCount() + increment);
473    
474                    mbThreadPersistence.update(thread, false);
475    
476                    return thread;
477            }
478    
479            public MBThread moveThread(long groupId, long categoryId, long threadId)
480                    throws PortalException, SystemException {
481    
482                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
483    
484                    long oldCategoryId = thread.getCategoryId();
485    
486                    MBCategory oldCategory = null;
487    
488                    if (oldCategoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
489                            oldCategory = mbCategoryPersistence.findByPrimaryKey(oldCategoryId);
490                    }
491    
492                    MBCategory category = null;
493    
494                    if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
495                            category = mbCategoryPersistence.findByPrimaryKey(categoryId);
496                    }
497    
498                    // Messages
499    
500                    List<MBMessage> messages = mbMessagePersistence.findByG_C_T(
501                            groupId, oldCategoryId, thread.getThreadId());
502    
503                    for (MBMessage message : messages) {
504                            message.setCategoryId(categoryId);
505    
506                            mbMessagePersistence.update(message, false);
507    
508                            // Indexer
509    
510                            if (!message.isDiscussion()) {
511                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
512                                            MBMessage.class);
513    
514                                    indexer.reindex(message);
515                            }
516                    }
517    
518                    // Thread
519    
520                    thread.setCategoryId(categoryId);
521    
522                    mbThreadPersistence.update(thread, false);
523    
524                    // Category
525    
526                    if ((oldCategory != null) && (categoryId != oldCategoryId)) {
527                            oldCategory.setThreadCount(oldCategory.getThreadCount() - 1);
528                            oldCategory.setMessageCount(
529                                    oldCategory.getMessageCount() - thread.getMessageCount());
530    
531                            mbCategoryPersistence.update(oldCategory, false);
532                    }
533    
534                    if ((category != null) && (categoryId != oldCategoryId)) {
535                            category.setThreadCount(category.getThreadCount() + 1);
536                            category.setMessageCount(
537                                    category.getMessageCount() + thread.getMessageCount());
538    
539                            mbCategoryPersistence.update(category, false);
540                    }
541    
542                    return thread;
543            }
544    
545            public MBThread splitThread(
546                            long messageId, String subject, ServiceContext serviceContext)
547                    throws PortalException, SystemException {
548    
549                    MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
550    
551                    if (message.isRoot()) {
552                            throw new SplitThreadException();
553                    }
554    
555                    MBCategory category = message.getCategory();
556                    MBThread oldThread = message.getThread();
557                    MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
558                            oldThread.getRootMessageId());
559                    String oldAttachmentsDir = message.getAttachmentsDir();
560    
561                    // Message flags
562    
563                    mbMessageLocalService.updateAnswer(message, false, true);
564    
565                    // Create new thread
566    
567                    MBThread thread = addThread(message.getCategoryId(), message);
568    
569                    // Update messages
570    
571                    if (Validator.isNotNull(subject)) {
572                            MBMessageDisplay messageDisplay =
573                                    mbMessageService.getMessageDisplay(
574                                            messageId, WorkflowConstants.STATUS_ANY,
575                                            MBThreadConstants.THREAD_VIEW_TREE, false);
576    
577                            MBTreeWalker treeWalker = messageDisplay.getTreeWalker();
578    
579                            List<MBMessage> messages = treeWalker.getMessages();
580    
581                            int[] range = treeWalker.getChildrenRange(message);
582    
583                            for (int i = range[0]; i < range[1]; i++) {
584                                    MBMessage curMessage = messages.get(i);
585    
586                                    String oldSubject = message.getSubject();
587                                    String curSubject = curMessage.getSubject();
588    
589                                    if (oldSubject.startsWith("RE: ")) {
590                                            curSubject = StringUtil.replace(
591                                                    curSubject, rootMessage.getSubject(), subject);
592                                    }
593                                    else {
594                                            curSubject = StringUtil.replace(
595                                                    curSubject, oldSubject, subject);
596                                    }
597    
598                                    curMessage.setSubject(curSubject);
599    
600                                    mbMessagePersistence.update(curMessage, false);
601                            }
602    
603                            message.setSubject(subject);
604                    }
605    
606                    message.setThreadId(thread.getThreadId());
607                    message.setRootMessageId(thread.getRootMessageId());
608                    message.setParentMessageId(0);
609                    message.setAttachmentsDir(null);
610    
611                    mbMessagePersistence.update(message, false);
612    
613                    // Attachments
614    
615                    moveAttachmentsFromOldThread(message, oldAttachmentsDir);
616    
617                    // Indexer
618    
619                    if (!message.isDiscussion()) {
620                            Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
621    
622                            indexer.reindex(message);
623                    }
624    
625                    // Update children
626    
627                    int messagesMoved = 1;
628    
629                    messagesMoved += moveChildrenMessages(
630                            message, category, oldThread.getThreadId());
631    
632                    // Update new thread
633    
634                    thread.setMessageCount(messagesMoved);
635    
636                    mbThreadPersistence.update(thread, false);
637    
638                    // Update old thread
639    
640                    oldThread.setMessageCount(oldThread.getMessageCount() - messagesMoved);
641    
642                    mbThreadPersistence.update(oldThread, false);
643    
644                    // Category
645    
646                    if ((message.getCategoryId() !=
647                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
648                            (message.getCategoryId() !=
649                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
650    
651                            category.setThreadCount(category.getThreadCount() + 1);
652    
653                            mbCategoryPersistence.update(category, false);
654                    }
655    
656                    return thread;
657            }
658    
659            public void updateQuestion(long threadId, boolean question)
660                    throws PortalException, SystemException {
661    
662                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
663    
664                    if (thread.isQuestion() == question) {
665                            return;
666                    }
667    
668                    thread.setQuestion(question);
669    
670                    mbThreadPersistence.update(thread, false);
671    
672                    if (!question) {
673                            MBMessage message = mbMessagePersistence.findByPrimaryKey(
674                                    thread.getRootMessageId());
675    
676                            mbMessageLocalService.updateAnswer(message, false, true);
677                    }
678            }
679    
680            /**
681             * @deprecated {@link #incrementViewCounter(long, int)}
682             */
683            public MBThread updateThread(long threadId, int viewCount)
684                    throws PortalException, SystemException {
685    
686                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
687    
688                    thread.setViewCount(viewCount);
689    
690                    mbThreadPersistence.update(thread, false);
691    
692                    return thread;
693            }
694    
695            protected void moveAttachmentFromOldThread(
696                            long companyId, String fileName, String newAttachmentsDir)
697                    throws PortalException, SystemException {
698    
699                    long repositoryId = CompanyConstants.SYSTEM;
700    
701                    StringBundler sb = new StringBundler(4);
702    
703                    sb.append(newAttachmentsDir);
704                    sb.append(StringPool.SLASH);
705                    sb.append(StringUtil.extractLast(fileName, CharPool.SLASH));
706    
707                    String newFileName = sb.toString();
708    
709                    try {
710                            File file = DLStoreUtil.getFile(companyId, repositoryId, fileName);
711    
712                            DLStoreUtil.addFile(
713                                    companyId, repositoryId, newFileName, false, file);
714                    }
715                    catch (UnsupportedOperationException uoe) {
716                            InputStream is = DLStoreUtil.getFileAsStream(
717                                    companyId, repositoryId, fileName);
718    
719                            try {
720                                    DLStoreUtil.addFile(
721                                            companyId, repositoryId, newFileName, false, is);
722                            }
723                            finally {
724                                    try {
725                                            is.close();
726                                    }
727                                    catch (IOException ioe) {
728                                            _log.error(ioe);
729                                    }
730                            }
731                    }
732    
733                    DLStoreUtil.deleteFile(companyId, repositoryId, fileName);
734            }
735    
736            protected void moveAttachmentsFromOldThread(
737                            MBMessage message, String oldAttachmentsDir)
738                    throws PortalException, SystemException {
739    
740                    if (!message.getAttachments()) {
741                            return;
742                    }
743    
744                    long companyId = message.getCompanyId();
745                    long repositoryId = CompanyConstants.SYSTEM;
746                    String newAttachmentsDir = message.getAttachmentsDir();
747    
748                    try {
749                            DLStoreUtil.addDirectory(
750                                    companyId, repositoryId, newAttachmentsDir);
751                    }
752                    catch (DuplicateDirectoryException dde) {
753                    }
754    
755                    String[] fileNames = DLStoreUtil.getFileNames(
756                            companyId, repositoryId, oldAttachmentsDir);
757    
758                    for (String fileName : fileNames) {
759                            moveAttachmentFromOldThread(companyId, fileName, newAttachmentsDir);
760                    }
761    
762                    try {
763                            DLStoreUtil.deleteDirectory(
764                                    companyId, repositoryId, oldAttachmentsDir);
765                    }
766                    catch (NoSuchDirectoryException nsde) {
767                    }
768            }
769    
770            protected int moveChildrenMessages(
771                            MBMessage parentMessage, MBCategory category, long oldThreadId)
772                    throws PortalException, SystemException {
773    
774                    int messagesMoved = 0;
775    
776                    List<MBMessage> messages = mbMessagePersistence.findByT_P(
777                            oldThreadId, parentMessage.getMessageId());
778    
779                    for (MBMessage message : messages) {
780                            String oldAttachmentsDir = message.getAttachmentsDir();
781    
782                            message.setCategoryId(parentMessage.getCategoryId());
783                            message.setThreadId(parentMessage.getThreadId());
784                            message.setRootMessageId(parentMessage.getRootMessageId());
785                            message.setAttachmentsDir(null);
786    
787                            mbMessagePersistence.update(message, false);
788    
789                            moveAttachmentsFromOldThread(message, oldAttachmentsDir);
790    
791                            if (!message.isDiscussion()) {
792                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
793                                            MBMessage.class);
794    
795                                    indexer.reindex(message);
796                            }
797    
798                            messagesMoved++;
799    
800                            messagesMoved += moveChildrenMessages(
801                                    message, category, oldThreadId);
802                    }
803    
804                    return messagesMoved;
805            }
806    
807            private static Log _log = LogFactoryUtil.getLog(
808                    MBThreadLocalServiceImpl.class);
809    
810    }