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.tags.inputdata; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.ArrayList; 021import java.util.List; 022 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 025import org.apache.avalon.framework.context.Context; 026import org.apache.avalon.framework.context.ContextException; 027import org.apache.avalon.framework.context.Contextualizable; 028import org.apache.avalon.framework.logger.AbstractLogEnabled; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032import org.apache.avalon.framework.thread.ThreadSafe; 033import org.apache.cocoon.ProcessingException; 034import org.apache.cocoon.components.ContextHelper; 035import org.apache.cocoon.environment.Request; 036import org.apache.cocoon.xml.XMLUtils; 037import org.apache.excalibur.source.Source; 038import org.apache.excalibur.source.SourceNotFoundException; 039import org.apache.excalibur.source.SourceResolver; 040import org.xml.sax.ContentHandler; 041import org.xml.sax.SAXException; 042 043import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 044import org.ametys.cms.tag.TagProviderExtensionPoint; 045import org.ametys.plugins.repository.AmetysObjectResolver; 046import org.ametys.runtime.plugin.component.PluginAware; 047import org.ametys.web.content.GetSiteAction; 048import org.ametys.web.filter.ContentFilterHelper; 049import org.ametys.web.filter.StaticWebContentFilter; 050import org.ametys.web.filter.WebContentFilter; 051import org.ametys.web.inputdata.InputData; 052import org.ametys.web.repository.page.Page; 053import org.ametys.web.repository.site.Site; 054import org.ametys.web.repository.site.SiteManager; 055 056/** 057 * This class generates an output with all existing filters defined on context's current page. 058 */ 059public class FilteredContentsInputData extends AbstractLogEnabled implements InputData, Serviceable, Contextualizable, ThreadSafe, PluginAware 060{ 061 /** The plugin name */ 062 protected String _pluginName; 063 /** The source resolver */ 064 protected SourceResolver _sourceResolver; 065 /** The repository */ 066 protected AmetysObjectResolver _resolver; 067 /** The extension point for content types */ 068 protected ContentTypeExtensionPoint _contentTypeEP; 069 /** The avalon context. */ 070 protected Context _context; 071 /** The site manager */ 072 protected SiteManager _siteManager; 073 /** The tag provider EP */ 074 protected TagProviderExtensionPoint _tagProviderEP; 075 076 private ContentFilterHelper _filterHelper; 077 078 @Override 079 public void service(ServiceManager smanager) throws ServiceException 080 { 081 _sourceResolver = (SourceResolver) smanager.lookup(SourceResolver.ROLE); 082 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 083 _contentTypeEP = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE); 084 _filterHelper = (ContentFilterHelper) smanager.lookup(ContentFilterHelper.ROLE); 085 _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE); 086 _tagProviderEP = (TagProviderExtensionPoint) smanager.lookup(TagProviderExtensionPoint.ROLE); 087 } 088 089 @Override 090 public boolean isCacheable(Site site, Page page) 091 { 092 return true; 093 } 094 095 @Override 096 public void toSAX(ContentHandler contentHandler) throws SAXException, ProcessingException 097 { 098 Page page = (Page) ContextHelper.getRequest(_context).getAttribute(Page.class.getName()); 099 String siteName = (String) ContextHelper.getRequest(_context).getAttribute("site"); 100 String lang = (String) ContextHelper.getRequest(_context).getAttribute("sitemapLanguage"); 101 102 contentHandler.startDocument(); 103 XMLUtils.startElement(contentHandler, "Model"); 104 105 try 106 { 107 List<WebContentFilter> filters = configureFilters(); 108 for (WebContentFilter filter : filters) 109 { 110 saxFilter(contentHandler, filter, siteName, lang, page); 111 } 112 } 113 catch (IOException e) 114 { 115 throw new ProcessingException("An error occurred while performing search on filtered contents", e); 116 } 117 118 XMLUtils.endElement(contentHandler, "Model"); 119 contentHandler.endDocument(); 120 } 121 122 /** 123 * Retrieves the configured filters 124 * @return The list of filters 125 * @throws ProcessingException If an error occurred while parsing the file. 126 */ 127 protected List<WebContentFilter> configureFilters () throws ProcessingException 128 { 129 List<WebContentFilter> filters = new ArrayList<>(); 130 131 Source source = null; 132 133 try 134 { 135 source = _sourceResolver.resolveURI("template://filters/default.xml"); 136 if (source.exists()) 137 { 138 try (InputStream is = source.getInputStream()) 139 { 140 Configuration configuration = new DefaultConfigurationBuilder().build(source.getInputStream()); 141 Configuration[] filterConfiguration = configuration.getChildren(); 142 143 for (Configuration filterConf : filterConfiguration) 144 { 145 if ("content".equals(filterConf.getAttribute("target"))) 146 { 147 StaticWebContentFilter filter = new StaticWebContentFilter (filterConf.getAttribute("id"), _resolver, _contentTypeEP, _siteManager, _tagProviderEP); 148 filter.configure(filterConf); 149 150 filters.add(filter); 151 } 152 } 153 } 154 } 155 156 return filters; 157 } 158 catch (SourceNotFoundException e) 159 { 160 return filters; 161 } 162 catch (Exception e) 163 { 164 throw new ProcessingException("Unable to parse filters file" , e); 165 } 166 finally 167 { 168 if (_sourceResolver != null && source != null) 169 { 170 _sourceResolver.release(source); 171 } 172 } 173 } 174 175 /** 176 * SAX a filter 177 * @param contentHandler The content handler 178 * @param filter The filter to SAX 179 * @param siteName The current site name 180 * @param lang The current language 181 * @param page The current page 182 * @throws SAXException If an errors occurs while SAXing 183 * @throws IOException If an errors occurs 184 */ 185 @SuppressWarnings("deprecation") 186 protected void saxFilter (ContentHandler contentHandler, WebContentFilter filter, String siteName, String lang, Page page) throws SAXException, IOException 187 { 188 Request request = ContextHelper.getRequest(_context); 189 String currentSiteName = (String) request.getAttribute("site"); 190 String currentSkinName = (String) request.getAttribute("skin"); 191 String currentTemplateName = (String) request.getAttribute("template"); 192 String currentLanguage = (String) request.getAttribute("renderingLanguage"); 193 194 // Issue CMS-3391 195 request.setAttribute(GetSiteAction.OVERRIDE_SITE_REQUEST_ATTR, currentSiteName); 196 request.setAttribute(GetSiteAction.OVERRIDE_SKIN_REQUEST_ATTR, currentSkinName); 197 198 try 199 { 200 String id = filter.getId(); 201 202 XMLUtils.startElement(contentHandler, id); 203 _filterHelper.saxMatchingContents(contentHandler, filter, siteName, lang, page); 204 XMLUtils.endElement(contentHandler, id); 205 } 206 finally 207 { 208 request.removeAttribute(GetSiteAction.OVERRIDE_SITE_REQUEST_ATTR); 209 request.removeAttribute(GetSiteAction.OVERRIDE_SKIN_REQUEST_ATTR); 210 request.setAttribute("site", currentSiteName); 211 request.setAttribute("skin", currentSkinName); 212 request.setAttribute("template", currentTemplateName); 213 request.setAttribute("renderingLanguage", currentLanguage); 214 } 215 } 216 217 @Override 218 public void contextualize(Context context) throws ContextException 219 { 220 _context = context; 221 } 222 223 @Override 224 public void setPluginInfo(String pluginName, String featureName, String id) 225 { 226 _pluginName = pluginName; 227 } 228}