001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.util.InstancePool;
025    import com.liferay.portal.kernel.util.PropsKeys;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.workflow.WorkflowConstants;
029    import com.liferay.portal.model.Group;
030    import com.liferay.portal.model.ResourceConstants;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portal.util.PropsUtil;
034    import com.liferay.portal.util.PropsValues;
035    import com.liferay.portlet.trash.model.TrashEntry;
036    import com.liferay.portlet.trash.util.TrashUtil;
037    import com.liferay.portlet.wiki.DuplicateNodeNameException;
038    import com.liferay.portlet.wiki.NodeNameException;
039    import com.liferay.portlet.wiki.importers.WikiImporter;
040    import com.liferay.portlet.wiki.model.WikiNode;
041    import com.liferay.portlet.wiki.model.WikiPage;
042    import com.liferay.portlet.wiki.service.base.WikiNodeLocalServiceBaseImpl;
043    
044    import java.io.InputStream;
045    
046    import java.util.ArrayList;
047    import java.util.Date;
048    import java.util.HashMap;
049    import java.util.List;
050    import java.util.Map;
051    
052    /**
053     * @author Brian Wing Shun Chan
054     * @author Charles May
055     * @author Raymond Augé
056     */
057    public class WikiNodeLocalServiceImpl extends WikiNodeLocalServiceBaseImpl {
058    
059            public WikiNode addDefaultNode(long userId, ServiceContext serviceContext)
060                    throws PortalException, SystemException {
061    
062                    return addNode(
063                            userId, PropsValues.WIKI_INITIAL_NODE_NAME, StringPool.BLANK,
064                            serviceContext);
065            }
066    
067            public WikiNode addNode(
068                            long userId, String name, String description,
069                            ServiceContext serviceContext)
070                    throws PortalException, SystemException {
071    
072                    // Node
073    
074                    User user = userPersistence.findByPrimaryKey(userId);
075                    long groupId = serviceContext.getScopeGroupId();
076                    Date now = new Date();
077    
078                    validate(groupId, name);
079    
080                    long nodeId = counterLocalService.increment();
081    
082                    WikiNode node = wikiNodePersistence.create(nodeId);
083    
084                    node.setUuid(serviceContext.getUuid());
085                    node.setGroupId(groupId);
086                    node.setCompanyId(user.getCompanyId());
087                    node.setUserId(user.getUserId());
088                    node.setUserName(user.getFullName());
089                    node.setCreateDate(serviceContext.getCreateDate(now));
090                    node.setModifiedDate(serviceContext.getModifiedDate(now));
091                    node.setName(name);
092                    node.setDescription(description);
093    
094                    try {
095                            wikiNodePersistence.update(node);
096                    }
097                    catch (SystemException se) {
098                            if (_log.isWarnEnabled()) {
099                                    _log.warn(
100                                            "Add failed, fetch {groupId=" + groupId + ", name=" +
101                                                    name + "}");
102                            }
103    
104                            node = wikiNodePersistence.fetchByG_N(groupId, name, false);
105    
106                            if (node == null) {
107                                    throw se;
108                            }
109    
110                            return node;
111                    }
112    
113                    // Resources
114    
115                    if (serviceContext.isAddGroupPermissions() ||
116                            serviceContext.isAddGuestPermissions()) {
117    
118                            addNodeResources(
119                                    node, serviceContext.isAddGroupPermissions(),
120                                    serviceContext.isAddGuestPermissions());
121                    }
122                    else {
123                            addNodeResources(
124                                    node, serviceContext.getGroupPermissions(),
125                                    serviceContext.getGuestPermissions());
126                    }
127    
128                    return node;
129            }
130    
131            public void addNodeResources(
132                            long nodeId, boolean addGroupPermissions,
133                            boolean addGuestPermissions)
134                    throws PortalException, SystemException {
135    
136                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
137    
138                    addNodeResources(node, addGroupPermissions, addGuestPermissions);
139            }
140    
141            public void addNodeResources(
142                            long nodeId, String[] groupPermissions, String[] guestPermissions)
143                    throws PortalException, SystemException {
144    
145                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
146    
147                    addNodeResources(node, groupPermissions, guestPermissions);
148            }
149    
150            public void addNodeResources(
151                            WikiNode node, boolean addGroupPermissions,
152                            boolean addGuestPermissions)
153                    throws PortalException, SystemException {
154    
155                    resourceLocalService.addResources(
156                            node.getCompanyId(), node.getGroupId(), node.getUserId(),
157                            WikiNode.class.getName(), node.getNodeId(), false,
158                            addGroupPermissions, addGuestPermissions);
159            }
160    
161            public void addNodeResources(
162                            WikiNode node, String[] groupPermissions, String[] guestPermissions)
163                    throws PortalException, SystemException {
164    
165                    resourceLocalService.addModelResources(
166                            node.getCompanyId(), node.getGroupId(), node.getUserId(),
167                            WikiNode.class.getName(), node.getNodeId(), groupPermissions,
168                            guestPermissions);
169            }
170    
171            public void deleteNode(long nodeId)
172                    throws PortalException, SystemException {
173    
174                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
175    
176                    deleteNode(node);
177            }
178    
179            public void deleteNode(WikiNode node)
180                    throws PortalException, SystemException {
181    
182                    // Pages
183    
184                    wikiPageLocalService.deletePages(node.getNodeId());
185    
186                    // Node
187    
188                    wikiNodePersistence.remove(node);
189    
190                    // Resources
191    
192                    resourceLocalService.deleteResource(
193                            node.getCompanyId(), WikiNode.class.getName(),
194                            ResourceConstants.SCOPE_INDIVIDUAL, node.getNodeId());
195    
196                    // Subscriptions
197    
198                    subscriptionLocalService.deleteSubscriptions(
199                            node.getCompanyId(), WikiNode.class.getName(), node.getNodeId());
200    
201                    if (node.isInTrash()) {
202                            node.setName(TrashUtil.stripTrashNamespace(node.getName()));
203    
204                            // Trash
205    
206                            trashEntryLocalService.deleteEntry(
207                                    WikiNode.class.getName(), node.getNodeId());
208    
209                            // Indexer
210    
211                            Indexer wikiNodeIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
212                                    WikiNode.class);
213    
214                            wikiNodeIndexer.delete(node);
215                    }
216    
217                    // Indexer
218    
219                    Indexer wikiPageIndexer = IndexerRegistryUtil.nullSafeGetIndexer(
220                            WikiPage.class);
221    
222                    wikiPageIndexer.delete(node);
223            }
224    
225            public void deleteNodes(long groupId)
226                    throws PortalException, SystemException {
227    
228                    List<WikiNode> nodes = wikiNodePersistence.findByGroupId(groupId);
229    
230                    for (WikiNode node : nodes) {
231                            deleteNode(node);
232                    }
233            }
234    
235            public WikiNode fetchWikiNode(long groupId, String name)
236                    throws SystemException {
237    
238                    return wikiNodePersistence.fetchByG_N(groupId, name);
239            }
240    
241            public List<WikiNode> getCompanyNodes(long companyId, int start, int end)
242                    throws SystemException {
243    
244                    return wikiNodePersistence.findByC_S(
245                            companyId, WorkflowConstants.STATUS_APPROVED, start, end);
246            }
247    
248            public List<WikiNode> getCompanyNodes(
249                            long companyId, int status, int start, int end)
250                    throws SystemException {
251    
252                    return wikiNodePersistence.findByC_S(companyId, status, start, end);
253            }
254    
255            public int getCompanyNodesCount(long companyId) throws SystemException {
256                    return wikiNodePersistence.countByC_S(
257                            companyId, WorkflowConstants.STATUS_APPROVED);
258            }
259    
260            public int getCompanyNodesCount(long companyId, int status)
261                    throws SystemException {
262    
263                    return wikiNodePersistence.countByC_S(companyId, status);
264            }
265    
266            public WikiNode getNode(long nodeId)
267                    throws PortalException, SystemException {
268    
269                    return wikiNodePersistence.findByPrimaryKey(nodeId);
270            }
271    
272            public WikiNode getNode(long groupId, String nodeName)
273                    throws PortalException, SystemException {
274    
275                    return wikiNodePersistence.findByG_N(groupId, nodeName);
276            }
277    
278            public List<WikiNode> getNodes(long groupId)
279                    throws PortalException, SystemException {
280    
281                    return getNodes(groupId, WorkflowConstants.STATUS_APPROVED);
282            }
283    
284            public List<WikiNode> getNodes(long groupId, int status)
285                    throws PortalException, SystemException {
286    
287                    List<WikiNode> nodes = wikiNodePersistence.findByG_S(groupId, status);
288    
289                    if (nodes.isEmpty()) {
290                            nodes = addDefaultNode(groupId);
291                    }
292    
293                    return nodes;
294            }
295    
296            public List<WikiNode> getNodes(long groupId, int start, int end)
297                    throws PortalException, SystemException {
298    
299                    return getNodes(groupId, WorkflowConstants.STATUS_APPROVED, start, end);
300            }
301    
302            public List<WikiNode> getNodes(long groupId, int status, int start, int end)
303                    throws PortalException, SystemException {
304    
305                    List<WikiNode> nodes = wikiNodePersistence.findByG_S(
306                            groupId, status, start, end);
307    
308                    if (nodes.isEmpty()) {
309                            nodes = addDefaultNode(groupId);
310                    }
311    
312                    return nodes;
313            }
314    
315            public int getNodesCount(long groupId) throws SystemException {
316                    return wikiNodePersistence.countByG_S(
317                            groupId, WorkflowConstants.STATUS_APPROVED);
318            }
319    
320            public int getNodesCount(long groupId, int status) throws SystemException {
321                    return wikiNodePersistence.countByG_S(groupId, status);
322            }
323    
324            public void importPages(
325                            long userId, long nodeId, String importer,
326                            InputStream[] inputStreams, Map<String, String[]> options)
327                    throws PortalException, SystemException {
328    
329                    WikiNode node = getNode(nodeId);
330    
331                    WikiImporter wikiImporter = getWikiImporter(importer);
332    
333                    wikiImporter.importPages(userId, node, inputStreams, options);
334            }
335    
336            public WikiNode moveNodeToTrash(long userId, long nodeId)
337                    throws PortalException, SystemException {
338    
339                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
340    
341                    return moveNodeToTrash(userId, node);
342            }
343    
344            public WikiNode moveNodeToTrash(long userId, WikiNode node)
345                    throws PortalException, SystemException {
346    
347                    node.setName(TrashUtil.appendTrashNamespace(node.getName()));
348    
349                    wikiNodePersistence.update(node);
350    
351                    return updateStatus(
352                            userId, node, WorkflowConstants.STATUS_IN_TRASH,
353                            new ServiceContext());
354            }
355    
356            public void restoreNodeFromTrash(long userId, WikiNode node)
357                    throws PortalException, SystemException {
358    
359                    String name = TrashUtil.stripTrashNamespace(node.getName());
360    
361                    node.setName(name);
362    
363                    wikiNodePersistence.update(node);
364    
365                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
366                            WikiNode.class.getName(), node.getNodeId());
367    
368                    updateStatus(
369                            userId, node, trashEntry.getStatus(), new ServiceContext());
370            }
371    
372            public void subscribeNode(long userId, long nodeId)
373                    throws PortalException, SystemException {
374    
375                    WikiNode node = getNode(nodeId);
376    
377                    subscriptionLocalService.addSubscription(
378                            userId, node.getGroupId(), WikiNode.class.getName(), nodeId);
379            }
380    
381            public void unsubscribeNode(long userId, long nodeId)
382                    throws PortalException, SystemException {
383    
384                    subscriptionLocalService.deleteSubscription(
385                            userId, WikiNode.class.getName(), nodeId);
386            }
387    
388            public WikiNode updateNode(
389                            long nodeId, String name, String description,
390                            ServiceContext serviceContext)
391                    throws PortalException, SystemException {
392    
393                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
394    
395                    validate(nodeId, node.getGroupId(), name);
396    
397                    node.setModifiedDate(serviceContext.getModifiedDate(null));
398                    node.setName(name);
399                    node.setDescription(description);
400    
401                    wikiNodePersistence.update(node);
402    
403                    return node;
404            }
405    
406            public WikiNode updateStatus(
407                            long userId, WikiNode node, int status,
408                            ServiceContext serviceContext)
409                    throws PortalException, SystemException {
410    
411                    // Node
412    
413                    int oldStatus = node.getStatus();
414    
415                    User user = userPersistence.findByPrimaryKey(userId);
416    
417                    Date now = new Date();
418    
419                    node.setStatus(status);
420                    node.setStatusByUserId(userId);
421                    node.setStatusByUserName(user.getFullName());
422                    node.setStatusDate(now);
423    
424                    wikiNodePersistence.update(node);
425    
426                    // Pages
427    
428                    List<WikiPage> pages = wikiPagePersistence.findByNodeId(
429                            node.getNodeId());
430    
431                    for (WikiPage page : pages) {
432                            wikiPageLocalService.updateStatus(
433                                    userId, page, status, status, serviceContext);
434                    }
435    
436                    // Trash
437    
438                    if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
439                            trashEntryLocalService.deleteEntry(
440                                    WikiNode.class.getName(), node.getNodeId());
441                    }
442                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
443                            trashEntryLocalService.addTrashEntry(
444                                    userId, node.getGroupId(), WikiNode.class.getName(),
445                                    node.getNodeId(), oldStatus, null, null);
446                    }
447    
448                    // Indexer
449    
450                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
451                            WikiNode.class);
452    
453                    if (status == WorkflowConstants.STATUS_IN_TRASH) {
454                            String oldName = node.getName();
455    
456                            node.setName(TrashUtil.stripTrashNamespace(oldName));
457    
458                            indexer.reindex(node);
459    
460                            node.setName(oldName);
461                    }
462                    else {
463                            indexer.delete(node);
464                    }
465    
466                    return node;
467            }
468    
469            protected List<WikiNode> addDefaultNode(long groupId)
470                    throws PortalException, SystemException {
471    
472                    Group group = groupPersistence.findByPrimaryKey(groupId);
473    
474                    long defaultUserId = userLocalService.getDefaultUserId(
475                            group.getCompanyId());
476    
477                    ServiceContext serviceContext = new ServiceContext();
478    
479                    serviceContext.setAddGroupPermissions(true);
480                    serviceContext.setAddGuestPermissions(true);
481                    serviceContext.setScopeGroupId(groupId);
482    
483                    WikiNode node = wikiNodeLocalService.addDefaultNode(
484                            defaultUserId, serviceContext);
485    
486                    List<WikiNode> nodes = new ArrayList<WikiNode>(1);
487    
488                    nodes.add(node);
489    
490                    return nodes;
491            }
492    
493            protected WikiImporter getWikiImporter(String importer)
494                    throws SystemException {
495    
496                    WikiImporter wikiImporter = _wikiImporters.get(importer);
497    
498                    if (wikiImporter == null) {
499                            String importerClass = PropsUtil.get(
500                                    PropsKeys.WIKI_IMPORTERS_CLASS, new Filter(importer));
501    
502                            if (importerClass != null) {
503                                    wikiImporter = (WikiImporter)InstancePool.get(importerClass);
504    
505                                    _wikiImporters.put(importer, wikiImporter);
506                            }
507    
508                            if (importer == null) {
509                                    throw new SystemException(
510                                            "Unable to instantiate wiki importer class " +
511                                                    importerClass);
512                            }
513                    }
514    
515                    return wikiImporter;
516            }
517    
518            protected void validate(long nodeId, long groupId, String name)
519                    throws PortalException, SystemException {
520    
521                    if (name.equalsIgnoreCase("tag")) {
522                            throw new NodeNameException(name + " is reserved");
523                    }
524    
525                    if (Validator.isNull(name)) {
526                            throw new NodeNameException();
527                    }
528    
529                    WikiNode node = wikiNodePersistence.fetchByG_N(groupId, name);
530    
531                    if ((node != null) && (node.getNodeId() != nodeId)) {
532                            throw new DuplicateNodeNameException();
533                    }
534            }
535    
536            protected void validate(long groupId, String name)
537                    throws PortalException, SystemException {
538    
539                    validate(0, groupId, name);
540            }
541    
542            private static Log _log = LogFactoryUtil.getLog(
543                    WikiNodeLocalServiceImpl.class);
544    
545            private Map<String, WikiImporter> _wikiImporters =
546                    new HashMap<String, WikiImporter>();
547    
548    }