001/*
002 *  Copyright 2015 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.content;
017
018import java.util.Collection;
019import java.util.Map;
020import java.util.Set;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.cocoon.xml.AttributesImpl;
025import org.apache.cocoon.xml.XMLUtils;
026import org.apache.commons.lang3.StringUtils;
027import org.xml.sax.SAXException;
028
029import org.ametys.cms.content.AdditionalContentPropertiesGenerator;
030import org.ametys.cms.repository.Content;
031import org.ametys.plugins.repository.AmetysRepositoryException;
032import org.ametys.web.repository.content.SharedContent;
033import org.ametys.web.repository.content.WebContent;
034import org.ametys.web.repository.content.shared.SharedContentManager;
035import org.ametys.web.repository.page.Page;
036import org.ametys.web.repository.page.Zone;
037import org.ametys.web.repository.page.ZoneItem;
038
039/**
040 * Generates addition information on web content
041 */
042public class AdditionalWebContentPropertiesGenerator extends AdditionalContentPropertiesGenerator
043{
044
045    /** The shared content helper. */
046    protected SharedContentManager _sharedContentComponent;
047
048    @Override
049    public void service(ServiceManager serviceManager) throws ServiceException
050    {
051        super.service(serviceManager);
052        _sharedContentComponent = (SharedContentManager) serviceManager.lookup(SharedContentManager.ROLE);
053    }
054    
055    @Override
056    protected void _saxOtherProperties(Content content) throws SAXException
057    {
058        _saxContentPages(content);
059        _saxSharedContent(content);
060    }
061    
062    @Override
063    protected Map<String, Object> getContextualParameters(Content content)
064    {
065        Map<String, Object> contextualParameters = super.getContextualParameters(content);
066        if (content instanceof WebContent)
067        {
068            contextualParameters.put("siteName", ((WebContent) content).getSiteName());
069        }
070        return contextualParameters;
071    }
072
073    private void _saxSharedContent(Content content) throws SAXException
074    {
075        Set<SharedContent> sharedContents = _sharedContentComponent.getSharedContents(content);
076
077        if (content instanceof SharedContent)
078        {
079            Content initialContent = ((SharedContent) content).getInitialContent();
080
081            if (initialContent != null)
082            {
083                AttributesImpl icAttrs = new AttributesImpl();
084
085                icAttrs.addCDATAAttribute("id", initialContent.getId());
086                icAttrs.addCDATAAttribute("title", initialContent.getTitle());
087
088                XMLUtils.startElement(contentHandler, "initial-content", icAttrs);
089                if (initialContent instanceof WebContent)
090                {
091                    Collection<Page> pages = ((WebContent) initialContent).getReferencingPages();
092                    for (Page page : pages)
093                    {
094                        _saxPage(page, null, null);
095                    }
096                }
097                XMLUtils.endElement(contentHandler, "initial-content");
098            }
099        }
100
101        for (SharedContent sharedContent : sharedContents)
102        {
103            AttributesImpl sharedAttrs = new AttributesImpl();
104            sharedAttrs.addCDATAAttribute("contentId", sharedContent.getId());
105            sharedAttrs.addCDATAAttribute("title", sharedContent.getTitle());
106
107            XMLUtils.startElement(contentHandler, "share", sharedAttrs);
108            for (Page page : sharedContent.getReferencingPages())
109            {
110                _saxPage(page, null, null);
111            }
112            XMLUtils.endElement(contentHandler, "share");
113        }
114    }
115
116    private void _saxContentPages(Content content) throws SAXException
117    {
118        XMLUtils.startElement(contentHandler, "pages");
119
120        if (content instanceof WebContent)
121        {
122            Collection<ZoneItem> zoneItems = ((WebContent) content).getReferencingZoneItems();
123
124            // For a shared content, we are mainly interrested in refereces of the initial content!
125            if (content instanceof SharedContent && ((SharedContent) content).getInitialContent() instanceof WebContent)
126            {
127                zoneItems.addAll(((WebContent) ((SharedContent) content).getInitialContent()).getReferencingZoneItems());
128            }
129
130            for (ZoneItem zoneItem : zoneItems)
131            {
132                Zone zone = zoneItem.getZone();
133                Page page = zone.getPage();
134
135                _saxPage(page, zone, zoneItem);
136            }
137        }
138
139        XMLUtils.endElement(contentHandler, "pages");
140    }
141
142    private String _escape(String target)
143    {
144        if (target == null)
145        {
146            return "";
147        }
148        return target.replaceAll("&", "&amp;").replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
149    }
150
151    /**
152     * SAX a content's page.
153     * @param page the page to SAX.
154     * @param zone the zone the content is in.
155     * @param zoneItem the the zone item the content belongs to.
156     * @throws SAXException if an error occurs.
157     */
158    protected void _saxPage(Page page, Zone zone, ZoneItem zoneItem) throws SAXException
159    {
160        AttributesImpl cAttsPage = new AttributesImpl();
161        cAttsPage.addCDATAAttribute("id", _escape(page.getId()));
162        cAttsPage.addCDATAAttribute("name", _escape(page.getName()));
163        cAttsPage.addCDATAAttribute("path", _escape(page.getPathInSitemap()));
164        cAttsPage.addCDATAAttribute("title", _escape(page.getTitle()));
165        cAttsPage.addCDATAAttribute("long-title", _escape(page.getLongTitle()));
166        cAttsPage.addCDATAAttribute("lang", _escape(page.getSitemap().getName()));
167        cAttsPage.addCDATAAttribute("site", _escape(page.getSite().getName()));
168        if (zone != null)
169        {
170            cAttsPage.addCDATAAttribute("zone", _escape(zone.getName()));
171        }
172        if (zoneItem != null)
173        {
174            cAttsPage.addCDATAAttribute("metadataSetName", _escape(StringUtils.defaultString(zoneItem.getMetadataSetName(), "main")));
175        }
176        _saxTags (page, cAttsPage);
177
178        XMLUtils.createElement(contentHandler, "page", cAttsPage);
179    }
180
181    /**
182     * SAX page's tags
183     * @param page the page  
184     * @param attrs the attributes to SAX into
185     * @throws AmetysRepositoryException if failed to get page's tags
186     */
187    protected void _saxTags(Page page, AttributesImpl attrs) throws AmetysRepositoryException
188    {
189        for (String tag : page.getTags())
190        {
191            // FIXME use nested element not this dirty XML
192            attrs.addCDATAAttribute("PLUGIN_TAGS_" + tag, "empty");
193        }
194    }
195}