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 *       Kevin Leturc <kleturc@nuxeo.com>
018 *       Nuno Cunha <ncunha@nuxeo.com>
019 */
020package org.nuxeo.ecm.platform.comment.impl;
021
022import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
023import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
024import static org.nuxeo.ecm.platform.comment.api.ExternalEntityConstants.EXTERNAL_ENTITY;
025import static org.nuxeo.ecm.platform.comment.api.ExternalEntityConstants.EXTERNAL_ENTITY_ID;
026import static org.nuxeo.ecm.platform.comment.api.ExternalEntityConstants.EXTERNAL_ENTITY_ORIGIN;
027import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_ANCESTOR_IDS_FIELD;
028import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_AUTHOR_FIELD;
029import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_CREATION_DATE_FIELD;
030import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_ENTITY_TYPE;
031import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_ID_FIELD;
032import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_LAST_REPLY_DATE;
033import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_MODIFICATION_DATE_FIELD;
034import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_NUMBER_OF_REPLIES;
035import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_PARENT_ID;
036import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_PARENT_ID_FIELD;
037import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_PERMISSIONS;
038import static org.nuxeo.ecm.platform.comment.workflow.utils.CommentsConstants.COMMENT_TEXT_FIELD;
039
040import java.io.IOException;
041import java.util.Arrays;
042import java.util.Collection;
043import java.util.Collections;
044
045import javax.inject.Inject;
046
047import org.nuxeo.ecm.core.api.CoreInstance;
048import org.nuxeo.ecm.core.api.CoreSession;
049import org.nuxeo.ecm.core.api.DocumentRef;
050import org.nuxeo.ecm.core.api.IdRef;
051import org.nuxeo.ecm.core.api.NuxeoPrincipal;
052import org.nuxeo.ecm.core.api.PartialList;
053import org.nuxeo.ecm.core.api.security.PermissionProvider;
054import org.nuxeo.ecm.core.io.marshallers.json.ExtensibleEntityJsonWriter;
055import org.nuxeo.ecm.core.io.registry.reflect.Setup;
056import org.nuxeo.ecm.platform.comment.api.Comment;
057import org.nuxeo.ecm.platform.comment.api.CommentManager;
058import org.nuxeo.ecm.platform.comment.api.ExternalEntity;
059import org.nuxeo.runtime.api.Framework;
060
061import com.fasterxml.jackson.core.JsonGenerator;
062
063/**
064 * @since 10.3
065 */
066@Setup(mode = SINGLETON, priority = REFERENCE)
067public class CommentJsonWriter extends ExtensibleEntityJsonWriter<Comment> {
068
069    public static final String FETCH_REPLIES_SUMMARY = "repliesSummary";
070
071    @Inject
072    protected CommentManager commentManager;
073
074    public CommentJsonWriter() {
075        super(COMMENT_ENTITY_TYPE, Comment.class);
076    }
077
078    @Override
079    protected void writeEntityBody(Comment entity, JsonGenerator jg) throws IOException {
080        writeCommentEntity(entity, jg);
081        CoreSession session = ctx.getSession(null).getSession();
082        NuxeoPrincipal principal = session.getPrincipal();
083        PermissionProvider permissionProvider = Framework.getService(PermissionProvider.class);
084
085        // Write permissions of current user on the annotation,
086        // which are the ones granted on the commented document
087        Collection<String> permissions = CoreInstance.doPrivileged(session, s -> {
088            if (entity.getId() == null) {
089                return Collections.emptyList();
090            }
091            DocumentRef ancestorRef = new IdRef(
092                    (String) commentManager.getThreadForComment(s.getDocument(new IdRef(entity.getId())))
093                                           .getPropertyValue(COMMENT_PARENT_ID));
094            return s.filterGrantedPermissions(principal, ancestorRef,
095                    Arrays.asList(permissionProvider.getPermissions()));
096        });
097        jg.writeArrayFieldStart(COMMENT_PERMISSIONS);
098        for (String permission : permissions) {
099            jg.writeString(permission);
100        }
101        jg.writeEndArray();
102        boolean includeRepliesSummary = ctx.getFetched(COMMENT_ENTITY_TYPE).contains(FETCH_REPLIES_SUMMARY);
103        if (includeRepliesSummary) {
104            writeRepliesSummary(session, entity, jg);
105        }
106    }
107
108    protected static void writeCommentEntity(Comment entity, JsonGenerator jg) throws IOException {
109        jg.writeStringField(COMMENT_ID_FIELD, entity.getId());
110        jg.writeStringField(COMMENT_PARENT_ID_FIELD, entity.getParentId());
111        jg.writeArrayFieldStart(COMMENT_ANCESTOR_IDS_FIELD);
112        for (String ancestorId : entity.getAncestorIds()) {
113            jg.writeString(ancestorId);
114        }
115        jg.writeEndArray();
116        jg.writeStringField(COMMENT_AUTHOR_FIELD, entity.getAuthor());
117        jg.writeStringField(COMMENT_TEXT_FIELD, entity.getText());
118
119        String creationDate = entity.getCreationDate() != null ? entity.getCreationDate().toString() : null;
120        jg.writeStringField(COMMENT_CREATION_DATE_FIELD, creationDate);
121        String modificationDate = entity.getModificationDate() != null ? entity.getModificationDate().toString() : null;
122        jg.writeStringField(COMMENT_MODIFICATION_DATE_FIELD, modificationDate);
123
124        if (entity instanceof ExternalEntity) {
125            jg.writeStringField(EXTERNAL_ENTITY_ID, ((ExternalEntity) entity).getEntityId());
126            jg.writeStringField(EXTERNAL_ENTITY_ORIGIN, ((ExternalEntity) entity).getOrigin());
127            jg.writeStringField(EXTERNAL_ENTITY, ((ExternalEntity) entity).getEntity());
128        }
129    }
130
131    protected void writeRepliesSummary(CoreSession session, Comment entity, JsonGenerator jg) throws IOException {
132        PartialList<Comment> comments = commentManager.getComments(session, entity.getId(), 1L, 0L, false);
133        jg.writeNumberField(COMMENT_NUMBER_OF_REPLIES, comments.totalSize());
134        if (comments.size() > 0) {
135            jg.writeStringField(COMMENT_LAST_REPLY_DATE, comments.get(0).getCreationDate().toString());
136        }
137    }
138}