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.content; 017 018import java.io.IOException; 019import java.util.Collection; 020import java.util.Map; 021 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.cocoon.ProcessingException; 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.lang.StringUtils; 031import org.xml.sax.SAXException; 032 033import org.ametys.cms.repository.Content; 034import org.ametys.cms.tag.TagProviderExtensionPoint; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.plugins.repository.AmetysRepositoryException; 037import org.ametys.plugins.repository.version.VersionableAmetysObject; 038import org.ametys.web.repository.content.SharedContent; 039import org.ametys.web.repository.content.WebContent; 040import org.ametys.web.repository.page.Page; 041import org.ametys.web.repository.page.SitemapElement; 042import org.ametys.web.repository.page.Zone; 043import org.ametys.web.repository.page.ZoneItem; 044 045/** 046 * SAX {@link Page}s referencing the content. 047 */ 048public class ContentPagesGenerator extends ServiceableGenerator 049{ 050 private AmetysObjectResolver _resolver; 051 private TagProviderExtensionPoint _tagProviderExtensionPoint; 052 053 @Override 054 public void service(ServiceManager smanager) throws ServiceException 055 { 056 super.service(smanager); 057 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 058 _tagProviderExtensionPoint = (TagProviderExtensionPoint) smanager.lookup(TagProviderExtensionPoint.ROLE); 059 } 060 061 @Override 062 public void generate() throws IOException, SAXException, ProcessingException 063 { 064 Request request = ObjectModelHelper.getRequest(objectModel); 065 Content content = (Content) request.getAttribute(Content.class.getName()); 066 067 if (content == null) 068 { 069 String contentId = request.getParameter("contentId"); 070 content = _resolver.resolveById(contentId); 071 } 072 073 contentHandler.startDocument(); 074 XMLUtils.startElement(contentHandler, "pages"); 075 076 // Take the HEAD revision 077 String revision = ((VersionableAmetysObject) content).getRevision(); 078 ((VersionableAmetysObject) content).switchToRevision(null); 079 080 if (content instanceof WebContent) 081 { 082 Collection<ZoneItem> zoneItems = ((WebContent) content).getReferencingZoneItems(); 083 084 // For a shared content, we are mainly interrested in refereces of the initial content! 085 if (content instanceof SharedContent && ((SharedContent) content).getInitialContent() instanceof WebContent) 086 { 087 zoneItems.addAll(((WebContent) ((SharedContent) content).getInitialContent()).getReferencingZoneItems()); 088 } 089 090 for (ZoneItem zoneItem : zoneItems) 091 { 092 Zone zone = zoneItem.getZone(); 093 SitemapElement sitemapElement = zone.getSitemapElement(); 094 095 if (sitemapElement instanceof Page page) 096 { 097 _saxPage(page, zone, zoneItem); 098 } 099 } 100 } 101 102 ((VersionableAmetysObject) content).switchToRevision(revision); 103 104 XMLUtils.endElement(contentHandler, "pages"); 105 contentHandler.endDocument(); 106 } 107 108 /** 109 * SAX a content's page. 110 * @param page the page to SAX. 111 * @param zone the zone the content is in. 112 * @param zoneItem the the zone item the content belongs to. 113 * @throws SAXException if an error occurs. 114 */ 115 protected void _saxPage(Page page, Zone zone, ZoneItem zoneItem) throws SAXException 116 { 117 AttributesImpl cAttsPage = new AttributesImpl(); 118 cAttsPage.addCDATAAttribute("id", _escape(page.getId())); 119 cAttsPage.addCDATAAttribute("name", _escape(page.getName())); 120 cAttsPage.addCDATAAttribute("path", _escape(page.getPathInSitemap())); 121 cAttsPage.addCDATAAttribute("title", _escape(page.getTitle())); 122 cAttsPage.addCDATAAttribute("long-title", _escape(page.getLongTitle())); 123 cAttsPage.addCDATAAttribute("lang", _escape(page.getSitemap().getName())); 124 cAttsPage.addCDATAAttribute("site", _escape(page.getSite().getName())); 125 cAttsPage.addCDATAAttribute("zone", _escape(zone.getName())); 126 cAttsPage.addCDATAAttribute("metadataSetName", _escape(StringUtils.defaultString(zoneItem.getViewName(), "main"))); 127 128 _saxTags (page, cAttsPage); 129 130 XMLUtils.createElement(contentHandler, "page", cAttsPage); 131 } 132 133 /** 134 * SAX page's tags 135 * @param page the page 136 * @param attrs the attributes to SAX into 137 * @throws AmetysRepositoryException if failed to get page's tags 138 */ 139 protected void _saxTags(Page page, AttributesImpl attrs) throws AmetysRepositoryException 140 { 141 for (String tag : page.getTags()) 142 { 143 Map<String, Object> params = Map.of("siteName", page.getSiteName()); 144 if (_tagProviderExtensionPoint.hasTag(tag, params)) 145 { 146 // FIXME use nested element not this dirty XML 147 attrs.addCDATAAttribute("PLUGIN_TAGS_" + tag, "empty"); 148 } 149 } 150 } 151 152 private String _escape(String target) 153 { 154 if (target == null) 155 { 156 return ""; 157 } 158 return target.replaceAll("&", "&").replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"").replaceAll("<", "<").replaceAll(">", ">"); 159 } 160 161}