• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 18154768944

01 Oct 2025 07:26AM UTC coverage: 81.882% (-0.005%) from 81.887%
18154768944

push

github

web-flow
Merge pull request #290 from TAKETODAY/dev/jspecify

jspecify

59788 of 78013 branches covered (76.64%)

Branch coverage included in aggregate %.

141239 of 167496 relevant lines covered (84.32%)

3.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.19
today-context/src/main/java/infra/validation/ValidationUtils.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.validation;
19

20
import org.jspecify.annotations.Nullable;
21

22
import infra.lang.Assert;
23
import infra.logging.Logger;
24
import infra.logging.LoggerFactory;
25
import infra.util.ObjectUtils;
26
import infra.util.StringUtils;
27

28
/**
29
 * Utility class offering convenient methods for invoking a {@link Validator}
30
 * and for rejecting empty fields.
31
 *
32
 * <p>Checks for an empty field in {@code Validator} implementations can become
33
 * one-liners when using {@link #rejectIfEmpty} or {@link #rejectIfEmptyOrWhitespace}.
34
 *
35
 * @author Juergen Hoeller
36
 * @author Dmitriy Kopylenko
37
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
38
 * @see Validator
39
 * @see Errors
40
 * @since 4.0
41
 */
42
public abstract class ValidationUtils {
×
43

44
  private static final Logger logger = LoggerFactory.getLogger(ValidationUtils.class);
4✔
45

46
  /**
47
   * Invoke the given {@link Validator} for the supplied object and
48
   * {@link Errors} instance.
49
   *
50
   * @param validator the {@code Validator} to be invoked
51
   * @param target the object to bind the parameters to
52
   * @param errors the {@link Errors} instance that should store the errors
53
   * @throws IllegalArgumentException if either of the {@code Validator} or {@code Errors}
54
   * arguments is {@code null}, or if the supplied {@code Validator} does not
55
   * {@link Validator#supports(Class) support} the validation of the supplied object's type
56
   */
57
  public static void invokeValidator(Validator validator, Object target, Errors errors) {
58
    invokeValidator(validator, target, errors, (Object[]) null);
6✔
59
  }
1✔
60

61
  /**
62
   * Invoke the given {@link Validator}/{@link SmartValidator} for the supplied object and
63
   * {@link Errors} instance.
64
   *
65
   * @param validator the {@code Validator} to be invoked
66
   * @param target the object to bind the parameters to
67
   * @param errors the {@link Errors} instance that should store the errors
68
   * @param validationHints one or more hint objects to be passed to the validation engine
69
   * @throws IllegalArgumentException if either of the {@code Validator} or {@code Errors}
70
   * arguments is {@code null}, or if the supplied {@code Validator} does not
71
   * {@link Validator#supports(Class) support} the validation of the supplied object's type
72
   */
73
  public static void invokeValidator(Validator validator,
74
          Object target, Errors errors, Object @Nullable ... validationHints) {
75

76
    Assert.notNull(validator, "Validator is required");
3✔
77
    Assert.notNull(target, "Target object is required");
3✔
78
    Assert.notNull(errors, "Errors object is required");
3✔
79

80
    if (logger.isDebugEnabled()) {
3!
81
      logger.debug("Invoking validator [{}]", validator);
×
82
    }
83
    if (!validator.supports(target.getClass())) {
5!
84
      throw new IllegalArgumentException(
×
85
              "Validator [%s] does not support [%s]".formatted(validator.getClass(), target.getClass()));
×
86
    }
87

88
    if (ObjectUtils.isNotEmpty(validationHints) && validator instanceof SmartValidator) {
3!
89
      ((SmartValidator) validator).validate(target, errors, validationHints);
×
90
    }
91
    else {
92
      validator.validate(target, errors);
4✔
93
    }
94

95
    if (logger.isDebugEnabled()) {
3!
96
      if (errors.hasErrors()) {
×
97
        logger.debug("Validator found {} errors", errors.getErrorCount());
×
98
      }
99
      else {
100
        logger.debug("Validator found no errors");
×
101
      }
102
    }
103
  }
1✔
104

105
  /**
106
   * Reject the given field with the given error code if the value is empty.
107
   * <p>An 'empty' value in this context means either {@code null} or
108
   * the empty string "".
109
   * <p>The object whose field is being validated does not need to be passed
110
   * in because the {@link Errors} instance can resolve field values by itself
111
   * (it will usually hold an internal reference to the target object).
112
   *
113
   * @param errors the {@code Errors} instance to register errors on
114
   * @param field the field name to check
115
   * @param errorCode the error code, interpretable as message key
116
   */
117
  public static void rejectIfEmpty(Errors errors, String field, String errorCode) {
118
    rejectIfEmpty(errors, field, errorCode, null, null);
6✔
119
  }
1✔
120

121
  /**
122
   * Reject the given field with the given error code and default message
123
   * if the value is empty.
124
   * <p>An 'empty' value in this context means either {@code null} or
125
   * the empty string "".
126
   * <p>The object whose field is being validated does not need to be passed
127
   * in because the {@link Errors} instance can resolve field values by itself
128
   * (it will usually hold an internal reference to the target object).
129
   *
130
   * @param errors the {@code Errors} instance to register errors on
131
   * @param field the field name to check
132
   * @param errorCode error code, interpretable as message key
133
   * @param defaultMessage fallback default message
134
   */
135
  public static void rejectIfEmpty(Errors errors, String field, String errorCode, String defaultMessage) {
136
    rejectIfEmpty(errors, field, errorCode, null, defaultMessage);
6✔
137
  }
1✔
138

139
  /**
140
   * Reject the given field with the given error code and error arguments
141
   * if the value is empty.
142
   * <p>An 'empty' value in this context means either {@code null} or
143
   * the empty string "".
144
   * <p>The object whose field is being validated does not need to be passed
145
   * in because the {@link Errors} instance can resolve field values by itself
146
   * (it will usually hold an internal reference to the target object).
147
   *
148
   * @param errors the {@code Errors} instance to register errors on
149
   * @param field the field name to check
150
   * @param errorCode the error code, interpretable as message key
151
   * @param errorArgs the error arguments, for argument binding via MessageFormat
152
   * (can be {@code null})
153
   */
154
  public static void rejectIfEmpty(Errors errors, String field, String errorCode, Object[] errorArgs) {
155
    rejectIfEmpty(errors, field, errorCode, errorArgs, null);
6✔
156
  }
1✔
157

158
  /**
159
   * Reject the given field with the given error code, error arguments
160
   * and default message if the value is empty.
161
   * <p>An 'empty' value in this context means either {@code null} or
162
   * the empty string "".
163
   * <p>The object whose field is being validated does not need to be passed
164
   * in because the {@link Errors} instance can resolve field values by itself
165
   * (it will usually hold an internal reference to the target object).
166
   *
167
   * @param errors the {@code Errors} instance to register errors on
168
   * @param field the field name to check
169
   * @param errorCode the error code, interpretable as message key
170
   * @param errorArgs the error arguments, for argument binding via MessageFormat
171
   * (can be {@code null})
172
   * @param defaultMessage fallback default message
173
   */
174
  public static void rejectIfEmpty(Errors errors, String field,
175
          String errorCode, Object @Nullable [] errorArgs, @Nullable String defaultMessage) {
176

177
    Assert.notNull(errors, "Errors object is required");
3✔
178
    Object value = errors.getFieldValue(field);
4✔
179
    if (value == null || StringUtils.isEmpty(value.toString())) {
6✔
180
      errors.rejectValue(field, errorCode, errorArgs, defaultMessage);
6✔
181
    }
182
  }
1✔
183

184
  /**
185
   * Reject the given field with the given error code if the value is empty
186
   * or just contains whitespace.
187
   * <p>An 'empty' value in this context means either {@code null},
188
   * the empty string "", or consisting wholly of whitespace.
189
   * <p>The object whose field is being validated does not need to be passed
190
   * in because the {@link Errors} instance can resolve field values by itself
191
   * (it will usually hold an internal reference to the target object).
192
   *
193
   * @param errors the {@code Errors} instance to register errors on
194
   * @param field the field name to check
195
   * @param errorCode the error code, interpretable as message key
196
   */
197
  public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode) {
198
    rejectIfEmptyOrWhitespace(errors, field, errorCode, null, null);
6✔
199
  }
1✔
200

201
  /**
202
   * Reject the given field with the given error code and default message
203
   * if the value is empty or just contains whitespace.
204
   * <p>An 'empty' value in this context means either {@code null},
205
   * the empty string "", or consisting wholly of whitespace.
206
   * <p>The object whose field is being validated does not need to be passed
207
   * in because the {@link Errors} instance can resolve field values by itself
208
   * (it will usually hold an internal reference to the target object).
209
   *
210
   * @param errors the {@code Errors} instance to register errors on
211
   * @param field the field name to check
212
   * @param errorCode the error code, interpretable as message key
213
   * @param defaultMessage fallback default message
214
   */
215
  public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode, String defaultMessage) {
216
    rejectIfEmptyOrWhitespace(errors, field, errorCode, null, defaultMessage);
6✔
217
  }
1✔
218

219
  /**
220
   * Reject the given field with the given error code and error arguments
221
   * if the value is empty or just contains whitespace.
222
   * <p>An 'empty' value in this context means either {@code null},
223
   * the empty string "", or consisting wholly of whitespace.
224
   * <p>The object whose field is being validated does not need to be passed
225
   * in because the {@link Errors} instance can resolve field values by itself
226
   * (it will usually hold an internal reference to the target object).
227
   *
228
   * @param errors the {@code Errors} instance to register errors on
229
   * @param field the field name to check
230
   * @param errorCode the error code, interpretable as message key
231
   * @param errorArgs the error arguments, for argument binding via MessageFormat
232
   * (can be {@code null})
233
   */
234
  public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode, Object @Nullable [] errorArgs) {
235
    rejectIfEmptyOrWhitespace(errors, field, errorCode, errorArgs, null);
6✔
236
  }
1✔
237

238
  /**
239
   * Reject the given field with the given error code, error arguments
240
   * and default message if the value is empty or just contains whitespace.
241
   * <p>An 'empty' value in this context means either {@code null},
242
   * the empty string "", or consisting wholly of whitespace.
243
   * <p>The object whose field is being validated does not need to be passed
244
   * in because the {@link Errors} instance can resolve field values by itself
245
   * (it will usually hold an internal reference to the target object).
246
   *
247
   * @param errors the {@code Errors} instance to register errors on
248
   * @param field the field name to check
249
   * @param errorCode the error code, interpretable as message key
250
   * @param errorArgs the error arguments, for argument binding via MessageFormat
251
   * (can be {@code null})
252
   * @param defaultMessage fallback default message
253
   */
254
  public static void rejectIfEmptyOrWhitespace(Errors errors, String field,
255
          String errorCode, Object @Nullable [] errorArgs, @Nullable String defaultMessage) {
256

257
    Assert.notNull(errors, "Errors object is required");
3✔
258
    Object value = errors.getFieldValue(field);
4✔
259
    if (value == null || StringUtils.isBlank(value.toString())) {
6✔
260
      errors.rejectValue(field, errorCode, errorArgs, defaultMessage);
6✔
261
    }
262
  }
1✔
263

264
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc