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.io.IOException;
019import java.util.ArrayList;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.ProcessingException;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.generation.ServiceableGenerator;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.apache.commons.lang.ArrayUtils;
032import org.apache.commons.lang.StringUtils;
033import org.xml.sax.SAXException;
034
035import org.ametys.cms.lock.LockContentManager;
036import org.ametys.cms.repository.Content;
037import org.ametys.cms.repository.ModifiableContent;
038import org.ametys.cms.repository.WorkflowAwareContent;
039import org.ametys.cms.workflow.ContentWorkflowHelper;
040import org.ametys.core.right.RightManager;
041import org.ametys.core.user.CurrentUserProvider;
042import org.ametys.core.user.UserIdentity;
043import org.ametys.plugins.repository.AmetysObjectResolver;
044import org.ametys.plugins.repository.UnknownAmetysObjectException;
045import org.ametys.plugins.repository.lock.LockAwareAmetysObject;
046import org.ametys.plugins.workflow.support.WorkflowProvider;
047import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow;
048import org.ametys.runtime.parameter.ParameterHelper;
049
050import com.opensymphony.workflow.spi.Step;
051
052/**
053 * SAX the contents information
054 */
055public class ContentInformationGenerator extends ServiceableGenerator
056{
057    /** Ametys object resovler. */
058    protected AmetysObjectResolver _resolver;
059    /** The rights manager */
060    protected RightManager _rightManager;
061    /** The user provider */
062    protected CurrentUserProvider _userProvider;
063    /** The workflow provider */
064    protected WorkflowProvider _workflowProvider;
065    /** The lock manager. */
066    protected LockContentManager _lockManager;
067    /** The content workflow helper */
068    protected ContentWorkflowHelper _contentWorkflowHelper;
069
070    @Override
071    public void service(ServiceManager serviceManager) throws ServiceException
072    {
073        super.service(serviceManager);
074        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
075        _userProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
076        _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE);
077        _workflowProvider = (WorkflowProvider) serviceManager.lookup(WorkflowProvider.ROLE);
078        _lockManager = (LockContentManager) serviceManager.lookup(LockContentManager.ROLE);
079        _contentWorkflowHelper = (ContentWorkflowHelper) serviceManager.lookup(ContentWorkflowHelper.ROLE);
080    }
081    
082    @SuppressWarnings("unchecked")
083    @Override
084    public void generate() throws IOException, SAXException, ProcessingException
085    {
086        Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
087        List<String> ids = null;
088        Object idParam = jsParameters.get("id");
089        if (idParam instanceof String)
090        {
091            ids = new ArrayList<>();
092            ids.add((String) idParam);
093        }
094        else
095        {
096            ids = (List<String>) idParam;
097        }
098        
099        contentHandler.startDocument();
100        XMLUtils.startElement(contentHandler, "contents");
101        
102        for (String contentID : ids)
103        {
104            AttributesImpl attrs = new AttributesImpl();
105            
106            try
107            {
108                Content content = _resolver.resolveById(contentID);
109                
110                attrs.addCDATAAttribute("id", content.getId());
111                attrs.addCDATAAttribute("title", content.getTitle());
112                attrs.addCDATAAttribute("name", content.getName());
113                attrs.addCDATAAttribute("path", content.getPath());
114                attrs.addCDATAAttribute("type", StringUtils.join(content.getTypes(), ','));
115                attrs.addCDATAAttribute("lang", content.getLanguage());
116                attrs.addCDATAAttribute("creator", content.getCreator().getLogin());
117                attrs.addCDATAAttribute("lastContributor", content.getLastContributor().getLogin());
118                attrs.addCDATAAttribute("creationDate", ParameterHelper.valueToString(content.getCreationDate()));
119                attrs.addCDATAAttribute("lastModified", ParameterHelper.valueToString(content.getLastModified()));
120                
121                if (content instanceof WorkflowAwareContent)
122                {
123                    WorkflowAwareContent waContent = (WorkflowAwareContent) content;
124                    AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent);
125                    
126                    attrs.addCDATAAttribute("workflowName", workflow.getWorkflowName(waContent.getWorkflowId()));
127                    attrs.addCDATAAttribute("workflowStep", this.__joinSteps(workflow.getCurrentSteps(waContent.getWorkflowId())));
128                    
129                    int[] availableActions = _contentWorkflowHelper.getAvailableActions(waContent);
130                    String workflowAvailableAction = StringUtils.join(ArrayUtils.toObject(availableActions), ", ");
131                    attrs.addCDATAAttribute("workflowAvailableActions", workflowAvailableAction);
132                }
133                
134                if (content instanceof ModifiableContent)
135                {
136                    attrs.addCDATAAttribute("isModifiable", "true");
137                }
138                
139                if (content instanceof LockAwareAmetysObject)
140                {
141                    LockAwareAmetysObject lockAwareContent = (LockAwareAmetysObject) content;
142                    if (lockAwareContent.isLocked())
143                    {
144                        attrs.addCDATAAttribute("locked", String.valueOf(lockAwareContent.isLocked()));
145                        attrs.addCDATAAttribute("canUnlock", String.valueOf(_lockManager.canUnlock(lockAwareContent)));
146                    }
147                }
148                
149                saxAdditionalAtttributes (content, attrs);
150                
151                XMLUtils.startElement(contentHandler, "content", attrs);
152                
153                saxUserRights(content);
154                saxAdditionalInformation(content);
155                XMLUtils.endElement(contentHandler, "content");
156            }
157            catch (UnknownAmetysObjectException e)
158            {
159                getLogger().warn("Content of id '" + contentID + "' does not exist.", e);
160                
161                attrs.addCDATAAttribute("id", contentID);
162                XMLUtils.createElement(contentHandler, "content-not-found", attrs);
163            }
164            
165        }
166        
167        XMLUtils.endElement(contentHandler, "contents");
168        contentHandler.endDocument();
169    }
170
171    private String __joinSteps(List<Step> steps)
172    {
173        StringBuffer a = new StringBuffer();
174        
175        for (Step s : steps)
176        {
177            if (a.length() > 0)
178            {
179                a.append(", ");
180            }
181            a.append(s.getStepId());
182        }
183        
184        return a.toString();
185    }
186    
187    
188    /**
189     * SAX the user rights on content
190     * @param content The content to check rights
191     * @throws SAXException if an error occurred while SAXing
192     */
193    protected void saxUserRights (Content content) throws SAXException
194    {
195        UserIdentity user = _userProvider.getUser();
196        Set<String> rights = _rightManager.getUserRights(user, content);
197        
198        XMLUtils.startElement(contentHandler, "user-rights");
199        
200        for (String rightID : rights)
201        {
202            AttributesImpl rightAttr = new AttributesImpl();
203            rightAttr.addCDATAAttribute("id", rightID);
204            XMLUtils.createElement(contentHandler, "right", rightAttr);
205        }
206        XMLUtils.endElement(contentHandler, "user-rights");
207    }
208    
209    /**
210     * SAX the additional attributes
211     * @param content The content
212     * @param attrs The attributes
213     * @throws SAXException if an error occurred while SAXing
214     */
215    protected void saxAdditionalAtttributes (Content content, AttributesImpl attrs) throws SAXException
216    {
217        // Nothing
218    }
219    
220    /**
221     * SAX additional information on content
222     * @param content The content
223     * @throws SAXException if an error occurred while SAXing
224     */
225    protected void saxAdditionalInformation (Content content) throws SAXException
226    {
227        // Nothing
228    }
229}