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