1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.lang3;
18
19 import java.util.Collection;
20 import java.util.Map;
21 import java.util.Objects;
22 import java.util.concurrent.atomic.AtomicInteger;
23 import java.util.function.Supplier;
24 import java.util.regex.Pattern;
25
26 /**
27 * This class assists in validating arguments. The validation methods are
28 * based along the following principles:
29 * <ul>
30 * <li>An invalid {@code null} argument causes a {@link NullPointerException}.</li>
31 * <li>A non-{@code null} argument causes an {@link IllegalArgumentException}.</li>
32 * <li>An invalid index into an array/collection/map/string causes an {@link IndexOutOfBoundsException}.</li>
33 * </ul>
34 *
35 * <p>All exceptions messages are
36 * <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax">format strings</a>
37 * as defined by the Java platform. For example:
38 *
39 * <pre>
40 * Validate.isTrue(i > 0, "The value must be greater than zero: %d", i);
41 * Validate.notNull(surname, "The surname must not be %s", null);
42 * </pre>
43 *
44 * <p>#ThreadSafe#</p>
45 * @see String#format(String, Object...)
46 * @since 2.0
47 */
48 public class Validate {
49
50 private static final String DEFAULT_NOT_NAN_EX_MESSAGE =
51 "The validated value is not a number";
52 private static final String DEFAULT_FINITE_EX_MESSAGE =
53 "The value is invalid: %f";
54 private static final String DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE =
55 "The value %s is not in the specified exclusive range of %s to %s";
56 private static final String DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE =
57 "The value %s is not in the specified inclusive range of %s to %s";
58 private static final String DEFAULT_MATCHES_PATTERN_EX = "The string %s does not match the pattern %s";
59 private static final String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null";
60 private static final String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false";
61 private static final String DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE =
62 "The validated array contains null element at index: %d";
63 private static final String DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE =
64 "The validated collection contains null element at index: %d";
65 private static final String DEFAULT_NOT_BLANK_EX_MESSAGE = "The validated character sequence is blank";
66 private static final String DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE = "The validated array is empty";
67 private static final String DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE =
68 "The validated character sequence is empty";
69 private static final String DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE = "The validated collection is empty";
70 private static final String DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE = "The validated map is empty";
71 private static final String DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE = "The validated array index is invalid: %d";
72 private static final String DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE =
73 "The validated character sequence index is invalid: %d";
74 private static final String DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE =
75 "The validated collection index is invalid: %d";
76 private static final String DEFAULT_VALID_STATE_EX_MESSAGE = "The validated state is false";
77 private static final String DEFAULT_IS_ASSIGNABLE_EX_MESSAGE = "Cannot assign a %s to a %s";
78 private static final String DEFAULT_IS_INSTANCE_OF_EX_MESSAGE = "Expected type: %s, actual: %s";
79
80 /**
81 * Validate that the specified primitive value falls between the two
82 * exclusive values specified; otherwise, throws an exception.
83 *
84 * <pre>Validate.exclusiveBetween(0.1, 2.1, 1.1);</pre>
85 *
86 * @param start the exclusive start value
87 * @param end the exclusive end value
88 * @param value the value to validate
89 * @throws IllegalArgumentException if the value falls out of the boundaries
90 * @since 3.3
91 */
92 @SuppressWarnings("boxing")
93 public static void exclusiveBetween(final double start, final double end, final double value) {
94 // TODO when breaking BC, consider returning value
95 if (value <= start || value >= end) {
96 throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
97 }
98 }
99
100 /**
101 * Validate that the specified primitive value falls between the two
102 * exclusive values specified; otherwise, throws an exception with the
103 * specified message.
104 *
105 * <pre>Validate.exclusiveBetween(0.1, 2.1, 1.1, "Not in range");</pre>
106 *
107 * @param start the exclusive start value
108 * @param end the exclusive end value
109 * @param value the value to validate
110 * @param message the exception message if invalid, not null
111 * @throws IllegalArgumentException if the value falls outside the boundaries
112 * @since 3.3
113 */
114 public static void exclusiveBetween(final double start, final double end, final double value, final String message) {
115 // TODO when breaking BC, consider returning value
116 if (value <= start || value >= end) {
117 throw new IllegalArgumentException(message);
118 }
119 }
120
121 /**
122 * Validate that the specified primitive value falls between the two
123 * exclusive values specified; otherwise, throws an exception.
124 *
125 * <pre>Validate.exclusiveBetween(0, 2, 1);</pre>
126 *
127 * @param start the exclusive start value
128 * @param end the exclusive end value
129 * @param value the value to validate
130 * @throws IllegalArgumentException if the value falls out of the boundaries
131 * @since 3.3
132 */
133 @SuppressWarnings("boxing")
134 public static void exclusiveBetween(final long start, final long end, final long value) {
135 // TODO when breaking BC, consider returning value
136 if (value <= start || value >= end) {
137 throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
138 }
139 }
140
141 /**
142 * Validate that the specified primitive value falls between the two
143 * exclusive values specified; otherwise, throws an exception with the
144 * specified message.
145 *
146 * <pre>Validate.exclusiveBetween(0, 2, 1, "Not in range");</pre>
147 *
148 * @param start the exclusive start value
149 * @param end the exclusive end value
150 * @param value the value to validate
151 * @param message the exception message if invalid, not null
152 * @throws IllegalArgumentException if the value falls outside the boundaries
153 * @since 3.3
154 */
155 public static void exclusiveBetween(final long start, final long end, final long value, final String message) {
156 // TODO when breaking BC, consider returning value
157 if (value <= start || value >= end) {
158 throw new IllegalArgumentException(message);
159 }
160 }
161
162 /**
163 * Validate that the specified argument object fall between the two
164 * exclusive values specified; otherwise, throws an exception.
165 *
166 * <pre>Validate.exclusiveBetween(0, 2, 1);</pre>
167 *
168 * @param <T> the type of the argument object
169 * @param start the exclusive start value, not null
170 * @param end the exclusive end value, not null
171 * @param value the object to validate, not null
172 * @throws IllegalArgumentException if the value falls outside the boundaries
173 * @see #exclusiveBetween(Object, Object, Comparable, String, Object...)
174 * @since 3.0
175 */
176 public static <T> void exclusiveBetween(final T start, final T end, final Comparable<T> value) {
177 // TODO when breaking BC, consider returning value
178 if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) {
179 throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
180 }
181 }
182
183 /**
184 * Validate that the specified argument object fall between the two
185 * exclusive values specified; otherwise, throws an exception with the
186 * specified message.
187 *
188 * <pre>Validate.exclusiveBetween(0, 2, 1, "Not in boundaries");</pre>
189 *
190 * @param <T> the type of the argument object
191 * @param start the exclusive start value, not null
192 * @param end the exclusive end value, not null
193 * @param value the object to validate, not null
194 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
195 * @param values the optional values for the formatted exception message, null array not recommended
196 * @throws IllegalArgumentException if the value falls outside the boundaries
197 * @see #exclusiveBetween(Object, Object, Comparable)
198 * @since 3.0
199 */
200 public static <T> void exclusiveBetween(final T start, final T end, final Comparable<T> value, final String message, final Object... values) {
201 // TODO when breaking BC, consider returning value
202 if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) {
203 throw new IllegalArgumentException(getMessage(message, values));
204 }
205 }
206
207 /**
208 * Validates that the specified argument is not infinite or Not-a-Number (NaN);
209 * otherwise throwing an exception.
210 *
211 * <pre>Validate.finite(myDouble);</pre>
212 *
213 * <p>The message of the exception is "The value is invalid: %f".</p>
214 *
215 * @param value the value to validate
216 * @throws IllegalArgumentException if the value is infinite or Not-a-Number (NaN)
217 * @see #finite(double, String, Object...)
218 * @since 3.5
219 */
220 public static void finite(final double value) {
221 finite(value, DEFAULT_FINITE_EX_MESSAGE, value);
222 }
223
224 /**
225 * Validates that the specified argument is not infinite or Not-a-Number (NaN);
226 * otherwise throwing an exception with the specified message.
227 *
228 * <pre>Validate.finite(myDouble, "The argument must contain a numeric value");</pre>
229 *
230 * @param value the value to validate
231 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
232 * @param values the optional values for the formatted exception message
233 * @throws IllegalArgumentException if the value is infinite or Not-a-Number (NaN)
234 * @see #finite(double)
235 * @since 3.5
236 */
237 public static void finite(final double value, final String message, final Object... values) {
238 if (Double.isNaN(value) || Double.isInfinite(value)) {
239 throw new IllegalArgumentException(getMessage(message, values));
240 }
241 }
242
243 /**
244 * Gets the message using {@link String#format(String, Object...) String.format(message, values)}
245 * if the values are not empty, otherwise return the message unformatted.
246 * This method exists to allow validation methods declaring a String message and varargs parameters
247 * to be used without any message parameters when the message contains special characters,
248 * e.g. {@code Validate.isTrue(false, "%Failed%")}.
249 *
250 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
251 * @param values the optional values for the formatted message
252 * @return formatted message using {@link String#format(String, Object...) String.format(message, values)}
253 * if the values are not empty, otherwise return the unformatted message.
254 */
255 private static String getMessage(final String message, final Object... values) {
256 return ArrayUtils.isEmpty(values) ? message : String.format(message, values);
257 }
258
259 /**
260 * Validate that the specified primitive value falls between the two
261 * inclusive values specified; otherwise, throws an exception.
262 *
263 * <pre>Validate.inclusiveBetween(0.1, 2.1, 1.1);</pre>
264 *
265 * @param start the inclusive start value
266 * @param end the inclusive end value
267 * @param value the value to validate
268 * @throws IllegalArgumentException if the value falls outside the boundaries (inclusive)
269 * @since 3.3
270 */
271 @SuppressWarnings("boxing")
272 public static void inclusiveBetween(final double start, final double end, final double value) {
273 // TODO when breaking BC, consider returning value
274 if (value < start || value > end) {
275 throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
276 }
277 }
278
279 /**
280 * Validate that the specified primitive value falls between the two
281 * inclusive values specified; otherwise, throws an exception with the
282 * specified message.
283 *
284 * <pre>Validate.inclusiveBetween(0.1, 2.1, 1.1, "Not in range");</pre>
285 *
286 * @param start the inclusive start value
287 * @param end the inclusive end value
288 * @param value the value to validate
289 * @param message the exception message if invalid, not null
290 * @throws IllegalArgumentException if the value falls outside the boundaries
291 * @since 3.3
292 */
293 public static void inclusiveBetween(final double start, final double end, final double value, final String message) {
294 // TODO when breaking BC, consider returning value
295 if (value < start || value > end) {
296 throw new IllegalArgumentException(message);
297 }
298 }
299
300 /**
301 * Validate that the specified primitive value falls between the two
302 * inclusive values specified; otherwise, throws an exception.
303 *
304 * <pre>Validate.inclusiveBetween(0, 2, 1);</pre>
305 *
306 * @param start the inclusive start value
307 * @param end the inclusive end value
308 * @param value the value to validate
309 * @throws IllegalArgumentException if the value falls outside the boundaries (inclusive)
310 * @since 3.3
311 */
312 @SuppressWarnings("boxing")
313 public static void inclusiveBetween(final long start, final long end, final long value) {
314 // TODO when breaking BC, consider returning value
315 if (value < start || value > end) {
316 throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
317 }
318 }
319
320 /**
321 * Validate that the specified primitive value falls between the two
322 * inclusive values specified; otherwise, throws an exception with the
323 * specified message.
324 *
325 * <pre>Validate.inclusiveBetween(0, 2, 1, "Not in range");</pre>
326 *
327 * @param start the inclusive start value
328 * @param end the inclusive end value
329 * @param value the value to validate
330 * @param message the exception message if invalid, not null
331 * @throws IllegalArgumentException if the value falls outside the boundaries
332 * @since 3.3
333 */
334 public static void inclusiveBetween(final long start, final long end, final long value, final String message) {
335 // TODO when breaking BC, consider returning value
336 if (value < start || value > end) {
337 throw new IllegalArgumentException(message);
338 }
339 }
340
341 /**
342 * Validate that the specified argument object fall between the two
343 * inclusive values specified; otherwise, throws an exception.
344 *
345 * <pre>Validate.inclusiveBetween(0, 2, 1);</pre>
346 *
347 * @param <T> the type of the argument object
348 * @param start the inclusive start value, not null
349 * @param end the inclusive end value, not null
350 * @param value the object to validate, not null
351 * @throws IllegalArgumentException if the value falls outside the boundaries
352 * @see #inclusiveBetween(Object, Object, Comparable, String, Object...)
353 * @since 3.0
354 */
355 public static <T> void inclusiveBetween(final T start, final T end, final Comparable<T> value) {
356 // TODO when breaking BC, consider returning value
357 if (value.compareTo(start) < 0 || value.compareTo(end) > 0) {
358 throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
359 }
360 }
361
362 /**
363 * Validate that the specified argument object fall between the two
364 * inclusive values specified; otherwise, throws an exception with the
365 * specified message.
366 *
367 * <pre>Validate.inclusiveBetween(0, 2, 1, "Not in boundaries");</pre>
368 *
369 * @param <T> the type of the argument object
370 * @param start the inclusive start value, not null
371 * @param end the inclusive end value, not null
372 * @param value the object to validate, not null
373 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
374 * @param values the optional values for the formatted exception message, null array not recommended
375 * @throws IllegalArgumentException if the value falls outside the boundaries
376 * @see #inclusiveBetween(Object, Object, Comparable)
377 * @since 3.0
378 */
379 public static <T> void inclusiveBetween(final T start, final T end, final Comparable<T> value, final String message, final Object... values) {
380 // TODO when breaking BC, consider returning value
381 if (value.compareTo(start) < 0 || value.compareTo(end) > 0) {
382 throw new IllegalArgumentException(getMessage(message, values));
383 }
384 }
385
386 /**
387 * Validates that the argument can be converted to the specified class, if not, throws an exception.
388 *
389 * <p>This method is useful when validating that there will be no casting errors.</p>
390 *
391 * <pre>Validate.isAssignableFrom(SuperClass.class, object.getClass());</pre>
392 *
393 * <p>The message format of the exception is "Cannot assign {type} to {superType}"</p>
394 *
395 * @param superType the class must be validated against, not null
396 * @param type the class to check, not null
397 * @throws IllegalArgumentException if type argument is not assignable to the specified superType
398 * @see #isAssignableFrom(Class, Class, String, Object...)
399 * @since 3.0
400 */
401 public static void isAssignableFrom(final Class<?> superType, final Class<?> type) {
402 // TODO when breaking BC, consider returning type
403 if (type == null || superType == null || !superType.isAssignableFrom(type)) {
404 throw new IllegalArgumentException(
405 String.format(DEFAULT_IS_ASSIGNABLE_EX_MESSAGE, ClassUtils.getName(type, "null type"), ClassUtils.getName(superType, "null type")));
406 }
407 }
408
409 /**
410 * Validates that the argument can be converted to the specified class, if not throws an exception.
411 *
412 * <p>This method is useful when validating if there will be no casting errors.</p>
413 *
414 * <pre>Validate.isAssignableFrom(SuperClass.class, object.getClass());</pre>
415 *
416 * <p>The message of the exception is "The validated object cannot be converted to the"
417 * followed by the name of the class and "class"</p>
418 *
419 * @param superType the class must be validated against, not null
420 * @param type the class to check, not null
421 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
422 * @param values the optional values for the formatted exception message, null array not recommended
423 * @throws IllegalArgumentException if argument cannot be converted to the specified class
424 * @see #isAssignableFrom(Class, Class)
425 */
426 public static void isAssignableFrom(final Class<?> superType, final Class<?> type, final String message, final Object... values) {
427 // TODO when breaking BC, consider returning type
428 if (!superType.isAssignableFrom(type)) {
429 throw new IllegalArgumentException(getMessage(message, values));
430 }
431 }
432
433 /**
434 * Validates that the argument is an instance of the specified class, if not throws an exception.
435 *
436 * <p>This method is useful when validating according to an arbitrary class</p>
437 *
438 * <pre>Validate.isInstanceOf(OkClass.class, object);</pre>
439 *
440 * <p>The message of the exception is "Expected type: {type}, actual: {obj_type}"</p>
441 *
442 * @param type the class the object must be validated against, not null
443 * @param obj the object to check, null throws an exception
444 * @throws IllegalArgumentException if argument is not of specified class
445 * @see #isInstanceOf(Class, Object, String, Object...)
446 * @since 3.0
447 */
448 public static void isInstanceOf(final Class<?> type, final Object obj) {
449 // TODO when breaking BC, consider returning obj
450 if (!type.isInstance(obj)) {
451 throw new IllegalArgumentException(String.format(DEFAULT_IS_INSTANCE_OF_EX_MESSAGE, type.getName(), ClassUtils.getName(obj, "null")));
452 }
453 }
454
455 /**
456 * Validate that the argument is an instance of the specified class; otherwise
457 * throwing an exception with the specified message. This method is useful when
458 * validating according to an arbitrary class
459 *
460 * <pre>Validate.isInstanceOf(OkClass.class, object, "Wrong class, object is of class %s",
461 * object.getClass().getName());</pre>
462 *
463 * @param type the class the object must be validated against, not null
464 * @param obj the object to check, null throws an exception
465 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
466 * @param values the optional values for the formatted exception message, null array not recommended
467 * @throws IllegalArgumentException if argument is not of specified class
468 * @see #isInstanceOf(Class, Object)
469 * @since 3.0
470 */
471 public static void isInstanceOf(final Class<?> type, final Object obj, final String message, final Object... values) {
472 // TODO when breaking BC, consider returning obj
473 if (!type.isInstance(obj)) {
474 throw new IllegalArgumentException(getMessage(message, values));
475 }
476 }
477
478 /**
479 * Validate that the argument condition is {@code true}; otherwise
480 * throwing an exception. This method is useful when validating according
481 * to an arbitrary boolean expression, such as validating a
482 * primitive number or using your own custom validation expression.
483 *
484 * <pre>
485 * Validate.isTrue(i > 0);
486 * Validate.isTrue(myObject.isOk());</pre>
487 *
488 * <p>The message of the exception is "The validated expression is
489 * false".</p>
490 *
491 * @param expression the boolean expression to check
492 * @throws IllegalArgumentException if expression is {@code false}
493 * @see #isTrue(boolean, String, long)
494 * @see #isTrue(boolean, String, double)
495 * @see #isTrue(boolean, String, Object...)
496 * @see #isTrue(boolean, Supplier)
497 */
498 public static void isTrue(final boolean expression) {
499 if (!expression) {
500 throw new IllegalArgumentException(DEFAULT_IS_TRUE_EX_MESSAGE);
501 }
502 }
503
504 /**
505 * Validate that the argument condition is {@code true}; otherwise
506 * throwing an exception with the specified message. This method is useful when
507 * validating according to an arbitrary boolean expression, such as validating a
508 * primitive number or using your own custom validation expression.
509 *
510 * <pre>Validate.isTrue(d > 0.0, "The value must be greater than zero: %s", d);</pre>
511 *
512 * <p>For performance reasons, the double value is passed as a separate parameter and
513 * appended to the exception message only in the case of an error.</p>
514 *
515 * @param expression the boolean expression to check
516 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
517 * @param value the value to append to the message when invalid
518 * @throws IllegalArgumentException if expression is {@code false}
519 * @see #isTrue(boolean)
520 * @see #isTrue(boolean, String, long)
521 * @see #isTrue(boolean, String, Object...)
522 * @see #isTrue(boolean, Supplier)
523 */
524 public static void isTrue(final boolean expression, final String message, final double value) {
525 if (!expression) {
526 throw new IllegalArgumentException(String.format(message, Double.valueOf(value)));
527 }
528 }
529
530 /**
531 * Validate that the argument condition is {@code true}; otherwise
532 * throwing an exception with the specified message. This method is useful when
533 * validating according to an arbitrary boolean expression, such as validating a
534 * primitive number or using your own custom validation expression.
535 *
536 * <pre>Validate.isTrue(i > 0.0, "The value must be greater than zero: %d", i);</pre>
537 *
538 * <p>For performance reasons, the long value is passed as a separate parameter and
539 * appended to the exception message only in the case of an error.</p>
540 *
541 * @param expression the boolean expression to check
542 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
543 * @param value the value to append to the message when invalid
544 * @throws IllegalArgumentException if expression is {@code false}
545 * @see #isTrue(boolean)
546 * @see #isTrue(boolean, String, double)
547 * @see #isTrue(boolean, String, Object...)
548 * @see #isTrue(boolean, Supplier)
549 */
550 public static void isTrue(final boolean expression, final String message, final long value) {
551 if (!expression) {
552 throw new IllegalArgumentException(String.format(message, Long.valueOf(value)));
553 }
554 }
555
556 /**
557 * Validate that the argument condition is {@code true}; otherwise
558 * throwing an exception with the specified message. This method is useful when
559 * validating according to an arbitrary boolean expression, such as validating a
560 * primitive number or using your own custom validation expression.
561 *
562 * <pre>{@code
563 * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max);}</pre>
564 *
565 * @param expression the boolean expression to check
566 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
567 * @param values the optional values for the formatted exception message, null array not recommended
568 * @throws IllegalArgumentException if expression is {@code false}
569 * @see #isTrue(boolean)
570 * @see #isTrue(boolean, String, long)
571 * @see #isTrue(boolean, String, double)
572 * @see #isTrue(boolean, Supplier)
573 */
574 public static void isTrue(final boolean expression, final String message, final Object... values) {
575 if (!expression) {
576 throw new IllegalArgumentException(getMessage(message, values));
577 }
578 }
579
580 /**
581 * Validate that the argument condition is {@code true}; otherwise throwing an exception with the specified message. This method is useful when validating
582 * according to an arbitrary boolean expression, such as validating a primitive number or using your own custom validation expression.
583 *
584 * <pre>{@code
585 * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max);
586 * }</pre>
587 *
588 * @param expression the boolean expression to check
589 * @param messageSupplier the exception message supplier
590 * @throws IllegalArgumentException if expression is {@code false}
591 * @see #isTrue(boolean)
592 * @see #isTrue(boolean, String, long)
593 * @see #isTrue(boolean, String, double)
594 * @since 3.18.0
595 */
596 public static void isTrue(final boolean expression, final Supplier<String> messageSupplier) {
597 if (!expression) {
598 throw new IllegalArgumentException(messageSupplier.get());
599 }
600 }
601
602 /**
603 * Validate that the specified argument character sequence matches the specified regular
604 * expression pattern; otherwise throwing an exception.
605 *
606 * <pre>Validate.matchesPattern("hi", "[a-z]*");</pre>
607 *
608 * <p>The syntax of the pattern is the one used in the {@link Pattern} class.</p>
609 *
610 * @param input the character sequence to validate, not null
611 * @param pattern the regular expression pattern, not null
612 * @throws IllegalArgumentException if the character sequence does not match the pattern
613 * @see #matchesPattern(CharSequence, String, String, Object...)
614 * @since 3.0
615 */
616 public static void matchesPattern(final CharSequence input, final String pattern) {
617 // TODO when breaking BC, consider returning input
618 if (!Pattern.matches(pattern, input)) {
619 throw new IllegalArgumentException(String.format(DEFAULT_MATCHES_PATTERN_EX, input, pattern));
620 }
621 }
622
623 /**
624 * Validate that the specified argument character sequence matches the specified regular
625 * expression pattern; otherwise throwing an exception with the specified message.
626 *
627 * <pre>Validate.matchesPattern("hi", "[a-z]*", "%s does not match %s", "hi" "[a-z]*");</pre>
628 *
629 * <p>The syntax of the pattern is the one used in the {@link Pattern} class.</p>
630 *
631 * @param input the character sequence to validate, not null
632 * @param pattern the regular expression pattern, not null
633 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
634 * @param values the optional values for the formatted exception message, null array not recommended
635 * @throws IllegalArgumentException if the character sequence does not match the pattern
636 * @see #matchesPattern(CharSequence, String)
637 * @since 3.0
638 */
639 public static void matchesPattern(final CharSequence input, final String pattern, final String message, final Object... values) {
640 // TODO when breaking BC, consider returning input
641 if (!Pattern.matches(pattern, input)) {
642 throw new IllegalArgumentException(getMessage(message, values));
643 }
644 }
645
646 /**
647 * Validate that the specified argument iterable is neither
648 * {@code null} nor contains any elements that are {@code null};
649 * otherwise throwing an exception.
650 *
651 * <pre>Validate.noNullElements(myCollection);</pre>
652 *
653 * <p>If the iterable is {@code null}, then the message in the exception
654 * is "The validated object is null".
655 *
656 * <p>If the array has a {@code null} element, then the message in the
657 * exception is "The validated iterable contains null element at index:
658 * " followed by the index.</p>
659 *
660 * @param <T> the iterable type
661 * @param iterable the iterable to check, validated not null by this method
662 * @return the validated iterable (never {@code null} method for chaining)
663 * @throws NullPointerException if the array is {@code null}
664 * @throws IllegalArgumentException if an element is {@code null}
665 * @see #noNullElements(Iterable, String, Object...)
666 */
667 public static <T extends Iterable<?>> T noNullElements(final T iterable) {
668 return noNullElements(iterable, DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE);
669 }
670
671 /**
672 * Validate that the specified argument iterable is neither
673 * {@code null} nor contains any elements that are {@code null};
674 * otherwise throwing an exception with the specified message.
675 *
676 * <pre>Validate.noNullElements(myCollection, "The collection contains null at position %d");</pre>
677 *
678 * <p>If the iterable is {@code null}, then the message in the exception
679 * is "The validated object is null".
680 *
681 * <p>If the iterable has a {@code null} element, then the iteration
682 * index of the invalid element is appended to the {@code values}
683 * argument.</p>
684 *
685 * @param <T> the iterable type
686 * @param iterable the iterable to check, validated not null by this method
687 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
688 * @param values the optional values for the formatted exception message, null array not recommended
689 * @return the validated iterable (never {@code null} method for chaining)
690 * @throws NullPointerException if the array is {@code null}
691 * @throws IllegalArgumentException if an element is {@code null}
692 * @see #noNullElements(Iterable)
693 */
694 public static <T extends Iterable<?>> T noNullElements(final T iterable, final String message, final Object... values) {
695 Objects.requireNonNull(iterable, "iterable");
696 final AtomicInteger ai = new AtomicInteger();
697 iterable.forEach(e -> {
698 if (e == null) {
699 throw new IllegalArgumentException(getMessage(message, ArrayUtils.addAll(values, ai.getAndIncrement())));
700 }
701 });
702 return iterable;
703 }
704
705 /**
706 * Validate that the specified argument array is neither
707 * {@code null} nor contains any elements that are {@code null};
708 * otherwise throwing an exception.
709 *
710 * <pre>Validate.noNullElements(myArray);</pre>
711 *
712 * <p>If the array is {@code null}, then the message in the exception
713 * is "The validated object is null".</p>
714 *
715 * <p>If the array has a {@code null} element, then the message in the
716 * exception is "The validated array contains null element at index:
717 * " followed by the index.</p>
718 *
719 * @param <T> the array type
720 * @param array the array to check, validated not null by this method
721 * @return the validated array (never {@code null} method for chaining)
722 * @throws NullPointerException if the array is {@code null}
723 * @throws IllegalArgumentException if an element is {@code null}
724 * @see #noNullElements(Object[], String, Object...)
725 */
726 public static <T> T[] noNullElements(final T[] array) {
727 return noNullElements(array, DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE);
728 }
729
730 /**
731 * Validate that the specified argument array is neither
732 * {@code null} nor contains any elements that are {@code null};
733 * otherwise throwing an exception with the specified message.
734 *
735 * <pre>Validate.noNullElements(myArray, "The array contain null at position %d");</pre>
736 *
737 * <p>If the array is {@code null}, then the message in the exception
738 * is "The validated object is null".
739 *
740 * <p>If the array has a {@code null} element, then the iteration
741 * index of the invalid element is appended to the {@code values}
742 * argument.</p>
743 *
744 * @param <T> the array type
745 * @param array the array to check, validated not null by this method
746 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
747 * @param values the optional values for the formatted exception message, null array not recommended
748 * @return the validated array (never {@code null} method for chaining)
749 * @throws NullPointerException if the array is {@code null}
750 * @throws IllegalArgumentException if an element is {@code null}
751 * @see #noNullElements(Object[])
752 */
753 public static <T> T[] noNullElements(final T[] array, final String message, final Object... values) {
754 Objects.requireNonNull(array, "array");
755 for (int i = 0; i < array.length; i++) {
756 if (array[i] == null) {
757 final Object[] values2 = ArrayUtils.add(values, Integer.valueOf(i));
758 throw new IllegalArgumentException(getMessage(message, values2));
759 }
760 }
761 return array;
762 }
763
764 /**
765 * <p>Validates that the specified argument character sequence is
766 * neither {@code null}, a length of zero (no characters), empty
767 * nor whitespace; otherwise throwing an exception.
768 *
769 * <pre>Validate.notBlank(myString);</pre>
770 *
771 * <p>The message in the exception is "The validated character
772 * sequence is blank".
773 *
774 * @param <T> the character sequence type
775 * @param chars the character sequence to check, validated not null by this method
776 * @return the validated character sequence (never {@code null} method for chaining)
777 * @throws NullPointerException if the character sequence is {@code null}
778 * @throws IllegalArgumentException if the character sequence is blank
779 * @see #notBlank(CharSequence, String, Object...)
780 * @since 3.0
781 */
782 public static <T extends CharSequence> T notBlank(final T chars) {
783 return notBlank(chars, DEFAULT_NOT_BLANK_EX_MESSAGE);
784 }
785
786 /**
787 * Validates that the specified argument character sequence is not {@link StringUtils#isBlank(CharSequence) blank} (whitespaces, empty ({@code ""}) or
788 * {@code null}); otherwise throwing an exception with the specified message.
789 *
790 * <pre>
791 * Validate.notBlank(myString, "The string must not be blank");
792 * </pre>
793 *
794 * @param <T> the character sequence type
795 * @param chars the character sequence to check, validated not null by this method
796 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
797 * @param values the optional values for the formatted exception message, null array not recommended
798 * @return the validated character sequence (never {@code null} method for chaining)
799 * @throws NullPointerException if the character sequence is {@code null}
800 * @throws IllegalArgumentException if the character sequence is blank
801 * @see #notBlank(CharSequence)
802 * @see StringUtils#isBlank(CharSequence)
803 * @since 3.0
804 */
805 public static <T extends CharSequence> T notBlank(final T chars, final String message, final Object... values) {
806 Objects.requireNonNull(chars, toSupplier(message, values));
807 if (StringUtils.isBlank(chars)) {
808 throw new IllegalArgumentException(getMessage(message, values));
809 }
810 return chars;
811 }
812
813 /**
814 * <p>Validates that the specified argument collection is neither {@code null}
815 * nor a size of zero (no elements); otherwise throwing an exception.
816 *
817 * <pre>Validate.notEmpty(myCollection);</pre>
818 *
819 * <p>The message in the exception is "The validated collection is
820 * empty".
821 *
822 * @param <T> the collection type
823 * @param collection the collection to check, validated not null by this method
824 * @return the validated collection (never {@code null} method for chaining)
825 * @throws NullPointerException if the collection is {@code null}
826 * @throws IllegalArgumentException if the collection is empty
827 * @see #notEmpty(Collection, String, Object...)
828 */
829 public static <T extends Collection<?>> T notEmpty(final T collection) {
830 return notEmpty(collection, DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE);
831 }
832
833 /**
834 * <p>Validates that the specified argument map is neither {@code null}
835 * nor a size of zero (no elements); otherwise throwing an exception.
836 *
837 * <pre>Validate.notEmpty(myMap);</pre>
838 *
839 * <p>The message in the exception is "The validated map is
840 * empty".
841 *
842 * @param <T> the map type
843 * @param map the map to check, validated not null by this method
844 * @return the validated map (never {@code null} method for chaining)
845 * @throws NullPointerException if the map is {@code null}
846 * @throws IllegalArgumentException if the map is empty
847 * @see #notEmpty(Map, String, Object...)
848 */
849 public static <T extends Map<?, ?>> T notEmpty(final T map) {
850 return notEmpty(map, DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE);
851 }
852
853 /**
854 * <p>Validates that the specified argument character sequence is
855 * neither {@code null} nor a length of zero (no characters);
856 * otherwise throwing an exception with the specified message.
857 *
858 * <pre>Validate.notEmpty(myString);</pre>
859 *
860 * <p>The message in the exception is "The validated
861 * character sequence is empty".
862 *
863 * @param <T> the character sequence type
864 * @param chars the character sequence to check, validated not null by this method
865 * @return the validated character sequence (never {@code null} method for chaining)
866 * @throws NullPointerException if the character sequence is {@code null}
867 * @throws IllegalArgumentException if the character sequence is empty
868 * @see #notEmpty(CharSequence, String, Object...)
869 */
870 public static <T extends CharSequence> T notEmpty(final T chars) {
871 return notEmpty(chars, DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE);
872 }
873
874 /**
875 * <p>Validates that the specified argument collection is neither {@code null}
876 * nor a size of zero (no elements); otherwise throwing an exception
877 * with the specified message.
878 *
879 * <pre>Validate.notEmpty(myCollection, "The collection must not be empty");</pre>
880 *
881 * @param <T> the collection type
882 * @param collection the collection to check, validated not null by this method
883 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
884 * @param values the optional values for the formatted exception message, null array not recommended
885 * @return the validated collection (never {@code null} method for chaining)
886 * @throws NullPointerException if the collection is {@code null}
887 * @throws IllegalArgumentException if the collection is empty
888 * @see #notEmpty(Object[])
889 */
890 public static <T extends Collection<?>> T notEmpty(final T collection, final String message, final Object... values) {
891 Objects.requireNonNull(collection, toSupplier(message, values));
892 if (collection.isEmpty()) {
893 throw new IllegalArgumentException(getMessage(message, values));
894 }
895 return collection;
896 }
897
898 /**
899 * Validate that the specified argument map is neither {@code null}
900 * nor a size of zero (no elements); otherwise throwing an exception
901 * with the specified message.
902 *
903 * <pre>Validate.notEmpty(myMap, "The map must not be empty");</pre>
904 *
905 * @param <T> the map type
906 * @param map the map to check, validated not null by this method
907 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
908 * @param values the optional values for the formatted exception message, null array not recommended
909 * @return the validated map (never {@code null} method for chaining)
910 * @throws NullPointerException if the map is {@code null}
911 * @throws IllegalArgumentException if the map is empty
912 * @see #notEmpty(Object[])
913 */
914 public static <T extends Map<?, ?>> T notEmpty(final T map, final String message, final Object... values) {
915 Objects.requireNonNull(map, toSupplier(message, values));
916 if (map.isEmpty()) {
917 throw new IllegalArgumentException(getMessage(message, values));
918 }
919 return map;
920 }
921
922 /**
923 * Validate that the specified argument character sequence is
924 * neither {@code null} nor a length of zero (no characters);
925 * otherwise throwing an exception with the specified message.
926 *
927 * <pre>Validate.notEmpty(myString, "The string must not be empty");</pre>
928 *
929 * @param <T> the character sequence type
930 * @param chars the character sequence to check, validated not null by this method
931 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
932 * @param values the optional values for the formatted exception message, null array not recommended
933 * @return the validated character sequence (never {@code null} method for chaining)
934 * @throws NullPointerException if the character sequence is {@code null}
935 * @throws IllegalArgumentException if the character sequence is empty
936 * @see #notEmpty(CharSequence)
937 */
938 public static <T extends CharSequence> T notEmpty(final T chars, final String message, final Object... values) {
939 Objects.requireNonNull(chars, toSupplier(message, values));
940 if (chars.length() == 0) {
941 throw new IllegalArgumentException(getMessage(message, values));
942 }
943 return chars;
944 }
945
946 /**
947 * <p>Validates that the specified argument array is neither {@code null}
948 * nor a length of zero (no elements); otherwise throwing an exception.
949 *
950 * <pre>Validate.notEmpty(myArray);</pre>
951 *
952 * <p>The message in the exception is "The validated array is
953 * empty".
954 *
955 * @param <T> the array type
956 * @param array the array to check, validated not null by this method
957 * @return the validated array (never {@code null} method for chaining)
958 * @throws NullPointerException if the array is {@code null}
959 * @throws IllegalArgumentException if the array is empty
960 * @see #notEmpty(Object[], String, Object...)
961 */
962 public static <T> T[] notEmpty(final T[] array) {
963 return notEmpty(array, DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE);
964 }
965
966 /**
967 * <p>Validates that the specified argument array is neither {@code null}
968 * nor a length of zero (no elements); otherwise throwing an exception
969 * with the specified message.
970 *
971 * <pre>Validate.notEmpty(myArray, "The array must not be empty");</pre>
972 *
973 * @param <T> the array type
974 * @param array the array to check, validated not null by this method
975 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
976 * @param values the optional values for the formatted exception message, null array not recommended
977 * @return the validated array (never {@code null} method for chaining)
978 * @throws NullPointerException if the array is {@code null}
979 * @throws IllegalArgumentException if the array is empty
980 * @see #notEmpty(Object[])
981 */
982 public static <T> T[] notEmpty(final T[] array, final String message, final Object... values) {
983 Objects.requireNonNull(array, toSupplier(message, values));
984 if (array.length == 0) {
985 throw new IllegalArgumentException(getMessage(message, values));
986 }
987 return array;
988 }
989
990 /**
991 * Validates that the specified argument is not Not-a-Number (NaN); otherwise
992 * throwing an exception.
993 *
994 * <pre>Validate.notNaN(myDouble);</pre>
995 *
996 * <p>The message of the exception is "The validated value is not a
997 * number".</p>
998 *
999 * @param value the value to validate
1000 * @throws IllegalArgumentException if the value is not a number
1001 * @see #notNaN(double, String, Object...)
1002 * @since 3.5
1003 */
1004 public static void notNaN(final double value) {
1005 notNaN(value, DEFAULT_NOT_NAN_EX_MESSAGE);
1006 }
1007
1008 /**
1009 * Validates that the specified argument is not Not-a-Number (NaN); otherwise
1010 * throwing an exception with the specified message.
1011 *
1012 * <pre>Validate.notNaN(myDouble, "The value must be a number");</pre>
1013 *
1014 * @param value the value to validate
1015 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
1016 * @param values the optional values for the formatted exception message
1017 * @throws IllegalArgumentException if the value is not a number
1018 * @see #notNaN(double)
1019 * @since 3.5
1020 */
1021 public static void notNaN(final double value, final String message, final Object... values) {
1022 if (Double.isNaN(value)) {
1023 throw new IllegalArgumentException(getMessage(message, values));
1024 }
1025 }
1026
1027 /**
1028 * Validate that the specified argument is not {@code null};
1029 * otherwise throwing an exception.
1030 *
1031 * <pre>Validate.notNull(myObject, "The object must not be null");</pre>
1032 *
1033 * <p>The message of the exception is "The validated object is
1034 * null".
1035 *
1036 * @param <T> the object type
1037 * @param object the object to check
1038 * @return the validated object (never {@code null} for method chaining)
1039 * @throws NullPointerException if the object is {@code null}
1040 * @see #notNull(Object, String, Object...)
1041 * @deprecated Use {@link Objects#requireNonNull(Object)}.
1042 */
1043 @Deprecated
1044 public static <T> T notNull(final T object) {
1045 return notNull(object, DEFAULT_IS_NULL_EX_MESSAGE);
1046 }
1047
1048 /**
1049 * Validate that the specified argument is not {@code null};
1050 * otherwise throwing an exception with the specified message.
1051 *
1052 * <pre>Validate.notNull(myObject, "The object must not be null");</pre>
1053 *
1054 * @param <T> the object type
1055 * @param object the object to check
1056 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
1057 * @param values the optional values for the formatted exception message
1058 * @return the validated object (never {@code null} for method chaining)
1059 * @throws NullPointerException if the object is {@code null}
1060 * @see Objects#requireNonNull(Object)
1061 */
1062 public static <T> T notNull(final T object, final String message, final Object... values) {
1063 return Objects.requireNonNull(object, toSupplier(message, values));
1064 }
1065
1066 private static Supplier<String> toSupplier(final String message, final Object... values) {
1067 return () -> getMessage(message, values);
1068 }
1069
1070 /**
1071 * Validates that the index is within the bounds of the argument
1072 * collection; otherwise throwing an exception.
1073 *
1074 * <pre>Validate.validIndex(myCollection, 2);</pre>
1075 *
1076 * <p>If the index is invalid, then the message of the exception
1077 * is "The validated collection index is invalid: "
1078 * followed by the index.</p>
1079 *
1080 * @param <T> the collection type
1081 * @param collection the collection to check, validated not null by this method
1082 * @param index the index to check
1083 * @return the validated collection (never {@code null} for method chaining)
1084 * @throws NullPointerException if the collection is {@code null}
1085 * @throws IndexOutOfBoundsException if the index is invalid
1086 * @see #validIndex(Collection, int, String, Object...)
1087 * @since 3.0
1088 */
1089 public static <T extends Collection<?>> T validIndex(final T collection, final int index) {
1090 return validIndex(collection, index, DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE, Integer.valueOf(index));
1091 }
1092
1093 /**
1094 * Validates that the index is within the bounds of the argument
1095 * character sequence; otherwise throwing an exception.
1096 *
1097 * <pre>Validate.validIndex(myStr, 2);</pre>
1098 *
1099 * <p>If the character sequence is {@code null}, then the message
1100 * of the exception is "The validated object is
1101 * null".</p>
1102 *
1103 * <p>If the index is invalid, then the message of the exception
1104 * is "The validated character sequence index is invalid: "
1105 * followed by the index.</p>
1106 *
1107 * @param <T> the character sequence type
1108 * @param chars the character sequence to check, validated not null by this method
1109 * @param index the index to check
1110 * @return the validated character sequence (never {@code null} for method chaining)
1111 * @throws NullPointerException if the character sequence is {@code null}
1112 * @throws IndexOutOfBoundsException if the index is invalid
1113 * @see #validIndex(CharSequence, int, String, Object...)
1114 * @since 3.0
1115 */
1116 public static <T extends CharSequence> T validIndex(final T chars, final int index) {
1117 return validIndex(chars, index, DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE, Integer.valueOf(index));
1118 }
1119
1120 /**
1121 * Validates that the index is within the bounds of the argument
1122 * collection; otherwise throwing an exception with the specified message.
1123 *
1124 * <pre>Validate.validIndex(myCollection, 2, "The collection index is invalid: ");</pre>
1125 *
1126 * <p>If the collection is {@code null}, then the message of the
1127 * exception is "The validated object is null".</p>
1128 *
1129 * @param <T> the collection type
1130 * @param collection the collection to check, validated not null by this method
1131 * @param index the index to check
1132 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
1133 * @param values the optional values for the formatted exception message, null array not recommended
1134 * @return the validated collection (never {@code null} for chaining)
1135 * @throws NullPointerException if the collection is {@code null}
1136 * @throws IndexOutOfBoundsException if the index is invalid
1137 * @see #validIndex(Collection, int)
1138 * @since 3.0
1139 */
1140 public static <T extends Collection<?>> T validIndex(final T collection, final int index, final String message, final Object... values) {
1141 Objects.requireNonNull(collection, "collection");
1142 if (index < 0 || index >= collection.size()) {
1143 throw new IndexOutOfBoundsException(getMessage(message, values));
1144 }
1145 return collection;
1146 }
1147
1148 /**
1149 * Validates that the index is within the bounds of the argument
1150 * character sequence; otherwise throwing an exception with the
1151 * specified message.
1152 *
1153 * <pre>Validate.validIndex(myStr, 2, "The string index is invalid: ");</pre>
1154 *
1155 * <p>If the character sequence is {@code null}, then the message
1156 * of the exception is "The validated object is null".</p>
1157 *
1158 * @param <T> the character sequence type
1159 * @param chars the character sequence to check, validated not null by this method
1160 * @param index the index to check
1161 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
1162 * @param values the optional values for the formatted exception message, null array not recommended
1163 * @return the validated character sequence (never {@code null} for method chaining)
1164 * @throws NullPointerException if the character sequence is {@code null}
1165 * @throws IndexOutOfBoundsException if the index is invalid
1166 * @see #validIndex(CharSequence, int)
1167 * @since 3.0
1168 */
1169 public static <T extends CharSequence> T validIndex(final T chars, final int index, final String message, final Object... values) {
1170 Objects.requireNonNull(chars, "chars");
1171 if (index < 0 || index >= chars.length()) {
1172 throw new IndexOutOfBoundsException(getMessage(message, values));
1173 }
1174 return chars;
1175 }
1176
1177 /**
1178 * Validates that the index is within the bounds of the argument
1179 * array; otherwise throwing an exception.
1180 *
1181 * <pre>Validate.validIndex(myArray, 2);</pre>
1182 *
1183 * <p>If the array is {@code null}, then the message of the exception
1184 * is "The validated object is null".</p>
1185 *
1186 * <p>If the index is invalid, then the message of the exception is
1187 * "The validated array index is invalid: " followed by the
1188 * index.</p>
1189 *
1190 * @param <T> the array type
1191 * @param array the array to check, validated not null by this method
1192 * @param index the index to check
1193 * @return the validated array (never {@code null} for method chaining)
1194 * @throws NullPointerException if the array is {@code null}
1195 * @throws IndexOutOfBoundsException if the index is invalid
1196 * @see #validIndex(Object[], int, String, Object...)
1197 * @since 3.0
1198 */
1199 public static <T> T[] validIndex(final T[] array, final int index) {
1200 return validIndex(array, index, DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE, Integer.valueOf(index));
1201 }
1202
1203 /**
1204 * Validates that the index is within the bounds of the argument
1205 * array; otherwise throwing an exception with the specified message.
1206 *
1207 * <pre>Validate.validIndex(myArray, 2, "The array index is invalid: ");</pre>
1208 *
1209 * <p>If the array is {@code null}, then the message of the exception
1210 * is "The validated object is null".</p>
1211 *
1212 * @param <T> the array type
1213 * @param array the array to check, validated not null by this method
1214 * @param index the index to check
1215 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
1216 * @param values the optional values for the formatted exception message, null array not recommended
1217 * @return the validated array (never {@code null} for method chaining)
1218 * @throws NullPointerException if the array is {@code null}
1219 * @throws IndexOutOfBoundsException if the index is invalid
1220 * @see #validIndex(Object[], int)
1221 * @since 3.0
1222 */
1223 public static <T> T[] validIndex(final T[] array, final int index, final String message, final Object... values) {
1224 Objects.requireNonNull(array, "array");
1225 if (index < 0 || index >= array.length) {
1226 throw new IndexOutOfBoundsException(getMessage(message, values));
1227 }
1228 return array;
1229 }
1230
1231 /**
1232 * Validate that the stateful condition is {@code true}; otherwise
1233 * throwing an exception. This method is useful when validating according
1234 * to an arbitrary boolean expression, such as validating a
1235 * primitive number or using your own custom validation expression.
1236 *
1237 * <pre>
1238 * Validate.validState(field > 0);
1239 * Validate.validState(this.isOk());</pre>
1240 *
1241 * <p>The message of the exception is "The validated state is
1242 * false".</p>
1243 *
1244 * @param expression the boolean expression to check
1245 * @throws IllegalStateException if expression is {@code false}
1246 * @see #validState(boolean, String, Object...)
1247 * @since 3.0
1248 */
1249 public static void validState(final boolean expression) {
1250 if (!expression) {
1251 throw new IllegalStateException(DEFAULT_VALID_STATE_EX_MESSAGE);
1252 }
1253 }
1254
1255 /**
1256 * Validate that the stateful condition is {@code true}; otherwise
1257 * throwing an exception with the specified message. This method is useful when
1258 * validating according to an arbitrary boolean expression, such as validating a
1259 * primitive number or using your own custom validation expression.
1260 *
1261 * <pre>Validate.validState(this.isOk(), "The state is not OK: %s", myObject);</pre>
1262 *
1263 * @param expression the boolean expression to check
1264 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
1265 * @param values the optional values for the formatted exception message, null array not recommended
1266 * @throws IllegalStateException if expression is {@code false}
1267 * @see #validState(boolean)
1268 * @since 3.0
1269 */
1270 public static void validState(final boolean expression, final String message, final Object... values) {
1271 if (!expression) {
1272 throw new IllegalStateException(getMessage(message, values));
1273 }
1274 }
1275
1276 /**
1277 * Constructs a new instance. This class should not normally be instantiated.
1278 */
1279 public Validate() {
1280 }
1281 }