001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.validator; 018 019import java.io.Serializable; 020import java.util.HashMap; 021import java.util.Locale; 022import java.util.Map; 023 024/** 025 * Validations are processed by the validate method. An instance of 026 * <code>ValidatorResources</code> is used to define the validators 027 * (validation methods) and the validation rules for a JavaBean. 028 * 029 * @version $Revision$ 030 */ 031// TODO mutable fields should be made private and accessed via suitable methods only 032public class Validator implements Serializable { 033 034 private static final long serialVersionUID = -7119418755208731611L; 035 036 /** 037 * Resources key the JavaBean is stored to perform validation on. 038 */ 039 public static final String BEAN_PARAM = "java.lang.Object"; 040 041 /** 042 * Resources key the <code>ValidatorAction</code> is stored under. 043 * This will be automatically passed into a validation method 044 * with the current <code>ValidatorAction</code> if it is 045 * specified in the method signature. 046 */ 047 public static final String VALIDATOR_ACTION_PARAM = 048 "org.apache.commons.validator.ValidatorAction"; 049 050 /** 051 * Resources key the <code>ValidatorResults</code> is stored under. 052 * This will be automatically passed into a validation method 053 * with the current <code>ValidatorResults</code> if it is 054 * specified in the method signature. 055 */ 056 public static final String VALIDATOR_RESULTS_PARAM = 057 "org.apache.commons.validator.ValidatorResults"; 058 059 /** 060 * Resources key the <code>Form</code> is stored under. 061 * This will be automatically passed into a validation method 062 * with the current <code>Form</code> if it is 063 * specified in the method signature. 064 */ 065 public static final String FORM_PARAM = "org.apache.commons.validator.Form"; 066 067 /** 068 * Resources key the <code>Field</code> is stored under. 069 * This will be automatically passed into a validation method 070 * with the current <code>Field</code> if it is 071 * specified in the method signature. 072 */ 073 public static final String FIELD_PARAM = "org.apache.commons.validator.Field"; 074 075 /** 076 * Resources key the <code>Validator</code> is stored under. 077 * This will be automatically passed into a validation method 078 * with the current <code>Validator</code> if it is 079 * specified in the method signature. 080 */ 081 public static final String VALIDATOR_PARAM = 082 "org.apache.commons.validator.Validator"; 083 084 /** 085 * Resources key the <code>Locale</code> is stored. 086 * This will be used to retrieve the appropriate 087 * <code>FormSet</code> and <code>Form</code> to be 088 * processed. 089 */ 090 public static final String LOCALE_PARAM = "java.util.Locale"; 091 092 /** 093 * The Validator Resources. 094 */ 095 protected ValidatorResources resources = null; 096 097 /** 098 * The name of the form to validate 099 */ 100 protected String formName = null; 101 102 /** 103 * The name of the field on the form to validate 104 * @since 1.2.0 105 */ 106 protected String fieldName = null; 107 108 /** 109 * Maps validation method parameter class names to the objects to be passed 110 * into the method. 111 */ 112 protected Map<String, Object> parameters = new HashMap<>(); // <String, Object> 113 114 /** 115 * The current page number to validate. 116 */ 117 protected int page = 0; 118 119 /** 120 * The class loader to use for instantiating application objects. 121 * If not specified, the context class loader, or the class loader 122 * used to load Digester itself, is used, based on the value of the 123 * <code>useContextClassLoader</code> variable. 124 */ 125 protected transient ClassLoader classLoader = null; 126 127 /** 128 * Whether or not to use the Context ClassLoader when loading classes 129 * for instantiating new objects. Default is <code>false</code>. 130 */ 131 protected boolean useContextClassLoader = false; 132 133 /** 134 * Set this to true to not return Fields that pass validation. Only return failures. 135 */ 136 protected boolean onlyReturnErrors = false; 137 138 /** 139 * Construct a <code>Validator</code> that will 140 * use the <code>ValidatorResources</code> 141 * passed in to retrieve pluggable validators 142 * the different sets of validation rules. 143 * 144 * @param resources <code>ValidatorResources</code> to use during validation. 145 */ 146 public Validator(ValidatorResources resources) { 147 this(resources, null); 148 } 149 150 /** 151 * Construct a <code>Validator</code> that will 152 * use the <code>ValidatorResources</code> 153 * passed in to retrieve pluggable validators 154 * the different sets of validation rules. 155 * 156 * @param resources <code>ValidatorResources</code> to use during validation. 157 * @param formName Key used for retrieving the set of validation rules. 158 */ 159 public Validator(ValidatorResources resources, String formName) { 160 if (resources == null) { 161 throw new IllegalArgumentException("Resources cannot be null."); 162 } 163 164 this.resources = resources; 165 this.formName = formName; 166 } 167 168 /** 169 * Construct a <code>Validator</code> that will 170 * use the <code>ValidatorResources</code> 171 * passed in to retrieve pluggable validators 172 * the different sets of validation rules. 173 * 174 * @param resources <code>ValidatorResources</code> to use during validation. 175 * @param formName Key used for retrieving the set of validation rules. 176 * @param fieldName Key used for retrieving the set of validation rules for a field 177 * @since 1.2.0 178 */ 179 public Validator(ValidatorResources resources, String formName, String fieldName) { 180 if (resources == null) { 181 throw new IllegalArgumentException("Resources cannot be null."); 182 } 183 184 this.resources = resources; 185 this.formName = formName; 186 this.fieldName = fieldName; 187 } 188 189 /** 190 * Set a parameter of a pluggable validation method. 191 * 192 * @param parameterClassName The full class name of the parameter of the 193 * validation method that corresponds to the value/instance passed in with it. 194 * 195 * @param parameterValue The instance that will be passed into the 196 * validation method. 197 */ 198 public void setParameter(String parameterClassName, Object parameterValue) { 199 this.parameters.put(parameterClassName, parameterValue); 200 } 201 202 /** 203 * Returns the value of the specified parameter that will be used during the 204 * processing of validations. 205 * 206 * @param parameterClassName The full class name of the parameter of the 207 * validation method that corresponds to the value/instance passed in with it. 208 * @return value of the specified parameter. 209 */ 210 public Object getParameterValue(String parameterClassName) { 211 return this.parameters.get(parameterClassName); 212 } 213 214 /** 215 * Gets the form name which is the key to a set of validation rules. 216 * @return the name of the form. 217 */ 218 public String getFormName() { 219 return formName; 220 } 221 222 /** 223 * Sets the form name which is the key to a set of validation rules. 224 * @param formName the name of the form. 225 */ 226 public void setFormName(String formName) { 227 this.formName = formName; 228 } 229 230 /** 231 * Sets the name of the field to validate in a form (optional) 232 * 233 * @param fieldName The name of the field in a form set 234 * @since 1.2.0 235 */ 236 public void setFieldName(String fieldName) { 237 this.fieldName = fieldName; 238 } 239 240 /** 241 * Gets the page. 242 * 243 * <p> 244 * This in conjunction with the page property of 245 * a {@code Field} can control the processing of fields. If the field's 246 * page is less than or equal to this page value, it will be processed. 247 * </p> 248 * 249 * @return the page number. 250 */ 251 public int getPage() { 252 return page; 253 } 254 255 /** 256 * Sets the page. 257 * <p> 258 * This in conjunction with the page property of 259 * a {@code Field} can control the processing of fields. If the field's page 260 * is less than or equal to this page value, it will be processed. 261 * </p> 262 * 263 * @param page the page number. 264 */ 265 public void setPage(int page) { 266 this.page = page; 267 } 268 269 /** 270 * Clears the form name, resources that were added, and the page that was 271 * set (if any). This can be called to reinitialize the Validator instance 272 * so it can be reused. The form name (key to set of validation rules) and any 273 * resources needed, like the JavaBean being validated, will need to 274 * set and/or added to this instance again. The 275 * <code>ValidatorResources</code> will not be removed since it can be used 276 * again and is thread safe. 277 */ 278 public void clear() { 279 this.formName = null; 280 this.fieldName = null; 281 this.parameters = new HashMap<>(); 282 this.page = 0; 283 } 284 285 /** 286 * Return the boolean as to whether the context classloader should be used. 287 * @return whether the context classloader should be used. 288 */ 289 public boolean getUseContextClassLoader() { 290 return this.useContextClassLoader; 291 } 292 293 /** 294 * Determine whether to use the Context ClassLoader (the one found by 295 * calling <code>Thread.currentThread().getContextClassLoader()</code>) 296 * to resolve/load classes that are defined in various rules. If not 297 * using Context ClassLoader, then the class-loading defaults to 298 * using the calling-class' ClassLoader. 299 * 300 * @param use determines whether to use Context ClassLoader. 301 */ 302 public void setUseContextClassLoader(boolean use) { 303 this.useContextClassLoader = use; 304 } 305 306 /** 307 * Return the class loader to be used for instantiating application objects 308 * when required. This is determined based upon the following rules: 309 * <ul> 310 * <li>The class loader set by <code>setClassLoader()</code>, if any</li> 311 * <li>The thread context class loader, if it exists and the 312 * <code>useContextClassLoader</code> property is set to true</li> 313 * <li>The class loader used to load the Digester class itself. 314 * </ul> 315 * @return the class loader. 316 */ 317 public ClassLoader getClassLoader() { 318 if (this.classLoader != null) { 319 return this.classLoader; 320 } 321 322 if (this.useContextClassLoader) { 323 ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); 324 if (contextLoader != null) { 325 return contextLoader; 326 } 327 } 328 329 return this.getClass().getClassLoader(); 330 } 331 332 /** 333 * Set the class loader to be used for instantiating application objects 334 * when required. 335 * 336 * @param classLoader The new class loader to use, or <code>null</code> 337 * to revert to the standard rules 338 */ 339 public void setClassLoader(ClassLoader classLoader) { 340 this.classLoader = classLoader; 341 } 342 343 /** 344 * Performs validations based on the configured resources. 345 * 346 * @return The <code>Map</code> returned uses the property of the 347 * <code>Field</code> for the key and the value is the number of error the 348 * field had. 349 * @throws ValidatorException If an error occurs during validation 350 */ 351 public ValidatorResults validate() throws ValidatorException { 352 Locale locale = (Locale) this.getParameterValue(LOCALE_PARAM); 353 354 if (locale == null) { 355 locale = Locale.getDefault(); 356 } 357 358 this.setParameter(VALIDATOR_PARAM, this); 359 360 Form form = this.resources.getForm(locale, this.formName); 361 if (form != null) { 362 this.setParameter(FORM_PARAM, form); 363 return form.validate( 364 this.parameters, 365 this.resources.getValidatorActions(), 366 this.page, 367 this.fieldName); 368 } 369 370 return new ValidatorResults(); 371 } 372 373 /** 374 * Returns true if the Validator is only returning Fields that fail validation. 375 * @return whether only failed fields are returned. 376 */ 377 public boolean getOnlyReturnErrors() { 378 return onlyReturnErrors; 379 } 380 381 /** 382 * Configures which Fields the Validator returns from the validate() method. Set this 383 * to true to only return Fields that failed validation. By default, validate() returns 384 * all fields. 385 * @param onlyReturnErrors whether only failed fields are returned. 386 */ 387 public void setOnlyReturnErrors(boolean onlyReturnErrors) { 388 this.onlyReturnErrors = onlyReturnErrors; 389 } 390 391}