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.web.workflow;
017
018import java.io.IOException;
019import java.util.Locale;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.cocoon.ProcessingException;
024import org.apache.cocoon.components.source.impl.SitemapSource;
025import org.apache.cocoon.environment.ObjectModelHelper;
026import org.apache.cocoon.environment.Request;
027import org.apache.cocoon.generation.ServiceableGenerator;
028import org.apache.cocoon.xml.AttributesImpl;
029import org.apache.cocoon.xml.XMLUtils;
030import org.apache.commons.lang3.StringUtils;
031import org.apache.excalibur.source.SourceResolver;
032import org.xml.sax.SAXException;
033
034import org.ametys.cms.content.ContentHelper;
035import org.ametys.cms.repository.Content;
036import org.ametys.core.util.DateUtils;
037import org.ametys.core.util.IgnoreRootHandler;
038import org.ametys.plugins.repository.AmetysObjectResolver;
039import org.ametys.plugins.repository.UnknownAmetysObjectException;
040import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
041import org.ametys.plugins.repository.version.VersionableAmetysObject;
042import org.ametys.web.WebConstants;
043import org.ametys.web.renderingcontext.RenderingContext;
044import org.ametys.web.renderingcontext.RenderingContextHandler;
045import org.ametys.web.repository.site.SiteManager;
046
047/**
048 * SAX the contents with id passed from request parameters
049 *
050 */
051public class GetLastPublishedContents extends ServiceableGenerator
052{
053    private SourceResolver _sourceResolver;
054    private AmetysObjectResolver _resolver;
055    private SiteManager _siteManager;
056    private RenderingContextHandler _renderingContextHandler;
057    private ContentHelper _contentHelper;
058    
059    @Override
060    public void service(ServiceManager smanager) throws ServiceException
061    {
062        _sourceResolver = (SourceResolver) smanager.lookup(SourceResolver.ROLE);
063        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
064        _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE);
065        _renderingContextHandler = (RenderingContextHandler) smanager.lookup(RenderingContextHandler.ROLE);
066        _contentHelper = (ContentHelper) smanager.lookup(ContentHelper.ROLE);
067    }
068    
069    @Override
070    public void generate() throws IOException, SAXException, ProcessingException
071    {
072        Request request = ObjectModelHelper.getRequest(objectModel);
073        String[] contentIds = request.getParameterValues("contentId");
074        String viewName = request.getParameter("viewName");
075        String lang = request.getParameter("lang");
076        
077        contentHandler.startDocument();
078        XMLUtils.startElement(contentHandler, "contents");
079        
080        String originalWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
081        
082        RequestAttributeWorkspaceSelector.setForcedWorkspace(request, WebConstants.LIVE_WORKSPACE);
083        
084        for (String id : contentIds)
085        {
086            try
087            {
088                Content content = _resolver.resolveById(id);
089                if (content instanceof VersionableAmetysObject)
090                {
091                    Locale locale = StringUtils.isNotEmpty(lang) ? new Locale(lang) : null;
092                    saxContent(request, content, viewName != null ? viewName : "main", locale);
093                }
094            }
095            catch (UnknownAmetysObjectException e)
096            {
097                // The content just doesn't have a live version: ignore.
098            }
099        }
100        
101        RequestAttributeWorkspaceSelector.setForcedWorkspace(request, originalWorkspace);
102        
103        XMLUtils.endElement(contentHandler, "contents");
104        contentHandler.endDocument();
105    }
106    
107    /**
108     * SAX a content in its specific view
109     * @param request the request
110     * @param content The content to SAX
111     * @param viewName The view to use
112     * @param locale The current locale
113     * @throws SAXException If an error occurs while SAXing
114     * @throws IOException If an error occurs while retrieving content.
115     */
116    protected void saxContent (Request request, Content content, String viewName, Locale locale) throws SAXException, IOException
117    {
118        RenderingContext currentContext = _renderingContextHandler.getRenderingContext();
119        _renderingContextHandler.setRenderingContext(RenderingContext.FRONT);
120        
121        // FIXME CMS-2611 Force absolute 
122        // FIXME CMS-4059 Force base64 encoding.
123        String siteName = (String) request.getAttribute("siteName");
124        String baseUrl = _siteManager.getSite(siteName).getUrl();
125        request.setAttribute("_baseServerPath", baseUrl);
126        request.setAttribute("_contextPath", "");
127        request.setAttribute("forceAbsoluteUrl", true);
128        request.setAttribute("forceBase64Encoding", true);
129        
130        AttributesImpl attrs = new AttributesImpl();
131        attrs.addCDATAAttribute("id", content.getId());
132        attrs.addCDATAAttribute("name", content.getName());
133        attrs.addCDATAAttribute("title", content.getTitle(locale));
134        attrs.addCDATAAttribute("lastModifiedAt", DateUtils.zonedDateTimeToString(content.getLastModified()));
135        
136        XMLUtils.startElement(contentHandler, "content", attrs);
137        
138        String uri = _contentHelper.getContentHtmlViewUrl(content, viewName);
139        SitemapSource src = null;
140        
141        try
142        {
143            src = (SitemapSource) _sourceResolver.resolveURI(uri);
144            src.toSAX(new IgnoreRootHandler(contentHandler));
145        }
146        finally
147        {
148            _sourceResolver.release(src);
149        }
150        
151        XMLUtils.endElement(contentHandler, "content");
152        
153        _renderingContextHandler.setRenderingContext(currentContext);
154        request.removeAttribute("forceAbsoluteUrl");
155        request.removeAttribute("forceBase64Encoding");
156        request.removeAttribute("_baseServerPath");
157        request.removeAttribute("_contextPath");
158    }
159}