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