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 *
019 */
020
021package org.nuxeo.ecm.annotation;
022
023import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_COLOR_PROPERTY;
024import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_CONTENT_PROPERTY;
025import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_CREATION_DATE_PROPERTY;
026import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_DATE_PROPERTY;
027import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_DOCUMENT_ID_PROPERTY;
028import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_ID_PROPERTY;
029import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_INTERIOR_COLOR_PROPERTY;
030import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_PARENT_ID_PROPERTY;
031import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_TYPE_PROPERTY;
032import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_XPATH_PROPERTY;
033import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_DOC_TYPE;
034import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_FLAGS_PROPERTY;
035import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_LAST_MODIFIER_PROPERTY;
036import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_OPACITY_PROPERTY;
037import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_PAGE_PROPERTY;
038import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_POSITION_PROPERTY;
039import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_SECURITY_PROPERTY;
040import static org.nuxeo.ecm.annotation.AnnotationConstants.ANNOTATION_SUBJECT_PROPERTY;
041
042import org.apache.commons.logging.Log;
043import org.apache.commons.logging.LogFactory;
044import org.nuxeo.ecm.core.api.CoreSession;
045import org.nuxeo.ecm.core.api.DocumentModel;
046import org.nuxeo.ecm.platform.query.api.PageProvider;
047import org.nuxeo.ecm.platform.query.api.PageProviderService;
048import org.nuxeo.ecm.platform.query.nxql.CoreQueryAndFetchPageProvider;
049import org.nuxeo.runtime.api.Framework;
050import org.nuxeo.runtime.model.DefaultComponent;
051
052import java.io.Serializable;
053import java.util.Collections;
054import java.util.List;
055import java.util.Map;
056import java.util.stream.Collectors;
057
058/**
059 * @since 10.1
060 */
061public class AnnotationServiceImpl extends DefaultComponent implements AnnotationService {
062
063    private static final Log log = LogFactory.getLog(AnnotationServiceImpl.class);
064
065    protected static final String ANNOTATION_NAME = "annotation";
066
067    protected static final String GET_ANNOTATION_PAGEPROVIDER_NAME = "GET_ANNOTATION";
068
069    protected static final String GET_ANNOTATIONS_FOR_DOC_PAGEPROVIDER_NAME = "GET_ANNOTATIONS_FOR_DOCUMENT";
070
071    @Override
072    public Annotation createAnnotation(CoreSession session, Annotation annotation) {
073
074        // Create annotation as a placeless document
075        DocumentModel annotationModel = session.createDocumentModel(null, ANNOTATION_NAME, ANNOTATION_DOC_TYPE);
076        setAnnotationProperties(annotationModel, annotation);
077        annotationModel = session.createDocument(annotationModel);
078        return new AnnotationImpl(annotationModel);
079    }
080
081    @Override
082    public Annotation getAnnotation(CoreSession session, String annotationId) {
083        DocumentModel annotationModel = getAnnotationModel(session, annotationId);
084        if (annotationModel == null) {
085            return null;
086        }
087        return new AnnotationImpl(annotationModel);
088    }
089
090    @Override
091    @SuppressWarnings("unchecked")
092    public List<Annotation> getAnnotations(CoreSession session, String documentId, String xpath) {
093        PageProviderService ppService = Framework.getService(PageProviderService.class);
094        Map<String, Serializable> props = Collections.singletonMap(CoreQueryAndFetchPageProvider.CORE_SESSION_PROPERTY,
095                (Serializable) session);
096        List<DocumentModel> annotationList = ((PageProvider<DocumentModel>) ppService.getPageProvider(
097                GET_ANNOTATIONS_FOR_DOC_PAGEPROVIDER_NAME, null, null, null, props, documentId,
098                xpath)).getCurrentPage();
099        return annotationList.stream().map(AnnotationImpl::new).collect(Collectors.toList());
100    }
101
102    @Override
103    public void updateAnnotation(CoreSession session, Annotation annotation) {
104        DocumentModel annotationModel = getAnnotationModel(session, annotation.getId());
105        if (annotationModel == null) {
106            if (log.isWarnEnabled()) {
107                log.warn("The annotation " + annotation.getId() + " on document blob " + annotation.getXpath()
108                        + " does not exist. Update operation is ignored.");
109            }
110            return;
111        }
112        setAnnotationProperties(annotationModel, annotation);
113        session.saveDocument(annotationModel);
114    }
115
116    @Override
117    public void deleteAnnotation(CoreSession session, String annotationId) throws IllegalArgumentException {
118        DocumentModel annotationModel = getAnnotationModel(session, annotationId);
119        if (annotationModel == null) {
120            throw new IllegalArgumentException("The annotation " + annotationId + " does not exist.");
121        }
122        session.removeDocument(annotationModel.getRef());
123    }
124
125    protected void setAnnotationProperties(DocumentModel annotationModel, Annotation annotation) {
126        annotationModel.setPropertyValue(ANNOTATION_ID_PROPERTY, annotation.getId());
127        annotationModel.setPropertyValue(ANNOTATION_TYPE_PROPERTY, annotation.getType());
128        annotationModel.setPropertyValue(ANNOTATION_DOCUMENT_ID_PROPERTY, annotation.getDocumentId());
129        annotationModel.setPropertyValue(ANNOTATION_XPATH_PROPERTY, annotation.getXpath());
130        annotationModel.setPropertyValue(ANNOTATION_COLOR_PROPERTY, annotation.getColor());
131        annotationModel.setPropertyValue(ANNOTATION_INTERIOR_COLOR_PROPERTY, annotation.getInteriorColor());
132        annotationModel.setPropertyValue(ANNOTATION_DATE_PROPERTY, annotation.getDate());
133        annotationModel.setPropertyValue(ANNOTATION_FLAGS_PROPERTY, annotation.getFlags());
134        annotationModel.setPropertyValue(ANNOTATION_LAST_MODIFIER_PROPERTY, annotation.getLastModifier());
135        annotationModel.setPropertyValue(ANNOTATION_PAGE_PROPERTY, annotation.getPage());
136        annotationModel.setPropertyValue(ANNOTATION_POSITION_PROPERTY, annotation.getPosition());
137        annotationModel.setPropertyValue(ANNOTATION_CREATION_DATE_PROPERTY, annotation.getCreationDate());
138        annotationModel.setPropertyValue(ANNOTATION_OPACITY_PROPERTY, annotation.getOpacity());
139        annotationModel.setPropertyValue(ANNOTATION_SUBJECT_PROPERTY, annotation.getSubject());
140        annotationModel.setPropertyValue(ANNOTATION_SECURITY_PROPERTY, annotation.getSecurity());
141        annotationModel.setPropertyValue(ANNOTATION_CONTENT_PROPERTY, annotation.getContent());
142        annotationModel.setPropertyValue(ANNOTATION_PARENT_ID_PROPERTY, annotation.getParentId());
143    }
144
145    @SuppressWarnings("unchecked")
146    protected DocumentModel getAnnotationModel(CoreSession session, String annotationId) {
147        PageProviderService ppService = Framework.getService(PageProviderService.class);
148        Map<String, Serializable> props = Collections.singletonMap(CoreQueryAndFetchPageProvider.CORE_SESSION_PROPERTY,
149                (Serializable) session);
150        List<DocumentModel> results = ((PageProvider<DocumentModel>) ppService.getPageProvider(
151                GET_ANNOTATION_PAGEPROVIDER_NAME, null, null, null, props, annotationId)).getCurrentPage();
152        if (results.isEmpty()) {
153            return null;
154        }
155        return results.get(0);
156    }
157
158}