001    /**
002     * Copyright (c) 2000-present 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.journal.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.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.json.JSONObject;
022    import com.liferay.portal.kernel.search.Indexable;
023    import com.liferay.portal.kernel.search.IndexableType;
024    import com.liferay.portal.kernel.search.Indexer;
025    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
026    import com.liferay.portal.kernel.systemevent.SystemEvent;
027    import com.liferay.portal.kernel.util.ArrayUtil;
028    import com.liferay.portal.kernel.util.ContentTypes;
029    import com.liferay.portal.kernel.util.ObjectValuePair;
030    import com.liferay.portal.kernel.util.OrderByComparator;
031    import com.liferay.portal.kernel.util.ParamUtil;
032    import com.liferay.portal.kernel.util.SetUtil;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.util.TreeModelTasksAdapter;
035    import com.liferay.portal.kernel.util.TreePathUtil;
036    import com.liferay.portal.kernel.util.UnicodeProperties;
037    import com.liferay.portal.kernel.workflow.WorkflowConstants;
038    import com.liferay.portal.model.ResourceConstants;
039    import com.liferay.portal.model.SystemEventConstants;
040    import com.liferay.portal.model.TreeModel;
041    import com.liferay.portal.model.User;
042    import com.liferay.portal.model.WorkflowDefinitionLink;
043    import com.liferay.portal.service.ServiceContext;
044    import com.liferay.portal.util.PortalUtil;
045    import com.liferay.portal.util.PropsValues;
046    import com.liferay.portlet.asset.model.AssetEntry;
047    import com.liferay.portlet.asset.model.AssetLinkConstants;
048    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
049    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureLink;
050    import com.liferay.portlet.journal.DuplicateFolderNameException;
051    import com.liferay.portlet.journal.InvalidDDMStructureException;
052    import com.liferay.portlet.journal.NoSuchFolderException;
053    import com.liferay.portlet.journal.model.JournalArticle;
054    import com.liferay.portlet.journal.model.JournalArticleConstants;
055    import com.liferay.portlet.journal.model.JournalFolder;
056    import com.liferay.portlet.journal.model.JournalFolderConstants;
057    import com.liferay.portlet.journal.service.base.JournalFolderLocalServiceBaseImpl;
058    import com.liferay.portlet.journal.util.JournalValidatorUtil;
059    import com.liferay.portlet.journal.util.comparator.FolderIdComparator;
060    import com.liferay.portlet.social.model.SocialActivityConstants;
061    import com.liferay.portlet.trash.model.TrashEntry;
062    import com.liferay.portlet.trash.model.TrashVersion;
063    import com.liferay.portlet.trash.util.TrashUtil;
064    
065    import java.util.ArrayList;
066    import java.util.Date;
067    import java.util.HashSet;
068    import java.util.List;
069    import java.util.Set;
070    
071    /**
072     * @author Juan Fern??ndez
073     */
074    public class JournalFolderLocalServiceImpl
075            extends JournalFolderLocalServiceBaseImpl {
076    
077            @Override
078            public JournalFolder addFolder(
079                            long userId, long groupId, long parentFolderId, String name,
080                            String description, ServiceContext serviceContext)
081                    throws PortalException {
082    
083                    // Folder
084    
085                    User user = userPersistence.findByPrimaryKey(userId);
086                    parentFolderId = getParentFolderId(groupId, parentFolderId);
087    
088                    validateFolder(0, groupId, parentFolderId, name);
089    
090                    long folderId = counterLocalService.increment();
091    
092                    JournalFolder folder = journalFolderPersistence.create(folderId);
093    
094                    folder.setUuid(serviceContext.getUuid());
095                    folder.setGroupId(groupId);
096                    folder.setCompanyId(user.getCompanyId());
097                    folder.setUserId(user.getUserId());
098                    folder.setUserName(user.getFullName());
099                    folder.setParentFolderId(parentFolderId);
100                    folder.setTreePath(folder.buildTreePath());
101                    folder.setName(name);
102                    folder.setDescription(description);
103                    folder.setExpandoBridgeAttributes(serviceContext);
104    
105                    journalFolderPersistence.update(folder);
106    
107                    // Resources
108    
109                    resourceLocalService.addModelResources(folder, serviceContext);
110    
111                    // Asset
112    
113                    updateAsset(
114                            userId, folder, serviceContext.getAssetCategoryIds(),
115                            serviceContext.getAssetTagNames(),
116                            serviceContext.getAssetLinkEntryIds());
117    
118                    return folder;
119            }
120    
121            @Indexable(type = IndexableType.DELETE)
122            @Override
123            @SystemEvent(
124                    action = SystemEventConstants.ACTION_SKIP,
125                    type = SystemEventConstants.TYPE_DELETE
126            )
127            public JournalFolder deleteFolder(JournalFolder folder)
128                    throws PortalException {
129    
130                    return deleteFolder(folder, true);
131            }
132    
133            @Indexable(type = IndexableType.DELETE)
134            @Override
135            @SystemEvent(
136                    action = SystemEventConstants.ACTION_SKIP,
137                    type = SystemEventConstants.TYPE_DELETE
138            )
139            public JournalFolder deleteFolder(
140                            JournalFolder folder, boolean includeTrashedEntries)
141                    throws PortalException {
142    
143                    // Folders
144    
145                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
146                            folder.getGroupId(), folder.getFolderId());
147    
148                    for (JournalFolder curFolder : folders) {
149                            if (includeTrashedEntries || !curFolder.isInTrashExplicitly()) {
150                                    journalFolderLocalService.deleteFolder(
151                                            curFolder, includeTrashedEntries);
152                            }
153                    }
154    
155                    // Folder
156    
157                    journalFolderPersistence.remove(folder);
158    
159                    // Resources
160    
161                    resourceLocalService.deleteResource(
162                            folder, ResourceConstants.SCOPE_INDIVIDUAL);
163    
164                    // Entries
165    
166                    journalArticleLocalService.deleteArticles(
167                            folder.getGroupId(), folder.getFolderId(), includeTrashedEntries);
168    
169                    // Asset
170    
171                    assetEntryLocalService.deleteEntry(
172                            JournalFolder.class.getName(), folder.getFolderId());
173    
174                    // Expando
175    
176                    expandoValueLocalService.deleteValues(
177                            JournalFolder.class.getName(), folder.getFolderId());
178    
179                    // Trash
180    
181                    if (folder.isInTrashExplicitly()) {
182                            trashEntryLocalService.deleteEntry(
183                                    JournalFolder.class.getName(), folder.getFolderId());
184                    }
185                    else {
186                            trashVersionLocalService.deleteTrashVersion(
187                                    JournalFolder.class.getName(), folder.getFolderId());
188                    }
189    
190                    // Workflow
191    
192                    List<DDMStructureLink> ddmStructureLinks =
193                            ddmStructureLinkLocalService.getStructureLinks(
194                                    classNameLocalService.getClassNameId(JournalFolder.class),
195                                    folder.getFolderId());
196    
197                    if (ddmStructureLinks.isEmpty()) {
198                            WorkflowDefinitionLink workflowDefinitionLink =
199                                    workflowDefinitionLinkLocalService.fetchWorkflowDefinitionLink(
200                                            folder.getCompanyId(), folder.getGroupId(),
201                                            JournalFolder.class.getName(), folder.getFolderId(),
202                                            JournalArticleConstants.DDM_STRUCTURE_ID_ALL);
203    
204                            if (workflowDefinitionLink != null) {
205                                    workflowDefinitionLinkLocalService.deleteWorkflowDefinitionLink(
206                                            workflowDefinitionLink);
207                            }
208                    }
209    
210                    for (DDMStructureLink ddmStructureLink : ddmStructureLinks ) {
211                            ddmStructureLinkLocalService.deleteStructureLink(
212                                    ddmStructureLink.getStructureLinkId());
213    
214                            WorkflowDefinitionLink workflowDefinitionLink =
215                                    workflowDefinitionLinkLocalService.fetchWorkflowDefinitionLink(
216                                            folder.getCompanyId(), folder.getGroupId(),
217                                            JournalFolder.class.getName(), folder.getFolderId(),
218                                            ddmStructureLink.getStructureId());
219    
220                            if (workflowDefinitionLink != null) {
221                                    workflowDefinitionLinkLocalService.deleteWorkflowDefinitionLink(
222                                            workflowDefinitionLink);
223                            }
224                    }
225    
226                    return folder;
227            }
228    
229            @Indexable(type = IndexableType.DELETE)
230            @Override
231            public JournalFolder deleteFolder(long folderId) throws PortalException {
232                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
233                            folderId);
234    
235                    return journalFolderLocalService.deleteFolder(folder, true);
236            }
237    
238            @Indexable(type = IndexableType.DELETE)
239            @Override
240            public JournalFolder deleteFolder(
241                            long folderId, boolean includeTrashedEntries)
242                    throws PortalException {
243    
244                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
245                            folderId);
246    
247                    return journalFolderLocalService.deleteFolder(
248                            folder, includeTrashedEntries);
249            }
250    
251            @Override
252            public void deleteFolders(long groupId) throws PortalException {
253                    List<JournalFolder> folders = journalFolderPersistence.findByGroupId(
254                            groupId);
255    
256                    for (JournalFolder folder : folders) {
257                            journalFolderLocalService.deleteFolder(folder);
258                    }
259            }
260    
261            @Override
262            public JournalFolder fetchFolder(long folderId) {
263                    return journalFolderPersistence.fetchByPrimaryKey(folderId);
264            }
265    
266            @Override
267            public JournalFolder fetchFolder(
268                    long groupId, long parentFolderId, String name) {
269    
270                    return journalFolderPersistence.fetchByG_P_N(
271                            groupId, parentFolderId, name);
272            }
273    
274            @Override
275            public JournalFolder fetchFolder(long groupId, String name) {
276                    return journalFolderPersistence.fetchByG_N(groupId, name);
277            }
278    
279            @Override
280            public List<JournalFolder> getCompanyFolders(
281                    long companyId, int start, int end) {
282    
283                    return journalFolderPersistence.findByCompanyId(companyId, start, end);
284            }
285    
286            @Override
287            public int getCompanyFoldersCount(long companyId) {
288                    return journalFolderPersistence.countByCompanyId(companyId);
289            }
290    
291            @Override
292            public List<DDMStructure> getDDMStructures(
293                            long[] groupIds, long folderId, int restrictionType)
294                    throws PortalException {
295    
296                    if (restrictionType ==
297                                    JournalFolderConstants.
298                                            RESTRICTION_TYPE_DDM_STRUCTURES_AND_WORKFLOW) {
299    
300                            return ddmStructureLinkLocalService.getStructureLinkStructures(
301                                    classNameLocalService.getClassNameId(JournalFolder.class),
302                                    folderId);
303                    }
304    
305                    folderId = getOverridedDDMStructuresFolderId(folderId);
306    
307                    if (folderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
308                            return ddmStructureLinkLocalService.getStructureLinkStructures(
309                                    classNameLocalService.getClassNameId(JournalFolder.class),
310                                    folderId);
311                    }
312    
313                    long classNameId = classNameLocalService.getClassNameId(
314                            JournalArticle.class);
315    
316                    return ddmStructurePersistence.findByG_C(groupIds, classNameId);
317            }
318    
319            @Override
320            public JournalFolder getFolder(long folderId) throws PortalException {
321                    return journalFolderPersistence.findByPrimaryKey(folderId);
322            }
323    
324            @Override
325            public List<JournalFolder> getFolders(long groupId) {
326                    return journalFolderPersistence.findByGroupId(groupId);
327            }
328    
329            @Override
330            public List<JournalFolder> getFolders(long groupId, long parentFolderId) {
331                    return getFolders(
332                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED);
333            }
334    
335            @Override
336            public List<JournalFolder> getFolders(
337                    long groupId, long parentFolderId, int status) {
338    
339                    return journalFolderPersistence.findByG_P_S(
340                            groupId, parentFolderId, status);
341            }
342    
343            @Override
344            public List<JournalFolder> getFolders(
345                    long groupId, long parentFolderId, int start, int end) {
346    
347                    return getFolders(
348                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED, start,
349                            end);
350            }
351    
352            @Override
353            public List<JournalFolder> getFolders(
354                    long groupId, long parentFolderId, int status, int start, int end) {
355    
356                    return journalFolderPersistence.findByG_P_S(
357                            groupId, parentFolderId, status, start, end);
358            }
359    
360            @Override
361            public List<Object> getFoldersAndArticles(long groupId, long folderId) {
362                    QueryDefinition<?> queryDefinition = new QueryDefinition<>(
363                            WorkflowConstants.STATUS_ANY);
364    
365                    return journalFolderFinder.findF_A_ByG_F(
366                            groupId, folderId, queryDefinition);
367            }
368    
369            @Override
370            public List<Object> getFoldersAndArticles(
371                    long groupId, long folderId, int status) {
372    
373                    QueryDefinition<?> queryDefinition = new QueryDefinition<>(status);
374    
375                    return journalFolderFinder.findF_A_ByG_F(
376                            groupId, folderId, queryDefinition);
377            }
378    
379            @Override
380            public List<Object> getFoldersAndArticles(
381                    long groupId, long folderId, int start, int end,
382                    OrderByComparator<?> obc) {
383    
384                    QueryDefinition<?> queryDefinition = new QueryDefinition<Object>(
385                            WorkflowConstants.STATUS_ANY, start, end,
386                            (OrderByComparator<Object>)obc);
387    
388                    return journalFolderFinder.findF_A_ByG_F(
389                            groupId, folderId, queryDefinition);
390            }
391    
392            @Override
393            public int getFoldersAndArticlesCount(
394                    long groupId, List<Long> folderIds, int status) {
395    
396                    QueryDefinition<JournalArticle> queryDefinition = new QueryDefinition<>(
397                            status);
398    
399                    if (folderIds.size() <= PropsValues.SQL_DATA_MAX_PARAMETERS) {
400                            return journalArticleFinder.countByG_F(
401                                    groupId, folderIds, queryDefinition);
402                    }
403                    else {
404                            int start = 0;
405                            int end = PropsValues.SQL_DATA_MAX_PARAMETERS;
406    
407                            int articlesCount = journalArticleFinder.countByG_F(
408                                    groupId, folderIds.subList(start, end), queryDefinition);
409    
410                            folderIds.subList(start, end).clear();
411    
412                            articlesCount += getFoldersAndArticlesCount(
413                                    groupId, folderIds, status);
414    
415                            return articlesCount;
416                    }
417            }
418    
419            @Override
420            public int getFoldersAndArticlesCount(long groupId, long folderId) {
421                    return journalFolderFinder.countF_A_ByG_F(
422                            groupId, folderId,
423                            new QueryDefinition<Object>(WorkflowConstants.STATUS_ANY));
424            }
425    
426            @Override
427            public int getFoldersAndArticlesCount(
428                    long groupId, long folderId, int status) {
429    
430                    return journalFolderFinder.countF_A_ByG_F(
431                            groupId, folderId, new QueryDefinition<Object>(status));
432            }
433    
434            @Override
435            public int getFoldersCount(long groupId, long parentFolderId) {
436                    return getFoldersCount(
437                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED);
438            }
439    
440            @Override
441            public int getFoldersCount(long groupId, long parentFolderId, int status) {
442                    return journalFolderPersistence.countByG_P_S(
443                            groupId, parentFolderId, status);
444            }
445    
446            @Override
447            public long getInheritedWorkflowFolderId(long folderId)
448                    throws NoSuchFolderException {
449    
450                    while (folderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
451                            JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
452                                    folderId);
453    
454                            if (folder.getRestrictionType() !=
455                                            JournalFolderConstants.RESTRICTION_TYPE_INHERIT) {
456    
457                                    break;
458                            }
459    
460                            folderId = folder.getParentFolderId();
461                    }
462    
463                    return folderId;
464            }
465    
466            @Override
467            public List<JournalFolder> getNoAssetFolders() {
468                    return journalFolderFinder.findF_ByNoAssets();
469            }
470    
471            @Override
472            public long getOverridedDDMStructuresFolderId(long folderId)
473                    throws NoSuchFolderException {
474    
475                    while (folderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
476                            JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
477                                    folderId);
478    
479                            if (folder.getRestrictionType() ==
480                                            JournalFolderConstants.
481                                                    RESTRICTION_TYPE_DDM_STRUCTURES_AND_WORKFLOW) {
482    
483                                    break;
484                            }
485    
486                            folderId = folder.getParentFolderId();
487                    }
488    
489                    return folderId;
490            }
491    
492            @Override
493            public void getSubfolderIds(
494                    List<Long> folderIds, long groupId, long folderId) {
495    
496                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
497                            groupId, folderId);
498    
499                    for (JournalFolder folder : folders) {
500                            folderIds.add(folder.getFolderId());
501    
502                            getSubfolderIds(
503                                    folderIds, folder.getGroupId(), folder.getFolderId());
504                    }
505            }
506    
507            @Indexable(type = IndexableType.REINDEX)
508            @Override
509            public JournalFolder moveFolder(
510                            long folderId, long parentFolderId, ServiceContext serviceContext)
511                    throws PortalException {
512    
513                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
514                            folderId);
515    
516                    parentFolderId = getParentFolderId(folder, parentFolderId);
517    
518                    if (folder.getParentFolderId() == parentFolderId) {
519                            return folder;
520                    }
521    
522                    validateFolderDDMStructures(folder.getFolderId(), parentFolderId);
523    
524                    validateFolder(
525                            folder.getFolderId(), folder.getGroupId(), parentFolderId,
526                            folder.getName());
527    
528                    folder.setParentFolderId(parentFolderId);
529                    folder.setTreePath(folder.buildTreePath());
530                    folder.setExpandoBridgeAttributes(serviceContext);
531    
532                    journalFolderPersistence.update(folder);
533    
534                    rebuildTree(
535                            folder.getCompanyId(), folderId, folder.getTreePath(), true);
536    
537                    return folder;
538            }
539    
540            @Override
541            public JournalFolder moveFolderFromTrash(
542                            long userId, long folderId, long parentFolderId,
543                            ServiceContext serviceContext)
544                    throws PortalException {
545    
546                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
547                            folderId);
548    
549                    if (folder.isInTrashExplicitly()) {
550                            restoreFolderFromTrash(userId, folderId);
551                    }
552                    else {
553    
554                            // Folder
555    
556                            TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
557                                    JournalFolder.class.getName(), folderId);
558    
559                            int status = WorkflowConstants.STATUS_APPROVED;
560    
561                            if (trashVersion != null) {
562                                    status = trashVersion.getStatus();
563                            }
564    
565                            updateStatus(userId, folder, status);
566    
567                            // Trash
568    
569                            if (trashVersion != null) {
570                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
571                            }
572    
573                            // Folders and articles
574    
575                            List<Object> foldersAndArticles =
576                                    journalFolderLocalService.getFoldersAndArticles(
577                                            folder.getGroupId(), folder.getFolderId(),
578                                            WorkflowConstants.STATUS_IN_TRASH);
579    
580                            restoreDependentsFromTrash(foldersAndArticles);
581                    }
582    
583                    return journalFolderLocalService.moveFolder(
584                            folderId, parentFolderId, serviceContext);
585            }
586    
587            @Override
588            public JournalFolder moveFolderToTrash(long userId, long folderId)
589                    throws PortalException {
590    
591                    // Folder
592    
593                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
594                            folderId);
595    
596                    String title = folder.getName();
597    
598                    folder = updateStatus(
599                            userId, folder, WorkflowConstants.STATUS_IN_TRASH);
600    
601                    // Trash
602    
603                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
604    
605                    typeSettingsProperties.put("title", folder.getName());
606    
607                    TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
608                            userId, folder.getGroupId(), JournalFolder.class.getName(),
609                            folder.getFolderId(), folder.getUuid(), null,
610                            WorkflowConstants.STATUS_APPROVED, null, typeSettingsProperties);
611    
612                    folder.setName(TrashUtil.getTrashTitle(trashEntry.getEntryId()));
613    
614                    journalFolderPersistence.update(folder);
615    
616                    // Folders and articles
617    
618                    List<Object> foldersAndArticles =
619                            journalFolderLocalService.getFoldersAndArticles(
620                                    folder.getGroupId(), folder.getFolderId());
621    
622                    moveDependentsToTrash(foldersAndArticles, trashEntry.getEntryId());
623    
624                    // Social
625    
626                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
627    
628                    extraDataJSONObject.put("title", title);
629    
630                    socialActivityLocalService.addActivity(
631                            userId, folder.getGroupId(), JournalFolder.class.getName(),
632                            folder.getFolderId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
633                            extraDataJSONObject.toString(), 0);
634    
635                    return folder;
636            }
637    
638            @Override
639            public void rebuildTree(long companyId) throws PortalException {
640                    rebuildTree(
641                            companyId, JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID,
642                            StringPool.SLASH, false);
643            }
644    
645            @Override
646            public void rebuildTree(
647                            long companyId, long parentFolderId, String parentTreePath,
648                            final boolean reindex)
649                    throws PortalException {
650    
651                    TreePathUtil.rebuildTree(
652                            companyId, parentFolderId, parentTreePath,
653                            new TreeModelTasksAdapter<JournalFolder>() {
654    
655                                    @Override
656                                    public List<JournalFolder> findTreeModels(
657                                            long previousId, long companyId, long parentPrimaryKey,
658                                            int size) {
659    
660                                            return journalFolderPersistence.findByF_C_P_NotS(
661                                                    previousId, companyId, parentPrimaryKey,
662                                                    WorkflowConstants.STATUS_IN_TRASH, QueryUtil.ALL_POS,
663                                                    size, new FolderIdComparator(true));
664                                    }
665    
666                                    @Override
667                                    public void rebuildDependentModelsTreePaths(
668                                                    long parentPrimaryKey, String treePath)
669                                            throws PortalException {
670    
671                                            journalArticleLocalService.setTreePaths(
672                                                    parentPrimaryKey, treePath, false);
673                                    }
674    
675                                    @Override
676                                    public void reindexTreeModels(List<TreeModel> treeModels)
677                                            throws PortalException {
678    
679                                            if (!reindex) {
680                                                    return;
681                                            }
682    
683                                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
684                                                    JournalFolder.class);
685    
686                                            for (TreeModel treeModel : treeModels) {
687                                                    indexer.reindex(treeModel);
688                                            }
689                                    }
690    
691                            }
692                    );
693            }
694    
695            @Override
696            public void restoreFolderFromTrash(long userId, long folderId)
697                    throws PortalException {
698    
699                    // Folder
700    
701                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
702                            folderId);
703    
704                    folder.setName(TrashUtil.getOriginalTitle(folder.getName()));
705    
706                    journalFolderPersistence.update(folder);
707    
708                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
709                            JournalFolder.class.getName(), folderId);
710    
711                    updateStatus(userId, folder, trashEntry.getStatus());
712    
713                    // Folders and articles
714    
715                    List<Object> foldersAndArticles =
716                            journalFolderLocalService.getFoldersAndArticles(
717                                    folder.getGroupId(), folder.getFolderId(),
718                                    WorkflowConstants.STATUS_IN_TRASH);
719    
720                    restoreDependentsFromTrash(foldersAndArticles);
721    
722                    // Trash
723    
724                    trashEntryLocalService.deleteEntry(
725                            JournalFolder.class.getName(), folder.getFolderId());
726    
727                    // Social
728    
729                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
730    
731                    extraDataJSONObject.put("title", folder.getName());
732    
733                    socialActivityLocalService.addActivity(
734                            userId, folder.getGroupId(), JournalFolder.class.getName(),
735                            folder.getFolderId(),
736                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
737                            extraDataJSONObject.toString(), 0);
738            }
739    
740            @Override
741            public void subscribe(long userId, long groupId, long folderId)
742                    throws PortalException {
743    
744                    if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
745                            folderId = groupId;
746                    }
747    
748                    subscriptionLocalService.addSubscription(
749                            userId, groupId, JournalFolder.class.getName(), folderId);
750            }
751    
752            @Override
753            public void unsubscribe(long userId, long groupId, long folderId)
754                    throws PortalException {
755    
756                    if (folderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
757                            folderId = groupId;
758                    }
759    
760                    subscriptionLocalService.deleteSubscription(
761                            userId, JournalFolder.class.getName(), folderId);
762            }
763    
764            @Override
765            public void updateAsset(
766                            long userId, JournalFolder folder, long[] assetCategoryIds,
767                            String[] assetTagNames, long[] assetLinkEntryIds)
768                    throws PortalException {
769    
770                    AssetEntry assetEntry = assetEntryLocalService.updateEntry(
771                            userId, folder.getGroupId(), folder.getCreateDate(),
772                            folder.getModifiedDate(), JournalFolder.class.getName(),
773                            folder.getFolderId(), folder.getUuid(), 0, assetCategoryIds,
774                            assetTagNames, true, null, null, null, ContentTypes.TEXT_PLAIN,
775                            folder.getName(), folder.getDescription(), null, null, null, 0, 0,
776                            null);
777    
778                    assetLinkLocalService.updateLinks(
779                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
780                            AssetLinkConstants.TYPE_RELATED);
781            }
782    
783            @Indexable(type = IndexableType.REINDEX)
784            @Override
785            public JournalFolder updateFolder(
786                            long userId, long groupId, long folderId, long parentFolderId,
787                            String name, String description, boolean mergeWithParentFolder,
788                            ServiceContext serviceContext)
789                    throws PortalException {
790    
791                    return updateFolder(
792                            userId, groupId, folderId, parentFolderId, name, description,
793                            new long[0], JournalFolderConstants.RESTRICTION_TYPE_INHERIT,
794                            mergeWithParentFolder, serviceContext);
795            }
796    
797            @Indexable(type = IndexableType.REINDEX)
798            @Override
799            public JournalFolder updateFolder(
800                            long userId, long groupId, long folderId, long parentFolderId,
801                            String name, String description, long[] ddmStructureIds,
802                            int restrictionType, boolean mergeWithParentFolder,
803                            ServiceContext serviceContext)
804                    throws PortalException {
805    
806                    JournalFolder folder = null;
807    
808                    Set<Long> originalDDMStructureIds = new HashSet<>();
809    
810                    if (folderId > JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
811                            originalDDMStructureIds = getDDMStructureIds(
812                                    ddmStructureLinkLocalService.getStructureLinks(
813                                            classNameLocalService.getClassNameId(JournalFolder.class),
814                                            folderId));
815    
816                            folder = doUpdateFolder(
817                                    userId, folderId, parentFolderId, name, description,
818                                    ddmStructureIds, restrictionType, mergeWithParentFolder,
819                                    serviceContext);
820                    }
821    
822                    List<ObjectValuePair<Long, String>> workflowDefinitionOVPs =
823                            new ArrayList<>();
824    
825                    if (restrictionType ==
826                                    JournalFolderConstants.
827                                            RESTRICTION_TYPE_DDM_STRUCTURES_AND_WORKFLOW) {
828    
829                            workflowDefinitionOVPs.add(
830                                    new ObjectValuePair<Long, String>(
831                                            JournalArticleConstants.DDM_STRUCTURE_ID_ALL,
832                                            StringPool.BLANK));
833    
834                            for (long ddmStructureId : ddmStructureIds) {
835                                    String workflowDefinition = ParamUtil.getString(
836                                            serviceContext, "workflowDefinition" + ddmStructureId);
837    
838                                    workflowDefinitionOVPs.add(
839                                            new ObjectValuePair<Long, String>(
840                                                    ddmStructureId, workflowDefinition));
841                            }
842                    }
843                    else if (restrictionType ==
844                                            JournalFolderConstants.RESTRICTION_TYPE_INHERIT) {
845    
846                            if (originalDDMStructureIds.isEmpty()) {
847                                    originalDDMStructureIds.add(
848                                            JournalArticleConstants.DDM_STRUCTURE_ID_ALL);
849                            }
850    
851                            for (long originalDDMStructureId : originalDDMStructureIds) {
852                                    workflowDefinitionOVPs.add(
853                                            new ObjectValuePair<Long, String>(
854                                                    originalDDMStructureId, StringPool.BLANK));
855                            }
856                    }
857                    else if (restrictionType ==
858                                            JournalFolderConstants.RESTRICTION_TYPE_WORKFLOW) {
859    
860                            String workflowDefinition = ParamUtil.getString(
861                                    serviceContext,
862                                    "workflowDefinition" +
863                                            JournalArticleConstants.DDM_STRUCTURE_ID_ALL);
864    
865                            workflowDefinitionOVPs.add(
866                                    new ObjectValuePair<Long, String>(
867                                            JournalArticleConstants.DDM_STRUCTURE_ID_ALL,
868                                            workflowDefinition));
869    
870                            for (long originalDDMStructureId : originalDDMStructureIds) {
871                                    workflowDefinitionOVPs.add(
872                                            new ObjectValuePair<Long, String>(
873                                                    originalDDMStructureId, StringPool.BLANK));
874                            }
875                    }
876    
877                    workflowDefinitionLinkLocalService.updateWorkflowDefinitionLinks(
878                            userId, serviceContext.getCompanyId(), groupId,
879                            JournalFolder.class.getName(), folderId, workflowDefinitionOVPs);
880    
881                    return folder;
882            }
883    
884            @Override
885            public void updateFolderDDMStructures(
886                            JournalFolder folder, long[] ddmStructureIdsArray)
887                    throws PortalException {
888    
889                    Set<Long> ddmStructureIds = SetUtil.fromArray(ddmStructureIdsArray);
890    
891                    List<DDMStructureLink> ddmStructureLinks =
892                            ddmStructureLinkLocalService.getStructureLinks(
893                                    classNameLocalService.getClassNameId(JournalFolder.class),
894                                    folder.getFolderId());
895    
896                    Set<Long> originalDDMStructureIds = getDDMStructureIds(
897                            ddmStructureLinks);
898    
899                    if (ddmStructureIds.equals(originalDDMStructureIds)) {
900                            return;
901                    }
902    
903                    for (Long ddmStructureId : ddmStructureIds) {
904                            if (!originalDDMStructureIds.contains(ddmStructureId)) {
905                                    ddmStructureLinkLocalService.addStructureLink(
906                                            classNameLocalService.getClassNameId(JournalFolder.class),
907                                            folder.getFolderId(), ddmStructureId);
908                            }
909                    }
910    
911                    for (Long originalDDMStructureId : originalDDMStructureIds) {
912                            if (!ddmStructureIds.contains(originalDDMStructureId)) {
913                                    ddmStructureLinkLocalService.deleteStructureLink(
914                                            classNameLocalService.getClassNameId(JournalFolder.class),
915                                            folder.getFolderId(), originalDDMStructureId);
916                            }
917                    }
918            }
919    
920            @Override
921            public JournalFolder updateStatus(
922                            long userId, JournalFolder folder, int status)
923                    throws PortalException {
924    
925                    // Folder
926    
927                    User user = userPersistence.findByPrimaryKey(userId);
928    
929                    folder.setStatus(status);
930                    folder.setStatusByUserId(userId);
931                    folder.setStatusByUserName(user.getFullName());
932                    folder.setStatusDate(new Date());
933    
934                    journalFolderPersistence.update(folder);
935    
936                    // Asset
937    
938                    if (status == WorkflowConstants.STATUS_APPROVED) {
939                            assetEntryLocalService.updateVisible(
940                                    JournalFolder.class.getName(), folder.getFolderId(), true);
941                    }
942                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
943                            assetEntryLocalService.updateVisible(
944                                    JournalFolder.class.getName(), folder.getFolderId(), false);
945                    }
946    
947                    // Index
948    
949                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
950                            JournalFolder.class);
951    
952                    indexer.reindex(folder);
953    
954                    return folder;
955            }
956    
957            @Override
958            public void validateFolderDDMStructures(long folderId, long parentFolderId)
959                    throws PortalException {
960    
961                    JournalFolder folder = journalFolderLocalService.fetchFolder(folderId);
962    
963                    int restrictionType =
964                            JournalFolderConstants.RESTRICTION_TYPE_DDM_STRUCTURES_AND_WORKFLOW;
965    
966                    JournalFolder parentFolder = journalFolderLocalService.fetchFolder(
967                            parentFolderId);
968    
969                    if (parentFolder != null) {
970                            restrictionType = parentFolder.getRestrictionType();
971                    }
972    
973                    List<DDMStructure> folderDDMStructures = getDDMStructures(
974                            PortalUtil.getCurrentAndAncestorSiteGroupIds(folder.getGroupId()),
975                            parentFolderId, restrictionType);
976    
977                    long[] ddmStructureIds = new long[folderDDMStructures.size()];
978    
979                    for (int i = 0; i < folderDDMStructures.size(); i++) {
980                            DDMStructure folderDDMStructure = folderDDMStructures.get(i);
981    
982                            ddmStructureIds[i] = folderDDMStructure.getStructureId();
983                    }
984    
985                    validateArticleDDMStructures(folderId, ddmStructureIds);
986            }
987    
988            protected JournalFolder doUpdateFolder(
989                            long userId, long folderId, long parentFolderId, String name,
990                            String description, long[] ddmStructureIds, int restrictionType,
991                            boolean mergeWithParentFolder, ServiceContext serviceContext)
992                    throws PortalException {
993    
994                    // Merge folders
995    
996                    if (restrictionType !=
997                                    JournalFolderConstants.
998                                            RESTRICTION_TYPE_DDM_STRUCTURES_AND_WORKFLOW) {
999    
1000                            ddmStructureIds = new long[0];
1001                    }
1002    
1003                    validateArticleDDMStructures(folderId, ddmStructureIds);
1004    
1005                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
1006                            folderId);
1007    
1008                    parentFolderId = getParentFolderId(folder, parentFolderId);
1009    
1010                    if (mergeWithParentFolder && (folderId != parentFolderId)) {
1011                            mergeFolders(folder, parentFolderId);
1012    
1013                            return folder;
1014                    }
1015    
1016                    // Folder
1017    
1018                    validateFolder(folderId, folder.getGroupId(), parentFolderId, name);
1019    
1020                    long oldParentFolderId = folder.getParentFolderId();
1021    
1022                    if (oldParentFolderId != parentFolderId) {
1023                            folder.setParentFolderId(parentFolderId);
1024                            folder.setTreePath(folder.buildTreePath());
1025                    }
1026    
1027                    folder.setName(name);
1028                    folder.setDescription(description);
1029                    folder.setRestrictionType(restrictionType);
1030                    folder.setExpandoBridgeAttributes(serviceContext);
1031    
1032                    journalFolderPersistence.update(folder);
1033    
1034                    // Asset
1035    
1036                    updateAsset(
1037                            userId, folder, serviceContext.getAssetCategoryIds(),
1038                            serviceContext.getAssetTagNames(),
1039                            serviceContext.getAssetLinkEntryIds());
1040    
1041                    // Dynamic data mapping
1042    
1043                    if (ddmStructureIds != null) {
1044                            updateFolderDDMStructures(folder, ddmStructureIds);
1045                    }
1046    
1047                    if (oldParentFolderId != parentFolderId) {
1048                            rebuildTree(
1049                                    folder.getCompanyId(), folderId, folder.getTreePath(), true);
1050                    }
1051    
1052                    return folder;
1053            }
1054    
1055            protected Set<Long> getDDMStructureIds(
1056                    List<DDMStructureLink> ddmStructureLinks) {
1057    
1058                    Set<Long> ddmStructureIds = new HashSet<>();
1059    
1060                    for (DDMStructureLink ddmStructureLink : ddmStructureLinks) {
1061                            ddmStructureIds.add(ddmStructureLink.getStructureId());
1062                    }
1063    
1064                    return ddmStructureIds;
1065            }
1066    
1067            protected long getParentFolderId(
1068                    JournalFolder folder, long parentFolderId) {
1069    
1070                    if (parentFolderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1071                            return parentFolderId;
1072                    }
1073    
1074                    if (folder.getFolderId() == parentFolderId) {
1075                            return folder.getParentFolderId();
1076                    }
1077    
1078                    JournalFolder parentFolder = journalFolderPersistence.fetchByPrimaryKey(
1079                            parentFolderId);
1080    
1081                    if ((parentFolder == null) ||
1082                            (folder.getGroupId() != parentFolder.getGroupId())) {
1083    
1084                            return folder.getParentFolderId();
1085                    }
1086    
1087                    List<Long> subfolderIds = new ArrayList<>();
1088    
1089                    getSubfolderIds(
1090                            subfolderIds, folder.getGroupId(), folder.getFolderId());
1091    
1092                    if (subfolderIds.contains(parentFolderId)) {
1093                            return folder.getParentFolderId();
1094                    }
1095    
1096                    return parentFolderId;
1097            }
1098    
1099            protected long getParentFolderId(long groupId, long parentFolderId) {
1100                    if (parentFolderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1101                            JournalFolder parentFolder =
1102                                    journalFolderPersistence.fetchByPrimaryKey(parentFolderId);
1103    
1104                            if ((parentFolder == null) ||
1105                                    (groupId != parentFolder.getGroupId())) {
1106    
1107                                    parentFolderId =
1108                                            JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID;
1109                            }
1110                    }
1111    
1112                    return parentFolderId;
1113            }
1114    
1115            protected void mergeFolders(JournalFolder fromFolder, long toFolderId)
1116                    throws PortalException {
1117    
1118                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
1119                            fromFolder.getGroupId(), fromFolder.getFolderId());
1120    
1121                    for (JournalFolder folder : folders) {
1122                            mergeFolders(folder, toFolderId);
1123                    }
1124    
1125                    List<JournalArticle> articles = journalArticlePersistence.findByG_F(
1126                            fromFolder.getGroupId(), fromFolder.getFolderId());
1127    
1128                    for (JournalArticle article : articles) {
1129                            article.setFolderId(toFolderId);
1130                            article.setTreePath(article.buildTreePath());
1131    
1132                            journalArticlePersistence.update(article);
1133    
1134                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1135                                    JournalArticle.class);
1136    
1137                            indexer.reindex(article);
1138                    }
1139    
1140                    journalFolderLocalService.deleteFolder(fromFolder);
1141            }
1142    
1143            protected void moveDependentsToTrash(
1144                            List<Object> foldersAndArticles, long trashEntryId)
1145                    throws PortalException {
1146    
1147                    for (Object object : foldersAndArticles) {
1148                            if (object instanceof JournalArticle) {
1149    
1150                                    // Article
1151    
1152                                    JournalArticle article = (JournalArticle)object;
1153    
1154                                    if (article.getStatus() == WorkflowConstants.STATUS_IN_TRASH) {
1155                                            continue;
1156                                    }
1157    
1158                                    // Articles
1159    
1160                                    List<JournalArticle> articles =
1161                                            journalArticlePersistence.findByG_A(
1162                                                    article.getGroupId(), article.getArticleId());
1163    
1164                                    for (JournalArticle curArticle : articles) {
1165    
1166                                            // Article
1167    
1168                                            int curArticleOldStatus = curArticle.getStatus();
1169    
1170                                            curArticle.setStatus(WorkflowConstants.STATUS_IN_TRASH);
1171    
1172                                            journalArticlePersistence.update(curArticle);
1173    
1174                                            // Trash
1175    
1176                                            int status = curArticleOldStatus;
1177    
1178                                            if (curArticleOldStatus ==
1179                                                            WorkflowConstants.STATUS_PENDING) {
1180    
1181                                                    status = WorkflowConstants.STATUS_DRAFT;
1182                                            }
1183    
1184                                            if (curArticleOldStatus !=
1185                                                            WorkflowConstants.STATUS_APPROVED) {
1186    
1187                                                    trashVersionLocalService.addTrashVersion(
1188                                                            trashEntryId, JournalArticle.class.getName(),
1189                                                            curArticle.getId(), status, null);
1190                                            }
1191    
1192                                            // Workflow
1193    
1194                                            if (curArticleOldStatus ==
1195                                                            WorkflowConstants.STATUS_PENDING) {
1196    
1197                                                    workflowInstanceLinkLocalService.
1198                                                            deleteWorkflowInstanceLink(
1199                                                                    curArticle.getCompanyId(),
1200                                                                    curArticle.getGroupId(),
1201                                                                    JournalArticle.class.getName(),
1202                                                                    curArticle.getId());
1203                                            }
1204                                    }
1205    
1206                                    // Asset
1207    
1208                                    assetEntryLocalService.updateVisible(
1209                                            JournalArticle.class.getName(),
1210                                            article.getResourcePrimKey(), false);
1211    
1212                                    // Indexer
1213    
1214                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1215                                            JournalArticle.class);
1216    
1217                                    indexer.reindex(article);
1218                            }
1219                            else if (object instanceof JournalFolder) {
1220    
1221                                    // Folder
1222    
1223                                    JournalFolder folder = (JournalFolder)object;
1224    
1225                                    if (folder.isInTrashExplicitly()) {
1226                                            continue;
1227                                    }
1228    
1229                                    int oldStatus = folder.getStatus();
1230    
1231                                    folder.setStatus(WorkflowConstants.STATUS_IN_TRASH);
1232    
1233                                    journalFolderPersistence.update(folder);
1234    
1235                                    // Trash
1236    
1237                                    if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
1238                                            trashVersionLocalService.addTrashVersion(
1239                                                    trashEntryId, JournalFolder.class.getName(),
1240                                                    folder.getFolderId(), oldStatus, null);
1241                                    }
1242    
1243                                    // Folders and articles
1244    
1245                                    List<Object> curFoldersAndArticles = getFoldersAndArticles(
1246                                            folder.getGroupId(), folder.getFolderId());
1247    
1248                                    moveDependentsToTrash(curFoldersAndArticles, trashEntryId);
1249    
1250                                    // Asset
1251    
1252                                    assetEntryLocalService.updateVisible(
1253                                            JournalFolder.class.getName(), folder.getFolderId(), false);
1254    
1255                                    // Index
1256    
1257                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1258                                            JournalFolder.class);
1259    
1260                                    indexer.reindex(folder);
1261                            }
1262                    }
1263            }
1264    
1265            protected void restoreDependentsFromTrash(List<Object> foldersAndArticles)
1266                    throws PortalException {
1267    
1268                    for (Object object : foldersAndArticles) {
1269                            if (object instanceof JournalArticle) {
1270    
1271                                    // Article
1272    
1273                                    JournalArticle article = (JournalArticle)object;
1274    
1275                                    if (!article.isInTrashImplicitly()) {
1276                                            continue;
1277                                    }
1278    
1279                                    TrashVersion trashVersion =
1280                                            trashVersionLocalService.fetchVersion(
1281                                                    JournalArticle.class.getName(), article.getId());
1282    
1283                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
1284    
1285                                    if (trashVersion != null) {
1286                                            oldStatus = trashVersion.getStatus();
1287                                    }
1288    
1289                                    // Articles
1290    
1291                                    List<JournalArticle> articles =
1292                                            journalArticlePersistence.findByG_A(
1293                                                    article.getGroupId(), article.getArticleId());
1294    
1295                                    for (JournalArticle curArticle : articles) {
1296    
1297                                            // Article
1298    
1299                                            trashVersion = trashVersionLocalService.fetchVersion(
1300                                                    JournalArticle.class.getName(), curArticle.getId());
1301    
1302                                            int curArticleOldStatus = WorkflowConstants.STATUS_APPROVED;
1303    
1304                                            if (trashVersion != null) {
1305                                                    curArticleOldStatus = trashVersion.getStatus();
1306                                            }
1307    
1308                                            curArticle.setStatus(curArticleOldStatus);
1309    
1310                                            journalArticlePersistence.update(curArticle);
1311    
1312                                            // Trash
1313    
1314                                            if (trashVersion != null) {
1315                                                    trashVersionLocalService.deleteTrashVersion(
1316                                                            trashVersion);
1317                                            }
1318                                    }
1319    
1320                                    // Asset
1321    
1322                                    if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
1323                                            assetEntryLocalService.updateVisible(
1324                                                    JournalArticle.class.getName(),
1325                                                    article.getResourcePrimKey(), true);
1326                                    }
1327    
1328                                    // Indexer
1329    
1330                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1331                                            JournalArticle.class);
1332    
1333                                    indexer.reindex(article);
1334                            }
1335                            else if (object instanceof JournalFolder) {
1336    
1337                                    // Folder
1338    
1339                                    JournalFolder folder = (JournalFolder)object;
1340    
1341                                    if (!folder.isInTrashImplicitly()) {
1342                                            continue;
1343                                    }
1344    
1345                                    TrashVersion trashVersion =
1346                                            trashVersionLocalService.fetchVersion(
1347                                                    JournalFolder.class.getName(), folder.getFolderId());
1348    
1349                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
1350    
1351                                    if (trashVersion != null) {
1352                                            oldStatus = trashVersion.getStatus();
1353                                    }
1354    
1355                                    folder.setStatus(oldStatus);
1356    
1357                                    journalFolderPersistence.update(folder);
1358    
1359                                    // Folders and articles
1360    
1361                                    List<Object> curFoldersAndArticles = getFoldersAndArticles(
1362                                            folder.getGroupId(), folder.getFolderId(),
1363                                            WorkflowConstants.STATUS_IN_TRASH);
1364    
1365                                    restoreDependentsFromTrash(curFoldersAndArticles);
1366    
1367                                    // Trash
1368    
1369                                    if (trashVersion != null) {
1370                                            trashVersionLocalService.deleteTrashVersion(trashVersion);
1371                                    }
1372    
1373                                    // Asset
1374    
1375                                    assetEntryLocalService.updateVisible(
1376                                            JournalFolder.class.getName(), folder.getFolderId(), true);
1377    
1378                                    // Index
1379    
1380                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1381                                            JournalFolder.class);
1382    
1383                                    indexer.reindex(folder);
1384                            }
1385                    }
1386            }
1387    
1388            protected void validateArticleDDMStructures(
1389                            long folderId, long[] ddmStructureIds)
1390                    throws PortalException {
1391    
1392                    if (ArrayUtil.isEmpty(ddmStructureIds)) {
1393                            return;
1394                    }
1395    
1396                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
1397                            folderId);
1398    
1399                    List<JournalArticle> articles = journalArticleLocalService.getArticles(
1400                            folder.getGroupId(), folderId);
1401    
1402                    if (!articles.isEmpty()) {
1403                            long classNameId = classNameLocalService.getClassNameId(
1404                                    JournalArticle.class);
1405    
1406                            for (JournalArticle article : articles) {
1407                                    DDMStructure ddmStructure =
1408                                            ddmStructureLocalService.fetchStructure(
1409                                                    article.getGroupId(), classNameId,
1410                                                    article.getDDMStructureKey(), true);
1411    
1412                                    if (ddmStructure == null) {
1413                                            throw new InvalidDDMStructureException();
1414                                    }
1415    
1416                                    if (!ArrayUtil.contains(
1417                                                    ddmStructureIds, ddmStructure.getStructureId())) {
1418    
1419                                            throw new InvalidDDMStructureException();
1420                                    }
1421                            }
1422                    }
1423    
1424                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
1425                            folder.getGroupId(), folder.getFolderId());
1426    
1427                    if (folders.isEmpty()) {
1428                            return;
1429                    }
1430    
1431                    for (JournalFolder curFolder : folders) {
1432                            validateArticleDDMStructures(
1433                                    curFolder.getFolderId(), ddmStructureIds);
1434                    }
1435            }
1436    
1437            protected void validateFolder(
1438                            long folderId, long groupId, long parentFolderId, String name)
1439                    throws PortalException {
1440    
1441                    JournalValidatorUtil.validateFolderName(name);
1442    
1443                    JournalFolder folder = journalFolderPersistence.fetchByG_P_N(
1444                            groupId, parentFolderId, name);
1445    
1446                    if ((folder != null) && (folder.getFolderId() != folderId)) {
1447                            throw new DuplicateFolderNameException(name);
1448                    }
1449            }
1450    
1451    }