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