001/* 002 * Copyright 2018 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.model; 017 018import java.util.Map; 019 020import org.apache.avalon.framework.configuration.Configuration; 021import org.apache.avalon.framework.configuration.ConfigurationException; 022import org.apache.avalon.framework.service.ServiceManager; 023import org.apache.commons.lang3.StringUtils; 024 025import org.ametys.runtime.i18n.I18nizableText; 026import org.ametys.runtime.model.disableconditions.DisableCondition; 027import org.ametys.runtime.model.disableconditions.DisableConditions; 028import org.ametys.runtime.model.exception.UnknownTypeException; 029import org.ametys.runtime.model.type.ModelItemType; 030import org.ametys.runtime.model.type.ModelItemTypeExtensionPoint; 031 032/** 033 * {@link ModelItem} parser from an XML configuration. 034 */ 035public abstract class AbstractModelItemParser 036{ 037 /** The extension point to use to get available model items types */ 038 protected ModelItemTypeExtensionPoint _modelItemTypeExtensionPoint; 039 040 /** 041 * Creates a model item parser. 042 * @param modelItemTypeExtensionPoint the extension point to use to get available model items types 043 */ 044 public AbstractModelItemParser(ModelItemTypeExtensionPoint modelItemTypeExtensionPoint) 045 { 046 _modelItemTypeExtensionPoint = modelItemTypeExtensionPoint; 047 } 048 049 /** 050 * Parses an element definition from a XML configuration. 051 * @param <T> type of the parsed item 052 * @param serviceManager the service manager 053 * @param pluginName the plugin name declaring this item. 054 * @param itemConfig the XML configuration of the model item. 055 * @param model the model which defines the model item 056 * @param parent the parent of the model item to create. Can be null if the model item to parse has no parent 057 * @return the parsed model item. 058 * @throws ConfigurationException if the configuration is not valid. 059 */ 060 @SuppressWarnings("unchecked") 061 public <T extends ModelItem> T parse(ServiceManager serviceManager, String pluginName, Configuration itemConfig, Model model, ModelItemGroup parent) throws ConfigurationException 062 { 063 return (T) parse(serviceManager, pluginName, "plugin." + pluginName, itemConfig, model, parent); 064 } 065 066 /** 067 * Parses an element definition from a XML configuration. 068 * @param <T> type of the parsed item 069 * @param serviceManager the service manager 070 * @param pluginName the plugin name declaring this item. 071 * @param catalog the catalog 072 * @param itemConfig the XML configuration of the model item. 073 * @param model the model which defines the model item 074 * @param parent the parent of the model item to create. Can be null if the model item to parse has no parent 075 * @return the parsed model item. 076 * @throws ConfigurationException if the configuration is not valid. 077 */ 078 @SuppressWarnings("unchecked") 079 public <T extends ModelItem> T parse(ServiceManager serviceManager, String pluginName, String catalog, Configuration itemConfig, Model model, ModelItemGroup parent) throws ConfigurationException 080 { 081 ModelItem modelItem = _createModelItem(itemConfig); 082 083 modelItem.setModel(model); 084 if (parent != null) 085 { 086 parent.addChild(modelItem); 087 } 088 089 modelItem.setName(_parseName(itemConfig)); 090 modelItem.setPluginName(pluginName); 091 modelItem.setLabel(_parseI18nizableText(itemConfig, catalog, "label")); 092 modelItem.setDescription(_parseI18nizableText(itemConfig, catalog, "description")); 093 modelItem.setType(_parseType(itemConfig)); 094 095 modelItem.setWidget(_parseWidget(itemConfig)); 096 modelItem.setWidgetParameters(_parseWidgetParameters(itemConfig, pluginName)); 097 modelItem.setDisableConditions(_parseDisableConditions(itemConfig)); 098 099 return (T) modelItem; 100 } 101 102 /** 103 * Create the model item to populate it. 104 * @param itemConfig the model item configuration to use. 105 * @return the item instantiated. 106 * @throws ConfigurationException if the configuration is not valid. 107 */ 108 protected abstract ModelItem _createModelItem(Configuration itemConfig) throws ConfigurationException; 109 110 /** 111 * Parses the name of the model item. 112 * @param itemConfig the model item configuration to use. 113 * @return the name of the model item. 114 * @throws ConfigurationException if the configuration is not valid. 115 */ 116 protected String _parseName(Configuration itemConfig) throws ConfigurationException 117 { 118 return ItemParserHelper.parseName(itemConfig, _getNameConfigurationAttribute()); 119 } 120 121 /** 122 * Retrieves the name of the configuration attribute that contains the name of the model item 123 * @return the name of the configuration attribute that contains the name of the model item 124 */ 125 protected String _getNameConfigurationAttribute() 126 { 127 return "name"; 128 } 129 130 /** 131 * Parses a mandatory i18n text configuration, throwing an exception if empty. 132 * @param config the configuration to use. 133 * @param catalog the catalog 134 * @param name the child name. 135 * @return the i18n text. 136 * @throws ConfigurationException if the configuration is not valid. 137 */ 138 protected I18nizableText _parseI18nizableText(Configuration config, String catalog, String name) throws ConfigurationException 139 { 140 return I18nizableText.parseI18nizableText(config.getChild(name), catalog); 141 } 142 143 /** 144 * Parse an optional i18n text configuration, with a default i18n text value. 145 * @param config the configuration to use. 146 * @param catalog the catalog 147 * @param name the child name. 148 * @param defaultValueCatalog the catalog of the default i18n text value 149 * @param defaultValue the default i18n text value. 150 * @return the i18n text. 151 */ 152 protected I18nizableText _parseI18nizableText(Configuration config, String catalog, String name, String defaultValueCatalog, String defaultValue) 153 { 154 return I18nizableText.parseI18nizableText(config.getChild(name), catalog, new I18nizableText(defaultValueCatalog, defaultValue)); 155 } 156 157 /** 158 * Parses the type. 159 * @param config the model item configuration to use. 160 * @return the type. 161 * @throws ConfigurationException if the configuration is not valid. 162 */ 163 protected ModelItemType _parseType(Configuration config) throws ConfigurationException 164 { 165 String typeId = config.getAttribute("type"); 166 167 if (!_modelItemTypeExtensionPoint.hasExtension(typeId)) 168 { 169 String modelItemName = _parseName(config); 170 String availableTypes = StringUtils.join(_modelItemTypeExtensionPoint.getExtensionsIds(), ", "); 171 UnknownTypeException ute = new UnknownTypeException("The type '" + typeId + "' is not available for the extension point '" + _modelItemTypeExtensionPoint + "'. Available types are: '" + availableTypes + "'."); 172 throw new ConfigurationException("Unable to find the type '" + typeId + "' defined on the item '" + modelItemName + "'.", ute); 173 } 174 175 return _modelItemTypeExtensionPoint.getExtension(typeId); 176 } 177 178 /** 179 * Parses the disable condition. 180 * @param definitionConfiguration the configuration of the model item 181 * @return result the parsed disable condition to be converted in JSON 182 * @throws ConfigurationException if an error occurred 183 */ 184 protected DisableConditions _parseDisableConditions(Configuration definitionConfiguration) throws ConfigurationException 185 { 186 Configuration disableConditionsConfiguration = definitionConfiguration.getChild("disable-conditions", false); 187 return _parseConditions(disableConditionsConfiguration); 188 } 189 190 /** 191 * Parses the disable condition. 192 * @param disableConditionsConfiguration the configuration of the disable condition 193 * @return result the parsed disable condition to be converted in JSON 194 * @throws ConfigurationException if an error occurred 195 */ 196 protected DisableConditions _parseConditions(Configuration disableConditionsConfiguration) throws ConfigurationException 197 { 198 DisableConditions conditions = null; 199 200 if (disableConditionsConfiguration != null) 201 { 202 conditions = new DisableConditions(); 203 204 Configuration[] conditionsConfiguration = disableConditionsConfiguration.getChildren(); 205 for (Configuration conditionConfiguration : conditionsConfiguration) 206 { 207 String tagName = conditionConfiguration.getName(); 208 209 // Recursive case 210 if (tagName.equals("conditions")) 211 { 212 conditions.getSubConditions().add(_parseConditions(conditionConfiguration)); 213 } 214 else if (tagName.equals("condition")) 215 { 216 String id = conditionConfiguration.getAttribute("id"); 217 DisableCondition.OPERATOR operator = DisableCondition.OPERATOR.valueOf(conditionConfiguration.getAttribute("operator", "eq").toUpperCase()); 218 String value = conditionConfiguration.getValue(""); 219 220 221 DisableCondition condition = new DisableCondition(id, operator, value); 222 conditions.getConditions().add(condition); 223 } 224 } 225 226 conditions.setAssociation(DisableConditions.ASSOCIATION_TYPE.valueOf(disableConditionsConfiguration.getAttribute("type", "and").toUpperCase())); 227 } 228 229 return conditions; 230 } 231 232 /** 233 * Parses the widget. 234 * @param definitionConfig the element definition configuration to use. 235 * @return the widget or <code>null</code> if none defined. 236 * @throws ConfigurationException if the configuration is not valid. 237 */ 238 protected String _parseWidget(Configuration definitionConfig) throws ConfigurationException 239 { 240 return ItemParserHelper.parseWidget(definitionConfig); 241 } 242 243 /** 244 * Parses the widget's parameters 245 * @param definitionConfig the parameter ele;ent definition to use. 246 * @param pluginName the current plugin name. 247 * @return the widget's parameters in a Map 248 * @throws ConfigurationException if the configuration is not valid. 249 */ 250 protected Map<String, I18nizableText> _parseWidgetParameters(Configuration definitionConfig, String pluginName) throws ConfigurationException 251 { 252 return ItemParserHelper.parseWidgetParameters(definitionConfig, pluginName); 253 } 254}