001
014
015 package com.liferay.portlet.wiki.service.impl;
016
017 import com.liferay.portal.kernel.configuration.Filter;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.search.Indexer;
023 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
024 import com.liferay.portal.kernel.systemevent.SystemEvent;
025 import com.liferay.portal.kernel.util.InstancePool;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.StringPool;
028 import com.liferay.portal.kernel.util.StringUtil;
029 import com.liferay.portal.kernel.util.UnicodeProperties;
030 import com.liferay.portal.kernel.util.Validator;
031 import com.liferay.portal.kernel.workflow.WorkflowConstants;
032 import com.liferay.portal.model.Group;
033 import com.liferay.portal.model.ResourceConstants;
034 import com.liferay.portal.model.SystemEventConstants;
035 import com.liferay.portal.model.User;
036 import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
037 import com.liferay.portal.service.ServiceContext;
038 import com.liferay.portal.util.PortletKeys;
039 import com.liferay.portal.util.PropsUtil;
040 import com.liferay.portal.util.PropsValues;
041 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
042 import com.liferay.portlet.trash.model.TrashEntry;
043 import com.liferay.portlet.trash.model.TrashVersion;
044 import com.liferay.portlet.trash.util.TrashUtil;
045 import com.liferay.portlet.wiki.DuplicateNodeNameException;
046 import com.liferay.portlet.wiki.NodeNameException;
047 import com.liferay.portlet.wiki.importers.WikiImporter;
048 import com.liferay.portlet.wiki.model.WikiNode;
049 import com.liferay.portlet.wiki.model.WikiPage;
050 import com.liferay.portlet.wiki.service.base.WikiNodeLocalServiceBaseImpl;
051 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
052 import com.liferay.portlet.wiki.util.WikiCacheUtil;
053
054 import java.io.InputStream;
055
056 import java.util.ArrayList;
057 import java.util.Date;
058 import java.util.HashMap;
059 import java.util.List;
060 import java.util.Map;
061
062
070 public class WikiNodeLocalServiceImpl extends WikiNodeLocalServiceBaseImpl {
071
072 @Override
073 public WikiNode addDefaultNode(long userId, ServiceContext serviceContext)
074 throws PortalException, SystemException {
075
076 return addNode(
077 userId, PropsValues.WIKI_INITIAL_NODE_NAME, StringPool.BLANK,
078 serviceContext);
079 }
080
081 @Override
082 public WikiNode addNode(
083 long userId, String name, String description,
084 ServiceContext serviceContext)
085 throws PortalException, SystemException {
086
087
088
089 User user = userPersistence.findByPrimaryKey(userId);
090 long groupId = serviceContext.getScopeGroupId();
091 Date now = new Date();
092
093 validate(groupId, name);
094
095 long nodeId = counterLocalService.increment();
096
097 WikiNode node = wikiNodePersistence.create(nodeId);
098
099 node.setUuid(serviceContext.getUuid());
100 node.setGroupId(groupId);
101 node.setCompanyId(user.getCompanyId());
102 node.setUserId(user.getUserId());
103 node.setUserName(user.getFullName());
104 node.setCreateDate(serviceContext.getCreateDate(now));
105 node.setModifiedDate(serviceContext.getModifiedDate(now));
106 node.setName(name);
107 node.setDescription(description);
108
109 try {
110 wikiNodePersistence.update(node);
111 }
112 catch (SystemException se) {
113 if (_log.isWarnEnabled()) {
114 _log.warn(
115 "Add failed, fetch {groupId=" + groupId + ", name=" +
116 name + "}");
117 }
118
119 node = wikiNodePersistence.fetchByG_N(groupId, name, false);
120
121 if (node == null) {
122 throw se;
123 }
124
125 return node;
126 }
127
128
129
130 if (serviceContext.isAddGroupPermissions() ||
131 serviceContext.isAddGuestPermissions()) {
132
133 addNodeResources(
134 node, serviceContext.isAddGroupPermissions(),
135 serviceContext.isAddGuestPermissions());
136 }
137 else {
138 addNodeResources(
139 node, serviceContext.getGroupPermissions(),
140 serviceContext.getGuestPermissions());
141 }
142
143 return node;
144 }
145
146 @Override
147 public void addNodeResources(
148 long nodeId, boolean addGroupPermissions,
149 boolean addGuestPermissions)
150 throws PortalException, SystemException {
151
152 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
153
154 addNodeResources(node, addGroupPermissions, addGuestPermissions);
155 }
156
157 @Override
158 public void addNodeResources(
159 long nodeId, String[] groupPermissions, String[] guestPermissions)
160 throws PortalException, SystemException {
161
162 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
163
164 addNodeResources(node, groupPermissions, guestPermissions);
165 }
166
167 @Override
168 public void addNodeResources(
169 WikiNode node, boolean addGroupPermissions,
170 boolean addGuestPermissions)
171 throws PortalException, SystemException {
172
173 resourceLocalService.addResources(
174 node.getCompanyId(), node.getGroupId(), node.getUserId(),
175 WikiNode.class.getName(), node.getNodeId(), false,
176 addGroupPermissions, addGuestPermissions);
177 }
178
179 @Override
180 public void addNodeResources(
181 WikiNode node, String[] groupPermissions, String[] guestPermissions)
182 throws PortalException, SystemException {
183
184 resourceLocalService.addModelResources(
185 node.getCompanyId(), node.getGroupId(), node.getUserId(),
186 WikiNode.class.getName(), node.getNodeId(), groupPermissions,
187 guestPermissions);
188 }
189
190 @Override
191 public void deleteNode(long nodeId)
192 throws PortalException, SystemException {
193
194 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
195
196 wikiNodeLocalService.deleteNode(node);
197 }
198
199 @Override
200 @SystemEvent(
201 action = SystemEventConstants.ACTION_SKIP,
202 type = SystemEventConstants.TYPE_DELETE)
203 public void deleteNode(WikiNode node)
204 throws PortalException, SystemException {
205
206
207
208 wikiPageLocalService.deletePages(node.getNodeId());
209
210
211
212 wikiNodePersistence.remove(node);
213
214
215
216 resourceLocalService.deleteResource(
217 node.getCompanyId(), WikiNode.class.getName(),
218 ResourceConstants.SCOPE_INDIVIDUAL, node.getNodeId());
219
220
221
222 long folderId = node.getAttachmentsFolderId();
223
224 if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
225 PortletFileRepositoryUtil.deleteFolder(folderId);
226 }
227
228
229
230 subscriptionLocalService.deleteSubscriptions(
231 node.getCompanyId(), WikiNode.class.getName(), node.getNodeId());
232
233 if (node.isInTrash()) {
234 node.setName(TrashUtil.getOriginalTitle(node.getName()));
235
236
237
238 trashEntryLocalService.deleteEntry(
239 WikiNode.class.getName(), node.getNodeId());
240
241
242
243 Indexer wikiNodeIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
244 WikiNode.class);
245
246 wikiNodeIndexer.delete(node);
247 }
248
249
250
251 Indexer wikiPageIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
252 WikiPage.class);
253
254 wikiPageIndexer.delete(node);
255 }
256
257 @Override
258 public void deleteNodes(long groupId)
259 throws PortalException, SystemException {
260
261 List<WikiNode> nodes = wikiNodePersistence.findByGroupId(groupId);
262
263 for (WikiNode node : nodes) {
264 wikiNodeLocalService.deleteNode(node);
265 }
266
267 PortletFileRepositoryUtil.deletePortletRepository(
268 groupId, PortletKeys.WIKI);
269 }
270
271 @Override
272 public WikiNode fetchNode(long groupId, String name)
273 throws SystemException {
274
275 return wikiNodePersistence.fetchByG_N(groupId, name);
276 }
277
278 @Override
279 public WikiNode fetchNodeByUuidAndGroupId(String uuid, long groupId)
280 throws SystemException {
281
282 return wikiNodePersistence.fetchByUUID_G(uuid, groupId);
283 }
284
285 @Override
286 public List<WikiNode> getCompanyNodes(long companyId, int start, int end)
287 throws SystemException {
288
289 return wikiNodePersistence.findByC_S(
290 companyId, WorkflowConstants.STATUS_APPROVED, start, end);
291 }
292
293 @Override
294 public List<WikiNode> getCompanyNodes(
295 long companyId, int status, int start, int end)
296 throws SystemException {
297
298 return wikiNodePersistence.findByC_S(companyId, status, start, end);
299 }
300
301 @Override
302 public int getCompanyNodesCount(long companyId) throws SystemException {
303 return wikiNodePersistence.countByC_S(
304 companyId, WorkflowConstants.STATUS_APPROVED);
305 }
306
307 @Override
308 public int getCompanyNodesCount(long companyId, int status)
309 throws SystemException {
310
311 return wikiNodePersistence.countByC_S(companyId, status);
312 }
313
314 @Override
315 public WikiNode getNode(long nodeId)
316 throws PortalException, SystemException {
317
318 return wikiNodePersistence.findByPrimaryKey(nodeId);
319 }
320
321 @Override
322 public WikiNode getNode(long groupId, String nodeName)
323 throws PortalException, SystemException {
324
325 return wikiNodePersistence.findByG_N(groupId, nodeName);
326 }
327
328 @Override
329 public List<WikiNode> getNodes(long groupId)
330 throws PortalException, SystemException {
331
332 return getNodes(groupId, WorkflowConstants.STATUS_APPROVED);
333 }
334
335 @Override
336 public List<WikiNode> getNodes(long groupId, int status)
337 throws PortalException, SystemException {
338
339 List<WikiNode> nodes = wikiNodePersistence.findByG_S(groupId, status);
340
341 if (nodes.isEmpty()) {
342 nodes = addDefaultNode(groupId);
343 }
344
345 return nodes;
346 }
347
348 @Override
349 public List<WikiNode> getNodes(long groupId, int start, int end)
350 throws PortalException, SystemException {
351
352 return getNodes(groupId, WorkflowConstants.STATUS_APPROVED, start, end);
353 }
354
355 @Override
356 public List<WikiNode> getNodes(long groupId, int status, int start, int end)
357 throws PortalException, SystemException {
358
359 List<WikiNode> nodes = wikiNodePersistence.findByG_S(
360 groupId, status, start, end);
361
362 if (nodes.isEmpty()) {
363 nodes = addDefaultNode(groupId);
364 }
365
366 return nodes;
367 }
368
369 @Override
370 public int getNodesCount(long groupId) throws SystemException {
371 return wikiNodePersistence.countByG_S(
372 groupId, WorkflowConstants.STATUS_APPROVED);
373 }
374
375 @Override
376 public int getNodesCount(long groupId, int status) throws SystemException {
377 return wikiNodePersistence.countByG_S(groupId, status);
378 }
379
380 @Override
381 public void importPages(
382 long userId, long nodeId, String importer,
383 InputStream[] inputStreams, Map<String, String[]> options)
384 throws PortalException, SystemException {
385
386 WikiNode node = getNode(nodeId);
387
388 WikiImporter wikiImporter = getWikiImporter(importer);
389
390 wikiImporter.importPages(userId, node, inputStreams, options);
391 }
392
393 @Override
394 public WikiNode moveNodeToTrash(long userId, long nodeId)
395 throws PortalException, SystemException {
396
397 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
398
399 return moveNodeToTrash(userId, node);
400 }
401
402 @Override
403 public WikiNode moveNodeToTrash(long userId, WikiNode node)
404 throws PortalException, SystemException {
405
406
407
408 int oldStatus = node.getStatus();
409
410 node = updateStatus(
411 userId, node, WorkflowConstants.STATUS_IN_TRASH,
412 new ServiceContext());
413
414
415
416 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
417
418 typeSettingsProperties.put("title", node.getName());
419
420 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
421 userId, node.getGroupId(), WikiNode.class.getName(),
422 node.getNodeId(), node.getUuid(), null, oldStatus, null,
423 typeSettingsProperties);
424
425 node.setName(TrashUtil.getTrashTitle(trashEntry.getEntryId()));
426
427 wikiNodePersistence.update(node);
428
429
430
431 moveDependentsToTrash(node.getNodeId(), trashEntry.getEntryId());
432
433 return node;
434 }
435
436 @Override
437 public void restoreNodeFromTrash(long userId, WikiNode node)
438 throws PortalException, SystemException {
439
440
441
442 node.setName(TrashUtil.getOriginalTitle(node.getName()));
443
444 wikiNodePersistence.update(node);
445
446 TrashEntry trashEntry = trashEntryLocalService.getEntry(
447 WikiNode.class.getName(), node.getNodeId());
448
449 updateStatus(
450 userId, node, trashEntry.getStatus(), new ServiceContext());
451
452
453
454 restoreDependentFromTrash(node.getNodeId(), trashEntry.getEntryId());
455
456
457
458 trashEntryLocalService.deleteEntry(trashEntry);
459 }
460
461 @Override
462 public void subscribeNode(long userId, long nodeId)
463 throws PortalException, SystemException {
464
465 WikiNode node = getNode(nodeId);
466
467 subscriptionLocalService.addSubscription(
468 userId, node.getGroupId(), WikiNode.class.getName(), nodeId);
469 }
470
471 @Override
472 public void unsubscribeNode(long userId, long nodeId)
473 throws PortalException, SystemException {
474
475 subscriptionLocalService.deleteSubscription(
476 userId, WikiNode.class.getName(), nodeId);
477 }
478
479 @Override
480 public WikiNode updateNode(
481 long nodeId, String name, String description,
482 ServiceContext serviceContext)
483 throws PortalException, SystemException {
484
485 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
486
487 validate(nodeId, node.getGroupId(), name);
488
489 node.setModifiedDate(serviceContext.getModifiedDate(null));
490 node.setName(name);
491 node.setDescription(description);
492
493 wikiNodePersistence.update(node);
494
495 return node;
496 }
497
498 @Override
499 public WikiNode updateStatus(
500 long userId, WikiNode node, int status,
501 ServiceContext serviceContext)
502 throws PortalException, SystemException {
503
504
505
506 User user = userPersistence.findByPrimaryKey(userId);
507
508 Date now = new Date();
509
510 node.setStatus(status);
511 node.setStatusByUserId(userId);
512 node.setStatusByUserName(user.getFullName());
513 node.setStatusDate(now);
514
515 wikiNodePersistence.update(node);
516
517
518
519 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
520 WikiNode.class);
521
522 indexer.reindex(node);
523
524 return node;
525 }
526
527 protected List<WikiNode> addDefaultNode(long groupId)
528 throws PortalException, SystemException {
529
530 Group group = groupPersistence.findByPrimaryKey(groupId);
531
532 long defaultUserId = userLocalService.getDefaultUserId(
533 group.getCompanyId());
534
535 ServiceContext serviceContext = new ServiceContext();
536
537 serviceContext.setAddGroupPermissions(true);
538 serviceContext.setAddGuestPermissions(true);
539 serviceContext.setScopeGroupId(groupId);
540
541 WikiNode node = wikiNodeLocalService.addDefaultNode(
542 defaultUserId, serviceContext);
543
544 List<WikiNode> nodes = new ArrayList<WikiNode>(1);
545
546 nodes.add(node);
547
548 return nodes;
549 }
550
551 protected WikiImporter getWikiImporter(String importer)
552 throws SystemException {
553
554 WikiImporter wikiImporter = _wikiImporters.get(importer);
555
556 if (wikiImporter == null) {
557 String importerClass = PropsUtil.get(
558 PropsKeys.WIKI_IMPORTERS_CLASS, new Filter(importer));
559
560 if (importerClass != null) {
561 wikiImporter = (WikiImporter)InstancePool.get(importerClass);
562
563 _wikiImporters.put(importer, wikiImporter);
564 }
565
566 if (importer == null) {
567 throw new SystemException(
568 "Unable to instantiate wiki importer class " +
569 importerClass);
570 }
571 }
572
573 return wikiImporter;
574 }
575
576 protected void moveDependentsToTrash(long nodeId, long trashEntryId)
577 throws PortalException, SystemException {
578
579 List<WikiPage> pages = wikiPagePersistence.findByNodeId(nodeId);
580
581 for (WikiPage page : pages) {
582
583
584
585 int oldStatus = page.getStatus();
586
587 if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
588 continue;
589 }
590
591
592
593 List<WikiPage> versionPages = wikiPagePersistence.findByR_N(
594 page.getResourcePrimKey(), page.getNodeId());
595
596 for (WikiPage versionPage : versionPages) {
597
598
599
600 int versionPageOldStatus = versionPage.getStatus();
601
602 versionPage.setStatus(WorkflowConstants.STATUS_IN_TRASH);
603
604 wikiPagePersistence.update(versionPage);
605
606
607
608 int status = versionPageOldStatus;
609
610 if (versionPageOldStatus ==
611 WorkflowConstants.STATUS_PENDING) {
612
613 status = WorkflowConstants.STATUS_DRAFT;
614 }
615
616 if (versionPageOldStatus !=
617 WorkflowConstants.STATUS_APPROVED) {
618
619 trashVersionLocalService.addTrashVersion(
620 trashEntryId, WikiPage.class.getName(),
621 versionPage.getPageId(), status);
622 }
623 }
624
625
626
627 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
628 assetEntryLocalService.updateVisible(
629 WikiPage.class.getName(), page.getResourcePrimKey(), false);
630 }
631
632
633
634 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
635 WikiPage.class);
636
637 indexer.reindex(page);
638
639
640
641 if (WikiCacheThreadLocal.isClearCache()) {
642 WikiCacheUtil.clearCache(page.getNodeId());
643 }
644
645
646
647 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
648 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
649 page.getCompanyId(), page.getGroupId(),
650 WikiPage.class.getName(), page.getResourcePrimKey());
651 }
652 }
653 }
654
655 protected void restoreDependentFromTrash(long nodeId, long trashEntryId)
656 throws PortalException, SystemException {
657
658 List<WikiPage> pages = wikiPagePersistence.findByNodeId(nodeId);
659
660 for (WikiPage page : pages) {
661
662
663
664 TrashEntry trashEntry = trashEntryLocalService.fetchEntry(
665 WikiPage.class.getName(), page.getResourcePrimKey());
666
667 if (trashEntry != null) {
668 continue;
669 }
670
671 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
672 trashEntryId, WikiPage.class.getName(), page.getPageId());
673
674 int oldStatus = WorkflowConstants.STATUS_APPROVED;
675
676 if (trashVersion != null) {
677 oldStatus = trashVersion.getStatus();
678 }
679
680
681
682 List<WikiPage> versionPages = wikiPagePersistence.findByR_N(
683 page.getResourcePrimKey(), page.getNodeId());
684
685 for (WikiPage versionPage : versionPages) {
686
687
688
689 trashVersion = trashVersionLocalService.fetchVersion(
690 trashEntryId, WikiPage.class.getName(),
691 versionPage.getPageId());
692
693 int versionPageOldStatus = WorkflowConstants.STATUS_APPROVED;
694
695 if (trashVersion != null) {
696 versionPageOldStatus = trashVersion.getStatus();
697 }
698
699 versionPage.setStatus(versionPageOldStatus);
700
701 wikiPagePersistence.update(versionPage);
702
703
704
705 if (trashVersion != null) {
706 trashVersionLocalService.deleteTrashVersion(trashVersion);
707 }
708 }
709
710
711
712 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
713 assetEntryLocalService.updateVisible(
714 WikiPage.class.getName(), page.getResourcePrimKey(), true);
715 }
716
717
718
719 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
720 WikiPage.class);
721
722 indexer.reindex(page);
723 }
724 }
725
726 protected void validate(long nodeId, long groupId, String name)
727 throws PortalException, SystemException {
728
729 if (StringUtil.equalsIgnoreCase(name, "tag")) {
730 throw new NodeNameException(name + " is reserved");
731 }
732
733 if (Validator.isNull(name)) {
734 throw new NodeNameException();
735 }
736
737 WikiNode node = wikiNodePersistence.fetchByG_N(groupId, name);
738
739 if ((node != null) && (node.getNodeId() != nodeId)) {
740 throw new DuplicateNodeNameException();
741 }
742 }
743
744 protected void validate(long groupId, String name)
745 throws PortalException, SystemException {
746
747 validate(0, groupId, name);
748 }
749
750 private static Log _log = LogFactoryUtil.getLog(
751 WikiNodeLocalServiceImpl.class);
752
753 private Map<String, WikiImporter> _wikiImporters =
754 new HashMap<String, WikiImporter>();
755
756 }