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