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