001/*
002 *  Copyright 2018 Anyware Services
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 */
016package org.ametys.cms.contenttype;
017
018import java.util.ArrayList;
019import java.util.LinkedHashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.cocoon.ProcessingException;
025import org.apache.cocoon.xml.AttributesImpl;
026import org.xml.sax.ContentHandler;
027import org.xml.sax.SAXException;
028
029import org.ametys.cms.contenttype.DefaultContentType.AnnotableDefinition;
030import org.ametys.cms.data.RichText;
031import org.ametys.cms.repository.Content;
032import org.ametys.core.right.RightManager;
033import org.ametys.core.right.RightManager.RightResult;
034import org.ametys.core.user.CurrentUserProvider;
035import org.ametys.core.util.XMLUtils;
036import org.ametys.runtime.model.DefinitionContext;
037
038/**
039 * RichText definition with its list of allowed semantic annotations
040 */
041public class RichTextAttributeDefinition extends AttributeDefinition<RichText> implements AnnotableDefinition
042{
043    /** Rights manager */
044    private RightManager _rightManager;
045    /** The current user provider */
046    private CurrentUserProvider _currentUserProvider;
047    
048    private List<SemanticAnnotation> _semanticAnnotations;
049
050    public List<SemanticAnnotation> getSemanticAnnotations()
051    {
052        return _semanticAnnotations;
053    }
054
055    public void setSemanticAnnotations(List<SemanticAnnotation> semAnnotations)
056    {
057        this._semanticAnnotations = semAnnotations;
058    }
059    
060    @Override
061    protected Map<String, Object> _toJSON(DefinitionContext context) throws ProcessingException
062    {
063        Map<String, Object> result = super._toJSON(context);
064        
065        if (context.getObject().isPresent())
066        {
067            Object object = context.getObject().get();
068            if (object instanceof Content)
069            {
070                Content content = (Content) object;
071                result.put("editableSource", _getRightManager().hasRight(_getCurrentUserProvider().getUser(), "CORE_Rights_SourceEdit", content) == RightResult.RIGHT_ALLOW);
072            }
073        }
074        
075        if (_semanticAnnotations != null && !_semanticAnnotations.isEmpty())
076        {
077            List<Map<String, Object>> annotationsObject = new ArrayList<>();
078
079            for (SemanticAnnotation annotation : _semanticAnnotations)
080            {
081                Map<String, Object> annotationObject = new LinkedHashMap<>();
082
083                annotationObject.put("name", annotation.getId());
084                annotationObject.put("label", annotation.getLabel());
085                annotationObject.put("description", annotation.getDescription());
086
087                annotationsObject.add(annotationObject);
088            }
089
090            result.put("annotations", annotationsObject);
091        }
092        
093        return result;
094    }
095    
096    @SuppressWarnings("static-access")
097    @Override
098    public void toSAX(ContentHandler contentHandler, DefinitionContext context) throws SAXException
099    {
100        super.toSAX(contentHandler, context);
101        
102        if (context.getObject().isPresent())
103        {
104            Object object = context.getObject().get();
105            if (object instanceof Content)
106            {
107                Content content = (Content) object;
108                boolean isEditableSource = _getRightManager().hasRight(_getCurrentUserProvider().getUser(), "CORE_Rights_SourceEdit", content) == RightResult.RIGHT_ALLOW;
109                XMLUtils.createElement(contentHandler, "editableSource", String.valueOf(isEditableSource));
110            }
111        }
112        
113        if (_semanticAnnotations != null && !_semanticAnnotations.isEmpty())
114        {
115            XMLUtils.startElement(contentHandler, "annotations");
116
117            for (SemanticAnnotation annotation : _semanticAnnotations)
118            {
119                AttributesImpl attributes = new AttributesImpl();
120                attributes.addCDATAAttribute("name", annotation.getId());
121                XMLUtils.startElement(contentHandler, "annotation", attributes);
122                
123                XMLUtils.createI18nElementIfNotNull(contentHandler, "label", annotation.getLabel());
124                XMLUtils.createI18nElementIfNotNull(contentHandler, "description", annotation.getDescription());
125
126                XMLUtils.endElement(contentHandler, "annotation");
127            }
128
129            XMLUtils.endElement(contentHandler, "annotations");
130        }
131    }
132    
133    /**
134     * Retrieves the {@link RightManager} 
135     * @return the {@link RightManager}
136     */
137    protected RightManager _getRightManager()
138    {
139        if (_rightManager == null)
140        {
141            try
142            {
143                _rightManager = (RightManager) __serviceManager.lookup(RightManager.ROLE);
144            }
145            catch (ServiceException e)
146            {
147                throw new RuntimeException("Unable to lookup after the right manager", e);
148            }
149        }
150        
151        return _rightManager;
152    }
153    
154    /**
155     * Retrieves the {@link CurrentUserProvider} 
156     * @return the {@link CurrentUserProvider}
157     */
158    protected CurrentUserProvider _getCurrentUserProvider()
159    {
160        if (_currentUserProvider == null)
161        {
162            try
163            {
164                _currentUserProvider = (CurrentUserProvider) __serviceManager.lookup(CurrentUserProvider.ROLE);
165            }
166            catch (ServiceException e)
167            {
168                throw new RuntimeException("Unable to lookup after the current user provider", e);
169            }
170        }
171        
172        return _currentUserProvider;
173    }
174}