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