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