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