001/* 002 * Copyright 2014 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.clientsideelement.styles; 017 018import java.io.InputStream; 019import java.util.Collections; 020import java.util.Date; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 027import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.commons.lang3.StringUtils; 031import org.apache.excalibur.source.Source; 032import org.apache.excalibur.source.SourceResolver; 033 034import org.ametys.cms.clientsideelement.styles.StaticHTMLEditorStyleExtension; 035import org.ametys.cms.clientsideelement.styles.Style; 036import org.ametys.cms.clientsideelement.styles.StyleCategory; 037import org.ametys.web.repository.site.Site; 038import org.ametys.web.repository.site.SiteManager; 039 040/** 041 * Based on a configuration like the StaticHTMLEditorStyleExtension but the file is located inside the current skin directory (skin/conf/edition-styles.xml). 042 */ 043public class SkinHTMLEditorStyleExtension extends StaticHTMLEditorStyleExtension 044{ 045 /** The assocation skinId lastUpdateDate ; to know for a given skin when its conf file was read for the last time */ 046 protected Map<String, Long> _lastUpdates = new HashMap<>(); 047 /** The assocation skinId Style ; to know for a given skin its style */ 048 protected Map<String, StyleCategory> _paraStyleCategories = new HashMap<>(); 049 /** The assocation skinId Style ; to know for a given skin its style */ 050 protected Map<String, StyleCategory> _tableStyleCategories = new HashMap<>(); 051 /** The assocation skinId Style ; to know for a given skin its style */ 052 protected Map<String, StyleCategory> _imageStyleCategories = new HashMap<>(); 053 /** The assocation skinId Style ; to know for a given skin its style */ 054 protected Map<String, StyleCategory> _linkStyleCategories = new HashMap<>(); 055 /** The assocation skinId Style ; to know for a given skin its style */ 056 protected Map<String, StyleCategory> _ulStyleCategories = new HashMap<>(); 057 /** The assocation skinId Style ; to know for a given skin its style */ 058 protected Map<String, StyleCategory> _olStyleCategories = new HashMap<>(); 059 060 /** The excalibur source resolver */ 061 protected SourceResolver _sourceResolver; 062 /** The sites manager */ 063 protected SiteManager _siteManager; 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 super.service(manager); 069 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 070 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 071 } 072 073 @Override 074 public void configure(Configuration configuration) throws ConfigurationException 075 { 076 // Do nothing 077 } 078 079 @Override 080 protected String _getImport(Configuration configuration, Map<String, Object> contextualParameters) 081 { 082 String siteId = (String) contextualParameters.get("siteName"); 083 if (siteId == null) 084 { 085 getLogger().info("Cannot determine the current skin because cannot determine current site. Continue as if there is no HTML skin styles."); 086 return null; 087 } 088 089 Site site = _siteManager.getSite(siteId); 090 String skinId = site.getSkinId(); 091 092 String boFileLocation = "/skins/" + skinId + "/resources/"; 093 094 String uri = configuration.getValue(null); 095 return StringUtils.isBlank(uri) ? null : boFileLocation + uri; 096 } 097 098 099 @Override 100 public StyleCategory getPara(Map<String, Object> contextualParameters) 101 { 102 String currentSkin = _updateStyleCategories(contextualParameters); 103 return _paraStyleCategories.get(currentSkin); 104 } 105 @Override 106 public StyleCategory getImage(Map<String, Object> contextualParameters) 107 { 108 String currentSkin = _updateStyleCategories(contextualParameters); 109 return _imageStyleCategories.get(currentSkin); 110 } 111 @Override 112 public StyleCategory getLink(Map<String, Object> contextualParameters) 113 { 114 String currentSkin = _updateStyleCategories(contextualParameters); 115 return _linkStyleCategories.get(currentSkin); 116 } 117 @Override 118 public StyleCategory getOrderedList(Map<String, Object> contextualParameters) 119 { 120 String currentSkin = _updateStyleCategories(contextualParameters); 121 return _olStyleCategories.get(currentSkin); 122 } 123 @Override 124 public StyleCategory getTable(Map<String, Object> contextualParameters) 125 { 126 String currentSkin = _updateStyleCategories(contextualParameters); 127 return _tableStyleCategories.get(currentSkin); 128 } 129 @Override 130 public StyleCategory getUnorderedList(Map<String, Object> contextualParameters) 131 { 132 String currentSkin = _updateStyleCategories(contextualParameters); 133 return _ulStyleCategories.get(currentSkin); 134 } 135 136 /** 137 * Update if necessary the values associated with the current skin 138 * @param contextualParameters Contextuals parameters transmitted by the environment. 139 * @return The current skin 140 */ 141 protected String _updateStyleCategories(Map<String, Object> contextualParameters) 142 { 143 String siteId = (String) contextualParameters.get("siteName"); 144 if (siteId == null) 145 { 146 getLogger().info("Cannot determine the current skin because cannot determine current site. Continue as if there is no HTML skin styles."); 147 return null; 148 } 149 150 Site site = _siteManager.getSite(siteId); 151 String skinId = site.getSkinId(); 152 153 String url = "skin:" + skinId + "://conf/edition-styles.xml"; 154 155 Source configurationFile = null; 156 try 157 { 158 configurationFile = _sourceResolver.resolveURI(url); 159 if (configurationFile.exists()) 160 { 161 Long lastUpdate = _lastUpdates.get(skinId); 162 163 if (lastUpdate == null || lastUpdate < configurationFile.getLastModified()) 164 { 165 try (InputStream is = configurationFile.getInputStream()) 166 { 167 Configuration configuration = new DefaultConfigurationBuilder().build(is); 168 169 StyleCategory paraStyleCategory = _configureStyleCategory(configuration.getChild("para"), "skin." + skinId, null, contextualParameters); 170 StyleCategory imageStyleCategory = _configureStyleCategory(configuration.getChild("image"), "skin." + skinId, IMAGE_DEFAULT_ICONS, contextualParameters); 171 StyleCategory tableStyleCategory = _configureStyleCategory(configuration.getChild("table"), "skin." + skinId, TABLE_DEFAULT_ICONS, contextualParameters); 172 StyleCategory linkStyleCategory = _configureStyleCategory(configuration.getChild("link"), "skin." + skinId, LINK_DEFAULT_ICONS, contextualParameters); 173 StyleCategory ulStyleCategory = _configureStyleCategory(configuration.getChild("unorderedlist"), "skin." + skinId, UL_DEFAULT_ICONS, contextualParameters); 174 StyleCategory olStyleCategory = _configureStyleCategory(configuration.getChild("orderedlist"), "skin." + skinId, OL_DEFAULT_ICONS, contextualParameters); 175 176 _paraStyleCategories.put(skinId, paraStyleCategory); 177 _imageStyleCategories.put(skinId, imageStyleCategory); 178 _tableStyleCategories.put(skinId, tableStyleCategory); 179 _linkStyleCategories.put(skinId, linkStyleCategory); 180 _ulStyleCategories.put(skinId, ulStyleCategory); 181 _olStyleCategories.put(skinId, olStyleCategory); 182 183 _lastUpdates.put(skinId, configurationFile.getLastModified()); 184 } 185 } 186 } 187 else 188 { 189 _defaultValues(skinId); 190 } 191 } 192 catch (Exception e) 193 { 194 _defaultValues(skinId); 195 if (getLogger().isWarnEnabled()) 196 { 197 getLogger().warn("Cannot read the configuration file " + url + ". Continue as if file was not existing", e); 198 } 199 } 200 201 return skinId; 202 } 203 204 /** 205 * Set default values for the given skin 206 * @param skinId The skin 207 */ 208 protected void _defaultValues(String skinId) 209 { 210 List<Style> emptyList = Collections.emptyList(); 211 _paraStyleCategories.put(skinId, new StyleCategory(null, null, emptyList)); 212 _lastUpdates.put(skinId, new Date().getTime()); 213 } 214}