001/*
002 *  Copyright 2010 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.content;
017
018import java.util.ArrayList;
019import java.util.Iterator;
020import java.util.List;
021
022import javax.jcr.RepositoryException;
023
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.avalon.framework.thread.ThreadSafe;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.apache.commons.lang.StringUtils;
032import org.xml.sax.ContentHandler;
033import org.xml.sax.SAXException;
034
035import org.ametys.cms.contenttype.ContentType;
036import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
037import org.ametys.cms.languages.Language;
038import org.ametys.cms.languages.LanguagesManager;
039import org.ametys.cms.repository.Content;
040import org.ametys.cms.repository.WorkflowAwareContent;
041import org.ametys.cms.repository.comment.CommentableContent;
042import org.ametys.core.user.UserIdentity;
043import org.ametys.core.util.DateUtils;
044import org.ametys.core.util.I18nUtils;
045import org.ametys.plugins.core.user.UserHelper;
046import org.ametys.plugins.workflow.support.WorkflowProvider;
047import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow;
048import org.ametys.runtime.i18n.I18nizableText;
049
050import com.opensymphony.workflow.loader.StepDescriptor;
051import com.opensymphony.workflow.loader.WorkflowDescriptor;
052import com.opensymphony.workflow.spi.Step;
053
054/**
055 * Component helper for saxing content's properties
056 *
057 */
058public class SAXContentHelper implements Component, ThreadSafe, Serviceable
059{
060    /** The avalon ROLE */
061    public static final String ROLE = SAXContentHelper.class.getName();
062    
063    private UserHelper _userHelper;
064    private WorkflowProvider _workflowProvider;
065    private LanguagesManager _languagesManager;
066    private ContentTypeExtensionPoint _contentTypeExtensionPoint;
067    private I18nUtils _i18nUtils;
068    
069    public void service(ServiceManager smanager) throws ServiceException
070    {
071        _contentTypeExtensionPoint = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE);
072        _languagesManager = (LanguagesManager) smanager.lookup(LanguagesManager.ROLE);
073        _workflowProvider = (WorkflowProvider) smanager.lookup(WorkflowProvider.ROLE);
074        _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE);
075        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
076    }
077
078    /**
079     * SAX the content's content types
080     * @param contentHandler The content handler where to sax
081     * @param content the content The content concerned
082     * @throws SAXException if an error occurred while saxing
083     */
084    public void saxContentTypes (ContentHandler contentHandler, Content content) throws SAXException
085    {
086        List<String> labels = new ArrayList<>();
087        
088        for (String cTypeId : content.getTypes())
089        {
090            ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId);
091            labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage()));
092        }
093        XMLUtils.createElement(contentHandler, "contentType", StringUtils.join(labels, ", "));
094    }
095    
096    /**
097     * SAX the content's mixins
098     * @param contentHandler The content handler where to sax
099     * @param content the content The content concerned
100     * @throws SAXException if an error occurred while saxing
101     */
102    public void saxMixinTypes (ContentHandler contentHandler, Content content) throws SAXException
103    {
104        List<String> labels = new ArrayList<>();
105        
106        for (String cTypeId : content.getMixinTypes())
107        {
108            ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId);
109            labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage()));
110        }
111        XMLUtils.createElement(contentHandler, "mixin", StringUtils.join(labels, ", "));
112    }
113    
114    /**
115     * SAX the content's mixins and content types
116     * @param contentHandler The content handler where to sax
117     * @param content the content The content concerned
118     * @throws SAXException if an error occurred while saxing
119     */
120    public void saxContentTypesAndMixins (ContentHandler contentHandler, Content content) throws SAXException
121    {
122        List<String> labels = new ArrayList<>();
123        
124        for (String cTypeId : content.getTypes())
125        {
126            ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId);
127            labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage()));
128        }
129        
130        for (String cTypeId : content.getMixinTypes())
131        {
132            ContentType cType = _contentTypeExtensionPoint.getExtension(cTypeId);
133            labels.add(_i18nUtils.translate(cType.getLabel(), content.getLanguage()));
134        }
135        
136        XMLUtils.createElement(contentHandler, "contentTypeOrMixin", StringUtils.join(labels, ", "));
137    }
138    
139    /**
140     * SAX the creator
141     * @param contentHandler The content handler where to sax
142     * @param content the content The content concerned
143     * @throws SAXException if an error occurred while saxing
144     */
145    public void saxCreator (ContentHandler contentHandler, Content content) throws SAXException
146    {
147        UserIdentity user = content.getCreator();
148        XMLUtils.createElement(contentHandler, "creator", user.getLogin());
149        
150        String fullName = _userHelper.getUserFullName(user);
151        if (fullName != null)
152        {
153            XMLUtils.createElement(contentHandler, "creatorDisplay", fullName);
154        }
155    }
156    
157    /**
158     * SAX the contributor
159     * @param contentHandler The content handler where to sax
160     * @param content the content The content concerned
161     * @throws SAXException if an error occurred while saxing
162     */
163    public void saxContributor (ContentHandler contentHandler, Content content) throws SAXException
164    {
165        UserIdentity user = content.getLastContributor();
166        XMLUtils.createElement(contentHandler, "contributor", user.getLogin());
167        
168        String fullName = _userHelper.getUserFullName(user);
169        if (fullName != null)
170        {
171            XMLUtils.createElement(contentHandler, "contributorDisplay", fullName);
172        }
173    }
174    
175    /**
176     * SAX the last modified date
177     * @param contentHandler The content handler where to sax
178     * @param content the content The content concerned
179     * @throws SAXException if an error occurred while saxing
180     */
181    public void saxLastModified (ContentHandler contentHandler, Content content) throws SAXException
182    {
183        XMLUtils.createElement(contentHandler, "lastModified", DateUtils.zonedDateTimeToString(content.getLastModified()));
184    }
185    
186    /**
187     * SAX the date of creation
188     * @param contentHandler The content handler where to sax
189     * @param content the content The content concerned
190     * @throws SAXException if an error occurred while saxing
191     */
192    public void saxCreationDate (ContentHandler contentHandler, Content content) throws SAXException
193    {
194        XMLUtils.createElement(contentHandler, "creationDate", DateUtils.zonedDateTimeToString(content.getCreationDate()));
195    }
196    
197    /**
198     * SAX the content's comments
199     * @param contentHandler The content handler where to sax
200     * @param content the content The content concerned
201     * @throws SAXException if an error occurred while saxing
202     */
203    public void saxComments (ContentHandler contentHandler, Content content) throws SAXException
204    {
205        if (content instanceof CommentableContent)
206        {
207            boolean hasComment = ((CommentableContent) content).getComments(true, true).size() != 0;
208            XMLUtils.createElement(contentHandler, "comments", String.valueOf(hasComment));
209        }
210    }
211    
212    /**
213     * SAX the content language
214     * @param contentHandler The content handler where to sax
215     * @param content the content The content concerned
216     * @throws SAXException if an error occurred while saxing
217     */
218    public void saxContentLanguage (ContentHandler contentHandler, Content content) throws SAXException
219    {
220        String contentLanguage = content.getLanguage();
221        if (contentLanguage != null)
222        {
223            Language language = _languagesManager.getAvailableLanguages().get(contentLanguage);
224            if (language != null)
225            {
226                XMLUtils.createElement(contentHandler, "contentLanguageIcon", language.getSmallIcon());
227            }
228            
229            XMLUtils.createElement(contentHandler, "contentLanguage", contentLanguage);
230        }
231    }
232    
233    /**
234     * SAX workflow current step of a {@link Content}
235     * @param contentHandler The content handler where to sax
236     * @param content the content The content concerned
237     * @throws SAXException if an error occurs while SAXing
238     * @throws RepositoryException if an error occurs while retrieving current step
239     */
240    public void saxContentCurrentState(ContentHandler contentHandler, Content content) throws SAXException, RepositoryException
241    {
242        if (content instanceof WorkflowAwareContent)
243        {
244            WorkflowAwareContent waContent = (WorkflowAwareContent) content;
245            int currentStepId = 0;
246            
247            AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent);
248            long workflowId = waContent.getWorkflowId();
249            
250            Iterator iterator = workflow.getCurrentSteps(workflowId).iterator();
251            
252            while (iterator.hasNext())
253            {
254                Step step = (Step) iterator.next();
255                currentStepId = step.getStepId();
256            }
257            
258            String workflowName = workflow.getWorkflowName(workflowId);
259            WorkflowDescriptor workflowDescriptor = workflow.getWorkflowDescriptor(workflowName);
260            StepDescriptor stepDescriptor = workflowDescriptor.getStep(currentStepId);
261            
262            if (stepDescriptor != null)
263            {
264                I18nizableText workflowStepName = new I18nizableText("application", stepDescriptor.getName());
265                
266                AttributesImpl attr = new AttributesImpl();
267                attr.addAttribute("", "id", "id", "CDATA", String.valueOf(currentStepId));
268                
269                XMLUtils.startElement(contentHandler, "workflowStep", attr);
270                workflowStepName.toSAX(contentHandler);
271                XMLUtils.endElement(contentHandler, "workflowStep");
272                
273                String[] icons = new String[]{"-small", "-medium", "-large"};
274                for (String icon : icons)
275                {
276                    if ("application".equals(workflowStepName.getCatalogue()))
277                    {
278                        XMLUtils.createElement(contentHandler, "workflow-icon" + icon, "/plugins/cms/resources_workflow/" + workflowStepName.getKey() + icon + ".png");
279                    }
280                    else
281                    {
282                        String pluginName = workflowStepName.getCatalogue().substring("plugin.".length());
283                        XMLUtils.createElement(contentHandler, "workflow-icon" + icon, "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + icon + ".png");
284                    }
285                }
286            }
287        }
288    }
289}