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