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