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