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