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