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<String, Object>()); 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 Set<String> boCSSFiles = new LinkedHashSet<>(); 122 Set<String> inlineEditorCSSFiles = new LinkedHashSet<>(); 123 124 for (Configuration configuration : styleConfiguration.getChild("import").getChildren("button")) 125 { 126 boCSSFiles.add(_getImport(configuration, contextParameters)); 127 // adding null will be ignored later 128 } 129 for (Configuration configuration : styleConfiguration.getChild("import").getChildren("inline-editor")) 130 { 131 inlineEditorCSSFiles.add(_getImport(configuration, contextParameters)); 132 // adding null will be ignored later 133 } 134 135 List<Style> styleList = new ArrayList<>(); 136 for (Configuration styleConf : styleConfiguration.getChildren("style")) 137 { 138 Style style = _configureStyle(styleConf, defaultCatalogue, defaultIcons, contextParameters); 139 styleList.add(style); 140 } 141 142 return new StyleCategory(boCSSFiles, inlineEditorCSSFiles, styleList); 143 } 144 145 /** 146 * Determine an url from a configuration node. 147 * @param configuration Read the optional plugin attribute and concatenate it to the value of the node. Can be null 148 * @param contextParameters Contextuals parameters transmitted by the environment. 149 * @return The non-null path to the plugin resource 150 */ 151 protected String _getImport(Configuration configuration, Map<String, Object> contextParameters) 152 { 153 String boPlugin = configuration.getAttribute("plugin", null); 154 155 String boFileLocation; 156 if (StringUtils.isNotBlank(boPlugin)) 157 { 158 boFileLocation = "/plugins/" + boPlugin + "/resources/"; 159 } 160 else 161 { 162 boFileLocation = "/param_resources/edition-styles/"; 163 } 164 165 String uri = configuration.getValue(null); 166 return StringUtils.isBlank(uri) ? null : boFileLocation + uri; 167 } 168 169 /** 170 * Configure a style 171 * @param configuration The style configuration 172 * @param defaultCatalogue The default i18n catalogue to use 173 * @param defaultIcons the path to the button's default icons in small, medium and large size 174 * @param contextParameters Contextual parameters transmitted by the environment. 175 * @return The style configured 176 * @throws ConfigurationException If the configuration is incorrect 177 */ 178 protected Style _configureStyle(Configuration configuration, String defaultCatalogue, String[] defaultIcons, Map<String, Object> contextParameters) throws ConfigurationException 179 { 180 String buttonSmallIcon = defaultIcons != null ? defaultIcons[0] : null; 181 String buttonMediumIcon = defaultIcons != null ? defaultIcons[1] : null; 182 String buttonLargeIcon = defaultIcons != null ? defaultIcons[2] : null; 183 I18nizableText buttonLabel; 184 I18nizableText buttonDescription; 185 String buttonCSSClass; 186 187 Configuration iconSmallConf = configuration.getChild("button").getChild("icon-small", false); 188 if (iconSmallConf != null) 189 { 190 buttonSmallIcon = _getImport(iconSmallConf, contextParameters); 191 } 192 193 Configuration iconMediumConf = configuration.getChild("button").getChild("icon-medium", false); 194 if (iconMediumConf == null) 195 { 196 // Try to look for "icon" if no "icon-medium". 197 iconMediumConf = configuration.getChild("button").getChild("icon", false); 198 } 199 200 if (iconMediumConf != null) 201 { 202 buttonMediumIcon = _getImport(iconMediumConf, contextParameters); 203 } 204 205 Configuration iconLargeConf = configuration.getChild("button").getChild("icon-large", false); 206 if (iconLargeConf == null) 207 { 208 // Try to look for "icon" if no "icon-large". 209 iconLargeConf = configuration.getChild("button").getChild("icon", false); 210 } 211 212 if (iconLargeConf != null) 213 { 214 buttonLargeIcon = _getImport(iconLargeConf, contextParameters); 215 } 216 217 Configuration labelConf = configuration.getChild("button").getChild("label"); 218 if (labelConf.getAttributeAsBoolean("i18n", false)) 219 { 220 buttonLabel = new I18nizableText(defaultCatalogue, labelConf.getValue()); 221 } 222 else 223 { 224 buttonLabel = new I18nizableText(labelConf.getValue()); 225 } 226 227 Configuration descriptionConf = configuration.getChild("button").getChild("description"); 228 if (descriptionConf.getAttributeAsBoolean("i18n", false)) 229 { 230 buttonDescription = new I18nizableText(defaultCatalogue, descriptionConf.getValue()); 231 } 232 else 233 { 234 buttonDescription = new I18nizableText(descriptionConf.getValue()); 235 } 236 237 buttonCSSClass = configuration.getChild("button").getChild("cssclass").getValue(""); 238 239 String inlineEditorRender = configuration.getChild("inline-editor").getValue(); 240 241 return new Style(buttonLabel, buttonDescription, buttonSmallIcon, buttonMediumIcon, buttonLargeIcon, buttonCSSClass, inlineEditorRender); 242 } 243 244 @Override 245 public Set<String> getCategories() 246 { 247 return Set.of("content"); 248 } 249 250 @Override 251 public StyleCategory getPara(String category, Map<String, Object> contextualParameters) 252 { 253 return "content".equals(category) ? _paraStyleCategory : null; 254 } 255 256 @Override 257 public StyleCategory getTable(String category, Map<String, Object> contextualParameters) 258 { 259 return "content".equals(category) ? _tableStyleCategory : null; 260 } 261 262 @Override 263 public StyleCategory getLink(String category, Map<String, Object> contextualParameters) 264 { 265 return "content".equals(category) ? _linkStyleCategory : null; 266 } 267 268 @Override 269 public StyleCategory getImage(String category, Map<String, Object> contextualParameters) 270 { 271 return "content".equals(category) ? _imageStyleCategory : null; 272 } 273 274 @Override 275 public StyleCategory getUnorderedList(String category, Map<String, Object> contextualParameters) 276 { 277 return "content".equals(category) ? _ulStyleCategory : null; 278 } 279 280 @Override 281 public StyleCategory getOrderedList(String category, Map<String, Object> contextualParameters) 282 { 283 return "content".equals(category) ? _olStyleCategory : null; 284 } 285}