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.cms.clientsideelement.styles; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.LinkedHashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import org.apache.avalon.framework.configuration.Configurable; 026import org.apache.avalon.framework.configuration.Configuration; 027import org.apache.avalon.framework.configuration.ConfigurationException; 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.commons.lang3.StringUtils; 033import org.apache.excalibur.source.SourceResolver; 034 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.runtime.plugin.component.PluginAware; 037 038/** 039 * This implementation is based upon a static configuration. 040 * FIXME For now, this implementation only supports styles for contents ('content' category). It cannot provided styles for other richtext 041 */ 042public class StaticHTMLEditorContentStyle extends AbstractLogEnabled implements HTMLEditorStyle, Configurable, Serviceable, PluginAware 043{ 044 /** Default icons style for table */ 045 protected static final String[] TABLE_DEFAULT_ICONS = new String[] {"/plugins/cms/resources/img/content/edition/table/Table_Border_16.png", "/plugins/cms/resources/img/content/edition/table/Table_Border_32.png", "/plugins/cms/resources/img/content/edition/table/Table_Border_32.png"}; 046 /** Default icons style for link */ 047 protected static final String[] LINK_DEFAULT_ICONS = new String[] {"/plugins/cms/resources/img/content/edition/link/Style_Normal_16.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png"}; 048 /** Default icons style for image */ 049 protected static final String[] IMAGE_DEFAULT_ICONS = new String[] {"/plugins/cms/resources/img/content/edition/image/Image_Style_Border_16.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png"}; 050 /** Default icons style for unordered list */ 051 protected static final String[] UL_DEFAULT_ICONS = new String[] {"/plugins/cms/resources/img/content/edition/list/disc_16.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png"}; 052 /** Default icons style for ordered list */ 053 protected static final String[] OL_DEFAULT_ICONS = new String[] {"/plugins/cms/resources/img/content/edition/list/decimal_16.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png", "/plugins/cms/resources/img/content/edition/link/Style_Normal_32.png"}; 054 055 /** Excalibur source resolver */ 056 protected SourceResolver _resolver; 057 /** The values of the file */ 058 protected StyleCategory _paraStyleCategory; 059 /** The values of the file */ 060 protected StyleCategory _tableStyleCategory; 061 /** The values of the file */ 062 protected StyleCategory _linkStyleCategory; 063 /** The values of the file */ 064 protected StyleCategory _imageStyleCategory; 065 /** The values of the file */ 066 protected StyleCategory _ulStyleCategory; 067 /** The values of the file */ 068 protected StyleCategory _olStyleCategory; 069 /** The plugin that declared the instance */ 070 protected String _pluginName; 071 /** The feature that declared the instance */ 072 protected String _featureName; 073 074 @Override 075 public void service(ServiceManager manager) throws ServiceException 076 { 077 _resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 078 } 079 080 @Override 081 public void setPluginInfo(String pluginName, String featureName, String id) 082 { 083 _pluginName = pluginName; 084 _featureName = featureName; 085 } 086 087 @Override 088 public void configure(Configuration configuration) throws ConfigurationException 089 { 090 _configure(configuration, "param.edition-styles", new HashMap<>()); 091 } 092 093 /** 094 * Configure this instance upon a configuration 095 * @param configuration The configuration 096 * @param defaultCatalogue The default i18n catalogue to use 097 * @param contextParameters Contextuals parameters transmitted by the environment. 098 * @throws ConfigurationException If the configuration is incorrect 099 */ 100 protected void _configure(Configuration configuration, String defaultCatalogue, Map<String, Object> contextParameters) throws ConfigurationException 101 { 102 _paraStyleCategory = _configureStyleCategory(configuration.getChild("para"), defaultCatalogue, null, contextParameters); 103 _tableStyleCategory = _configureStyleCategory(configuration.getChild("table"), defaultCatalogue, TABLE_DEFAULT_ICONS, contextParameters); 104 _linkStyleCategory = _configureStyleCategory(configuration.getChild("link"), defaultCatalogue, LINK_DEFAULT_ICONS, contextParameters); 105 _imageStyleCategory = _configureStyleCategory(configuration.getChild("image"), defaultCatalogue, IMAGE_DEFAULT_ICONS, contextParameters); 106 _ulStyleCategory = _configureStyleCategory(configuration.getChild("unorderedlist"), defaultCatalogue, UL_DEFAULT_ICONS, contextParameters); 107 _olStyleCategory = _configureStyleCategory(configuration.getChild("orderedlist"), defaultCatalogue, OL_DEFAULT_ICONS, contextParameters); 108 } 109 110 /** 111 * Configure this instance upon the style part of a configuration 112 * @param styleConfiguration The style part of the configuration 113 * @param defaultCatalogue The default i18n catalogue to use 114 * @param defaultIcons the path to the button's default icons in small, medium and large size 115 * @param contextParameters Contextuals parameters transmitted by the environment. 116 * @return The style that represents the values read 117 * @throws ConfigurationException If the configuration is incorrect 118 */ 119 protected StyleCategory _configureStyleCategory(Configuration styleConfiguration, String defaultCatalogue, String[] defaultIcons, Map<String, Object> contextParameters) throws ConfigurationException 120 { 121 String defaultInlineEditor = styleConfiguration.getAttribute("defaultInlineEditor", null); 122 List<String> removeInlineEditor = List.of(StringUtils.split(styleConfiguration.getAttribute("removeInlineEditor", ""), " ,")); 123 124 Set<String> boCSSFiles = new LinkedHashSet<>(); 125 Set<String> inlineEditorCSSFiles = new LinkedHashSet<>(); 126 127 for (Configuration configuration : styleConfiguration.getChild("import").getChildren("button")) 128 { 129 boCSSFiles.add(_getImport(configuration, contextParameters)); 130 // adding null will be ignored later 131 } 132 for (Configuration configuration : styleConfiguration.getChild("import").getChildren("inline-editor")) 133 { 134 inlineEditorCSSFiles.add(_getImport(configuration, contextParameters)); 135 // adding null will be ignored later 136 } 137 138 List<Style> styleList = new ArrayList<>(); 139 for (Configuration styleConf : styleConfiguration.getChildren("style")) 140 { 141 Style style = _configureStyle(styleConf, defaultCatalogue, defaultIcons, contextParameters); 142 styleList.add(style); 143 } 144 145 return new StyleCategory(boCSSFiles, inlineEditorCSSFiles, styleList, defaultInlineEditor, removeInlineEditor); 146 } 147 148 /** 149 * Determine an url from a configuration node. 150 * @param configuration Read the optional plugin attribute and concatenate it to the value of the node. Can be null 151 * @param contextParameters Contextuals parameters transmitted by the environment. 152 * @return The non-null path to the plugin resource 153 */ 154 protected String _getImport(Configuration configuration, Map<String, Object> contextParameters) 155 { 156 String boPlugin = configuration.getAttribute("plugin", null); 157 158 String boFileLocation; 159 if (StringUtils.isNotBlank(boPlugin)) 160 { 161 boFileLocation = "/plugins/" + boPlugin + "/resources/"; 162 } 163 else 164 { 165 boFileLocation = "/param_resources/edition-styles/"; 166 } 167 168 String uri = configuration.getValue(null); 169 return StringUtils.isBlank(uri) ? null : boFileLocation + uri; 170 } 171 172 /** 173 * Configure a style 174 * @param configuration The style configuration 175 * @param defaultCatalogue The default i18n catalogue to use 176 * @param defaultIcons the path to the button's default icons in small, medium and large size 177 * @param contextParameters Contextual parameters transmitted by the environment. 178 * @return The style configured 179 * @throws ConfigurationException If the configuration is incorrect 180 */ 181 protected Style _configureStyle(Configuration configuration, String defaultCatalogue, String[] defaultIcons, Map<String, Object> contextParameters) throws ConfigurationException 182 { 183 String buttonSmallIcon = defaultIcons != null ? defaultIcons[0] : null; 184 String buttonMediumIcon = defaultIcons != null ? defaultIcons[1] : null; 185 String buttonLargeIcon = defaultIcons != null ? defaultIcons[2] : null; 186 I18nizableText buttonLabel; 187 I18nizableText buttonDescription; 188 String buttonCSSClass; 189 190 Configuration iconSmallConf = configuration.getChild("button").getChild("icon-small", false); 191 if (iconSmallConf != null) 192 { 193 buttonSmallIcon = _getImport(iconSmallConf, contextParameters); 194 } 195 196 Configuration iconMediumConf = configuration.getChild("button").getChild("icon-medium", false); 197 if (iconMediumConf == null) 198 { 199 // Try to look for "icon" if no "icon-medium". 200 iconMediumConf = configuration.getChild("button").getChild("icon", false); 201 } 202 203 if (iconMediumConf != null) 204 { 205 buttonMediumIcon = _getImport(iconMediumConf, contextParameters); 206 } 207 208 Configuration iconLargeConf = configuration.getChild("button").getChild("icon-large", false); 209 if (iconLargeConf == null) 210 { 211 // Try to look for "icon" if no "icon-large". 212 iconLargeConf = configuration.getChild("button").getChild("icon", false); 213 } 214 215 if (iconLargeConf != null) 216 { 217 buttonLargeIcon = _getImport(iconLargeConf, contextParameters); 218 } 219 220 Configuration labelConf = configuration.getChild("button").getChild("label"); 221 if (labelConf.getAttributeAsBoolean("i18n", false)) 222 { 223 buttonLabel = new I18nizableText(defaultCatalogue, labelConf.getValue()); 224 } 225 else 226 { 227 buttonLabel = new I18nizableText(labelConf.getValue()); 228 } 229 230 Configuration descriptionConf = configuration.getChild("button").getChild("description"); 231 if (descriptionConf.getAttributeAsBoolean("i18n", false)) 232 { 233 buttonDescription = new I18nizableText(defaultCatalogue, descriptionConf.getValue()); 234 } 235 else 236 { 237 buttonDescription = new I18nizableText(descriptionConf.getValue()); 238 } 239 240 buttonCSSClass = configuration.getChild("button").getChild("cssclass").getValue(""); 241 242 String inlineEditorRender = configuration.getChild("inline-editor").getValue(); 243 244 return new Style(buttonLabel, buttonDescription, buttonSmallIcon, buttonMediumIcon, buttonLargeIcon, buttonCSSClass, inlineEditorRender); 245 } 246 247 @Override 248 public Set<String> getCategories() 249 { 250 return Set.of("content"); 251 } 252 253 @Override 254 public StyleCategory getPara(String category, Map<String, Object> contextualParameters) 255 { 256 return "content".equals(category) ? _paraStyleCategory : null; 257 } 258 259 @Override 260 public StyleCategory getTable(String category, Map<String, Object> contextualParameters) 261 { 262 return "content".equals(category) ? _tableStyleCategory : null; 263 } 264 265 @Override 266 public StyleCategory getLink(String category, Map<String, Object> contextualParameters) 267 { 268 return "content".equals(category) ? _linkStyleCategory : null; 269 } 270 271 @Override 272 public StyleCategory getImage(String category, Map<String, Object> contextualParameters) 273 { 274 return "content".equals(category) ? _imageStyleCategory : null; 275 } 276 277 @Override 278 public StyleCategory getUnorderedList(String category, Map<String, Object> contextualParameters) 279 { 280 return "content".equals(category) ? _ulStyleCategory : null; 281 } 282 283 @Override 284 public StyleCategory getOrderedList(String category, Map<String, Object> contextualParameters) 285 { 286 return "content".equals(category) ? _olStyleCategory : null; 287 } 288}