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