001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3;
018
019import java.util.Collection;
020import java.util.Map;
021import java.util.Objects;
022import java.util.concurrent.atomic.AtomicInteger;
023import java.util.function.Supplier;
024import java.util.regex.Pattern;
025
026/**
027 * This class assists in validating arguments. The validation methods are
028 * based along the following principles:
029 * <ul>
030 *   <li>An invalid {@code null} argument causes a {@link NullPointerException}.</li>
031 *   <li>A non-{@code null} argument causes an {@link IllegalArgumentException}.</li>
032 *   <li>An invalid index into an array/collection/map/string causes an {@link IndexOutOfBoundsException}.</li>
033 * </ul>
034 *
035 * <p>
036 * All exceptions messages are
037 * <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax">format strings</a>
038 * as defined by the Java platform. For example:
039 *
040 * <pre>
041 * Validate.isTrue(i &gt; 0, "The value must be greater than zero: %d", i);
042 * Validate.notNull(surname, "The surname must not be %s", null);
043 * </pre>
044 *
045 * <p>
046 * #ThreadSafe#
047 * </p>
048 *
049 * @see String#format(String, Object...)
050 * @since 2.0
051 */
052public class Validate {
053
054    private static final String DEFAULT_NOT_NAN_EX_MESSAGE =
055        "The validated value is not a number";
056    private static final String DEFAULT_FINITE_EX_MESSAGE =
057        "The value is invalid: %f";
058    private static final String DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE =
059        "The value %s is not in the specified exclusive range of %s to %s";
060    private static final String DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE =
061        "The value %s is not in the specified inclusive range of %s to %s";
062    private static final String DEFAULT_MATCHES_PATTERN_EX = "The string %s does not match the pattern %s";
063    private static final String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null";
064    private static final String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false";
065    private static final String DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE =
066        "The validated array contains null element at index: %d";
067    private static final String DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE =
068        "The validated collection contains null element at index: %d";
069    private static final String DEFAULT_NOT_BLANK_EX_MESSAGE = "The validated character sequence is blank";
070    private static final String DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE = "The validated array is empty";
071    private static final String DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE =
072        "The validated character sequence is empty";
073    private static final String DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE = "The validated collection is empty";
074    private static final String DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE = "The validated map is empty";
075    private static final String DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE = "The validated array index is invalid: %d";
076    private static final String DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE =
077        "The validated character sequence index is invalid: %d";
078    private static final String DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE =
079        "The validated collection index is invalid: %d";
080    private static final String DEFAULT_VALID_STATE_EX_MESSAGE = "The validated state is false";
081    private static final String DEFAULT_IS_ASSIGNABLE_EX_MESSAGE = "Cannot assign a %s to a %s";
082    private static final String DEFAULT_IS_INSTANCE_OF_EX_MESSAGE = "Expected type: %s, actual: %s";
083
084    /**
085     * Validate that the specified primitive value falls between the two
086     * exclusive values specified; otherwise, throws an exception.
087     *
088     * <pre>Validate.exclusiveBetween(0.1, 2.1, 1.1);</pre>
089     *
090     * @param start The exclusive start value.
091     * @param end   The exclusive end value.
092     * @param value The value to validate.
093     * @throws IllegalArgumentException Thrown if the value falls out of the boundaries.
094     * @since 3.3
095     */
096    @SuppressWarnings("boxing")
097    public static void exclusiveBetween(final double start, final double end, final double value) {
098        // TODO when breaking BC, consider returning value
099        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}