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.inputdata; 017 018import java.io.InputStream; 019import java.util.HashMap; 020import java.util.Map; 021 022import org.apache.avalon.framework.configuration.Configuration; 023import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 024import org.apache.avalon.framework.context.Context; 025import org.apache.avalon.framework.context.ContextException; 026import org.apache.avalon.framework.context.Contextualizable; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.cocoon.ProcessingException; 031import org.apache.cocoon.components.ContextHelper; 032import org.apache.cocoon.environment.Request; 033import org.xml.sax.ContentHandler; 034import org.xml.sax.SAXException; 035 036import org.ametys.core.util.filereloader.FileReloader; 037import org.ametys.core.util.filereloader.FileReloaderUtils; 038import org.ametys.runtime.plugin.component.AbstractLogEnabled; 039import org.ametys.web.WebConstants; 040import org.ametys.web.pageaccess.RestrictedPagePolicy; 041import org.ametys.web.repository.page.Page; 042import org.ametys.web.repository.site.Site; 043import org.ametys.web.repository.site.SiteManager; 044 045/** 046 * {@link InputData} for SAXing events about the current sitemap. 047 */ 048public class SitemapInputData extends AbstractLogEnabled implements InputData, Contextualizable, Serviceable, FileReloader 049{ 050 private static final String __INITIAL_DEPTH = "initial-depth"; 051 private static final String __DESCENDANT_DEPTH = "descendant-depth"; 052 053 private static final int __DEFAULT_INITIAL_DEPTH = 2; 054 private static final int __DEFAULT_DESCENDANT_DEPTH = 1; 055 056 private Context _context; 057 private SitemapSaxer _sitemapSaxer; 058 private FileReloaderUtils _fileReloaderUtils; 059 060 private Map<String, Map<String, Integer>> _sitemapCfgCache = new HashMap<>(); 061 private SiteManager _siteManager; 062 063 @Override 064 public void service(ServiceManager manager) throws ServiceException 065 { 066 _sitemapSaxer = (SitemapSaxer) manager.lookup(SitemapSaxer.ROLE); 067 _fileReloaderUtils = (FileReloaderUtils) manager.lookup(FileReloaderUtils.ROLE); 068 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 069 } 070 071 @Override 072 public void contextualize(Context context) throws ContextException 073 { 074 _context = context; 075 } 076 077 @Override 078 public boolean isCacheable(Site site, Page page) 079 { 080 return site.getRestrictedPagePolicy() == RestrictedPagePolicy.DISPLAYED; 081 } 082 083 public boolean shouldBeCached(Site site, Page page) 084 { 085 // Sometimes we return true to #isCacheable because the whole page is cacheable 086 // but we don't use general cache, so here we always answer yes 087 return false; 088 } 089 090 @Override 091 public void toSAX(ContentHandler handler) throws SAXException, ProcessingException 092 { 093 Request request = ContextHelper.getRequest(_context); 094 095 String siteName = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SITE_NAME); 096 String sitemapName = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SITEMAP_NAME); 097 098 Page page = (Page) request.getAttribute(WebConstants.REQUEST_ATTR_PAGE); 099 100 String skinId = _getSkinId(); 101 _loadSitemapConfiguration(); 102 103 int initialDepth = _sitemapCfgCache.get(skinId).get(__INITIAL_DEPTH); 104 int descendantDepth = _sitemapCfgCache.get(skinId).get(__DESCENDANT_DEPTH); 105 106 _sitemapSaxer.toSAX(handler, siteName, sitemapName, page, initialDepth, descendantDepth); 107 } 108 109 private void _loadSitemapConfiguration() 110 { 111 try 112 { 113 String file = "skin://conf/sitemap.xml"; 114 _fileReloaderUtils.updateFile(file, this); 115 } 116 catch (Exception e) 117 { 118 getLogger().error("An error occurred reading the sitemap configuration file {}.", "skin://conf/sitemap.xml", e); 119 } 120 } 121 122 public String getId(String sourceUrl) 123 { 124 return SitemapInputData.class.getName() + "#" + _getSkinId(); 125 } 126 127 private String _getSkinId() 128 { 129 Request request = ContextHelper.getRequest(_context); 130 131 String skinId = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SKIN_ID); 132 133 if (skinId == null) 134 { 135 String siteName = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SITE_NAME); 136 Site site = _siteManager.getSite(siteName); 137 return site.getSkinId(); 138 } 139 else 140 { 141 return skinId; 142 } 143 144 } 145 146 public void updateFile(String sourceUrl, InputStream is) throws Exception 147 { 148 int initialDepth = __DEFAULT_INITIAL_DEPTH; 149 int descendantDepth = __DEFAULT_DESCENDANT_DEPTH; 150 151 if (is != null) 152 { 153 Configuration cfg = new DefaultConfigurationBuilder().build(is); 154 initialDepth = _parseInt(cfg, __INITIAL_DEPTH, __DEFAULT_INITIAL_DEPTH); 155 descendantDepth = _parseInt(cfg, __DESCENDANT_DEPTH, __DEFAULT_DESCENDANT_DEPTH); 156 } 157 158 String skinId = _getSkinId(); 159 160 if (!_sitemapCfgCache.containsKey(skinId)) 161 { 162 _sitemapCfgCache.put(skinId, new HashMap<>()); 163 } 164 165 Map<String, Integer> skinConf = _sitemapCfgCache.get(skinId); 166 skinConf.put(__INITIAL_DEPTH, initialDepth); 167 skinConf.put(__DESCENDANT_DEPTH, descendantDepth); 168 } 169 170 private int _parseInt(Configuration cfg, String tagName, int defaultValue) 171 { 172 return cfg.getChild(tagName, true).getValueAsInteger(defaultValue); 173 } 174}