001/*
002 * (C) Copyright 2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Funsho David
018 *     Nuno Cunha <ncunha@nuxeo.com>
019 */
020
021package org.nuxeo.ecm.platform.comment.impl;
022
023import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_AUTHOR;
024import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_PARENT_ID;
025import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_SCHEMA;
026
027import java.io.Serializable;
028import java.util.Collection;
029import java.util.HashMap;
030import java.util.HashSet;
031import java.util.List;
032import java.util.Map;
033
034import org.apache.commons.logging.Log;
035import org.apache.commons.logging.LogFactory;
036import org.nuxeo.ecm.core.api.CoreSession;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.DocumentRef;
039import org.nuxeo.ecm.core.api.IdRef;
040import org.nuxeo.ecm.core.api.NuxeoPrincipal;
041import org.nuxeo.ecm.core.api.PartialList;
042import org.nuxeo.ecm.core.api.PropertyException;
043import org.nuxeo.ecm.core.api.security.ACE;
044import org.nuxeo.ecm.core.api.security.ACL;
045import org.nuxeo.ecm.core.api.security.ACP;
046import org.nuxeo.ecm.core.api.security.SecurityConstants;
047import org.nuxeo.ecm.core.api.security.impl.ACLImpl;
048import org.nuxeo.ecm.core.api.security.impl.ACPImpl;
049import org.nuxeo.ecm.core.event.Event;
050import org.nuxeo.ecm.core.event.EventProducer;
051import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
052import org.nuxeo.ecm.platform.comment.api.Comment;
053import org.nuxeo.ecm.platform.comment.api.CommentConstants;
054import org.nuxeo.ecm.platform.comment.api.CommentManager;
055import org.nuxeo.ecm.platform.usermanager.UserManager;
056import org.nuxeo.runtime.api.Framework;
057
058/**
059 * @since 10.3
060 */
061public abstract class AbstractCommentManager implements CommentManager {
062
063    private static final Log log = LogFactory.getLog(AbstractCommentManager.class);
064
065    protected static final String COMMENTS_DIRECTORY = "Comments";
066
067    @Override
068    public List<DocumentModel> getComments(DocumentModel docModel) {
069        return getComments(docModel.getCoreSession(), docModel);
070    }
071
072    @Override
073    public List<DocumentModel> getComments(DocumentModel docModel, DocumentModel parent) {
074        return getComments(docModel);
075    }
076
077    @Override
078    public List<Comment> getComments(CoreSession session, String documentId) {
079        return getComments(session, documentId, 0L, 0L, true);
080    }
081
082    @Override
083    public List<Comment> getComments(CoreSession session, String documentId, boolean sortAscending) {
084        return getComments(session, documentId, 0L, 0L, sortAscending);
085    }
086
087    @Override
088    public PartialList<Comment> getComments(CoreSession session, String documentId, Long pageSize,
089            Long currentPageIndex) {
090        return getComments(session, documentId, pageSize, currentPageIndex, true);
091    }
092
093    protected void notifyEvent(CoreSession session, String eventType, DocumentModel commentedDoc,
094            DocumentModel comment) {
095
096        UserManager userManager = Framework.getService(UserManager.class);
097        NuxeoPrincipal principal = null;
098        if (userManager != null) {
099            principal = userManager.getPrincipal((String) comment.getPropertyValue(COMMENT_AUTHOR));
100            if (principal == null) {
101                try {
102                    principal = getAuthor(comment);
103                } catch (PropertyException e) {
104                    log.error("Error building principal for comment author", e);
105                    return;
106                }
107            }
108        }
109        DocumentEventContext ctx = new DocumentEventContext(session, principal, commentedDoc);
110        Map<String, Serializable> props = new HashMap<>();
111        props.put(CommentConstants.PARENT_COMMENT, commentedDoc);
112        props.put(CommentConstants.COMMENT_DOCUMENT, comment);
113        props.put(CommentConstants.COMMENT, (String) comment.getProperty("comment", "text"));
114        // Keep comment_text for compatibility
115        props.put(CommentConstants.COMMENT_TEXT, (String) comment.getProperty("comment", "text"));
116        props.put("category", CommentConstants.EVENT_COMMENT_CATEGORY);
117        ctx.setProperties(props);
118        Event event = ctx.newEvent(eventType);
119
120        EventProducer evtProducer = Framework.getService(EventProducer.class);
121        evtProducer.fireEvent(event);
122    }
123
124    protected NuxeoPrincipal getAuthor(DocumentModel docModel) {
125        String[] contributors = (String[]) docModel.getProperty("dublincore", "contributors");
126        UserManager userManager = Framework.getService(UserManager.class);
127        return userManager.getPrincipal(contributors[0]);
128    }
129
130    protected void setFolderPermissions(CoreSession session, DocumentModel documentModel) {
131        ACP acp = new ACPImpl();
132        ACE grantAddChildren = new ACE("members", SecurityConstants.ADD_CHILDREN, true);
133        ACE grantRemoveChildren = new ACE("members", SecurityConstants.REMOVE_CHILDREN, true);
134        ACE grantRemove = new ACE("members", SecurityConstants.REMOVE, true);
135        ACL acl = new ACLImpl();
136        acl.setACEs(new ACE[] { grantAddChildren, grantRemoveChildren, grantRemove });
137        acp.addACL(acl);
138        session.setACP(documentModel.getRef(), acp, true);
139    }
140
141    protected void setCommentPermissions(CoreSession session, DocumentModel documentModel) {
142        ACP acp = new ACPImpl();
143        ACE grantRead = new ACE(SecurityConstants.EVERYONE, SecurityConstants.READ, true);
144        ACE grantRemove = new ACE("members", SecurityConstants.REMOVE, true);
145        ACL acl = new ACLImpl();
146        acl.setACEs(new ACE[] { grantRead, grantRemove });
147        acp.addACL(acl);
148        session.setACP(documentModel.getRef(), acp, true);
149    }
150
151    protected Collection<String> computeAncestorIds(CoreSession session, String parentId) {
152        Collection<String> ancestorIds = new HashSet<>();
153        ancestorIds.add(parentId);
154        DocumentRef parentRef = new IdRef(parentId);
155        while (session.exists(parentRef) && session.getDocument(parentRef).hasSchema(COMMENT_SCHEMA)) {
156            parentId = (String) session.getDocument(parentRef).getPropertyValue(COMMENT_PARENT_ID);
157            ancestorIds.add(parentId);
158            parentRef = new IdRef(parentId);
159        }
160        return ancestorIds;
161    }
162
163}