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. 236 * </ul> 237 * @return the class loader. 238 */ 239 public ClassLoader getClassLoader() { 240 if (classLoader != null) { 241 return classLoader; 242 } 243 244 if (useContextClassLoader) { 245 final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); 246 if (contextLoader != null) { 247 return contextLoader; 248 } 249 } 250 251 return this.getClass().getClassLoader(); 252 } 253 254 /** 255 * Gets the field name. 256 * 257 * @return the field name. 258 * @since 1.10.0 259 */ 260 public String getFieldName() { 261 return fieldName; 262 } 263 264 /** 265 * Gets the form name which is the key to a set of validation rules. 266 * @return the name of the form. 267 */ 268 public String getFormName() { 269 return formName; 270 } 271 272 /** 273 * Returns true if the Validator is only returning Fields that fail validation. 274 * @return whether only failed fields are returned. 275 */ 276 public boolean getOnlyReturnErrors() { 277 return onlyReturnErrors; 278 } 279 280 /** 281 * Gets the page. 282 * 283 * <p> 284 * This in conjunction with the page property of 285 * a {@code Field} can control the processing of fields. If the field's 286 * page is less than or equal to this page value, it will be processed. 287 * </p> 288 * 289 * @return the page number. 290 */ 291 public int getPage() { 292 return page; 293 } 294 295 /** 296 * Gets the parameter map. 297 * 298 * @return the parameter map. 299 * @since 1.10.0 300 */ 301 public Map<String, Object> getParameters() { 302 return parameters; 303 } 304 305 /** 306 * Returns the value of the specified parameter that will be used during the 307 * processing of validations. 308 * 309 * @param parameterClassName The full class name of the parameter of the 310 * validation method that corresponds to the value/instance passed in with it. 311 * @return value of the specified parameter. 312 */ 313 public Object getParameterValue(final String parameterClassName) { 314 return parameters.get(parameterClassName); 315 } 316 317 /** 318 * Gets the validator resource. 319 * 320 * @return the validator resource. 321 * @since 1.10.0 322 */ 323 public ValidatorResources getResources() { 324 return resources; 325 } 326 327 /** 328 * Gets the boolean as to whether the context classloader should be used. 329 * @return whether the context classloader should be used. 330 */ 331 public boolean getUseContextClassLoader() { 332 return useContextClassLoader; 333 } 334 335 /** 336 * Sets the class loader to be used for instantiating application objects 337 * when required. 338 * 339 * @param classLoader The new class loader to use, or {@code null} 340 * to revert to the standard rules 341 */ 342 public void setClassLoader(final ClassLoader classLoader) { 343 this.classLoader = classLoader; 344 } 345 346 /** 347 * Sets the name of the field to validate in a form (optional) 348 * 349 * @param fieldName The name of the field in a form set 350 * @since 1.2.0 351 */ 352 public void setFieldName(final String fieldName) { 353 this.fieldName = fieldName; 354 } 355 356 /** 357 * Sets the form name which is the key to a set of validation rules. 358 * @param formName the name of the form. 359 */ 360 public void setFormName(final String formName) { 361 this.formName = formName; 362 } 363 364 /** 365 * Configures which Fields the Validator returns from the validate() method. Set this 366 * to true to only return Fields that failed validation. By default, validate() returns 367 * all fields. 368 * @param onlyReturnErrors whether only failed fields are returned. 369 */ 370 public void setOnlyReturnErrors(final boolean onlyReturnErrors) { 371 this.onlyReturnErrors = onlyReturnErrors; 372 } 373 374 /** 375 * Sets the page. 376 * <p> 377 * This in conjunction with the page property of 378 * a {@code Field} can control the processing of fields. If the field's page 379 * is less than or equal to this page value, it will be processed. 380 * </p> 381 * 382 * @param page the page number. 383 */ 384 public void setPage(final int page) { 385 this.page = page; 386 } 387 388 /** 389 * Sets a parameter of a pluggable validation method. 390 * 391 * @param parameterClassName The full class name of the parameter of the 392 * validation method that corresponds to the value/instance passed in with it. 393 * 394 * @param parameterValue The instance that will be passed into the 395 * validation method. 396 */ 397 public void setParameter(final String parameterClassName, final Object parameterValue) { 398 parameters.put(parameterClassName, parameterValue); 399 } 400 401 /** 402 * Sets whether to use the Context ClassLoader (the one found by 403 * calling {@code Thread.currentThread().getContextClassLoader()}) 404 * to resolve/load classes that are defined in various rules. If not 405 * using Context ClassLoader, then the class-loading defaults to 406 * using the calling-class' ClassLoader. 407 * 408 * @param useContextClassLoader determines whether to use Context ClassLoader. 409 */ 410 public void setUseContextClassLoader(final boolean useContextClassLoader) { 411 this.useContextClassLoader = useContextClassLoader; 412 } 413 414 /** 415 * Performs validations based on the configured resources. 416 * 417 * @return The {@link Map} returned uses the property of the 418 * {@code Field} for the key and the value is the number of error the 419 * field had. 420 * @throws ValidatorException If an error occurs during validation 421 */ 422 public ValidatorResults validate() throws ValidatorException { 423 Locale locale = (Locale) getParameterValue(LOCALE_PARAM); 424 425 if (locale == null) { 426 locale = Locale.getDefault(); 427 } 428 429 setParameter(VALIDATOR_PARAM, this); 430 431 final Form form = resources.getForm(locale, formName); 432 if (form != null) { 433 setParameter(FORM_PARAM, form); 434 return form.validate( 435 parameters, 436 resources.getValidatorActions(), 437 page, 438 fieldName); 439 } 440 441 return new ValidatorResults(); 442 } 443 444}