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.regex.Pattern; 021 022import org.apache.avalon.framework.configuration.Configurable; 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.logger.AbstractLogEnabled; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.cocoon.util.log.SLF4JLoggerAdapter; 030import org.slf4j.LoggerFactory; 031 032import org.ametys.runtime.i18n.I18nizableText; 033import org.ametys.runtime.plugin.component.PluginAware; 034 035 036/** 037 * This default implementation validates the following configurable stuff: 038 * <ul> 039 * <li>mandatory: check the parameter is set</li> 040 * <li>regexp: check the string parameter matches a regexp</li> 041 * </ul> 042 */ 043public class DefaultValidator extends AbstractLogEnabled implements Validator, Configurable, PluginAware, Serviceable 044{ 045 /** Is the value mandatory ? */ 046 protected boolean _isMandatory; 047 /** Does the value need to match a regexp */ 048 protected Pattern _regexp; 049 /** The error text to display if regexp fails */ 050 protected I18nizableText _invalidText; 051 /** The plugin name */ 052 protected String _pluginName; 053 054 /** The service manager */ 055 protected ServiceManager _smanager; 056 057 /** 058 * Default constructor for avalon 059 */ 060 public DefaultValidator() 061 { 062 // empty 063 } 064 065 /** 066 * Manual constructor 067 * @param regexp The regexp to check or null 068 * @param mandatory Is the value mandatory 069 */ 070 public DefaultValidator(String regexp, boolean mandatory) 071 { 072 _isMandatory = mandatory; 073 if (regexp != null) 074 { 075 _regexp = Pattern.compile(regexp); 076 } 077 enableLogging(new SLF4JLoggerAdapter(LoggerFactory.getLogger(this.getClass()))); 078 } 079 080 /** 081 * Manual constructor 082 * @param regexp The regexp to check or null 083 * @param invalidText The error text to display 084 * @param mandatory Is the value mandatory 085 */ 086 public DefaultValidator(String regexp, I18nizableText invalidText, boolean mandatory) 087 { 088 _isMandatory = mandatory; 089 if (regexp != null) 090 { 091 _regexp = Pattern.compile(regexp); 092 } 093 _invalidText = invalidText; 094 095 enableLogging(new SLF4JLoggerAdapter(LoggerFactory.getLogger(this.getClass()))); 096 } 097 098 @Override 099 public void service(ServiceManager smanager) throws ServiceException 100 { 101 _smanager = smanager; 102 } 103 104 @Override 105 public void setPluginInfo(String pluginName, String featureName, String id) 106 { 107 _pluginName = pluginName; 108 } 109 110 @Override 111 public void configure(Configuration configuration) throws ConfigurationException 112 { 113 Configuration validatorConfig = configuration.getChild("validation"); 114 115 _isMandatory = validatorConfig.getChild("mandatory", false) != null; 116 117 String regexp = validatorConfig.getChild("regexp").getValue(null); 118 if (regexp != null) 119 { 120 _regexp = Pattern.compile(regexp); 121 } 122 123 Configuration textConfig = validatorConfig.getChild("invalidText", false); 124 if (textConfig != null) 125 { 126 _invalidText = I18nizableText.parseI18nizableText(textConfig, "plugin." + _pluginName); 127 } 128 } 129 130 @Override 131 public Map<String, Object> getConfiguration() 132 { 133 Map<String, Object> configuration = new HashMap<>(); 134 135 configuration.put("mandatory", Boolean.valueOf(_isMandatory)); 136 137 if (_regexp != null) 138 { 139 configuration.put("regexp", _regexp); 140 } 141 142 if (_invalidText != null) 143 { 144 configuration.put("invalidText", _invalidText); 145 } 146 147 return configuration; 148 } 149 150 @Override 151 public ValidationResult validate(Object value) 152 { 153 return value != null && value.getClass().isArray() 154 ? validateArrayValues((Object[]) value) 155 : validateSingleValue (value); 156 } 157 158 /** 159 * Validates a single value. 160 * @param value the value to validate (can be <code>null</code>). 161 * @return the validation result 162 */ 163 protected ValidationResult validateSingleValue (Object value) 164 { 165 ValidationResult result = new ValidationResult(); 166 167 if (_isMandatory && (value == null || value.toString().length() == 0)) 168 { 169 if (getLogger().isDebugEnabled()) 170 { 171 getLogger().debug("The validator refused a missing or empty value for a mandatory parameter"); 172 } 173 174 result.addError(new I18nizableText("plugin.core-ui", "PLUGINS_CORE_UI_DEFAULT_VALIDATOR_MANDATORY")); 175 } 176 177 if (_regexp != null && value != null && value.toString().length() != 0 && !_regexp.matcher(value.toString()).matches()) 178 { 179 if (getLogger().isDebugEnabled()) 180 { 181 getLogger().debug("The validator refused a value for a parameter that should respect a regexep"); 182 } 183 184 result.addError(new I18nizableText("plugin.core-ui", "PLUGINS_CORE_UI_DEFAULT_VALIDATOR_PATTERN_FAILED")); 185 } 186 187 return result; 188 } 189 190 /** 191 * Validates a array of values. 192 * @param values the values to validate 193 * @return the validation result 194 */ 195 protected ValidationResult validateArrayValues (Object[] values) 196 { 197 ValidationResult result = new ValidationResult(); 198 199 if (_isMandatory && (values == null || values.length == 0)) 200 { 201 if (getLogger().isDebugEnabled()) 202 { 203 getLogger().debug("The validator refused a missing or empty value for a mandatory parameter"); 204 } 205 206 result.addError(new I18nizableText("plugin.core-ui", "PLUGINS_CORE_UI_DEFAULT_VALIDATOR_MANDATORY")); 207 } 208 209 if (_regexp != null && values != null && !_matchRegexp(values)) 210 { 211 if (getLogger().isDebugEnabled()) 212 { 213 getLogger().debug("The validator refused a value for a parameter that should respect a regexep"); 214 } 215 216 result.addError(new I18nizableText("plugin.core-ui", "PLUGINS_CORE_UI_DEFAULT_VALIDATOR_PATTERN_FAILED")); 217 } 218 219 return result; 220 } 221 222 private boolean _matchRegexp (Object[] values) 223 { 224 for (Object value : values) 225 { 226 if (!_regexp.matcher(value.toString()).matches()) 227 { 228 return false; 229 } 230 } 231 return true; 232 } 233 234 @Override 235 public int hashCode() 236 { 237 final int prime = 31; 238 int result = 1; 239 result = prime * result + ((_invalidText == null) ? 0 : _invalidText.hashCode()); 240 result = prime * result + (_isMandatory ? 1231 : 1237); 241 result = prime * result + ((_pluginName == null) ? 0 : _pluginName.hashCode()); 242 result = prime * result + ((_regexp == null) ? 0 : _regexp.hashCode()); 243 result = prime * result + ((_smanager == null) ? 0 : _smanager.hashCode()); 244 return result; 245 } 246 247 @Override 248 public boolean equals(Object obj) 249 { 250 // Generated method but modified to correctly compare patterns 251 if (this == obj) 252 { 253 return true; 254 } 255 if (obj == null) 256 { 257 return false; 258 } 259 if (getClass() != obj.getClass()) 260 { 261 return false; 262 } 263 DefaultValidator other = (DefaultValidator) obj; 264 if (_invalidText == null) 265 { 266 if (other._invalidText != null) 267 { 268 return false; 269 } 270 } 271 else if (!_invalidText.equals(other._invalidText)) 272 { 273 return false; 274 } 275 if (_isMandatory != other._isMandatory) 276 { 277 return false; 278 } 279 if (_regexp == null) 280 { 281 if (other._regexp != null) 282 { 283 return false; 284 } 285 } 286 // Beginning of the modification 287 else if (other._regexp == null) 288 { 289 return false; 290 } 291 else if (!_regexp.pattern().equals(other._regexp.pattern())) 292 { 293 return false; 294 } 295 // End of the modification 296 return true; 297 } 298}