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.I18nUtils;
044import org.ametys.plugins.core.user.UserHelper;
045import org.ametys.plugins.workflow.support.WorkflowProvider;
046import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow;
047import org.ametys.runtime.i18n.I18nizableText;
048import org.ametys.runtime.parameter.ParameterHelper;
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        XMLUtils.createElement(contentHandler, "creatorDisplay", _userHelper.getUserFullName(user));
150    }
151    
152    /**
153     * SAX the contributor
154     * @param contentHandler The content handler where to sax
155     * @param content the content The content concerned
156     * @throws SAXException if an error occurred while saxing
157     */
158    public void saxContributor (ContentHandler contentHandler, Content content) throws SAXException
159    {
160        UserIdentity user = content.getLastContributor();
161        XMLUtils.createElement(contentHandler, "contributor", user.getLogin());
162        XMLUtils.createElement(contentHandler, "contributorDisplay", _userHelper.getUserFullName(user));
163    }
164    
165    /**
166     * SAX the last modified date
167     * @param contentHandler The content handler where to sax
168     * @param content the content The content concerned
169     * @throws SAXException if an error occurred while saxing
170     */
171    public void saxLastModified (ContentHandler contentHandler, Content content) throws SAXException
172    {
173        XMLUtils.createElement(contentHandler, "lastModified", ParameterHelper.valueToString(content.getLastModified()));
174    }
175    
176    /**
177     * SAX the date of creation
178     * @param contentHandler The content handler where to sax
179     * @param content the content The content concerned
180     * @throws SAXException if an error occurred while saxing
181     */
182    public void saxCreationDate (ContentHandler contentHandler, Content content) throws SAXException
183    {
184        XMLUtils.createElement(contentHandler, "creationDate", ParameterHelper.valueToString(content.getCreationDate()));
185    }
186    
187    /**
188     * SAX the content's comments
189     * @param contentHandler The content handler where to sax
190     * @param content the content The content concerned
191     * @throws SAXException if an error occurred while saxing
192     */
193    public void saxComments (ContentHandler contentHandler, Content content) throws SAXException
194    {
195        if (content instanceof CommentableContent)
196        {
197            boolean hasComment = ((CommentableContent) content).getComments(true, true).size() != 0;
198            XMLUtils.createElement(contentHandler, "comments", String.valueOf(hasComment));
199        }
200    }
201    
202    /**
203     * SAX the content language
204     * @param contentHandler The content handler where to sax
205     * @param content the content The content concerned
206     * @throws SAXException if an error occurred while saxing
207     */
208    public void saxContentLanguage (ContentHandler contentHandler, Content content) throws SAXException
209    {
210        Language language = _languagesManager.getAvailableLanguages().get(content.getLanguage());
211        if (language != null)
212        {
213            XMLUtils.createElement(contentHandler, "contentLanguageIcon", language.getSmallIcon());
214        }
215        
216        XMLUtils.createElement(contentHandler, "contentLanguage", content.getLanguage());
217    }
218    
219    /**
220     * SAX workflow current step of a {@link Content}
221     * @param contentHandler The content handler where to sax
222     * @param content the content The content concerned
223     * @throws SAXException if an error occurs while SAXing
224     * @throws RepositoryException if an error occurs while retrieving current step
225     */
226    public void saxContentCurrentState(ContentHandler contentHandler, Content content) throws SAXException, RepositoryException
227    {
228        if (content instanceof WorkflowAwareContent)
229        {
230            WorkflowAwareContent waContent = (WorkflowAwareContent) content;
231            int currentStepId = 0;
232            
233            AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent);
234            long workflowId = waContent.getWorkflowId();
235            
236            Iterator iterator = workflow.getCurrentSteps(workflowId).iterator();
237            
238            while (iterator.hasNext())
239            {
240                Step step = (Step) iterator.next();
241                currentStepId = step.getStepId();
242            }
243            
244            String workflowName = workflow.getWorkflowName(workflowId);
245            WorkflowDescriptor workflowDescriptor = workflow.getWorkflowDescriptor(workflowName);
246            StepDescriptor stepDescriptor = workflowDescriptor.getStep(currentStepId);
247            
248            if (stepDescriptor != null)
249            {
250                I18nizableText workflowStepName = new I18nizableText("application", stepDescriptor.getName());
251                
252                AttributesImpl attr = new AttributesImpl();
253                attr.addAttribute("", "id", "id", "CDATA", String.valueOf(currentStepId));
254                
255                XMLUtils.startElement(contentHandler, "workflowStep", attr);
256                workflowStepName.toSAX(contentHandler);
257                XMLUtils.endElement(contentHandler, "workflowStep");
258                
259                String[] icons = new String[]{"-small", "-medium", "-large"};
260                for (String icon : icons)
261                {
262                    if ("application".equals(workflowStepName.getCatalogue()))
263                    {
264                        XMLUtils.createElement(contentHandler, "workflow-icon" + icon, "/plugins/cms/resources_workflow/" + workflowStepName.getKey() + icon + ".png");
265                    }
266                    else
267                    {
268                        String pluginName = workflowStepName.getCatalogue().substring("plugin.".length());
269                        XMLUtils.createElement(contentHandler, "workflow-icon" + icon, "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + icon + ".png");
270                    }
271                }
272            }
273        }
274    }
275}