001    /**
002     * Copyright (c) 2000-2013 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.dao.orm.QueryDefinition;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.search.Indexer;
022    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
023    import com.liferay.portal.kernel.systemevent.SystemEvent;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.workflow.WorkflowConstants;
026    import com.liferay.portal.model.ResourceConstants;
027    import com.liferay.portal.model.SystemEventConstants;
028    import com.liferay.portal.model.User;
029    import com.liferay.portal.service.ServiceContext;
030    import com.liferay.portlet.messageboards.CategoryNameException;
031    import com.liferay.portlet.messageboards.NoSuchMailingListException;
032    import com.liferay.portlet.messageboards.model.MBCategory;
033    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
034    import com.liferay.portlet.messageboards.model.MBMailingList;
035    import com.liferay.portlet.messageboards.model.MBMessage;
036    import com.liferay.portlet.messageboards.model.MBThread;
037    import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
038    import com.liferay.portlet.messageboards.service.base.MBCategoryLocalServiceBaseImpl;
039    import com.liferay.portlet.trash.model.TrashEntry;
040    
041    import java.util.ArrayList;
042    import java.util.Date;
043    import java.util.List;
044    
045    /**
046     * @author Brian Wing Shun Chan
047     * @author Wesley Gong
048     */
049    public class MBCategoryLocalServiceImpl extends MBCategoryLocalServiceBaseImpl {
050    
051            @Override
052            public MBCategory addCategory(
053                            long userId, long parentCategoryId, String name, String description,
054                            ServiceContext serviceContext)
055                    throws PortalException, SystemException {
056    
057                    return addCategory(
058                            userId, parentCategoryId, name, description,
059                            MBCategoryConstants.DEFAULT_DISPLAY_STYLE, null, null, null, 0,
060                            false, null, null, 0, null, false, null, 0, false, null, null,
061                            false, false, serviceContext);
062            }
063    
064            @Override
065            public MBCategory addCategory(
066                            long userId, long parentCategoryId, String name, String description,
067                            String displayStyle, String emailAddress, String inProtocol,
068                            String inServerName, int inServerPort, boolean inUseSSL,
069                            String inUserName, String inPassword, int inReadInterval,
070                            String outEmailAddress, boolean outCustom, String outServerName,
071                            int outServerPort, boolean outUseSSL, String outUserName,
072                            String outPassword, boolean allowAnonymous,
073                            boolean mailingListActive, ServiceContext serviceContext)
074                    throws PortalException, SystemException {
075    
076                    // Category
077    
078                    User user = userPersistence.findByPrimaryKey(userId);
079                    long groupId = serviceContext.getScopeGroupId();
080                    parentCategoryId = getParentCategoryId(groupId, parentCategoryId);
081                    Date now = new Date();
082    
083                    validate(name);
084    
085                    long categoryId = counterLocalService.increment();
086    
087                    MBCategory category = mbCategoryPersistence.create(categoryId);
088    
089                    category.setUuid(serviceContext.getUuid());
090                    category.setGroupId(groupId);
091                    category.setCompanyId(user.getCompanyId());
092                    category.setUserId(user.getUserId());
093                    category.setUserName(user.getFullName());
094                    category.setCreateDate(serviceContext.getCreateDate(now));
095                    category.setModifiedDate(serviceContext.getModifiedDate(now));
096                    category.setParentCategoryId(parentCategoryId);
097                    category.setName(name);
098                    category.setDescription(description);
099                    category.setDisplayStyle(displayStyle);
100                    category.setExpandoBridgeAttributes(serviceContext);
101    
102                    mbCategoryPersistence.update(category);
103    
104                    // Resources
105    
106                    if (serviceContext.isAddGroupPermissions() ||
107                            serviceContext.isAddGuestPermissions()) {
108    
109                            addCategoryResources(
110                                    category, serviceContext.isAddGroupPermissions(),
111                                    serviceContext.isAddGuestPermissions());
112                    }
113                    else {
114                            addCategoryResources(
115                                    category, serviceContext.getGroupPermissions(),
116                                    serviceContext.getGuestPermissions());
117                    }
118    
119                    // Mailing list
120    
121                    mbMailingListLocalService.addMailingList(
122                            userId, groupId, category.getCategoryId(), emailAddress, inProtocol,
123                            inServerName, inServerPort, inUseSSL, inUserName, inPassword,
124                            inReadInterval, outEmailAddress, outCustom, outServerName,
125                            outServerPort, outUseSSL, outUserName, outPassword, allowAnonymous,
126                            mailingListActive, serviceContext);
127    
128                    return category;
129            }
130    
131            @Override
132            public void addCategoryResources(
133                            long categoryId, boolean addGroupPermissions,
134                            boolean addGuestPermissions)
135                    throws PortalException, SystemException {
136    
137                    if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
138                            (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
139    
140                            return;
141                    }
142    
143                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
144                            categoryId);
145    
146                    addCategoryResources(
147                            category, addGroupPermissions, addGuestPermissions);
148            }
149    
150            @Override
151            public void addCategoryResources(
152                            long categoryId, String[] groupPermissions,
153                            String[] guestPermissions)
154                    throws PortalException, SystemException {
155    
156                    if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
157                            (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
158    
159                            return;
160                    }
161    
162                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
163                            categoryId);
164    
165                    addCategoryResources(category, groupPermissions, guestPermissions);
166            }
167    
168            @Override
169            public void addCategoryResources(
170                            MBCategory category, boolean addGroupPermissions,
171                            boolean addGuestPermissions)
172                    throws PortalException, SystemException {
173    
174                    resourceLocalService.addResources(
175                            category.getCompanyId(), category.getGroupId(),
176                            category.getUserId(), MBCategory.class.getName(),
177                            category.getCategoryId(), false, addGroupPermissions,
178                            addGuestPermissions);
179            }
180    
181            @Override
182            public void addCategoryResources(
183                            MBCategory category, String[] groupPermissions,
184                            String[] guestPermissions)
185                    throws PortalException, SystemException {
186    
187                    resourceLocalService.addModelResources(
188                            category.getCompanyId(), category.getGroupId(),
189                            category.getUserId(), MBCategory.class.getName(),
190                            category.getCategoryId(), groupPermissions, guestPermissions);
191            }
192    
193            @Override
194            public void deleteCategories(long groupId)
195                    throws PortalException, SystemException {
196    
197                    List<MBCategory> categories = mbCategoryPersistence.findByGroupId(
198                            groupId);
199    
200                    for (MBCategory category : categories) {
201                            mbCategoryLocalService.deleteCategory(category);
202                    }
203            }
204    
205            @Override
206            public void deleteCategory(long categoryId)
207                    throws PortalException, SystemException {
208    
209                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
210                            categoryId);
211    
212                    mbCategoryLocalService.deleteCategory(category);
213            }
214    
215            @Override
216            @SystemEvent(
217                    action = SystemEventConstants.ACTION_SKIP,
218                    type = SystemEventConstants.TYPE_DELETE)
219            public void deleteCategory(MBCategory category)
220                    throws PortalException, SystemException {
221    
222                    deleteCategory(category, true);
223            }
224    
225            @Override
226            @SystemEvent(
227                    action = SystemEventConstants.ACTION_SKIP,
228                    type = SystemEventConstants.TYPE_DELETE)
229            public void deleteCategory(
230                            MBCategory category, boolean includeTrashedEntries)
231                    throws PortalException, SystemException {
232    
233                    // Categories
234    
235                    List<MBCategory> categories = mbCategoryPersistence.findByG_P(
236                            category.getGroupId(), category.getCategoryId());
237    
238                    for (MBCategory curCategory : categories) {
239                            if (includeTrashedEntries || !curCategory.isInTrash()) {
240                                    deleteCategory(curCategory, includeTrashedEntries);
241                            }
242                    }
243    
244                    // Indexer
245    
246                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
247                            MBMessage.class);
248    
249                    indexer.delete(category);
250    
251                    // Threads
252    
253                    mbThreadLocalService.deleteThreads(
254                            category.getGroupId(), category.getCategoryId(),
255                            includeTrashedEntries);
256    
257                    // Mailing list
258    
259                    try {
260                            mbMailingListLocalService.deleteCategoryMailingList(
261                                    category.getGroupId(), category.getCategoryId());
262                    }
263                    catch (NoSuchMailingListException nsmle) {
264                    }
265    
266                    // Subscriptions
267    
268                    subscriptionLocalService.deleteSubscriptions(
269                            category.getCompanyId(), MBCategory.class.getName(),
270                            category.getCategoryId());
271    
272                    // Expando
273    
274                    expandoRowLocalService.deleteRows(category.getCategoryId());
275    
276                    // Resources
277    
278                    resourceLocalService.deleteResource(
279                            category.getCompanyId(), MBCategory.class.getName(),
280                            ResourceConstants.SCOPE_INDIVIDUAL, category.getCategoryId());
281    
282                    // Trash
283    
284                    trashEntryLocalService.deleteEntry(
285                            MBCategory.class.getName(), category.getCategoryId());
286    
287                    // Category
288    
289                    mbCategoryPersistence.remove(category);
290            }
291    
292            @Override
293            public List<MBCategory> getCategories(long groupId) throws SystemException {
294                    return mbCategoryPersistence.findByGroupId(groupId);
295            }
296    
297            @Override
298            public List<MBCategory> getCategories(long groupId, int status)
299                    throws SystemException {
300    
301                    return mbCategoryPersistence.findByG_S(groupId, status);
302            }
303    
304            @Override
305            public List<MBCategory> getCategories(
306                            long groupId, long parentCategoryId, int start, int end)
307                    throws SystemException {
308    
309                    return mbCategoryPersistence.findByG_P(
310                            groupId, parentCategoryId, start, end);
311            }
312    
313            @Override
314            public List<MBCategory> getCategories(
315                            long groupId, long parentCategoryId, int status, int start, int end)
316                    throws SystemException {
317    
318                    if (status == WorkflowConstants.STATUS_ANY) {
319                            return mbCategoryPersistence.findByG_P(
320                                    groupId, parentCategoryId, start, end);
321                    }
322    
323                    return mbCategoryPersistence.findByG_P_S(
324                            groupId, parentCategoryId, status, start, end);
325            }
326    
327            @Override
328            public List<MBCategory> getCategories(
329                            long groupId, long[] parentCategoryIds, int start, int end)
330                    throws SystemException {
331    
332                    return mbCategoryPersistence.findByG_P(
333                            groupId, parentCategoryIds, start, end);
334            }
335    
336            @Override
337            public List<MBCategory> getCategories(
338                            long groupId, long[] parentCategoryIds, int status, int start,
339                            int end)
340                    throws SystemException {
341    
342                    if (status == WorkflowConstants.STATUS_ANY) {
343                            return mbCategoryPersistence.findByG_P(
344                                    groupId, parentCategoryIds, start, end);
345                    }
346    
347                    return mbCategoryPersistence.findByG_P_S(
348                            groupId, parentCategoryIds, status, start, end);
349            }
350    
351            @Override
352            public List<Object> getCategoriesAndThreads(long groupId, long categoryId)
353                    throws SystemException {
354    
355                    List<Object> categoriesAndThreads = new ArrayList<Object>();
356    
357                    List<MBCategory> categories = getCategories(
358                            groupId, categoryId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
359    
360                    categoriesAndThreads.addAll(categories);
361    
362                    List<MBThread> threads = mbThreadLocalService.getThreads(
363                            groupId, categoryId, WorkflowConstants.STATUS_ANY,
364                            QueryUtil.ALL_POS, QueryUtil.ALL_POS);
365    
366                    categoriesAndThreads.addAll(threads);
367    
368                    return categoriesAndThreads;
369            }
370    
371            @Override
372            public int getCategoriesCount(long groupId) throws SystemException {
373                    return mbCategoryPersistence.countByGroupId(groupId);
374            }
375    
376            @Override
377            public int getCategoriesCount(long groupId, int status)
378                    throws SystemException {
379    
380                    return mbCategoryPersistence.countByG_S(groupId, status);
381            }
382    
383            @Override
384            public int getCategoriesCount(long groupId, long parentCategoryId)
385                    throws SystemException {
386    
387                    return mbCategoryPersistence.countByG_P(groupId, parentCategoryId);
388            }
389    
390            @Override
391            public int getCategoriesCount(
392                            long groupId, long parentCategoryId, int status)
393                    throws SystemException {
394    
395                    if (status == WorkflowConstants.STATUS_ANY) {
396                            return mbCategoryPersistence.countByG_P(groupId, parentCategoryId);
397                    }
398    
399                    return mbCategoryPersistence.countByG_P_S(
400                            groupId, parentCategoryId, status);
401            }
402    
403            @Override
404            public int getCategoriesCount(long groupId, long[] parentCategoryIds)
405                    throws SystemException {
406    
407                    return mbCategoryPersistence.countByG_P(groupId, parentCategoryIds);
408            }
409    
410            @Override
411            public int getCategoriesCount(
412                            long groupId, long[] parentCategoryIds, int status)
413                    throws SystemException {
414    
415                    if (status == WorkflowConstants.STATUS_ANY) {
416                            return mbCategoryPersistence.countByG_P(groupId, parentCategoryIds);
417                    }
418    
419                    return mbCategoryPersistence.countByG_P_S(
420                            groupId, parentCategoryIds, status);
421            }
422    
423            @Override
424            public MBCategory getCategory(long categoryId)
425                    throws PortalException, SystemException {
426    
427                    MBCategory category = null;
428    
429                    if ((categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
430                            (categoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
431    
432                            category = mbCategoryPersistence.findByPrimaryKey(categoryId);
433                    }
434                    else {
435                            category = new MBCategoryImpl();
436    
437                            category.setCategoryId(categoryId);
438                            category.setParentCategoryId(categoryId);
439                    }
440    
441                    return category;
442            }
443    
444            @Override
445            public List<MBCategory> getCompanyCategories(
446                            long companyId, int start, int end)
447                    throws SystemException {
448    
449                    return mbCategoryPersistence.findByCompanyId(companyId, start, end);
450            }
451    
452            @Override
453            public int getCompanyCategoriesCount(long companyId)
454                    throws SystemException {
455    
456                    return mbCategoryPersistence.countByCompanyId(companyId);
457            }
458    
459            @Override
460            public List<Long> getSubcategoryIds(
461                            List<Long> categoryIds, long groupId, long categoryId)
462                    throws SystemException {
463    
464                    List<MBCategory> categories = mbCategoryPersistence.findByG_P(
465                            groupId, categoryId);
466    
467                    for (MBCategory category : categories) {
468                            categoryIds.add(category.getCategoryId());
469    
470                            getSubcategoryIds(
471                                    categoryIds, category.getGroupId(), category.getCategoryId());
472                    }
473    
474                    return categoryIds;
475            }
476    
477            @Override
478            public List<MBCategory> getSubscribedCategories(
479                            long groupId, long userId, int start, int end)
480                    throws SystemException {
481    
482                    QueryDefinition queryDefinition = new QueryDefinition(
483                            WorkflowConstants.STATUS_ANY, start, end, null);
484    
485                    return mbCategoryFinder.findByS_G_U_P(
486                            groupId, userId, null, queryDefinition);
487            }
488    
489            @Override
490            public int getSubscribedCategoriesCount(long groupId, long userId)
491                    throws SystemException {
492    
493                    QueryDefinition queryDefinition = new QueryDefinition(
494                            WorkflowConstants.STATUS_ANY);
495    
496                    return mbCategoryFinder.countByS_G_U_P(
497                            groupId, userId, null, queryDefinition);
498            }
499    
500            @Override
501            public void moveCategoriesToTrash(long groupId, long userId)
502                    throws PortalException, SystemException {
503    
504                    List<MBCategory> categories = mbCategoryPersistence.findByGroupId(
505                            groupId);
506    
507                    for (MBCategory category : categories) {
508                            moveCategoryToTrash(userId, category.getCategoryId());
509                    }
510            }
511    
512            @Override
513            public MBCategory moveCategory(
514                            long categoryId, long parentCategoryId,
515                            boolean mergeWithParentCategory)
516                    throws PortalException, SystemException {
517    
518                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
519                            categoryId);
520    
521                    parentCategoryId = getParentCategoryId(category, parentCategoryId);
522    
523                    if (mergeWithParentCategory &&
524                            (categoryId != parentCategoryId) &&
525                            (parentCategoryId !=
526                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
527                            (parentCategoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
528    
529                            mergeCategories(category, parentCategoryId);
530    
531                            return category;
532                    }
533    
534                    category.setParentCategoryId(parentCategoryId);
535    
536                    return mbCategoryPersistence.update(category);
537            }
538    
539            @Override
540            public MBCategory moveCategoryFromTrash(
541                            long userId, long categoryId, long newCategoryId)
542                    throws PortalException, SystemException {
543    
544                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
545                            categoryId);
546    
547                    if (category.isInTrash()) {
548                            restoreCategoryFromTrash(userId, categoryId);
549                    }
550                    else {
551                            updateStatus(userId, categoryId, category.getStatus());
552                    }
553    
554                    return moveCategory(categoryId, newCategoryId, false);
555            }
556    
557            @Override
558            public MBCategory moveCategoryToTrash(long userId, long categoryId)
559                    throws PortalException, SystemException {
560    
561                    return updateStatus(
562                            userId, categoryId, WorkflowConstants.STATUS_IN_TRASH);
563            }
564    
565            @Override
566            public void restoreCategoryFromTrash(long userId, long categoryId)
567                    throws PortalException, SystemException {
568    
569                    // Category
570    
571                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
572                            MBCategory.class.getName(), categoryId);
573    
574                    updateStatus(userId, categoryId, WorkflowConstants.STATUS_APPROVED);
575    
576                    // Trash
577    
578                    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
579            }
580    
581            @Override
582            public void subscribeCategory(long userId, long groupId, long categoryId)
583                    throws PortalException, SystemException {
584    
585                    if (categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
586                            categoryId = groupId;
587                    }
588    
589                    subscriptionLocalService.addSubscription(
590                            userId, groupId, MBCategory.class.getName(), categoryId);
591            }
592    
593            @Override
594            public void unsubscribeCategory(long userId, long groupId, long categoryId)
595                    throws PortalException, SystemException {
596    
597                    if (categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
598                            categoryId = groupId;
599                    }
600    
601                    subscriptionLocalService.deleteSubscription(
602                            userId, MBCategory.class.getName(), categoryId);
603            }
604    
605            @Override
606            public MBCategory updateCategory(
607                            long categoryId, long parentCategoryId, String name,
608                            String description, String displayStyle, String emailAddress,
609                            String inProtocol, String inServerName, int inServerPort,
610                            boolean inUseSSL, String inUserName, String inPassword,
611                            int inReadInterval, String outEmailAddress, boolean outCustom,
612                            String outServerName, int outServerPort, boolean outUseSSL,
613                            String outUserName, String outPassword, boolean allowAnonymous,
614                            boolean mailingListActive, boolean mergeWithParentCategory,
615                            ServiceContext serviceContext)
616                    throws PortalException, SystemException {
617    
618                    // Merge categories
619    
620                    if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
621                            (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
622    
623                            return null;
624                    }
625    
626                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
627                            categoryId);
628    
629                    parentCategoryId = getParentCategoryId(category, parentCategoryId);
630    
631                    if (mergeWithParentCategory &&
632                            (categoryId != parentCategoryId) &&
633                            (parentCategoryId !=
634                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
635                            (parentCategoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
636    
637                            mergeCategories(category, parentCategoryId);
638    
639                            return category;
640                    }
641    
642                    // Category
643    
644                    validate(name);
645    
646                    category.setModifiedDate(serviceContext.getModifiedDate(null));
647                    category.setParentCategoryId(parentCategoryId);
648                    category.setName(name);
649                    category.setDescription(description);
650    
651                    if (!displayStyle.equals(category.getDisplayStyle())) {
652                            category.setDisplayStyle(displayStyle);
653    
654                            updateChildCategoriesDisplayStyle(category, displayStyle);
655                    }
656    
657                    category.setExpandoBridgeAttributes(serviceContext);
658    
659                    mbCategoryPersistence.update(category);
660    
661                    // Mailing list
662    
663                    MBMailingList mailingList = mbMailingListPersistence.fetchByG_C(
664                            category.getGroupId(), category.getCategoryId());
665    
666                    if (mailingList != null) {
667                            mbMailingListLocalService.updateMailingList(
668                                    mailingList.getMailingListId(), emailAddress, inProtocol,
669                                    inServerName, inServerPort, inUseSSL, inUserName, inPassword,
670                                    inReadInterval, outEmailAddress, outCustom, outServerName,
671                                    outServerPort, outUseSSL, outUserName, outPassword,
672                                    allowAnonymous, mailingListActive, serviceContext);
673                    }
674                    else {
675                            mbMailingListLocalService.addMailingList(
676                                    category.getUserId(), category.getGroupId(),
677                                    category.getCategoryId(), emailAddress, inProtocol,
678                                    inServerName, inServerPort, inUseSSL, inUserName, inPassword,
679                                    inReadInterval, outEmailAddress, outCustom, outServerName,
680                                    outServerPort, outUseSSL, outUserName, outPassword,
681                                    allowAnonymous, mailingListActive, serviceContext);
682                    }
683    
684                    return category;
685            }
686    
687            @Override
688            public void updateDependentStatus(
689                            User user, List<Object> categoriesAndThreads, int status)
690                    throws PortalException, SystemException {
691    
692                    for (Object object : categoriesAndThreads) {
693                            if (object instanceof MBThread) {
694                                    MBThread thread = (MBThread)object;
695    
696                                    if ((status == WorkflowConstants.STATUS_APPROVED) &&
697                                            (thread.getStatus() == WorkflowConstants.STATUS_IN_TRASH)) {
698    
699                                            continue;
700                                    }
701    
702                                    mbThreadLocalService.updateStatus(
703                                            user.getUserId(), thread.getThreadId(), status, status);
704                            }
705                            else if (object instanceof MBCategory) {
706                                    MBCategory category = (MBCategory)object;
707    
708                                    if (category.isInTrash()) {
709                                            continue;
710                                    }
711    
712                                    updateDependentStatus(
713                                            user,
714                                            getCategoriesAndThreads(
715                                                    category.getGroupId(), category.getCategoryId()),
716                                            status);
717                            }
718                    }
719            }
720    
721            @Override
722            public MBCategory updateStatus(long userId, long categoryId, int status)
723                    throws PortalException, SystemException {
724    
725                    // Category
726    
727                    User user = userPersistence.findByPrimaryKey(userId);
728    
729                    MBCategory category = mbCategoryPersistence.findByPrimaryKey(
730                            categoryId);
731    
732                    category.setStatus(status);
733                    category.setStatusByUserId(user.getUserId());
734                    category.setStatusByUserName(user.getFullName());
735                    category.setStatusDate(new Date());
736    
737                    mbCategoryPersistence.update(category);
738    
739                    // Categories and threads
740    
741                    List<Object> categoriesAndThreads = getCategoriesAndThreads(
742                            category.getGroupId(), categoryId);
743    
744                    updateDependentStatus(user, categoriesAndThreads, status);
745    
746                    // Trash
747    
748                    if (status == WorkflowConstants.STATUS_IN_TRASH) {
749                            trashEntryLocalService.addTrashEntry(
750                                    userId, category.getGroupId(), MBCategory.class.getName(),
751                                    categoryId, WorkflowConstants.STATUS_APPROVED, null, null);
752                    }
753    
754                    return category;
755            }
756    
757            protected long getParentCategoryId(long groupId, long parentCategoryId)
758                    throws SystemException {
759    
760                    if ((parentCategoryId !=
761                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
762                            (parentCategoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
763    
764                            MBCategory parentCategory = mbCategoryPersistence.fetchByPrimaryKey(
765                                    parentCategoryId);
766    
767                            if ((parentCategory == null) ||
768                                    (groupId != parentCategory.getGroupId())) {
769    
770                                    parentCategoryId =
771                                            MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
772                            }
773                    }
774    
775                    return parentCategoryId;
776            }
777    
778            protected long getParentCategoryId(
779                            MBCategory category, long parentCategoryId)
780                    throws SystemException {
781    
782                    if ((parentCategoryId ==
783                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
784                            (parentCategoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
785    
786                            return parentCategoryId;
787                    }
788    
789                    if (category.getCategoryId() == parentCategoryId) {
790                            return category.getParentCategoryId();
791                    }
792    
793                    MBCategory parentCategory = mbCategoryPersistence.fetchByPrimaryKey(
794                            parentCategoryId);
795    
796                    if ((parentCategory == null) ||
797                            (category.getGroupId() != parentCategory.getGroupId())) {
798    
799                            return category.getParentCategoryId();
800                    }
801    
802                    List<Long> subcategoryIds = new ArrayList<Long>();
803    
804                    getSubcategoryIds(
805                            subcategoryIds, category.getGroupId(), category.getCategoryId());
806    
807                    if (subcategoryIds.contains(parentCategoryId)) {
808                            return category.getParentCategoryId();
809                    }
810    
811                    return parentCategoryId;
812            }
813    
814            protected void mergeCategories(MBCategory fromCategory, long toCategoryId)
815                    throws PortalException, SystemException {
816    
817                    if ((toCategoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
818                            (toCategoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
819    
820                            return;
821                    }
822    
823                    List<MBCategory> categories = mbCategoryPersistence.findByG_P(
824                            fromCategory.getGroupId(), fromCategory.getCategoryId());
825    
826                    for (MBCategory category : categories) {
827                            mergeCategories(category, toCategoryId);
828                    }
829    
830                    List<MBThread> threads = mbThreadPersistence.findByG_C(
831                            fromCategory.getGroupId(), fromCategory.getCategoryId());
832    
833                    for (MBThread thread : threads) {
834    
835                            // Thread
836    
837                            thread.setCategoryId(toCategoryId);
838    
839                            mbThreadPersistence.update(thread);
840    
841                            List<MBMessage> messages = mbMessagePersistence.findByThreadId(
842                                    thread.getThreadId());
843    
844                            for (MBMessage message : messages) {
845    
846                                    // Message
847    
848                                    message.setCategoryId(toCategoryId);
849    
850                                    mbMessagePersistence.update(message);
851    
852                                    // Indexer
853    
854                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
855                                            MBMessage.class);
856    
857                                    indexer.reindex(message);
858                            }
859                    }
860    
861                    MBCategory toCategory = mbCategoryPersistence.findByPrimaryKey(
862                            toCategoryId);
863    
864                    toCategory.setThreadCount(
865                            fromCategory.getThreadCount() + toCategory.getThreadCount());
866                    toCategory.setMessageCount(
867                            fromCategory.getMessageCount() + toCategory.getMessageCount());
868    
869                    mbCategoryPersistence.update(toCategory);
870    
871                    deleteCategory(fromCategory);
872            }
873    
874            protected void updateChildCategoriesDisplayStyle(
875                            MBCategory category, String displayStyle)
876                    throws PortalException, SystemException {
877    
878                    List<MBCategory> categories = getCategories(
879                            category.getGroupId(), category.getCategoryId(), QueryUtil.ALL_POS,
880                            QueryUtil.ALL_POS);
881    
882                    for (MBCategory curCategory : categories) {
883                            updateChildCategoriesDisplayStyle(curCategory, displayStyle);
884    
885                            curCategory.setDisplayStyle(displayStyle);
886    
887                            mbCategoryPersistence.update(curCategory);
888                    }
889            }
890    
891            protected void validate(String name) throws PortalException {
892                    if (Validator.isNull(name)) {
893                            throw new CategoryNameException();
894                    }
895            }
896    
897    }