001 package org.apache.fulcrum.intake.validator; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.util.Map; 023 024 import org.apache.commons.lang.StringUtils; 025 import org.apache.commons.logging.Log; 026 import org.apache.commons.logging.LogFactory; 027 import org.apache.fulcrum.intake.model.Field; 028 029 /** 030 * DefaultValidator that will compare a testValue against the following 031 * constraints: 032 * 033 * <table> 034 * <tr><th>Name</th><th>Valid Values</th><th>Default Value</th></tr> 035 * <tr><td>required</td><td>true|false</td><td>false</td></tr> 036 * <tr><td>mask</td><td>regexp</td><td> </td></tr> 037 * <tr><td>minLength</td><td>integer</td><td>0</td></tr> 038 * <tr><td>maxLength</td><td>integer</td><td> </td></tr> 039 * </table> 040 * 041 * This validator can serve as the base class for more specific validators 042 * 043 * @author <a href="mailto:jmcnally@collab.net">John McNally</a> 044 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> 045 * @author <a href="mailto:Colin.Chalmers@maxware.nl">Colin Chalmers</a> 046 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> 047 * @version $Id: DefaultValidator.java 670328 2008-06-22 09:34:11Z tv $ 048 */ 049 abstract public class DefaultValidator 050 implements Validator, InitableByConstraintMap 051 { 052 /** A boolean value to signify if the field is definately required or not */ 053 protected boolean required = false; 054 055 /** The message to show if field fails required test */ 056 protected String requiredMessage = null; 057 058 /** The minimum length of the field */ 059 protected int minLength = 0; 060 061 /** The message to show if field fails min-length test */ 062 protected String minLengthMessage = null; 063 064 /** The maximum length of the field */ 065 protected int maxLength = 0; 066 067 /** The message to show if field fails max-length test */ 068 protected String maxLengthMessage = null; 069 070 /** Error message pertaining to Rule that was broken */ 071 protected String errorMessage = null; 072 073 /** Logging */ 074 protected Log log = LogFactory.getLog(this.getClass()); 075 076 /** 077 * Constructor 078 * 079 * @param paramMap a <code>Map</code> of <code>Rule</code>'s 080 * containing constraints on the input. 081 * @exception InvalidMaskException An invalid mask was specified for one of the rules 082 083 */ 084 public DefaultValidator(Map paramMap) 085 throws InvalidMaskException 086 { 087 init(paramMap); 088 } 089 090 /** 091 * Default constructor 092 */ 093 public DefaultValidator() 094 { 095 // 096 } 097 098 /** 099 * Extract the relevant parameters from the constraints listed 100 * in <rule> tags within the intake.xml file. 101 * 102 * @param paramMap a <code>Map</code> of <code>Rule</code>'s 103 * containing constraints on the input. 104 * @exception InvalidMaskException An invalid mask was specified for one of the rules 105 */ 106 public void init(Map paramMap) 107 throws InvalidMaskException 108 { 109 Constraint constraint = (Constraint) paramMap.get(REQUIRED_RULE_NAME); 110 if (constraint != null) 111 { 112 String param = constraint.getValue(); 113 required = Boolean.valueOf(param).booleanValue(); 114 requiredMessage = constraint.getMessage(); 115 } 116 117 constraint = (Constraint) paramMap.get(MIN_LENGTH_RULE_NAME); 118 if (constraint != null) 119 { 120 String param = constraint.getValue(); 121 minLength = Integer.parseInt(param); 122 minLengthMessage = constraint.getMessage(); 123 } 124 125 constraint = (Constraint) paramMap.get(MAX_LENGTH_RULE_NAME); 126 if (constraint != null) 127 { 128 String param = constraint.getValue(); 129 maxLength = Integer.parseInt(param); 130 maxLengthMessage = constraint.getMessage(); 131 } 132 } 133 134 /** 135 * Determine whether a field meets the criteria specified 136 * in the constraints defined for this validator 137 * 138 * @param field a <code>Field</code> to be tested 139 * @return true if valid, false otherwise 140 */ 141 public boolean isValid(Field field) 142 { 143 boolean valid = false; 144 try 145 { 146 assertValidity(field); 147 valid = true; 148 } 149 catch (ValidationException ve) 150 { 151 valid = false; 152 } 153 return valid; 154 } 155 156 /** 157 * Determine whether a field meets the criteria specified 158 * in the constraints defined for this validator 159 * 160 * @param field a <code>Field</code> to be tested 161 * @exception ValidationException containing an error message if the 162 * testValue did not pass the validation tests. 163 */ 164 public void assertValidity(Field field) 165 throws ValidationException 166 { 167 if (field.isMultiValued()) 168 { 169 String[] stringValues = (String[])field.getTestValue(); 170 171 for (int i = 0; i < stringValues.length; i++) 172 { 173 assertValidity(stringValues[i]); 174 } 175 } 176 else 177 { 178 assertValidity((String)field.getTestValue()); 179 } 180 } 181 182 /** 183 * Determine whether a testValue meets the criteria specified 184 * in the constraints defined for this validator 185 * 186 * @param testValue a <code>String</code> to be tested 187 * @return true if valid, false otherwise 188 * 189 * @deprecated use isValid(Field) instead 190 */ 191 public boolean isValid(String testValue) 192 { 193 boolean valid = false; 194 try 195 { 196 assertValidity(testValue); 197 valid = true; 198 } 199 catch (ValidationException ve) 200 { 201 valid = false; 202 } 203 return valid; 204 } 205 206 /** 207 * Determine whether a testValue meets the criteria specified 208 * in the constraints defined for this validator 209 * 210 * @param testValue a <code>String</code> to be tested 211 * @exception ValidationException containing an error message if the 212 * testValue did not pass the validation tests. 213 */ 214 public void assertValidity(String testValue) 215 throws ValidationException 216 { 217 if (!required && StringUtils.isEmpty(testValue)) 218 { 219 return; 220 } 221 if (required && StringUtils.isEmpty(testValue)) 222 { 223 errorMessage = requiredMessage; 224 throw new ValidationException(requiredMessage); 225 } 226 227 if (minLength > 0 && testValue.length() < minLength) 228 { 229 errorMessage = minLengthMessage; 230 throw new ValidationException(minLengthMessage); 231 } 232 if (maxLength > 0 && testValue.length() > maxLength) 233 { 234 errorMessage = maxLengthMessage; 235 throw new ValidationException(maxLengthMessage); 236 } 237 } 238 239 240 /** 241 * Get the error message resulting from invalid input. 242 * 243 * @return a <code>String</code> message, or the empty String "". 244 */ 245 public String getMessage() 246 { 247 String retValue = ""; 248 249 if(errorMessage != null) 250 { 251 retValue = errorMessage; 252 } 253 254 return retValue; 255 } 256 257 // ************************************************************ 258 // ** Bean accessor methods ** 259 // ************************************************************ 260 261 /** 262 * Get the value of required. 263 * 264 * @return value of required. 265 */ 266 public boolean isRequired() 267 { 268 return required; 269 } 270 271 /** 272 * Set the value of required. 273 * 274 * @param required Value to assign to required. 275 */ 276 public void setRequired(boolean required) 277 { 278 this.required = required; 279 } 280 281 /** 282 * Get the value of requiredMessage. 283 * 284 * @return value of requiredMessage. 285 */ 286 public String getRequiredMessage() 287 { 288 return requiredMessage; 289 } 290 291 /** 292 * Set the value of requiredMessage. 293 * 294 * @param requiredMessage Value to assign to requiredMessage. 295 */ 296 public void setRequiredMessage(String requiredMessage) 297 { 298 this.requiredMessage = requiredMessage; 299 } 300 301 /** 302 * Get the value of minLength. 303 * 304 * @return value of minLength. 305 */ 306 public int getMinLength() 307 { 308 return minLength; 309 } 310 311 /** 312 * Set the value of minLength. 313 * 314 * @param minLength Value to assign to minLength. 315 */ 316 public void setMinLength(int minLength) 317 { 318 this.minLength = minLength; 319 } 320 321 /** 322 * Get the value of minLengthMessage. 323 * 324 * @return value of minLengthMessage. 325 */ 326 public String getMinLengthMessage() 327 { 328 return minLengthMessage; 329 } 330 331 /** 332 * Set the value of minLengthMessage. 333 * 334 * @param minLengthMessage Value to assign to minLengthMessage. 335 */ 336 public void setMinLengthMessage(String minLengthMessage) 337 { 338 this.minLengthMessage = minLengthMessage; 339 } 340 341 /** 342 * Get the value of maxLength. 343 * 344 * @return value of maxLength. 345 */ 346 public int getMaxLength() 347 { 348 return maxLength; 349 } 350 351 /** 352 * Set the value of maxLength. 353 * 354 * @param maxLength Value to assign to maxLength. 355 */ 356 public void setMaxLength(int maxLength) 357 { 358 this.maxLength = maxLength; 359 } 360 361 /** 362 * Get the value of maxLengthMessage. 363 * 364 * @return value of maxLengthMessage. 365 */ 366 public String getMaxLengthMessage() 367 { 368 return maxLengthMessage; 369 } 370 371 /** 372 * Set the value of maxLengthMessage. 373 * 374 * @param maxLengthMessage Value to assign to maxLengthMessage. 375 */ 376 public void setMaxLengthMessage(String maxLengthMessage) 377 { 378 this.maxLengthMessage = maxLengthMessage; 379 } 380 }