001/* 002 * Copyright 2002-2018 the original author or authors. 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 * https://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 */ 016 017package org.springframework.validation; 018 019import org.apache.commons.logging.Log; 020import org.apache.commons.logging.LogFactory; 021 022import org.springframework.lang.Nullable; 023import org.springframework.util.Assert; 024import org.springframework.util.ObjectUtils; 025import org.springframework.util.StringUtils; 026 027/** 028 * Utility class offering convenient methods for invoking a {@link Validator} 029 * and for rejecting empty fields. 030 * 031 * <p>Checks for an empty field in {@code Validator} implementations can become 032 * one-liners when using {@link #rejectIfEmpty} or {@link #rejectIfEmptyOrWhitespace}. 033 * 034 * @author Juergen Hoeller 035 * @author Dmitriy Kopylenko 036 * @since 06.05.2003 037 * @see Validator 038 * @see Errors 039 */ 040public abstract class ValidationUtils { 041 042 private static final Log logger = LogFactory.getLog(ValidationUtils.class); 043 044 045 /** 046 * Invoke the given {@link Validator} for the supplied object and 047 * {@link Errors} instance. 048 * @param validator the {@code Validator} to be invoked 049 * @param target the object to bind the parameters to 050 * @param errors the {@link Errors} instance that should store the errors 051 * @throws IllegalArgumentException if either of the {@code Validator} or {@code Errors} 052 * arguments is {@code null}, or if the supplied {@code Validator} does not 053 * {@link Validator#supports(Class) support} the validation of the supplied object's type 054 */ 055 public static void invokeValidator(Validator validator, Object target, Errors errors) { 056 invokeValidator(validator, target, errors, (Object[]) null); 057 } 058 059 /** 060 * Invoke the given {@link Validator}/{@link SmartValidator} for the supplied object and 061 * {@link Errors} instance. 062 * @param validator the {@code Validator} to be invoked 063 * @param target the object to bind the parameters to 064 * @param errors the {@link Errors} instance that should store the errors 065 * @param validationHints one or more hint objects to be passed to the validation engine 066 * @throws IllegalArgumentException if either of the {@code Validator} or {@code Errors} 067 * arguments is {@code null}, or if the supplied {@code Validator} does not 068 * {@link Validator#supports(Class) support} the validation of the supplied object's type 069 */ 070 public static void invokeValidator( 071 Validator validator, Object target, Errors errors, @Nullable Object... validationHints) { 072 073 Assert.notNull(validator, "Validator must not be null"); 074 Assert.notNull(target, "Target object must not be null"); 075 Assert.notNull(errors, "Errors object must not be null"); 076 077 if (logger.isDebugEnabled()) { 078 logger.debug("Invoking validator [" + validator + "]"); 079 } 080 if (!validator.supports(target.getClass())) { 081 throw new IllegalArgumentException( 082 "Validator [" + validator.getClass() + "] does not support [" + target.getClass() + "]"); 083 } 084 085 if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) { 086 ((SmartValidator) validator).validate(target, errors, validationHints); 087 } 088 else { 089 validator.validate(target, errors); 090 } 091 092 if (logger.isDebugEnabled()) { 093 if (errors.hasErrors()) { 094 logger.debug("Validator found " + errors.getErrorCount() + " errors"); 095 } 096 else { 097 logger.debug("Validator found no errors"); 098 } 099 } 100 } 101 102 103 /** 104 * Reject the given field with the given error code if the value is empty. 105 * <p>An 'empty' value in this context means either {@code null} or 106 * the empty string "". 107 * <p>The object whose field is being validated does not need to be passed 108 * in because the {@link Errors} instance can resolve field values by itself 109 * (it will usually hold an internal reference to the target object). 110 * @param errors the {@code Errors} instance to register errors on 111 * @param field the field name to check 112 * @param errorCode the error code, interpretable as message key 113 */ 114 public static void rejectIfEmpty(Errors errors, String field, String errorCode) { 115 rejectIfEmpty(errors, field, errorCode, null, null); 116 } 117 118 /** 119 * Reject the given field with the given error code and default message 120 * if the value is empty. 121 * <p>An 'empty' value in this context means either {@code null} or 122 * the empty string "". 123 * <p>The object whose field is being validated does not need to be passed 124 * in because the {@link Errors} instance can resolve field values by itself 125 * (it will usually hold an internal reference to the target object). 126 * @param errors the {@code Errors} instance to register errors on 127 * @param field the field name to check 128 * @param errorCode error code, interpretable as message key 129 * @param defaultMessage fallback default message 130 */ 131 public static void rejectIfEmpty(Errors errors, String field, String errorCode, String defaultMessage) { 132 rejectIfEmpty(errors, field, errorCode, null, defaultMessage); 133 } 134 135 /** 136 * Reject the given field with the given error code and error arguments 137 * if the value is empty. 138 * <p>An 'empty' value in this context means either {@code null} or 139 * the empty string "". 140 * <p>The object whose field is being validated does not need to be passed 141 * in because the {@link Errors} instance can resolve field values by itself 142 * (it will usually hold an internal reference to the target object). 143 * @param errors the {@code Errors} instance to register errors on 144 * @param field the field name to check 145 * @param errorCode the error code, interpretable as message key 146 * @param errorArgs the error arguments, for argument binding via MessageFormat 147 * (can be {@code null}) 148 */ 149 public static void rejectIfEmpty(Errors errors, String field, String errorCode, Object[] errorArgs) { 150 rejectIfEmpty(errors, field, errorCode, errorArgs, null); 151 } 152 153 /** 154 * Reject the given field with the given error code, error arguments 155 * and default message if the value is empty. 156 * <p>An 'empty' value in this context means either {@code null} or 157 * the empty string "". 158 * <p>The object whose field is being validated does not need to be passed 159 * in because the {@link Errors} instance can resolve field values by itself 160 * (it will usually hold an internal reference to the target object). 161 * @param errors the {@code Errors} instance to register errors on 162 * @param field the field name to check 163 * @param errorCode the error code, interpretable as message key 164 * @param errorArgs the error arguments, for argument binding via MessageFormat 165 * (can be {@code null}) 166 * @param defaultMessage fallback default message 167 */ 168 public static void rejectIfEmpty(Errors errors, String field, String errorCode, 169 @Nullable Object[] errorArgs, @Nullable String defaultMessage) { 170 171 Assert.notNull(errors, "Errors object must not be null"); 172 Object value = errors.getFieldValue(field); 173 if (value == null || !StringUtils.hasLength(value.toString())) { 174 errors.rejectValue(field, errorCode, errorArgs, defaultMessage); 175 } 176 } 177 178 /** 179 * Reject the given field with the given error code if the value is empty 180 * or just contains whitespace. 181 * <p>An 'empty' value in this context means either {@code null}, 182 * the empty string "", or consisting wholly of whitespace. 183 * <p>The object whose field is being validated does not need to be passed 184 * in because the {@link Errors} instance can resolve field values by itself 185 * (it will usually hold an internal reference to the target object). 186 * @param errors the {@code Errors} instance to register errors on 187 * @param field the field name to check 188 * @param errorCode the error code, interpretable as message key 189 */ 190 public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode) { 191 rejectIfEmptyOrWhitespace(errors, field, errorCode, null, null); 192 } 193 194 /** 195 * Reject the given field with the given error code and default message 196 * if the value is empty or just contains whitespace. 197 * <p>An 'empty' value in this context means either {@code null}, 198 * the empty string "", or consisting wholly of whitespace. 199 * <p>The object whose field is being validated does not need to be passed 200 * in because the {@link Errors} instance can resolve field values by itself 201 * (it will usually hold an internal reference to the target object). 202 * @param errors the {@code Errors} instance to register errors on 203 * @param field the field name to check 204 * @param errorCode the error code, interpretable as message key 205 * @param defaultMessage fallback default message 206 */ 207 public static void rejectIfEmptyOrWhitespace( 208 Errors errors, String field, String errorCode, String defaultMessage) { 209 210 rejectIfEmptyOrWhitespace(errors, field, errorCode, null, defaultMessage); 211 } 212 213 /** 214 * Reject the given field with the given error code and error arguments 215 * if the value is empty or just contains whitespace. 216 * <p>An 'empty' value in this context means either {@code null}, 217 * the empty string "", or consisting wholly of whitespace. 218 * <p>The object whose field is being validated does not need to be passed 219 * in because the {@link Errors} instance can resolve field values by itself 220 * (it will usually hold an internal reference to the target object). 221 * @param errors the {@code Errors} instance to register errors on 222 * @param field the field name to check 223 * @param errorCode the error code, interpretable as message key 224 * @param errorArgs the error arguments, for argument binding via MessageFormat 225 * (can be {@code null}) 226 */ 227 public static void rejectIfEmptyOrWhitespace( 228 Errors errors, String field, String errorCode, @Nullable Object[] errorArgs) { 229 230 rejectIfEmptyOrWhitespace(errors, field, errorCode, errorArgs, null); 231 } 232 233 /** 234 * Reject the given field with the given error code, error arguments 235 * and default message if the value is empty or just contains whitespace. 236 * <p>An 'empty' value in this context means either {@code null}, 237 * the empty string "", or consisting wholly of whitespace. 238 * <p>The object whose field is being validated does not need to be passed 239 * in because the {@link Errors} instance can resolve field values by itself 240 * (it will usually hold an internal reference to the target object). 241 * @param errors the {@code Errors} instance to register errors on 242 * @param field the field name to check 243 * @param errorCode the error code, interpretable as message key 244 * @param errorArgs the error arguments, for argument binding via MessageFormat 245 * (can be {@code null}) 246 * @param defaultMessage fallback default message 247 */ 248 public static void rejectIfEmptyOrWhitespace( 249 Errors errors, String field, String errorCode, @Nullable Object[] errorArgs, @Nullable String defaultMessage) { 250 251 Assert.notNull(errors, "Errors object must not be null"); 252 Object value = errors.getFieldValue(field); 253 if (value == null ||!StringUtils.hasText(value.toString())) { 254 errors.rejectValue(field, errorCode, errorArgs, defaultMessage); 255 } 256 } 257 258}