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