001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.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.exception.SystemException;
021    import com.liferay.portal.kernel.json.JSONFactoryUtil;
022    import com.liferay.portal.kernel.json.JSONObject;
023    import com.liferay.portal.kernel.search.Indexable;
024    import com.liferay.portal.kernel.search.IndexableType;
025    import com.liferay.portal.kernel.search.Indexer;
026    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
027    import com.liferay.portal.kernel.systemevent.SystemEvent;
028    import com.liferay.portal.kernel.util.ContentTypes;
029    import com.liferay.portal.kernel.util.OrderByComparator;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.TreeModelFinder;
032    import com.liferay.portal.kernel.util.TreePathUtil;
033    import com.liferay.portal.kernel.util.UnicodeProperties;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.model.ResourceConstants;
036    import com.liferay.portal.model.SystemEventConstants;
037    import com.liferay.portal.model.TreeModel;
038    import com.liferay.portal.model.User;
039    import com.liferay.portal.service.ServiceContext;
040    import com.liferay.portal.util.PropsValues;
041    import com.liferay.portlet.asset.model.AssetEntry;
042    import com.liferay.portlet.asset.model.AssetLinkConstants;
043    import com.liferay.portlet.asset.util.AssetUtil;
044    import com.liferay.portlet.journal.DuplicateFolderNameException;
045    import com.liferay.portlet.journal.FolderNameException;
046    import com.liferay.portlet.journal.model.JournalArticle;
047    import com.liferay.portlet.journal.model.JournalFolder;
048    import com.liferay.portlet.journal.model.JournalFolderConstants;
049    import com.liferay.portlet.journal.service.base.JournalFolderLocalServiceBaseImpl;
050    import com.liferay.portlet.journal.util.comparator.FolderIdComparator;
051    import com.liferay.portlet.social.model.SocialActivityConstants;
052    import com.liferay.portlet.trash.model.TrashEntry;
053    import com.liferay.portlet.trash.model.TrashVersion;
054    import com.liferay.portlet.trash.util.TrashUtil;
055    
056    import java.util.ArrayList;
057    import java.util.Date;
058    import java.util.List;
059    
060    /**
061     * @author Juan Fern??ndez
062     */
063    public class JournalFolderLocalServiceImpl
064            extends JournalFolderLocalServiceBaseImpl {
065    
066            @Override
067            public JournalFolder addFolder(
068                            long userId, long groupId, long parentFolderId, String name,
069                            String description, ServiceContext serviceContext)
070                    throws PortalException, SystemException {
071    
072                    // Folder
073    
074                    User user = userPersistence.findByPrimaryKey(userId);
075                    parentFolderId = getParentFolderId(groupId, parentFolderId);
076                    Date now = new Date();
077    
078                    validateFolder(0, groupId, parentFolderId, name);
079    
080                    long folderId = counterLocalService.increment();
081    
082                    JournalFolder folder = journalFolderPersistence.create(folderId);
083    
084                    folder.setUuid(serviceContext.getUuid());
085                    folder.setGroupId(groupId);
086                    folder.setCompanyId(user.getCompanyId());
087                    folder.setUserId(user.getUserId());
088                    folder.setUserName(user.getFullName());
089                    folder.setCreateDate(serviceContext.getCreateDate(now));
090                    folder.setModifiedDate(serviceContext.getModifiedDate(now));
091                    folder.setParentFolderId(parentFolderId);
092                    folder.setTreePath(folder.buildTreePath());
093                    folder.setName(name);
094                    folder.setDescription(description);
095                    folder.setExpandoBridgeAttributes(serviceContext);
096    
097                    journalFolderPersistence.update(folder);
098    
099                    // Resources
100    
101                    resourceLocalService.addModelResources(folder, serviceContext);
102    
103                    // Asset
104    
105                    updateAsset(
106                            userId, folder, serviceContext.getAssetCategoryIds(),
107                            serviceContext.getAssetTagNames(),
108                            serviceContext.getAssetLinkEntryIds());
109    
110                    return folder;
111            }
112    
113            @Indexable(type = IndexableType.DELETE)
114            @Override
115            @SystemEvent(
116                    action = SystemEventConstants.ACTION_SKIP, send = false,
117                    type = SystemEventConstants.TYPE_DELETE)
118            public JournalFolder deleteFolder(JournalFolder folder)
119                    throws PortalException, SystemException {
120    
121                    return deleteFolder(folder, true);
122            }
123    
124            @Indexable(type = IndexableType.DELETE)
125            @Override
126            @SystemEvent(
127                    action = SystemEventConstants.ACTION_SKIP, send = false,
128                    type = SystemEventConstants.TYPE_DELETE)
129            public JournalFolder deleteFolder(
130                            JournalFolder folder, boolean includeTrashedEntries)
131                    throws PortalException, SystemException {
132    
133                    // Folders
134    
135                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
136                            folder.getGroupId(), folder.getFolderId());
137    
138                    for (JournalFolder curFolder : folders) {
139                            if (includeTrashedEntries || !curFolder.isInTrashExplicitly()) {
140                                    deleteFolder(curFolder, includeTrashedEntries);
141                            }
142                    }
143    
144                    // Folder
145    
146                    journalFolderPersistence.remove(folder);
147    
148                    // Resources
149    
150                    resourceLocalService.deleteResource(
151                            folder, ResourceConstants.SCOPE_INDIVIDUAL);
152    
153                    // Entries
154    
155                    journalArticleLocalService.deleteArticles(
156                            folder.getGroupId(), folder.getFolderId(), includeTrashedEntries);
157    
158                    // Asset
159    
160                    assetEntryLocalService.deleteEntry(
161                            JournalFolder.class.getName(), folder.getFolderId());
162    
163                    // Expando
164    
165                    expandoValueLocalService.deleteValues(
166                            JournalFolder.class.getName(), folder.getFolderId());
167    
168                    // Trash
169    
170                    trashEntryLocalService.deleteEntry(
171                            JournalFolder.class.getName(), folder.getFolderId());
172    
173                    return folder;
174            }
175    
176            @Indexable(type = IndexableType.DELETE)
177            @Override
178            public JournalFolder deleteFolder(long folderId)
179                    throws PortalException, SystemException {
180    
181                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
182                            folderId);
183    
184                    return journalFolderLocalService.deleteFolder(folder, true);
185            }
186    
187            @Indexable(type = IndexableType.DELETE)
188            @Override
189            public JournalFolder deleteFolder(
190                            long folderId, boolean includeTrashedEntries)
191                    throws PortalException, SystemException {
192    
193                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
194                            folderId);
195    
196                    return journalFolderLocalService.deleteFolder(
197                            folder, includeTrashedEntries);
198            }
199    
200            @Override
201            public void deleteFolders(long groupId)
202                    throws PortalException, SystemException {
203    
204                    List<JournalFolder> folders = journalFolderPersistence.findByGroupId(
205                            groupId);
206    
207                    for (JournalFolder folder : folders) {
208                            journalFolderLocalService.deleteFolder(folder);
209                    }
210            }
211    
212            @Override
213            public JournalFolder fetchFolder(long folderId) throws SystemException {
214                    return journalFolderPersistence.fetchByPrimaryKey(folderId);
215            }
216    
217            @Override
218            public JournalFolder fetchFolder(
219                            long groupId, long parentFolderId, String name)
220                    throws SystemException {
221    
222                    return journalFolderPersistence.fetchByG_P_N(
223                                    groupId, parentFolderId, name);
224            }
225    
226            @Override
227            public JournalFolder fetchFolder(long groupId, String name)
228                    throws SystemException {
229    
230                    return journalFolderPersistence.fetchByG_N(groupId, name);
231            }
232    
233            @Override
234            public List<JournalFolder> getCompanyFolders(
235                            long companyId, int start, int end)
236                    throws SystemException {
237    
238                    return journalFolderPersistence.findByCompanyId(companyId, start, end);
239            }
240    
241            @Override
242            public int getCompanyFoldersCount(long companyId) throws SystemException {
243                    return journalFolderPersistence.countByCompanyId(companyId);
244            }
245    
246            @Override
247            public JournalFolder getFolder(long folderId)
248                    throws PortalException, SystemException {
249    
250                    return journalFolderPersistence.findByPrimaryKey(folderId);
251            }
252    
253            @Override
254            public List<JournalFolder> getFolders(long groupId) throws SystemException {
255                    return journalFolderPersistence.findByGroupId(groupId);
256            }
257    
258            @Override
259            public List<JournalFolder> getFolders(long groupId, long parentFolderId)
260                    throws SystemException {
261    
262                    return getFolders(
263                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED);
264            }
265    
266            @Override
267            public List<JournalFolder> getFolders(
268                            long groupId, long parentFolderId, int status)
269                    throws SystemException {
270    
271                    return journalFolderPersistence.findByG_P_S(
272                            groupId, parentFolderId, status);
273            }
274    
275            @Override
276            public List<JournalFolder> getFolders(
277                            long groupId, long parentFolderId, int start, int end)
278                    throws SystemException {
279    
280                    return getFolders(
281                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED, start,
282                            end);
283            }
284    
285            @Override
286            public List<JournalFolder> getFolders(
287                            long groupId, long parentFolderId, int status, int start, int end)
288                    throws SystemException {
289    
290                    return journalFolderPersistence.findByG_P_S(
291                                    groupId, parentFolderId, status, start, end);
292            }
293    
294            @Override
295            public List<Object> getFoldersAndArticles(long groupId, long folderId)
296                    throws SystemException {
297    
298                    QueryDefinition queryDefinition = new QueryDefinition(
299                            WorkflowConstants.STATUS_ANY);
300    
301                    return journalFolderFinder.findF_A_ByG_F(
302                            groupId, folderId, queryDefinition);
303            }
304    
305            @Override
306            public List<Object> getFoldersAndArticles(
307                            long groupId, long folderId, int status)
308                    throws SystemException {
309    
310                    QueryDefinition queryDefinition = new QueryDefinition(status);
311    
312                    return journalFolderFinder.findF_A_ByG_F(
313                            groupId, folderId, queryDefinition);
314            }
315    
316            @Override
317            public List<Object> getFoldersAndArticles(
318                            long groupId, long folderId, int start, int end,
319                            OrderByComparator obc)
320                    throws SystemException {
321    
322                    QueryDefinition queryDefinition = new QueryDefinition(
323                            WorkflowConstants.STATUS_ANY, start, end, obc);
324    
325                    return journalFolderFinder.findF_A_ByG_F(
326                            groupId, folderId, queryDefinition);
327            }
328    
329            @Override
330            public int getFoldersAndArticlesCount(
331                            long groupId, List<Long> folderIds, int status)
332                    throws SystemException {
333    
334                    QueryDefinition queryDefinition = new QueryDefinition(status);
335    
336                    if (folderIds.size() <= PropsValues.SQL_DATA_MAX_PARAMETERS) {
337                            return journalArticleFinder.countByG_F(
338                                    groupId, folderIds, queryDefinition);
339                    }
340                    else {
341                            int start = 0;
342                            int end = PropsValues.SQL_DATA_MAX_PARAMETERS;
343    
344                            int articlesCount = journalArticleFinder.countByG_F(
345                                    groupId, folderIds.subList(start, end), queryDefinition);
346    
347                            folderIds.subList(start, end).clear();
348    
349                            articlesCount += getFoldersAndArticlesCount(
350                                    groupId, folderIds, status);
351    
352                            return articlesCount;
353                    }
354            }
355    
356            @Override
357            public int getFoldersAndArticlesCount(long groupId, long folderId)
358                    throws SystemException {
359    
360                    QueryDefinition queryDefinition = new QueryDefinition(
361                            WorkflowConstants.STATUS_ANY);
362    
363                    return journalFolderFinder.countF_A_ByG_F(
364                            groupId, folderId, queryDefinition);
365            }
366    
367            @Override
368            public int getFoldersAndArticlesCount(
369                            long groupId, long folderId, int status)
370                    throws SystemException {
371    
372                    QueryDefinition queryDefinition = new QueryDefinition(status, 0, false);
373    
374                    return journalFolderFinder.countF_A_ByG_F(
375                            groupId, folderId, queryDefinition);
376            }
377    
378            @Override
379            public int getFoldersCount(long groupId, long parentFolderId)
380                    throws SystemException {
381    
382                    return getFoldersCount(
383                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED);
384            }
385    
386            @Override
387            public int getFoldersCount(long groupId, long parentFolderId, int status)
388                    throws SystemException {
389    
390                    return journalFolderPersistence.countByG_P_S(
391                            groupId, parentFolderId, status);
392            }
393    
394            @Override
395            public List<JournalFolder> getNoAssetFolders() throws SystemException {
396                    return journalFolderFinder.findF_ByNoAssets();
397            }
398    
399            @Override
400            public void getSubfolderIds(
401                            List<Long> folderIds, long groupId, long folderId)
402                    throws SystemException {
403    
404                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
405                            groupId, folderId);
406    
407                    for (JournalFolder folder : folders) {
408                            folderIds.add(folder.getFolderId());
409    
410                            getSubfolderIds(
411                                    folderIds, folder.getGroupId(), folder.getFolderId());
412                    }
413            }
414    
415            @Indexable(type = IndexableType.REINDEX)
416            @Override
417            public JournalFolder moveFolder(
418                            long folderId, long parentFolderId, ServiceContext serviceContext)
419                    throws PortalException, SystemException {
420    
421                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
422                            folderId);
423    
424                    parentFolderId = getParentFolderId(folder, parentFolderId);
425    
426                    if (folder.getParentFolderId() == parentFolderId) {
427                            return folder;
428                    }
429    
430                    validateFolder(
431                            folder.getFolderId(), folder.getGroupId(), parentFolderId,
432                            folder.getName());
433    
434                    folder.setModifiedDate(serviceContext.getModifiedDate(null));
435                    folder.setParentFolderId(parentFolderId);
436                    folder.setTreePath(folder.buildTreePath());
437                    folder.setExpandoBridgeAttributes(serviceContext);
438    
439                    journalFolderPersistence.update(folder);
440    
441                    rebuildTree(
442                            folder.getCompanyId(), folderId, folder.getTreePath(), true);
443    
444                    return folder;
445            }
446    
447            @Override
448            public JournalFolder moveFolderFromTrash(
449                            long userId, long folderId, long parentFolderId,
450                            ServiceContext serviceContext)
451                    throws PortalException, SystemException {
452    
453                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
454                            folderId);
455    
456                    if (folder.isInTrashExplicitly()) {
457                            restoreFolderFromTrash(userId, folderId);
458                    }
459                    else {
460    
461                            // Folder
462    
463                            TrashEntry trashEntry = folder.getTrashEntry();
464    
465                            TrashVersion trashVersion =
466                                    trashVersionLocalService.fetchVersion(
467                                            trashEntry.getEntryId(), JournalFolder.class.getName(),
468                                            folderId);
469    
470                            int status = WorkflowConstants.STATUS_APPROVED;
471    
472                            if (trashVersion != null) {
473                                    status = trashVersion.getStatus();
474                            }
475    
476                            updateStatus(userId, folder, status);
477    
478                            // Trash
479    
480                            if (trashVersion != null) {
481                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
482                            }
483    
484                            // Folders and articles
485    
486                            List<Object> foldersAndArticles =
487                                    journalFolderLocalService.getFoldersAndArticles(
488                                            folder.getGroupId(), folder.getFolderId(),
489                                            WorkflowConstants.STATUS_IN_TRASH);
490    
491                            restoreDependentsFromTrash(
492                                    foldersAndArticles, trashEntry.getEntryId());
493                    }
494    
495                    return journalFolderLocalService.moveFolder(
496                            folderId, parentFolderId, serviceContext);
497            }
498    
499            @Indexable(type = IndexableType.REINDEX)
500            @Override
501            public JournalFolder moveFolderToTrash(long userId, long folderId)
502                    throws PortalException, SystemException {
503    
504                    // Folder
505    
506                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
507                            folderId);
508    
509                    String title = folder.getName();
510    
511                    folder = updateStatus(
512                            userId, folder, WorkflowConstants.STATUS_IN_TRASH);
513    
514                    // Trash
515    
516                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
517    
518                    typeSettingsProperties.put("title", folder.getName());
519    
520                    TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
521                            userId, folder.getGroupId(), JournalFolder.class.getName(),
522                            folder.getFolderId(), folder.getUuid(), null,
523                            WorkflowConstants.STATUS_APPROVED, null, typeSettingsProperties);
524    
525                    folder.setName(TrashUtil.getTrashTitle(trashEntry.getEntryId()));
526    
527                    journalFolderPersistence.update(folder);
528    
529                    // Folders and articles
530    
531                    List<Object> foldersAndArticles =
532                            journalFolderLocalService.getFoldersAndArticles(
533                                    folder.getGroupId(), folder.getFolderId());
534    
535                    moveDependentsToTrash(foldersAndArticles, trashEntry.getEntryId());
536    
537                    // Social
538    
539                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
540    
541                    extraDataJSONObject.put("title", title);
542    
543                    socialActivityLocalService.addActivity(
544                            userId, folder.getGroupId(), JournalFolder.class.getName(),
545                            folder.getFolderId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
546                            extraDataJSONObject.toString(), 0);
547    
548                    return folder;
549            }
550    
551            @Override
552            public void rebuildTree(long companyId)
553                    throws PortalException, SystemException {
554    
555                    rebuildTree(
556                            companyId, JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID,
557                            StringPool.SLASH, false);
558            }
559    
560            @Override
561            public void rebuildTree(
562                            long companyId, long parentFolderId, String parentTreePath,
563                            final boolean reindex)
564                    throws PortalException, SystemException {
565    
566                    TreePathUtil.rebuildTree(
567                            companyId, parentFolderId, parentTreePath,
568                            new TreeModelFinder<JournalFolder>() {
569    
570                                    @Override
571                                    public List<JournalFolder> findTreeModels(
572                                                    long previousId, long companyId, long parentPrimaryKey,
573                                                    int size)
574                                            throws SystemException {
575    
576                                            return journalFolderPersistence.findByF_C_P_NotS(
577                                                    previousId, companyId, parentPrimaryKey,
578                                                    WorkflowConstants.STATUS_IN_TRASH, QueryUtil.ALL_POS,
579                                                    size, new FolderIdComparator());
580                                    }
581    
582                                    @Override
583                                    public void rebuildDependentModelsTreePaths(
584                                                    long parentPrimaryKey, String treePath)
585                                            throws PortalException, SystemException {
586    
587                                            journalArticleLocalService.setTreePaths(
588                                                    parentPrimaryKey, treePath, false);
589                            }
590    
591                                    @Override
592                                    public void reindexTreeModels(List<TreeModel> treeModels)
593                                            throws PortalException {
594    
595                                            if (!reindex) {
596                                                    return;
597                                            }
598    
599                                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
600                                                    JournalFolder.class);
601    
602                                            for (TreeModel treeModel : treeModels) {
603                                                    indexer.reindex(treeModel);
604                                            }
605                                    }
606                            }
607                    );
608            }
609    
610            @Override
611            public void restoreFolderFromTrash(long userId, long folderId)
612                    throws PortalException, SystemException {
613    
614                    // Folder
615    
616                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
617                            folderId);
618    
619                    folder.setName(TrashUtil.getOriginalTitle(folder.getName()));
620    
621                    journalFolderPersistence.update(folder);
622    
623                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
624                            JournalFolder.class.getName(), folderId);
625    
626                    updateStatus(userId, folder, trashEntry.getStatus());
627    
628                    // Folders and articles
629    
630                    List<Object> foldersAndArticles =
631                            journalFolderLocalService.getFoldersAndArticles(
632                                    folder.getGroupId(), folder.getFolderId(),
633                                    WorkflowConstants.STATUS_IN_TRASH);
634    
635                    restoreDependentsFromTrash(foldersAndArticles, trashEntry.getEntryId());
636    
637                    // Trash
638    
639                    trashEntryLocalService.deleteEntry(
640                            JournalFolder.class.getName(), folder.getFolderId());
641    
642                    // Social
643    
644                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
645    
646                    extraDataJSONObject.put("title", folder.getName());
647    
648                    socialActivityLocalService.addActivity(
649                            userId, folder.getGroupId(), JournalFolder.class.getName(),
650                            folder.getFolderId(),
651                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
652                            extraDataJSONObject.toString(), 0);
653            }
654    
655            @Override
656            public void updateAsset(
657                            long userId, JournalFolder folder, long[] assetCategoryIds,
658                            String[] assetTagNames, long[] assetLinkEntryIds)
659                    throws PortalException, SystemException {
660    
661                    AssetEntry assetEntry = assetEntryLocalService.updateEntry(
662                            userId, folder.getGroupId(), folder.getCreateDate(),
663                            folder.getModifiedDate(), JournalFolder.class.getName(),
664                            folder.getFolderId(), folder.getUuid(), 0, assetCategoryIds,
665                            assetTagNames, true, null, null, null, ContentTypes.TEXT_PLAIN,
666                            folder.getName(), folder.getDescription(), null, null, null, 0, 0,
667                            null, false);
668    
669                    assetLinkLocalService.updateLinks(
670                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
671                            AssetLinkConstants.TYPE_RELATED);
672            }
673    
674            @Indexable(type = IndexableType.REINDEX)
675            @Override
676            public JournalFolder updateFolder(
677                            long userId, long folderId, long parentFolderId, String name,
678                            String description, boolean mergeWithParentFolder,
679                            ServiceContext serviceContext)
680                    throws PortalException, SystemException {
681    
682                    // Merge folders
683    
684                    JournalFolder folder = journalFolderPersistence.findByPrimaryKey(
685                            folderId);
686    
687                    parentFolderId = getParentFolderId(folder, parentFolderId);
688    
689                    if (mergeWithParentFolder && (folderId != parentFolderId)) {
690                            mergeFolders(folder, parentFolderId);
691    
692                            return folder;
693                    }
694    
695                    // Folder
696    
697                    validateFolder(folderId, folder.getGroupId(), parentFolderId, name);
698    
699                    long oldParentFolderId = folder.getParentFolderId();
700    
701                    if (oldParentFolderId != parentFolderId) {
702                            folder.setParentFolderId(parentFolderId);
703                            folder.setTreePath(folder.buildTreePath());
704                    }
705    
706                    folder.setModifiedDate(serviceContext.getModifiedDate(null));
707                    folder.setName(name);
708                    folder.setDescription(description);
709                    folder.setExpandoBridgeAttributes(serviceContext);
710    
711                    journalFolderPersistence.update(folder);
712    
713                    // Asset
714    
715                    updateAsset(
716                            userId, folder, serviceContext.getAssetCategoryIds(),
717                            serviceContext.getAssetTagNames(),
718                            serviceContext.getAssetLinkEntryIds());
719    
720                    if (oldParentFolderId != parentFolderId) {
721                            rebuildTree(
722                                    folder.getCompanyId(), folderId, folder.getTreePath(), true);
723                    }
724    
725                    return folder;
726            }
727    
728            @Override
729            public JournalFolder updateStatus(
730                            long userId, JournalFolder folder, int status)
731                    throws PortalException, SystemException {
732    
733                    // Folder
734    
735                    User user = userPersistence.findByPrimaryKey(userId);
736    
737                    folder.setStatus(status);
738                    folder.setStatusByUserId(userId);
739                    folder.setStatusByUserName(user.getFullName());
740                    folder.setStatusDate(new Date());
741    
742                    journalFolderPersistence.update(folder);
743    
744                    // Asset
745    
746                    if (status == WorkflowConstants.STATUS_APPROVED) {
747                            assetEntryLocalService.updateVisible(
748                                    JournalFolder.class.getName(), folder.getFolderId(), true);
749                    }
750                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
751                            assetEntryLocalService.updateVisible(
752                                    JournalFolder.class.getName(), folder.getFolderId(), false);
753                    }
754    
755                    // Indexer
756    
757                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
758                            JournalFolder.class);
759    
760                    indexer.reindex(folder);
761    
762                    return folder;
763            }
764    
765            protected long getParentFolderId(JournalFolder folder, long parentFolderId)
766                    throws SystemException {
767    
768                    if (parentFolderId == JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
769                            return parentFolderId;
770                    }
771    
772                    if (folder.getFolderId() == parentFolderId) {
773                            return folder.getParentFolderId();
774                    }
775    
776                    JournalFolder parentFolder = journalFolderPersistence.fetchByPrimaryKey(
777                            parentFolderId);
778    
779                    if ((parentFolder == null) ||
780                            (folder.getGroupId() != parentFolder.getGroupId())) {
781    
782                            return folder.getParentFolderId();
783                    }
784    
785                    List<Long> subfolderIds = new ArrayList<Long>();
786    
787                    getSubfolderIds(
788                            subfolderIds, folder.getGroupId(), folder.getFolderId());
789    
790                    if (subfolderIds.contains(parentFolderId)) {
791                            return folder.getParentFolderId();
792                    }
793    
794                    return parentFolderId;
795            }
796    
797            protected long getParentFolderId(long groupId, long parentFolderId)
798                    throws SystemException {
799    
800                    if (parentFolderId != JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
801                            JournalFolder parentFolder =
802                                    journalFolderPersistence.fetchByPrimaryKey(parentFolderId);
803    
804                            if ((parentFolder == null) ||
805                                    (groupId != parentFolder.getGroupId())) {
806    
807                                    parentFolderId =
808                                            JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID;
809                            }
810                    }
811    
812                    return parentFolderId;
813            }
814    
815            protected void mergeFolders(JournalFolder fromFolder, long toFolderId)
816                    throws PortalException, SystemException {
817    
818                    List<JournalFolder> folders = journalFolderPersistence.findByG_P(
819                            fromFolder.getGroupId(), fromFolder.getFolderId());
820    
821                    for (JournalFolder folder : folders) {
822                            mergeFolders(folder, toFolderId);
823                    }
824    
825                    List<JournalArticle> articles = journalArticlePersistence.findByG_F(
826                            fromFolder.getGroupId(), fromFolder.getFolderId());
827    
828                    for (JournalArticle article : articles) {
829                            article.setFolderId(toFolderId);
830                            article.setTreePath(article.buildTreePath());
831    
832                            journalArticlePersistence.update(article);
833    
834                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
835                                    JournalArticle.class);
836    
837                            indexer.reindex(article);
838                    }
839    
840                    journalFolderLocalService.deleteFolder(fromFolder);
841            }
842    
843            protected void moveDependentsToTrash(
844                            List<Object> foldersAndArticles, long trashEntryId)
845                    throws PortalException, SystemException {
846    
847                    for (Object object : foldersAndArticles) {
848                            if (object instanceof JournalArticle) {
849    
850                                    // Article
851    
852                                    JournalArticle article = (JournalArticle)object;
853    
854                                    if (article.getStatus() == WorkflowConstants.STATUS_IN_TRASH) {
855                                            continue;
856                                    }
857    
858                                    // Articles
859    
860                                    List<JournalArticle> articles =
861                                            journalArticlePersistence.findByG_A(
862                                                    article.getGroupId(), article.getArticleId());
863    
864                                    for (JournalArticle curArticle : articles) {
865    
866                                            // Article
867    
868                                            int curArticleOldStatus = curArticle.getStatus();
869    
870                                            curArticle.setStatus(WorkflowConstants.STATUS_IN_TRASH);
871    
872                                            journalArticlePersistence.update(curArticle);
873    
874                                            // Trash
875    
876                                            int status = curArticleOldStatus;
877    
878                                            if (curArticleOldStatus ==
879                                                            WorkflowConstants.STATUS_PENDING) {
880    
881                                                    status = WorkflowConstants.STATUS_DRAFT;
882                                            }
883    
884                                            if (curArticleOldStatus !=
885                                                            WorkflowConstants.STATUS_APPROVED) {
886    
887                                                    trashVersionLocalService.addTrashVersion(
888                                                            trashEntryId, JournalArticle.class.getName(),
889                                                            curArticle.getId(), status, null);
890                                            }
891    
892                                            // Workflow
893    
894                                            if (curArticleOldStatus ==
895                                                            WorkflowConstants.STATUS_PENDING) {
896    
897                                                    workflowInstanceLinkLocalService.
898                                                            deleteWorkflowInstanceLink(
899                                                                    curArticle.getCompanyId(),
900                                                                    curArticle.getGroupId(),
901                                                                    JournalArticle.class.getName(),
902                                                                    curArticle.getId());
903                                            }
904                                    }
905    
906                                    // Asset
907    
908                                    assetEntryLocalService.updateVisible(
909                                            JournalArticle.class.getName(),
910                                            article.getResourcePrimKey(), false);
911    
912                                    // Indexer
913    
914                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
915                                            JournalArticle.class);
916    
917                                    indexer.reindex(article);
918                            }
919                            else if (object instanceof JournalFolder) {
920    
921                                    // Folder
922    
923                                    JournalFolder folder = (JournalFolder)object;
924    
925                                    if (folder.isInTrashExplicitly()) {
926                                            continue;
927                                    }
928    
929                                    int oldStatus = folder.getStatus();
930    
931                                    folder.setStatus(WorkflowConstants.STATUS_IN_TRASH);
932    
933                                    journalFolderPersistence.update(folder);
934    
935                                    // Trash
936    
937                                    if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
938                                            trashVersionLocalService.addTrashVersion(
939                                                    trashEntryId, JournalFolder.class.getName(),
940                                                    folder.getFolderId(), oldStatus, null);
941                                    }
942    
943                                    // Folders and articles
944    
945                                    List<Object> curFoldersAndArticles = getFoldersAndArticles(
946                                            folder.getGroupId(), folder.getFolderId());
947    
948                                    moveDependentsToTrash(curFoldersAndArticles, trashEntryId);
949    
950                                    // Asset
951    
952                                    assetEntryLocalService.updateVisible(
953                                            JournalFolder.class.getName(), folder.getFolderId(), false);
954    
955                                    // Indexer
956    
957                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
958                                            JournalFolder.class);
959    
960                                    indexer.reindex(folder);
961                            }
962                    }
963            }
964    
965            protected void restoreDependentsFromTrash(
966                            List<Object> foldersAndArticles, long trashEntryId)
967                    throws PortalException, SystemException {
968    
969                    for (Object object : foldersAndArticles) {
970                            if (object instanceof JournalArticle) {
971    
972                                    // Article
973    
974                                    JournalArticle article = (JournalArticle)object;
975    
976                                    TrashEntry trashEntry = trashEntryLocalService.fetchEntry(
977                                            JournalArticle.class.getName(),
978                                            article.getResourcePrimKey());
979    
980                                    if (trashEntry != null) {
981                                            continue;
982                                    }
983    
984                                    TrashVersion trashVersion =
985                                            trashVersionLocalService.fetchVersion(
986                                                    trashEntryId, JournalArticle.class.getName(),
987                                                    article.getId());
988    
989                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
990    
991                                    if (trashVersion != null) {
992                                            oldStatus = trashVersion.getStatus();
993                                    }
994    
995                                    // Articles
996    
997                                    List<JournalArticle> articles =
998                                            journalArticlePersistence.findByG_A(
999                                                    article.getGroupId(), article.getArticleId());
1000    
1001                                    for (JournalArticle curArticle : articles) {
1002    
1003                                            // Article
1004    
1005                                            trashVersion =
1006                                                    trashVersionLocalService.fetchVersion(
1007                                                            trashEntryId, JournalArticle.class.getName(),
1008                                                            curArticle.getId());
1009    
1010                                            int curArticleOldStatus = WorkflowConstants.STATUS_APPROVED;
1011    
1012                                            if (trashVersion != null) {
1013                                                    curArticleOldStatus = trashVersion.getStatus();
1014                                            }
1015    
1016                                            curArticle.setStatus(curArticleOldStatus);
1017    
1018                                            journalArticlePersistence.update(curArticle);
1019    
1020                                            // Trash
1021    
1022                                            if (trashVersion != null) {
1023                                                    trashVersionLocalService.deleteTrashVersion(
1024                                                            trashVersion);
1025                                            }
1026                                    }
1027    
1028                                    // Asset
1029    
1030                                    if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
1031                                            assetEntryLocalService.updateVisible(
1032                                                    JournalArticle.class.getName(),
1033                                                    article.getResourcePrimKey(), true);
1034                                    }
1035    
1036                                    // Indexer
1037    
1038                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1039                                            JournalArticle.class);
1040    
1041                                    indexer.reindex(article);
1042                            }
1043                            else if (object instanceof JournalFolder) {
1044    
1045                                    // Folder
1046    
1047                                    JournalFolder folder = (JournalFolder)object;
1048    
1049                                    TrashEntry trashEntry = trashEntryLocalService.fetchEntry(
1050                                            JournalFolder.class.getName(), folder.getFolderId());
1051    
1052                                    if (trashEntry != null) {
1053                                            continue;
1054                                    }
1055    
1056                                    TrashVersion trashVersion =
1057                                            trashVersionLocalService.fetchVersion(
1058                                                    trashEntryId, JournalFolder.class.getName(),
1059                                                    folder.getFolderId());
1060    
1061                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
1062    
1063                                    if (trashVersion != null) {
1064                                            oldStatus = trashVersion.getStatus();
1065                                    }
1066    
1067                                    folder.setStatus(oldStatus);
1068    
1069                                    journalFolderPersistence.update(folder);
1070    
1071                                    // Folders and articles
1072    
1073                                    List<Object> curFoldersAndArticles = getFoldersAndArticles(
1074                                            folder.getGroupId(), folder.getFolderId(),
1075                                            WorkflowConstants.STATUS_IN_TRASH);
1076    
1077                                    restoreDependentsFromTrash(curFoldersAndArticles, trashEntryId);
1078    
1079                                    // Trash
1080    
1081                                    if (trashVersion != null) {
1082                                            trashVersionLocalService.deleteTrashVersion(trashVersion);
1083                                    }
1084    
1085                                    // Asset
1086    
1087                                    assetEntryLocalService.updateVisible(
1088                                            JournalFolder.class.getName(), folder.getFolderId(), true);
1089    
1090                                    // Indexer
1091    
1092                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1093                                            JournalFolder.class);
1094    
1095                                    indexer.reindex(folder);
1096                            }
1097                    }
1098            }
1099    
1100            protected void validateFolder(
1101                            long folderId, long groupId, long parentFolderId, String name)
1102                    throws PortalException, SystemException {
1103    
1104                    validateFolderName(name);
1105    
1106                    JournalFolder folder = journalFolderPersistence.fetchByG_P_N(
1107                            groupId, parentFolderId, name);
1108    
1109                    if ((folder != null) && (folder.getFolderId() != folderId)) {
1110                            throw new DuplicateFolderNameException(name);
1111                    }
1112            }
1113    
1114            protected void validateFolderName(String name) throws PortalException {
1115                    if (!AssetUtil.isValidWord(name)) {
1116                            throw new FolderNameException();
1117                    }
1118    
1119                    if (name.contains("\\\\") || name.contains("//")) {
1120                            throw new FolderNameException();
1121                    }
1122            }
1123    
1124    }