001
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
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
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
108
109 resourceLocalService.addModelResources(folder, serviceContext);
110
111
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
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
156
157 journalFolderPersistence.remove(folder);
158
159
160
161 resourceLocalService.deleteResource(
162 folder, ResourceConstants.SCOPE_INDIVIDUAL);
163
164
165
166 journalArticleLocalService.deleteArticles(
167 folder.getGroupId(), folder.getFolderId(), includeTrashedEntries);
168
169
170
171 assetEntryLocalService.deleteEntry(
172 JournalFolder.class.getName(), folder.getFolderId());
173
174
175
176 expandoValueLocalService.deleteValues(
177 JournalFolder.class.getName(), folder.getFolderId());
178
179
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
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
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
568
569 if (trashVersion != null) {
570 trashVersionLocalService.deleteTrashVersion(trashVersion);
571 }
572
573
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
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
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
617
618 List<Object> foldersAndArticles =
619 journalFolderLocalService.getFoldersAndArticles(
620 folder.getGroupId(), folder.getFolderId());
621
622 moveDependentsToTrash(foldersAndArticles, trashEntry.getEntryId());
623
624
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
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
714
715 List<Object> foldersAndArticles =
716 journalFolderLocalService.getFoldersAndArticles(
717 folder.getGroupId(), folder.getFolderId(),
718 WorkflowConstants.STATUS_IN_TRASH);
719
720 restoreDependentsFromTrash(foldersAndArticles);
721
722
723
724 trashEntryLocalService.deleteEntry(
725 JournalFolder.class.getName(), folder.getFolderId());
726
727
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
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
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
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
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
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
1035
1036 updateAsset(
1037 userId, folder, serviceContext.getAssetCategoryIds(),
1038 serviceContext.getAssetTagNames(),
1039 serviceContext.getAssetLinkEntryIds());
1040
1041
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
1151
1152 JournalArticle article = (JournalArticle)object;
1153
1154 if (article.getStatus() == WorkflowConstants.STATUS_IN_TRASH) {
1155 continue;
1156 }
1157
1158
1159
1160 List<JournalArticle> articles =
1161 journalArticlePersistence.findByG_A(
1162 article.getGroupId(), article.getArticleId());
1163
1164 for (JournalArticle curArticle : articles) {
1165
1166
1167
1168 int curArticleOldStatus = curArticle.getStatus();
1169
1170 curArticle.setStatus(WorkflowConstants.STATUS_IN_TRASH);
1171
1172 journalArticlePersistence.update(curArticle);
1173
1174
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
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
1207
1208 assetEntryLocalService.updateVisible(
1209 JournalArticle.class.getName(),
1210 article.getResourcePrimKey(), false);
1211
1212
1213
1214 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1215 JournalArticle.class);
1216
1217 indexer.reindex(article);
1218 }
1219 else if (object instanceof JournalFolder) {
1220
1221
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
1236
1237 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
1238 trashVersionLocalService.addTrashVersion(
1239 trashEntryId, JournalFolder.class.getName(),
1240 folder.getFolderId(), oldStatus, null);
1241 }
1242
1243
1244
1245 List<Object> curFoldersAndArticles = getFoldersAndArticles(
1246 folder.getGroupId(), folder.getFolderId());
1247
1248 moveDependentsToTrash(curFoldersAndArticles, trashEntryId);
1249
1250
1251
1252 assetEntryLocalService.updateVisible(
1253 JournalFolder.class.getName(), folder.getFolderId(), false);
1254
1255
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
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
1290
1291 List<JournalArticle> articles =
1292 journalArticlePersistence.findByG_A(
1293 article.getGroupId(), article.getArticleId());
1294
1295 for (JournalArticle curArticle : articles) {
1296
1297
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
1313
1314 if (trashVersion != null) {
1315 trashVersionLocalService.deleteTrashVersion(
1316 trashVersion);
1317 }
1318 }
1319
1320
1321
1322 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
1323 assetEntryLocalService.updateVisible(
1324 JournalArticle.class.getName(),
1325 article.getResourcePrimKey(), true);
1326 }
1327
1328
1329
1330 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1331 JournalArticle.class);
1332
1333 indexer.reindex(article);
1334 }
1335 else if (object instanceof JournalFolder) {
1336
1337
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
1360
1361 List<Object> curFoldersAndArticles = getFoldersAndArticles(
1362 folder.getGroupId(), folder.getFolderId(),
1363 WorkflowConstants.STATUS_IN_TRASH);
1364
1365 restoreDependentsFromTrash(curFoldersAndArticles);
1366
1367
1368
1369 if (trashVersion != null) {
1370 trashVersionLocalService.deleteTrashVersion(trashVersion);
1371 }
1372
1373
1374
1375 assetEntryLocalService.updateVisible(
1376 JournalFolder.class.getName(), folder.getFolderId(), true);
1377
1378
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 }