001/*
002 *  Copyright 2012 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.repository.content.shared;
017
018import java.io.IOException;
019import java.util.Collection;
020import java.util.Locale;
021import java.util.Set;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.ProcessingException;
026import org.apache.cocoon.generation.ServiceableGenerator;
027import org.apache.cocoon.xml.AttributesImpl;
028import org.apache.cocoon.xml.XMLUtils;
029import org.apache.commons.lang.StringUtils;
030import org.xml.sax.SAXException;
031
032import org.ametys.cms.repository.Content;
033import org.ametys.plugins.repository.AmetysObjectResolver;
034import org.ametys.web.repository.content.SharedContent;
035import org.ametys.web.repository.content.WebContent;
036import org.ametys.web.repository.page.Page;
037
038/**
039 * Indicates if a content is shared (is a copy of another content) or if it is copied by contents.
040 */
041public class ContentSharesGenerator extends ServiceableGenerator
042{
043    
044    /** The ametys object resolver. */
045    protected AmetysObjectResolver _resolver;
046    
047    /** The shared content helper. */
048    protected SharedContentManager _sharedContentComponent;
049    
050    @Override
051    public void service(ServiceManager serviceManager) throws ServiceException
052    {
053        super.service(serviceManager);
054        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
055        _sharedContentComponent = (SharedContentManager) serviceManager.lookup(SharedContentManager.ROLE);
056    }
057    
058    @Override
059    public void generate() throws IOException, SAXException, ProcessingException
060    {
061        String contentId = parameters.getParameter("contentId", "");
062        
063        if (StringUtils.isEmpty(contentId))
064        {
065            throw new IllegalArgumentException("A content ID must be provided.");
066        }
067        
068        Content content = _resolver.resolveById(contentId);
069        Locale locale = content.getLanguage() != null ? new Locale(content.getLanguage()) : null;
070        
071        Set<SharedContent> sharedContents = _sharedContentComponent.getSharedContents(content);
072        
073        contentHandler.startDocument();
074        
075        AttributesImpl attrs = new AttributesImpl();
076        attrs.addCDATAAttribute("id", contentId);
077        
078        XMLUtils.startElement(contentHandler, "content-shares", attrs);
079        
080        if (content instanceof SharedContent)
081        {
082            Content initialContent = ((SharedContent) content).getInitialContent();
083            
084            if (initialContent != null)
085            {
086                AttributesImpl icAttrs = new AttributesImpl();
087                
088                icAttrs.addCDATAAttribute("id", initialContent.getId());
089                icAttrs.addCDATAAttribute("title", initialContent.getTitle(locale));
090                
091                XMLUtils.startElement(contentHandler, "initial-content", icAttrs);
092                
093                if (initialContent instanceof WebContent)
094                {
095                    Collection<Page> pages = ((WebContent) initialContent).getReferencingPages();
096                    for (Page page : pages)
097                    {
098                        saxPage(page);
099                    }
100                }
101                
102                XMLUtils.endElement(contentHandler, "initial-content");
103            }
104        }
105        
106        for (SharedContent sharedContent : sharedContents)
107        {
108            AttributesImpl sharedAttrs = new AttributesImpl();
109            sharedAttrs.addCDATAAttribute("contentId", sharedContent.getId());
110            sharedAttrs.addCDATAAttribute("title", sharedContent.getTitle(locale));
111            
112            XMLUtils.startElement(contentHandler, "share", sharedAttrs);
113            
114            for (Page page : sharedContent.getReferencingPages())
115            {
116                saxPage(page);
117            }
118            
119            XMLUtils.endElement(contentHandler, "share");
120        }
121        
122        XMLUtils.endElement(contentHandler, "content-shares");
123        
124        contentHandler.endDocument();
125    }
126    
127    /**
128     * SAX the page.
129     * @param page the page to sax.
130     * @throws SAXException if an error occurs.
131     */
132    protected void saxPage(Page page) throws SAXException
133    {
134        AttributesImpl pageAttrs = new AttributesImpl();
135        pageAttrs.addCDATAAttribute("id", _escape(page.getId()));
136        pageAttrs.addCDATAAttribute("name", _escape(page.getName()));
137        pageAttrs.addCDATAAttribute("path", _escape(page.getPathInSitemap()));
138        pageAttrs.addCDATAAttribute("title", _escape(page.getTitle()));
139        pageAttrs.addCDATAAttribute("long-title", _escape(page.getLongTitle()));
140        pageAttrs.addCDATAAttribute("lang", _escape(page.getSitemap().getName()));
141        pageAttrs.addCDATAAttribute("site", _escape(page.getSite().getName()));
142        
143        XMLUtils.createElement(contentHandler, "page", pageAttrs);
144    }
145    
146    private String _escape(String target)
147    {
148        if (target == null)
149        {
150            return "";
151        }
152        return target.replaceAll("&", "&amp;").replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
153    }
154    
155}