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 * https://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} is used to define the validators 027 * (validation methods) and the validation rules for a JavaBean. 028 */ 029// TODO mutable fields should be made private and accessed via suitable methods only 030public class Validator implements Serializable { 031 032 private static final long serialVersionUID = -7119418755208731611L; 033 034 /** 035 * Resources key the JavaBean is stored to perform validation on. 036 */ 037 public static final String BEAN_PARAM = "java.lang.Object"; 038 039 /** 040 * Resources key the {@code ValidatorAction} is stored under. 041 * This will be automatically passed into a validation method 042 * with the current {@code ValidatorAction} if it is 043 * specified in the method signature. 044 */ 045 public static final String VALIDATOR_ACTION_PARAM = 046 "org.apache.commons.validator.ValidatorAction"; 047 048 /** 049 * Resources key the {@code ValidatorResults} is stored under. 050 * This will be automatically passed into a validation method 051 * with the current {@code ValidatorResults} if it is 052 * specified in the method signature. 053 */ 054 public static final String VALIDATOR_RESULTS_PARAM = 055 "org.apache.commons.validator.ValidatorResults"; 056 057 /** 058 * Resources key the {@code Form} is stored under. 059 * This will be automatically passed into a validation method 060 * with the current {@code Form} if it is 061 * specified in the method signature. 062 */ 063 public static final String FORM_PARAM = "org.apache.commons.validator.Form"; 064 065 /** 066 * Resources key the {@code Field} is stored under. 067 * This will be automatically passed into a validation method 068 * with the current {@code Field} if it is 069 * specified in the method signature. 070 */ 071 public static final String FIELD_PARAM = "org.apache.commons.validator.Field"; 072 073 /** 074 * Resources key the {@code Validator} is stored under. 075 * This will be automatically passed into a validation method 076 * with the current {@code Validator} if it is 077 * specified in the method signature. 078 */ 079 public static final String VALIDATOR_PARAM = 080 "org.apache.commons.validator.Validator"; 081 082 /** 083 * Resources key the {@link Locale} is stored. 084 * This will be used to retrieve the appropriate 085 * {@code FormSet} and {@code Form} to be 086 * processed. 087 */ 088 public static final String LOCALE_PARAM = "java.util.Locale"; 089 090 /** 091 * The Validator Resources. 092 * 093 * @deprecated Use {@link #getResources()}, will be private in the next major version. 094 */ 095 @Deprecated 096 protected ValidatorResources resources; 097 098 /** 099 * The name of the form to validate 100 * 101 * @deprecated Use {@link #getFormName()}, will be private in the next major version. 102 */ 103 @Deprecated 104 protected String formName; 105 106 /** 107 * The name of the field on the form to validate 108 * 109 * @since 1.2.0 110 * 111 * @deprecated Use {@link #getFieldName()}, will be private in the next major version. 112 */ 113 @Deprecated 114 protected String fieldName; 115 116 /** 117 * Maps validation method parameter class names to the objects to be passed 118 * into the method. 119 * 120 * @deprecated Use {@link #getParameters()}, will be private in the next major version. 121 */ 122 @Deprecated 123 protected Map<String, Object> parameters = new HashMap<>(); 124 125 /** 126 * The current page number to validate. 127 * 128 * @deprecated Use {@link #getPage()}, will be private in the next major version. 129 */ 130 @Deprecated 131 protected int page; 132 133 /** 134 * The class loader to use for instantiating application objects. 135 * If not specified, the context class loader, or the class loader 136 * used to load Digester itself, is used, based on the value of the 137 * {@code useContextClassLoader} variable. 138 * 139 * @deprecated Use {@link #getClassLoader()}, will be private in the next major version. 140 */ 141 @Deprecated 142 protected transient ClassLoader classLoader; 143 144 /** 145 * Whether or not to use the Context ClassLoader when loading classes 146 * for instantiating new objects. Default is {@code false}. 147 * 148 * @deprecated Use {@link #getUseContextClassLoader()}, will be private in the next major version. 149 */ 150 @Deprecated 151 protected boolean useContextClassLoader; 152 153 /** 154 * Sets this to true to not return Fields that pass validation. Only return failures. 155 * 156 * @deprecated Use {@link #getOnlyReturnErrors()}, will be private in the next major version. 157 */ 158 @Deprecated 159 protected boolean onlyReturnErrors; 160 161 /** 162 * Constructs a {@code Validator} that will 163 * use the {@code ValidatorResources} 164 * passed in to retrieve pluggable validators 165 * the different sets of validation rules. 166 * 167 * @param resources {@code ValidatorResources} to use during validation. 168 */ 169 public Validator(final ValidatorResources resources) { 170 this(resources, null); 171 } 172 173 /** 174 * Constructs a {@code Validator} that will 175 * use the {@code ValidatorResources} 176 * passed in to retrieve pluggable validators 177 * the different sets of validation rules. 178 * 179 * @param resources {@code ValidatorResources} to use during validation. 180 * @param formName Key used for retrieving the set of validation rules. 181 */ 182 public Validator(final ValidatorResources resources, final String formName) { 183 if (resources == null) { 184 throw new IllegalArgumentException("Resources cannot be null."); 185 } 186 187 this.resources = resources; 188 this.formName = formName; 189 } 190 191 /** 192 * Constructs a {@code Validator} that will 193 * use the {@code ValidatorResources} 194 * passed in to retrieve pluggable validators 195 * the different sets of validation rules. 196 * 197 * @param resources {@code ValidatorResources} to use during validation. 198 * @param formName Key used for retrieving the set of validation rules. 199 * @param fieldName Key used for retrieving the set of validation rules for a field 200 * @since 1.2.0 201 */ 202 public Validator(final ValidatorResources resources, final String formName, final String fieldName) { 203 if (resources == null) { 204 throw new IllegalArgumentException("Resources cannot be null."); 205 } 206 207 this.resources = resources; 208 this.formName = formName; 209 this.fieldName = fieldName; 210 } 211 212 /** 213 * Clears the form name, resources that were added, and the page that was 214 * set (if any). This can be called to reinitialize the Validator instance 215 * so it can be reused. The form name (key to set of validation rules) and any 216 * resources needed, like the JavaBean being validated, will need to 217 * set and/or added to this instance again. The 218 * {@code ValidatorResources} will not be removed since it can be used 219 * again and is thread safe. 220 */ 221 public void clear() { 222 formName = null; 223 fieldName = null; 224 parameters.clear(); 225 page = 0; 226 } 227 228 /** 229 * Gets the class loader to be used for instantiating application objects 230 * when required. This is determined based upon the following rules: 231 * <ul> 232 * <li>The class loader set by {@code setClassLoader()}, if any</li> 233 * <li>The thread context class loader, if it exists and the 234 * {@code useContextClassLoader} property is set to true</li> 235 * <li>The class loader used to load the Digester class itself.</li> 236 * </ul> 237 * 238 * @return the class loader. 239 */ 240 public ClassLoader getClassLoader() { 241 if (classLoader != null) { 242 return classLoader; 243 } 244 245 if (useContextClassLoader) { 246 final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); 247 if (contextLoader != null) { 248 return contextLoader; 249 } 250 } 251 252 return this.getClass().getClassLoader(); 253 } 254 255 /** 256 * Gets the field name. 257 * 258 * @return the field name. 259 * @since 1.10.0 260 */ 261 public String getFieldName() { 262 return fieldName; 263 } 264 265 /** 266 * Gets the form name which is the key to a set of validation rules. 267 * 268 * @return the name of the form. 269 */ 270 public String getFormName() { 271 return formName; 272 } 273 274 /** 275 * Returns true if the Validator is only returning Fields that fail validation. 276 * 277 * @return whether only failed fields are returned. 278 */ 279 public boolean getOnlyReturnErrors() { 280 return onlyReturnErrors; 281 } 282 283 /** 284 * Gets the page. 285 * 286 * <p> 287 * This in conjunction with the page property of 288 * a {@code Field} can control the processing of fields. If the field's 289 * page is less than or equal to this page value, it will be processed. 290 * </p> 291 * 292 * @return the page number. 293 */ 294 public int getPage() { 295 return page; 296 } 297 298 /** 299 * Gets the parameter map. 300 * 301 * @return the parameter map. 302 * @since 1.10.0 303 */ 304 public Map<String, Object> getParameters() { 305 return parameters; 306 } 307 308 /** 309 * Returns the value of the specified parameter that will be used during the 310 * processing of validations. 311 * 312 * @param parameterClassName The full class name of the parameter of the 313 * validation method that corresponds to the value/instance passed in with it. 314 * @return value of the specified parameter. 315 */ 316 public Object getParameterValue(final String parameterClassName) { 317 return parameters.get(parameterClassName); 318 } 319 320 /** 321 * Gets the validator resource. 322 * 323 * @return the validator resource. 324 * @since 1.10.0 325 */ 326 public ValidatorResources getResources() { 327 return resources; 328 } 329 330 /** 331 * Gets the boolean as to whether the context classloader should be used. 332 * 333 * @return whether the context classloader should be used. 334 */ 335 public boolean getUseContextClassLoader() { 336 return useContextClassLoader; 337 } 338 339 /** 340 * Sets the class loader to be used for instantiating application objects 341 * when required. 342 * 343 * @param classLoader The new class loader to use, or {@code null} 344 * to revert to the standard rules 345 */ 346 public void setClassLoader(final ClassLoader classLoader) { 347 this.classLoader = classLoader; 348 } 349 350 /** 351 * Sets the name of the field to validate in a form (optional) 352 * 353 * @param fieldName The name of the field in a form set 354 * @since 1.2.0 355 */ 356 public void setFieldName(final String fieldName) { 357 this.fieldName = fieldName; 358 } 359 360 /** 361 * Sets the form name which is the key to a set of validation rules. 362 * 363 * @param formName the name of the form. 364 */ 365 public void setFormName(final String formName) { 366 this.formName = formName; 367 } 368 369 /** 370 * Configures which Fields the Validator returns from the validate() method. Set this 371 * to true to only return Fields that failed validation. By default, validate() returns 372 * all fields. 373 * 374 * @param onlyReturnErrors whether only failed fields are returned. 375 */ 376 public void setOnlyReturnErrors(final boolean onlyReturnErrors) { 377 this.onlyReturnErrors = onlyReturnErrors; 378 } 379 380 /** 381 * Sets the page. 382 * <p> 383 * This in conjunction with the page property of 384 * a {@code Field} can control the processing of fields. If the field's page 385 * is less than or equal to this page value, it will be processed. 386 * </p> 387 * 388 * @param page the page number. 389 */ 390 public void setPage(final int page) { 391 this.page = page; 392 } 393 394 /** 395 * Sets a parameter of a pluggable validation method. 396 * 397 * @param parameterClassName The full class name of the parameter of the 398 * validation method that corresponds to the value/instance passed in with it. 399 * 400 * @param parameterValue The instance that will be passed into the 401 * validation method. 402 */ 403 public void setParameter(final String parameterClassName, final Object parameterValue) { 404 parameters.put(parameterClassName, parameterValue); 405 } 406 407 /** 408 * Sets whether to use the Context ClassLoader (the one found by 409 * calling {@code Thread.currentThread().getContextClassLoader()}) 410 * to resolve/load classes that are defined in various rules. If not 411 * using Context ClassLoader, then the class-loading defaults to 412 * using the calling-class' ClassLoader. 413 * 414 * @param useContextClassLoader determines whether to use Context ClassLoader. 415 */ 416 public void setUseContextClassLoader(final boolean useContextClassLoader) { 417 this.useContextClassLoader = useContextClassLoader; 418 } 419 420 /** 421 * Performs validations based on the configured resources. 422 * 423 * @return The {@link Map} returned uses the property of the 424 * {@code Field} for the key and the value is the number of error the 425 * field had. 426 * @throws ValidatorException If an error occurs during validation 427 */ 428 public ValidatorResults validate() throws ValidatorException { 429 Locale locale = (Locale) getParameterValue(LOCALE_PARAM); 430 431 if (locale == null) { 432 locale = Locale.getDefault(); 433 } 434 435 setParameter(VALIDATOR_PARAM, this); 436 437 final Form form = resources.getForm(locale, formName); 438 if (form != null) { 439 setParameter(FORM_PARAM, form); 440 return form.validate( 441 parameters, 442 resources.getValidatorActions(), 443 page, 444 fieldName); 445 } 446 447 return new ValidatorResults(); 448 } 449 450}