001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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(
483                            threadId);
484    
485                    long oldCategoryId = thread.getCategoryId();
486    
487                    MBCategory oldCategory = null;
488    
489                    if (oldCategoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
490                            oldCategory = mbCategoryPersistence.findByPrimaryKey(
491                                    oldCategoryId);
492                    }
493    
494                    MBCategory category = null;
495    
496                    if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
497                            category = mbCategoryPersistence.findByPrimaryKey(
498                                    categoryId);
499                    }
500    
501                    // Messages
502    
503                    List<MBMessage> messages = mbMessagePersistence.findByG_C_T(
504                            groupId, oldCategoryId, thread.getThreadId());
505    
506                    for (MBMessage message : messages) {
507                            message.setCategoryId(categoryId);
508    
509                            mbMessagePersistence.update(message, false);
510    
511                            // Indexer
512    
513                            if (!message.isDiscussion()) {
514                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
515                                            MBMessage.class);
516    
517                                    indexer.reindex(message);
518                            }
519                    }
520    
521                    // Thread
522    
523                    thread.setCategoryId(categoryId);
524    
525                    mbThreadPersistence.update(thread, false);
526    
527                    // Category
528    
529                    if ((oldCategory != null) && (categoryId != oldCategoryId)) {
530                            oldCategory.setThreadCount(oldCategory.getThreadCount() - 1);
531                            oldCategory.setMessageCount(
532                                    oldCategory.getMessageCount() - thread.getMessageCount());
533    
534                            mbCategoryPersistence.update(oldCategory, false);
535                    }
536    
537                    if ((category != null) && (categoryId != oldCategoryId)) {
538                            category.setThreadCount(category.getThreadCount() + 1);
539                            category.setMessageCount(
540                                    category.getMessageCount() + thread.getMessageCount());
541    
542                            mbCategoryPersistence.update(category, false);
543                    }
544    
545                    return thread;
546            }
547    
548            public MBThread splitThread(
549                            long messageId, String subject, ServiceContext serviceContext)
550                    throws PortalException, SystemException {
551    
552                    MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
553    
554                    if (message.isRoot()) {
555                            throw new SplitThreadException();
556                    }
557    
558                    MBCategory category = message.getCategory();
559                    MBThread oldThread = message.getThread();
560                    MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
561                            oldThread.getRootMessageId());
562                    String oldAttachmentsDir = message.getAttachmentsDir();
563    
564                    // Message flags
565    
566                    mbMessageLocalService.updateAnswer(message, false, true);
567    
568                    // Create new thread
569    
570                    MBThread thread = addThread(message.getCategoryId(), message);
571    
572                    // Update messages
573    
574                    if (Validator.isNotNull(subject)) {
575                            MBMessageDisplay messageDisplay =
576                                    mbMessageService.getMessageDisplay(
577                                            messageId, WorkflowConstants.STATUS_ANY,
578                                            MBThreadConstants.THREAD_VIEW_TREE, false);
579    
580                            MBTreeWalker treeWalker = messageDisplay.getTreeWalker();
581    
582                            List<MBMessage> messages = treeWalker.getMessages();
583    
584                            int[] range = treeWalker.getChildrenRange(message);
585    
586                            for (int i = range[0]; i < range[1]; i++) {
587                                    MBMessage curMessage = messages.get(i);
588    
589                                    String oldSubject = message.getSubject();
590                                    String curSubject = curMessage.getSubject();
591    
592                                    if (oldSubject.startsWith("RE: ")) {
593                                            curSubject = StringUtil.replace(
594                                                    curSubject, rootMessage.getSubject(), subject);
595                                    }
596                                    else {
597                                            curSubject = StringUtil.replace(
598                                                    curSubject, oldSubject, subject);
599                                    }
600    
601                                    curMessage.setSubject(curSubject);
602    
603                                    mbMessagePersistence.update(curMessage, false);
604                            }
605    
606                            message.setSubject(subject);
607                    }
608    
609                    message.setThreadId(thread.getThreadId());
610                    message.setRootMessageId(thread.getRootMessageId());
611                    message.setParentMessageId(0);
612                    message.setAttachmentsDir(null);
613    
614                    mbMessagePersistence.update(message, false);
615    
616                    // Attachments
617    
618                    moveAttachmentsFromOldThread(message, oldAttachmentsDir);
619    
620                    // Indexer
621    
622                    if (!message.isDiscussion()) {
623                            Indexer indexer = IndexerRegistryUtil.getIndexer(MBMessage.class);
624    
625                            indexer.reindex(message);
626                    }
627    
628                    // Update children
629    
630                    int messagesMoved = 1;
631    
632                    messagesMoved += moveChildrenMessages(
633                            message, category, oldThread.getThreadId());
634    
635                    // Update new thread
636    
637                    thread.setMessageCount(messagesMoved);
638    
639                    mbThreadPersistence.update(thread, false);
640    
641                    // Update old thread
642    
643                    oldThread.setMessageCount(oldThread.getMessageCount() - messagesMoved);
644    
645                    mbThreadPersistence.update(oldThread, false);
646    
647                    // Category
648    
649                    if ((message.getCategoryId() !=
650                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
651                            (message.getCategoryId() !=
652                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
653    
654                            category.setThreadCount(category.getThreadCount() + 1);
655    
656                            mbCategoryPersistence.update(category, false);
657                    }
658    
659                    return thread;
660            }
661    
662            public void updateQuestion(long threadId, boolean question)
663                    throws PortalException, SystemException {
664    
665                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
666    
667                    if (thread.isQuestion() == question) {
668                            return;
669                    }
670    
671                    thread.setQuestion(question);
672    
673                    mbThreadPersistence.update(thread, false);
674    
675                    if (!question) {
676                            MBMessage message = mbMessagePersistence.findByPrimaryKey(
677                                    thread.getRootMessageId());
678    
679                            mbMessageLocalService.updateAnswer(message, false, true);
680                    }
681            }
682    
683            /**
684             * @deprecated {@link #incrementViewCounter(long, int)}
685             */
686            public MBThread updateThread(long threadId, int viewCount)
687                    throws PortalException, SystemException {
688    
689                    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);
690    
691                    thread.setViewCount(viewCount);
692    
693                    mbThreadPersistence.update(thread, false);
694    
695                    return thread;
696            }
697    
698            protected void moveAttachmentFromOldThread(
699                            long companyId, String fileName, String newAttachmentsDir)
700                    throws PortalException, SystemException {
701    
702                    long repositoryId = CompanyConstants.SYSTEM;
703    
704                    StringBundler sb = new StringBundler(4);
705    
706                    sb.append(newAttachmentsDir);
707                    sb.append(StringPool.SLASH);
708                    sb.append(StringUtil.extractLast(fileName, CharPool.SLASH));
709    
710                    String newFileName = sb.toString();
711    
712                    try {
713                            File file = DLStoreUtil.getFile(
714                                    companyId, repositoryId, fileName);
715    
716                            DLStoreUtil.addFile(
717                                    companyId, repositoryId, newFileName, false, file);
718                    }
719                    catch (UnsupportedOperationException uoe) {
720                            InputStream is = DLStoreUtil.getFileAsStream(
721                                    companyId, repositoryId, fileName);
722    
723                            try {
724                                    DLStoreUtil.addFile(
725                                            companyId, repositoryId, newFileName, false, is);
726                            }
727                            finally {
728                                    try {
729                                            is.close();
730                                    }
731                                    catch (IOException ioe) {
732                                            _log.error(ioe);
733                                    }
734                            }
735                    }
736    
737                    DLStoreUtil.deleteFile(companyId, repositoryId, fileName);
738            }
739    
740            protected void moveAttachmentsFromOldThread(
741                            MBMessage message, String oldAttachmentsDir)
742                    throws PortalException, SystemException {
743    
744                    if (!message.getAttachments()) {
745                            return;
746                    }
747    
748                    long companyId = message.getCompanyId();
749                    long repositoryId = CompanyConstants.SYSTEM;
750                    String newAttachmentsDir = message.getAttachmentsDir();
751    
752                    try {
753                            DLStoreUtil.addDirectory(
754                                    companyId, repositoryId, newAttachmentsDir);
755                    }
756                    catch (DuplicateDirectoryException dde) {
757                    }
758    
759                    String[] fileNames = DLStoreUtil.getFileNames(
760                            companyId, repositoryId, oldAttachmentsDir);
761    
762                    for (String fileName : fileNames) {
763                            moveAttachmentFromOldThread(companyId, fileName, newAttachmentsDir);
764                    }
765    
766                    try {
767                            DLStoreUtil.deleteDirectory(
768                                    companyId, repositoryId, oldAttachmentsDir);
769                    }
770                    catch (NoSuchDirectoryException nsde) {
771                    }
772            }
773    
774            protected int moveChildrenMessages(
775                            MBMessage parentMessage, MBCategory category, long oldThreadId)
776                    throws PortalException, SystemException {
777    
778                    int messagesMoved = 0;
779    
780                    List<MBMessage> messages = mbMessagePersistence.findByT_P(
781                            oldThreadId, parentMessage.getMessageId());
782    
783                    for (MBMessage message : messages) {
784                            String oldAttachmentsDir = message.getAttachmentsDir();
785    
786                            message.setCategoryId(parentMessage.getCategoryId());
787                            message.setThreadId(parentMessage.getThreadId());
788                            message.setRootMessageId(parentMessage.getRootMessageId());
789                            message.setAttachmentsDir(null);
790    
791                            mbMessagePersistence.update(message, false);
792    
793                            moveAttachmentsFromOldThread(message, oldAttachmentsDir);
794    
795                            if (!message.isDiscussion()) {
796                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
797                                            MBMessage.class);
798    
799                                    indexer.reindex(message);
800                            }
801    
802                            messagesMoved++;
803    
804                            messagesMoved += moveChildrenMessages(
805                                    message, category, oldThreadId);
806                    }
807    
808                    return messagesMoved;
809            }
810    
811            private static Log _log = LogFactoryUtil.getLog(
812                    MBThreadLocalServiceImpl.class);
813    
814    }