001/* 002 * Copyright 2012 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.runtime.parameter; 017 018import java.util.HashMap; 019import java.util.Map; 020import java.util.Map.Entry; 021 022import org.apache.avalon.framework.component.ComponentException; 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.commons.lang3.StringUtils; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029 030import org.ametys.plugins.core.ui.util.ConfigurationHelper; 031import org.ametys.runtime.i18n.I18nizableText; 032import org.ametys.runtime.model.ElementDefinitionParser; 033import org.ametys.runtime.plugin.component.ThreadSafeComponentManager; 034 035/** 036 * {@link Parameter} parser from an XML configuration. 037 * @param <P> the actual type of parameter. 038 * @param <T> the actual type of parameter type. 039 * @deprecated Use {@link ElementDefinitionParser} instead 040 */ 041@Deprecated 042public abstract class AbstractParameterParser<P extends Parameter<T>, T extends Enum<T>> 043{ 044 private static final Logger __LOGGER = LoggerFactory.getLogger(AbstractParameterParser.class); 045 046 /** The enumerators component manager. */ 047 protected ThreadSafeComponentManager<Enumerator> _enumeratorManager; 048 /** The validators component manager. */ 049 protected ThreadSafeComponentManager<Validator> _validatorManager; 050 private final Map<P, String> _validatorsToLookup = new HashMap<>(); 051 private final Map<P, String> _enumeratorsToLookup = new HashMap<>(); 052 053 054 /** 055 * Creates an AbstractParameterParser. 056 * @param enumeratorManager the enumerator component manager. 057 * @param validatorManager the validator component manager. 058 */ 059 public AbstractParameterParser(ThreadSafeComponentManager<Enumerator> enumeratorManager, ThreadSafeComponentManager<Validator> validatorManager) 060 { 061 _enumeratorManager = enumeratorManager; 062 _validatorManager = validatorManager; 063 } 064 065 /** 066 * Parses a parameter from a XML configuration. 067 * @param manager the service manager. 068 * @param pluginName the plugin name declaring this parameter. 069 * @param parameterConfig the XML configuration. 070 * @return the parsed parameter. 071 * @throws ConfigurationException if the configuration is not valid. 072 */ 073 public P parseParameter(ServiceManager manager, String pluginName, Configuration parameterConfig) throws ConfigurationException 074 { 075 P parameter = _createParameter(parameterConfig); 076 String parameterId = _parseId(parameterConfig); 077 078 parameter.setId(parameterId); 079 parameter.setPluginName(pluginName); 080 parameter.setLabel(_parseI18nizableText(parameterConfig, pluginName, "label")); 081 parameter.setDescription(_parseI18nizableText(parameterConfig, pluginName, "description")); 082 parameter.setType(_parseType(parameterConfig)); 083 parameter.setWidget(_parseWidget(parameterConfig)); 084 parameter.setWidgetParameters(_parseWidgetParameters(parameterConfig, pluginName)); 085 _parseAndSetEnumerator(pluginName, parameter, parameterId, parameterConfig); 086 _parseAndSetValidator(pluginName, parameter, parameterId, parameterConfig); 087 parameter.setDefaultValue(_parseDefaultValue(parameterConfig, parameter)); 088 089 _additionalParsing(manager, pluginName, parameterConfig, parameterId, parameter); 090 091 return parameter; 092 } 093 094 /** 095 * Retrieves local validators and enumerators components and set them into 096 * previous parameter parsed. 097 * @throws Exception if an error occurs. 098 */ 099 public void lookupComponents() throws Exception 100 { 101 _validatorManager.initialize(); 102 _enumeratorManager.initialize(); 103 104 for (Map.Entry<P, String> entry : _validatorsToLookup.entrySet()) 105 { 106 P parameter = entry.getKey(); 107 String validatorRole = entry.getValue(); 108 109 try 110 { 111 parameter.setValidator(_validatorManager.lookup(validatorRole)); 112 } 113 catch (ComponentException e) 114 { 115 throw new Exception("Unable to lookup validator role: '" + validatorRole + "' for parameter: " + parameter, e); 116 } 117 } 118 119 for (Map.Entry<P, String> entry : _enumeratorsToLookup.entrySet()) 120 { 121 P parameter = entry.getKey(); 122 String enumeratorRole = entry.getValue(); 123 124 try 125 { 126 parameter.setEnumerator(_enumeratorManager.lookup(enumeratorRole)); 127 } 128 catch (ComponentException e) 129 { 130 throw new Exception("Unable to lookup enumerator role: '" + enumeratorRole + "' for parameter: " + parameter, e); 131 } 132 } 133 } 134 135 /** 136 * Create the parameter to populate it. 137 * @param parameterConfig the parameter configuration to use. 138 * @return the parameter instantiated. 139 * @throws ConfigurationException if the configuration is not valid. 140 */ 141 protected abstract P _createParameter(Configuration parameterConfig) throws ConfigurationException; 142 143 /** 144 * Parses the id. 145 * @param parameterConfig the parameter configuration to use. 146 * @return the id. 147 * @throws ConfigurationException if the configuration is not valid. 148 */ 149 protected abstract String _parseId(Configuration parameterConfig) throws ConfigurationException; 150 151 /** 152 * Parses an i18n text. 153 * @param config the configuration to use. 154 * @param pluginName the current plugin name. 155 * @param name the child name. 156 * @return the i18n text. 157 * @throws ConfigurationException if the configuration is not valid. 158 */ 159 protected I18nizableText _parseI18nizableText(Configuration config, String pluginName, String name) throws ConfigurationException 160 { 161 return I18nizableText.parseI18nizableText(config.getChild(name), "plugin." + pluginName); 162 } 163 164 /** 165 * Parses the type. 166 * @param parameterConfig the parameter configuration to use. 167 * @return the type. 168 * @throws ConfigurationException if the configuration is not valid. 169 */ 170 protected abstract T _parseType(Configuration parameterConfig) throws ConfigurationException; 171 172 /** 173 * Parses the widget. 174 * @param parameterConfig the parameter configuration to use. 175 * @return the widget or <code>null</code> if none defined. 176 * @throws ConfigurationException if the configuration is not valid. 177 */ 178 protected String _parseWidget(Configuration parameterConfig) throws ConfigurationException 179 { 180 return parameterConfig.getChild("widget").getValue(null); 181 } 182 183 /** 184 * Parses the widget's parameters 185 * @param parameterConfig the parameter configuration to use. 186 * @param pluginName the current plugin name. 187 * @return the widget's parameters in a Map 188 * @throws ConfigurationException if the configuration is not valid. 189 */ 190 protected Map<String, I18nizableText> _parseWidgetParameters(Configuration parameterConfig, String pluginName) throws ConfigurationException 191 { 192 Map<String, I18nizableText> widgetParams = new HashMap<>(); 193 194 Configuration widgetParamsConfig = parameterConfig.getChild("widget-params", false); 195 if (widgetParamsConfig != null) 196 { 197 Map<String, Object> parsedParams = ConfigurationHelper.parsePluginParameters(widgetParamsConfig, pluginName, __LOGGER); 198 199 for (Entry<String, Object> param : parsedParams.entrySet()) 200 { 201 String paramName = param.getKey(); 202 Object value = param.getValue(); 203 if (value instanceof I18nizableText) 204 { 205 widgetParams.put(paramName, (I18nizableText) value); 206 } 207 else if (value instanceof String) 208 { 209 widgetParams.put(paramName, new I18nizableText((String) value)); 210 } 211 else 212 { 213 __LOGGER.warn("Widget parameter '{}' at location {} is of type [{}] which is not supported. It will be ignored.", paramName, parameterConfig.getLocation(), value.getClass()); 214 } 215 } 216 } 217 218 return widgetParams; 219 } 220 221 /** 222 * Parses the enumerator. 223 * @param pluginName the plugin name. 224 * @param parameter the parameter. 225 * @param parameterId the parameter id. 226 * @param parameterConfig the parameter configuration. 227 * @throws ConfigurationException if the configuration is not valid. 228 */ 229 @SuppressWarnings("unchecked") 230 protected void _parseAndSetEnumerator(String pluginName, P parameter, String parameterId, Configuration parameterConfig) throws ConfigurationException 231 { 232 Configuration enumeratorConfig = parameterConfig.getChild("enumeration", false); 233 234 if (enumeratorConfig != null) 235 { 236 Configuration customEnumerator = enumeratorConfig.getChild("custom-enumerator", false); 237 238 if (customEnumerator != null) 239 { 240 String enumeratorClassName = customEnumerator.getAttribute("class"); 241 242 try 243 { 244 Class enumeratorClass = Class.forName(enumeratorClassName); 245 _enumeratorManager.addComponent(pluginName, null, parameterId, enumeratorClass, parameterConfig); 246 } 247 catch (Exception e) 248 { 249 throw new ConfigurationException("Unable to instantiate enumerator for class: " + enumeratorClassName, e); 250 } 251 252 // This enumerator will be affected later when validatorManager 253 // will be initialized in lookupComponents() call 254 _enumeratorsToLookup.put(parameter, parameterId); 255 256 } 257 else 258 { 259 StaticEnumerator staticEnumerator = new StaticEnumerator(); 260 261 for (Configuration entryConfig : enumeratorConfig.getChildren("entry")) 262 { 263 String value = entryConfig.getChild("value").getValue(""); 264 I18nizableText label = null; 265 266 if (entryConfig.getChild("label", false) != null) 267 { 268 label = _parseI18nizableText(entryConfig, pluginName, "label"); 269 } 270 271 staticEnumerator.add(label, value); 272 } 273 274 parameter.setEnumerator(staticEnumerator); 275 } 276 } 277 } 278 279 /** 280 * Parses the validator. 281 * @param pluginName the plugin name. 282 * @param parameter the parameter. 283 * @param parameterId the parameter id. 284 * @param parameterConfig the parameter configuration. 285 * @throws ConfigurationException if the configuration is not valid. 286 */ 287 @SuppressWarnings("unchecked") 288 protected void _parseAndSetValidator(String pluginName, P parameter, String parameterId, Configuration parameterConfig) throws ConfigurationException 289 { 290 Configuration validatorConfig = parameterConfig.getChild("validation", false); 291 292 if (validatorConfig != null) 293 { 294 String validatorClassName = StringUtils.defaultIfBlank(validatorConfig.getChild("custom-validator").getAttribute("class", ""), DefaultValidator.class.getName()); 295 296 try 297 { 298 Class validatorClass = Class.forName(validatorClassName); 299 _validatorManager.addComponent(pluginName, null, parameterId, validatorClass, parameterConfig); 300 } 301 catch (Exception e) 302 { 303 throw new ConfigurationException("Unable to instantiate validator for class: " + validatorClassName, e); 304 } 305 306 // Will be affected later when validatorManager will be initialized 307 // in lookupComponents() call 308 _validatorsToLookup.put(parameter, parameterId); 309 } 310 } 311 312 /** 313 * Parses the default value. 314 * @param parameterConfig the parameter configuration. 315 * @param parameter the parameter. 316 * @return the default value or <code>null</code> if none defined. 317 * @throws ConfigurationException if the configuration is not valid. 318 */ 319 protected abstract Object _parseDefaultValue(Configuration parameterConfig, P parameter) throws ConfigurationException; 320 321 /** 322 * Called for additional parsing.<br> 323 * Default implementation does nothing. 324 * @param manager the sservice manager. 325 * @param pluginName the plugin name. 326 * @param parameterConfig the parameter configuration. 327 * @param parameterId the parameter id. 328 * @param parameter the parameter to populate. 329 * @throws ConfigurationException if the configuration is not valid. 330 */ 331 protected void _additionalParsing(ServiceManager manager, String pluginName, Configuration parameterConfig, String parameterId, P parameter) throws ConfigurationException 332 { 333 // Nothing to do 334 } 335}