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 indexer = IndexerRegistryUtil.nullSafeGetIndexer(
244 WikiNode.class);
245
246 indexer.delete(node);
247 }
248 }
249
250 @Override
251 public void deleteNodes(long groupId)
252 throws PortalException, SystemException {
253
254 List<WikiNode> nodes = wikiNodePersistence.findByGroupId(groupId);
255
256 for (WikiNode node : nodes) {
257 wikiNodeLocalService.deleteNode(node);
258 }
259
260 PortletFileRepositoryUtil.deletePortletRepository(
261 groupId, PortletKeys.WIKI);
262 }
263
264 @Override
265 public WikiNode fetchNode(long groupId, String name)
266 throws SystemException {
267
268 return wikiNodePersistence.fetchByG_N(groupId, name);
269 }
270
271 @Override
272 public WikiNode fetchNodeByUuidAndGroupId(String uuid, long groupId)
273 throws SystemException {
274
275 return wikiNodePersistence.fetchByUUID_G(uuid, groupId);
276 }
277
278 @Override
279 public List<WikiNode> getCompanyNodes(long companyId, int start, int end)
280 throws SystemException {
281
282 return wikiNodePersistence.findByC_S(
283 companyId, WorkflowConstants.STATUS_APPROVED, start, end);
284 }
285
286 @Override
287 public List<WikiNode> getCompanyNodes(
288 long companyId, int status, int start, int end)
289 throws SystemException {
290
291 return wikiNodePersistence.findByC_S(companyId, status, start, end);
292 }
293
294 @Override
295 public int getCompanyNodesCount(long companyId) throws SystemException {
296 return wikiNodePersistence.countByC_S(
297 companyId, WorkflowConstants.STATUS_APPROVED);
298 }
299
300 @Override
301 public int getCompanyNodesCount(long companyId, int status)
302 throws SystemException {
303
304 return wikiNodePersistence.countByC_S(companyId, status);
305 }
306
307 @Override
308 public WikiNode getNode(long nodeId)
309 throws PortalException, SystemException {
310
311 return wikiNodePersistence.findByPrimaryKey(nodeId);
312 }
313
314 @Override
315 public WikiNode getNode(long groupId, String nodeName)
316 throws PortalException, SystemException {
317
318 return wikiNodePersistence.findByG_N(groupId, nodeName);
319 }
320
321 @Override
322 public List<WikiNode> getNodes(long groupId)
323 throws PortalException, SystemException {
324
325 return getNodes(groupId, WorkflowConstants.STATUS_APPROVED);
326 }
327
328 @Override
329 public List<WikiNode> getNodes(long groupId, int status)
330 throws PortalException, SystemException {
331
332 List<WikiNode> nodes = wikiNodePersistence.findByG_S(groupId, status);
333
334 if (nodes.isEmpty()) {
335 nodes = addDefaultNode(groupId);
336 }
337
338 return nodes;
339 }
340
341 @Override
342 public List<WikiNode> getNodes(long groupId, int start, int end)
343 throws PortalException, SystemException {
344
345 return getNodes(groupId, WorkflowConstants.STATUS_APPROVED, start, end);
346 }
347
348 @Override
349 public List<WikiNode> getNodes(long groupId, int status, int start, int end)
350 throws PortalException, SystemException {
351
352 List<WikiNode> nodes = wikiNodePersistence.findByG_S(
353 groupId, status, start, end);
354
355 if (nodes.isEmpty()) {
356 nodes = addDefaultNode(groupId);
357 }
358
359 return nodes;
360 }
361
362 @Override
363 public int getNodesCount(long groupId) throws SystemException {
364 return wikiNodePersistence.countByG_S(
365 groupId, WorkflowConstants.STATUS_APPROVED);
366 }
367
368 @Override
369 public int getNodesCount(long groupId, int status) throws SystemException {
370 return wikiNodePersistence.countByG_S(groupId, status);
371 }
372
373 @Override
374 public void importPages(
375 long userId, long nodeId, String importer,
376 InputStream[] inputStreams, Map<String, String[]> options)
377 throws PortalException, SystemException {
378
379 WikiNode node = getNode(nodeId);
380
381 WikiImporter wikiImporter = getWikiImporter(importer);
382
383 wikiImporter.importPages(userId, node, inputStreams, options);
384 }
385
386 @Override
387 public WikiNode moveNodeToTrash(long userId, long nodeId)
388 throws PortalException, SystemException {
389
390 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
391
392 return moveNodeToTrash(userId, node);
393 }
394
395 @Override
396 public WikiNode moveNodeToTrash(long userId, WikiNode node)
397 throws PortalException, SystemException {
398
399
400
401 int oldStatus = node.getStatus();
402
403 node = updateStatus(
404 userId, node, WorkflowConstants.STATUS_IN_TRASH,
405 new ServiceContext());
406
407
408
409 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
410
411 typeSettingsProperties.put("title", node.getName());
412
413 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
414 userId, node.getGroupId(), WikiNode.class.getName(),
415 node.getNodeId(), node.getUuid(), null, oldStatus, null,
416 typeSettingsProperties);
417
418 node.setName(TrashUtil.getTrashTitle(trashEntry.getEntryId()));
419
420 wikiNodePersistence.update(node);
421
422
423
424 moveDependentsToTrash(node.getNodeId(), trashEntry.getEntryId());
425
426 return node;
427 }
428
429 @Override
430 public void restoreNodeFromTrash(long userId, WikiNode node)
431 throws PortalException, SystemException {
432
433
434
435 node.setName(TrashUtil.getOriginalTitle(node.getName()));
436
437 wikiNodePersistence.update(node);
438
439 TrashEntry trashEntry = trashEntryLocalService.getEntry(
440 WikiNode.class.getName(), node.getNodeId());
441
442 updateStatus(
443 userId, node, trashEntry.getStatus(), new ServiceContext());
444
445
446
447 restoreDependentFromTrash(node.getNodeId(), trashEntry.getEntryId());
448
449
450
451 trashEntryLocalService.deleteEntry(trashEntry);
452 }
453
454 @Override
455 public void subscribeNode(long userId, long nodeId)
456 throws PortalException, SystemException {
457
458 WikiNode node = getNode(nodeId);
459
460 subscriptionLocalService.addSubscription(
461 userId, node.getGroupId(), WikiNode.class.getName(), nodeId);
462 }
463
464 @Override
465 public void unsubscribeNode(long userId, long nodeId)
466 throws PortalException, SystemException {
467
468 subscriptionLocalService.deleteSubscription(
469 userId, WikiNode.class.getName(), nodeId);
470 }
471
472 @Override
473 public WikiNode updateNode(
474 long nodeId, String name, String description,
475 ServiceContext serviceContext)
476 throws PortalException, SystemException {
477
478 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
479
480 validate(nodeId, node.getGroupId(), name);
481
482 node.setModifiedDate(serviceContext.getModifiedDate(null));
483 node.setName(name);
484 node.setDescription(description);
485
486 wikiNodePersistence.update(node);
487
488 return node;
489 }
490
491 @Override
492 public WikiNode updateStatus(
493 long userId, WikiNode node, int status,
494 ServiceContext serviceContext)
495 throws PortalException, SystemException {
496
497
498
499 User user = userPersistence.findByPrimaryKey(userId);
500
501 Date now = new Date();
502
503 node.setStatus(status);
504 node.setStatusByUserId(userId);
505 node.setStatusByUserName(user.getFullName());
506 node.setStatusDate(now);
507
508 wikiNodePersistence.update(node);
509
510
511
512 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
513 WikiNode.class);
514
515 indexer.reindex(node);
516
517 return node;
518 }
519
520 protected List<WikiNode> addDefaultNode(long groupId)
521 throws PortalException, SystemException {
522
523 Group group = groupPersistence.findByPrimaryKey(groupId);
524
525 long defaultUserId = userLocalService.getDefaultUserId(
526 group.getCompanyId());
527
528 ServiceContext serviceContext = new ServiceContext();
529
530 serviceContext.setAddGroupPermissions(true);
531 serviceContext.setAddGuestPermissions(true);
532 serviceContext.setScopeGroupId(groupId);
533
534 WikiNode node = wikiNodeLocalService.addDefaultNode(
535 defaultUserId, serviceContext);
536
537 List<WikiNode> nodes = new ArrayList<WikiNode>(1);
538
539 nodes.add(node);
540
541 return nodes;
542 }
543
544 protected WikiImporter getWikiImporter(String importer)
545 throws SystemException {
546
547 WikiImporter wikiImporter = _wikiImporters.get(importer);
548
549 if (wikiImporter == null) {
550 String importerClass = PropsUtil.get(
551 PropsKeys.WIKI_IMPORTERS_CLASS, new Filter(importer));
552
553 if (importerClass != null) {
554 wikiImporter = (WikiImporter)InstancePool.get(importerClass);
555
556 _wikiImporters.put(importer, wikiImporter);
557 }
558
559 if (importer == null) {
560 throw new SystemException(
561 "Unable to instantiate wiki importer class " +
562 importerClass);
563 }
564 }
565
566 return wikiImporter;
567 }
568
569 protected void moveDependentsToTrash(long nodeId, long trashEntryId)
570 throws PortalException, SystemException {
571
572 List<WikiPage> pages = wikiPagePersistence.findByNodeId(nodeId);
573
574 for (WikiPage page : pages) {
575
576
577
578 int oldStatus = page.getStatus();
579
580 if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
581 continue;
582 }
583
584
585
586 List<WikiPage> versionPages = wikiPagePersistence.findByR_N(
587 page.getResourcePrimKey(), page.getNodeId());
588
589 for (WikiPage versionPage : versionPages) {
590
591
592
593 int versionPageOldStatus = versionPage.getStatus();
594
595 versionPage.setStatus(WorkflowConstants.STATUS_IN_TRASH);
596
597 wikiPagePersistence.update(versionPage);
598
599
600
601 int status = versionPageOldStatus;
602
603 if (versionPageOldStatus ==
604 WorkflowConstants.STATUS_PENDING) {
605
606 status = WorkflowConstants.STATUS_DRAFT;
607 }
608
609 if (versionPageOldStatus !=
610 WorkflowConstants.STATUS_APPROVED) {
611
612 trashVersionLocalService.addTrashVersion(
613 trashEntryId, WikiPage.class.getName(),
614 versionPage.getPageId(), status, null);
615 }
616 }
617
618
619
620 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
621 assetEntryLocalService.updateVisible(
622 WikiPage.class.getName(), page.getResourcePrimKey(), false);
623 }
624
625
626
627 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
628 WikiPage.class);
629
630 indexer.reindex(page);
631
632
633
634 if (WikiCacheThreadLocal.isClearCache()) {
635 WikiCacheUtil.clearCache(page.getNodeId());
636 }
637
638
639
640 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
641 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
642 page.getCompanyId(), page.getGroupId(),
643 WikiPage.class.getName(), page.getResourcePrimKey());
644 }
645 }
646 }
647
648 protected void restoreDependentFromTrash(long nodeId, long trashEntryId)
649 throws PortalException, SystemException {
650
651 List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
652
653 for (WikiPage page : pages) {
654
655
656
657 TrashEntry trashEntry = trashEntryLocalService.fetchEntry(
658 WikiPage.class.getName(), page.getResourcePrimKey());
659
660 if (trashEntry != null) {
661 continue;
662 }
663
664 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
665 trashEntryId, WikiPage.class.getName(), page.getPageId());
666
667 int oldStatus = WorkflowConstants.STATUS_APPROVED;
668
669 if (trashVersion != null) {
670 oldStatus = trashVersion.getStatus();
671 }
672
673
674
675 List<WikiPage> versionPages = wikiPagePersistence.findByR_N(
676 page.getResourcePrimKey(), page.getNodeId());
677
678 for (WikiPage versionPage : versionPages) {
679
680
681
682 trashVersion = trashVersionLocalService.fetchVersion(
683 trashEntryId, WikiPage.class.getName(),
684 versionPage.getPageId());
685
686 int versionPageOldStatus = WorkflowConstants.STATUS_APPROVED;
687
688 if (trashVersion != null) {
689 versionPageOldStatus = trashVersion.getStatus();
690 }
691
692 versionPage.setStatus(versionPageOldStatus);
693
694 wikiPagePersistence.update(versionPage);
695
696
697
698 if (trashVersion != null) {
699 trashVersionLocalService.deleteTrashVersion(trashVersion);
700 }
701 }
702
703
704
705 if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
706 assetEntryLocalService.updateVisible(
707 WikiPage.class.getName(), page.getResourcePrimKey(), true);
708 }
709
710
711
712 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
713 WikiPage.class);
714
715 indexer.reindex(page);
716 }
717 }
718
719 protected void validate(long nodeId, long groupId, String name)
720 throws PortalException, SystemException {
721
722 if (StringUtil.equalsIgnoreCase(name, "tag")) {
723 throw new NodeNameException(name + " is reserved");
724 }
725
726 if (Validator.isNull(name)) {
727 throw new NodeNameException();
728 }
729
730 WikiNode node = wikiNodePersistence.fetchByG_N(groupId, name);
731
732 if ((node != null) && (node.getNodeId() != nodeId)) {
733 throw new DuplicateNodeNameException("{nodeId=" + nodeId + "}");
734 }
735 }
736
737 protected void validate(long groupId, String name)
738 throws PortalException, SystemException {
739
740 validate(0, groupId, name);
741 }
742
743 private static Log _log = LogFactoryUtil.getLog(
744 WikiNodeLocalServiceImpl.class);
745
746 private Map<String, WikiImporter> _wikiImporters =
747 new HashMap<String, WikiImporter>();
748
749 }