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