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