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