/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.collect; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import com.google.common.base.CharMatcher; import com.google.common.math.DoubleMath; /** * Contains utility methods for checking inputs to methods. * <p> * This utility is used throughout the system to validate inputs to methods. * Most of the methods return their validated input, allowing patterns like this: * <pre> * // constructor * public Person(String name, int age) { * this.name = ArgChecker.notBlank(name, "name"); * this.age = ArgChecker.notNegative(age, "age"); * } * </pre> */ public final class ArgChecker { /** * Restricted constructor. */ private ArgChecker() { } //------------------------------------------------------------------------- /** * Checks that the specified boolean is true. * <p> * Given the input argument, this returns normally only if it is true. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isTrue(collection.contains("value")); * </pre> * <p> * It is strongly recommended to pass an additional message argument using * {@link #isTrue(boolean, String)}. * * @param validIfTrue a boolean resulting from testing an argument * @throws IllegalArgumentException if the test value is false */ public static void isTrue(boolean validIfTrue) { // return void, not the argument, as no need to check a boolean method argument if (!validIfTrue) { throw new IllegalArgumentException("Invalid argument, expression must be true"); } } /** * Checks that the specified boolean is true. * <p> * Given the input argument, this returns normally only if it is true. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isTrue(collection.contains("value"), "Collection must contain 'value'"); * </pre> * * @param validIfTrue a boolean resulting from testing an argument * @param message the error message, not null * @throws IllegalArgumentException if the test value is false */ public static void isTrue(boolean validIfTrue, String message) { // return void, not the argument, as no need to check a boolean method argument if (!validIfTrue) { throw new IllegalArgumentException(message); } } /** * Checks that the specified boolean is true. * <p> * Given the input argument, this returns normally only if it is true. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isTrue(collection.contains("value"), "Collection must contain 'value': {}", collection); * </pre> * <p> * This returns {@code void}, and not the value being checked, as there is * never a good reason to validate a boolean argument value. * <p> * The message is produced using a template that contains zero to many "{}" placeholders. * Each placeholder is replaced by the next available argument. * If there are too few arguments, then the message will be left with placeholders. * If there are too many arguments, then the excess arguments are appended to the * end of the message. No attempt is made to format the arguments. * See {@link Messages#format(String, Object...)} for more details. * * @param validIfTrue a boolean resulting from testing an argument * @param message the error message with {} placeholders, not null * @param arg the message arguments * @throws IllegalArgumentException if the test value is false */ public static void isTrue(boolean validIfTrue, String message, Object... arg) { // return void, not the argument, as no need to check a boolean method argument if (!validIfTrue) { throw new IllegalArgumentException(Messages.format(message, arg)); } } /** * Checks that the specified boolean is true. * <p> * Given the input argument, this returns normally only if it is true. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isTrue(value > check, "Value must be greater than check: {}", value); * </pre> * <p> * This returns {@code void}, and not the value being checked, as there is * never a good reason to validate a boolean argument value. * <p> * The message is produced using a template that contains zero or one "{}" placeholders. * The placeholder, if present, is replaced by the argument. * If there is no placeholder, the argument is appended to the end of the message. * * @param validIfTrue a boolean resulting from testing an argument * @param message the error message with {} placeholders, not null * @param arg the message argument * @throws IllegalArgumentException if the test value is false */ public static void isTrue(boolean validIfTrue, String message, long arg) { // return void, not the argument, as no need to check a boolean method argument if (!validIfTrue) { throw new IllegalArgumentException(Messages.format(message, arg)); } } /** * Checks that the specified boolean is true. * <p> * Given the input argument, this returns normally only if it is true. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isTrue(value > check, "Value must be greater than check: {}", value); * </pre> * <p> * This returns {@code void}, and not the value being checked, as there is * never a good reason to validate a boolean argument value. * <p> * The message is produced using a template that contains zero or one "{}" placeholders. * The placeholder, if present, is replaced by the argument. * If there is no placeholder, the argument is appended to the end of the message. * * @param validIfTrue a boolean resulting from testing an argument * @param message the error message with {} placeholders, not null * @param arg the message argument * @throws IllegalArgumentException if the test value is false */ public static void isTrue(boolean validIfTrue, String message, double arg) { // return void, not the argument, as no need to check a boolean method argument if (!validIfTrue) { throw new IllegalArgumentException(Messages.format(message, arg)); } } /** * Checks that the specified boolean is false. * <p> * Given the input argument, this returns normally only if it is false. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isFalse(collection.contains("value"), "Collection must not contain 'value'"); * </pre> * <p> * This returns {@code void}, and not the value being checked, as there is * never a good reason to validate a boolean argument value. * * @param validIfFalse a boolean resulting from testing an argument * @param message the error message, not null * @throws IllegalArgumentException if the test value is true */ public static void isFalse(boolean validIfFalse, String message) { // return void, not the argument, as no need to check a boolean method argument if (validIfFalse) { throw new IllegalArgumentException(message); } } /** * Checks that the specified boolean is false. * <p> * Given the input argument, this returns normally only if it is false. * This will typically be the result of a caller-specific check. * For example: * <pre> * ArgChecker.isFalse(collection.contains("value"), "Collection must not contain 'value': {}", collection); * </pre> * <p> * This returns {@code void}, and not the value being checked, as there is * never a good reason to validate a boolean argument value. * <p> * The message is produced using a template that contains zero to many "{}" placeholders. * Each placeholder is replaced by the next available argument. * If there are too few arguments, then the message will be left with placeholders. * If there are too many arguments, then the excess arguments are appended to the * end of the message. No attempt is made to format the arguments. * See {@link Messages#format(String, Object...)} for more details. * * @param validIfFalse a boolean resulting from testing an argument * @param message the error message with {} placeholders, not null * @param arg the message arguments, not null * @throws IllegalArgumentException if the test value is true */ public static void isFalse(boolean validIfFalse, String message, Object... arg) { // return void, not the argument, as no need to check a boolean method argument if (validIfFalse) { throw new IllegalArgumentException(Messages.format(message, arg)); } } //------------------------------------------------------------------------- /** * Checks that the specified argument is non-null. * <p> * Given the input argument, this returns only if it is non-null. * For example, in a constructor: * <pre> * this.name = ArgChecker.notNull(name, "name"); * </pre> * * @param <T> the type of the input argument reflected in the result * @param argument the argument to check, null throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null */ public static <T> T notNull(T argument, String name) { if (argument == null) { throw new IllegalArgumentException(notNullMsg(name)); } return argument; } // extracted to aid inlining performance private static String notNullMsg(String name) { return "Argument '" + name + "' must not be null"; } /** * Checks that the specified item is non-null. * <p> * Given the input argument, this returns only if it is non-null. * One use for this method is in a stream: * <pre> * ArgChecker.notNull(coll, "coll") * coll.stream() * .map(ArgChecker::notNullItem) * ... * </pre> * * @param <T> the type of the input argument reflected in the result * @param argument the argument to check, null throws an exception * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null */ public static <T> T notNullItem(T argument) { if (argument == null) { throw new IllegalArgumentException("Argument array/collection/map must not contain null"); } return argument; } //------------------------------------------------------------------------- /** * Checks that the specified argument is non-null and matches the specified pattern. * <p> * Given the input argument, this returns only if it is non-null and matches * the regular expression pattern specified. * For example, in a constructor: * <pre> * this.name = ArgChecker.matches(REGEX_NAME, name, "name"); * </pre> * * @param pattern the pattern to check against, not null * @param argument the argument to check, null throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static String matches(Pattern pattern, String argument, String name) { notNull(pattern, "pattern"); notNull(argument, name); if (!pattern.matcher(argument).matches()) { throw new IllegalArgumentException(matchesMsg(pattern, name, argument)); } return argument; } // extracted to aid inlining performance private static String matchesMsg(Pattern pattern, String name, String value) { return "Argument '" + name + "' with value '" + value + "' must match pattern: " + pattern; } //------------------------------------------------------------------------- /** * Checks that the specified argument is non-null and only contains the specified characters. * <p> * Given the input argument, this returns only if it is non-null and matches * the {@link CharMatcher} specified. * For example, in a constructor: * <pre> * this.name = ArgChecker.matches(REGEX_NAME, 1, Integer.MAX_VALUE, name, "name", "[A-Z]+"); * </pre> * * @param matcher the matcher to check against, not null * @param minLength the minimum length to allow * @param maxLength the minimum length to allow * @param argument the argument to check, null throws an exception * @param name the name of the argument to use in the error message, not null * @param equivalentRegex the equivalent regular expression pattern * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static String matches( CharMatcher matcher, int minLength, int maxLength, String argument, String name, String equivalentRegex) { notNull(matcher, "pattern"); notNull(argument, name); if (argument.length() < minLength || argument.length() > maxLength || !matcher.matchesAllOf(argument)) { throw new IllegalArgumentException(matchesMsg(matcher, name, argument, equivalentRegex)); } return argument; } // extracted to aid inlining performance private static String matchesMsg(CharMatcher matcher, String name, String value, String equivalentRegex) { return "Argument '" + name + "' with value '" + value + "' must match pattern: " + equivalentRegex; } //------------------------------------------------------------------------- /** * Checks that the specified argument is non-null and not blank. * <p> * Given the input argument, this returns the input only if it is non-null * and contains at least one non whitespace character. * This is often linked with a call to {@code trim()}. * For example, in a constructor: * <pre> * this.name = ArgChecker.notBlank(name, "name").trim(); * </pre> * <p> * The argument is trimmed using {@link String#trim()} to determine if it is empty. * The result is the original argument, not the trimmed one. * * @param argument the argument to check, null or blank throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or blank */ public static String notBlank(String argument, String name) { notNull(argument, name); if (argument.trim().isEmpty()) { throw new IllegalArgumentException(notBlankMsg(name)); } return argument; } // extracted to aid inlining performance private static String notBlankMsg(String name) { return "Argument '" + name + "' must not be blank"; } //------------------------------------------------------------------------- /** * Checks that the specified argument is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains * at least one character, which may be a whitespace character. * See also {@link #notBlank(String, String)}. * For example, in a constructor: * <pre> * this.name = ArgChecker.notEmpty(name, "name"); * </pre> * * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static String notEmpty(String argument, String name) { notNull(argument, name); if (argument.isEmpty()) { throw new IllegalArgumentException(notEmptyMsg(name)); } return argument; } // extracted to aid inlining performance private static String notEmptyMsg(String name) { return "Argument '" + name + "' must not be empty"; } /** * Checks that the specified argument array is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains * at least one element. The element is not validated and may be null. * For example, in a constructor: * <pre> * this.names = ArgChecker.notEmpty(names, "names"); * </pre> * * @param <T> the type of the input array reflected in the result * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static <T> T[] notEmpty(T[] argument, String name) { notNull(argument, name); if (argument.length == 0) { throw new IllegalArgumentException(notEmptyArrayMsg(name)); } return argument; } // extracted to aid inlining performance private static String notEmptyArrayMsg(String name) { return "Argument array '" + name + "' must not be empty"; } /** * Checks that the specified argument array is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains * at least one element. * For example, in a constructor: * <pre> * this.values = ArgChecker.notEmpty(values, "values"); * </pre> * * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static int[] notEmpty(int[] argument, String name) { notNull(argument, name); if (argument.length == 0) { throw new IllegalArgumentException(notEmptyArrayMsg(name)); } return argument; } /** * Checks that the specified argument array is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains * at least one element. * For example, in a constructor: * <pre> * this.values = ArgChecker.notEmpty(values, "values"); * </pre> * * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static long[] notEmpty(long[] argument, String name) { notNull(argument, name); if (argument.length == 0) { throw new IllegalArgumentException(notEmptyArrayMsg(name)); } return argument; } /** * Checks that the specified argument array is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains * at least one element. * For example, in a constructor: * <pre> * this.values = ArgChecker.notEmpty(values, "values"); * </pre> * * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static double[] notEmpty(double[] argument, String name) { notNull(argument, name); if (argument.length == 0) { throw new IllegalArgumentException(notEmptyArrayMsg(name)); } return argument; } /** * Checks that the specified argument iterable is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains * at least one element. The element is not validated and may be null. * For example, in a constructor: * <pre> * this.values = ArgChecker.notEmpty(values, "values"); * </pre> * * @param <T> the element type of the input iterable reflected in the result * @param <I> the type of the input iterable, reflected in the result * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static <T, I extends Iterable<T>> I notEmpty(I argument, String name) { notNull(argument, name); if (!argument.iterator().hasNext()) { throw new IllegalArgumentException(notEmptyIterableMsg(name)); } return argument; } // extracted to aid inlining performance private static String notEmptyIterableMsg(String name) { return "Argument iterable '" + name + "' must not be empty"; } /** * Checks that the specified argument collection is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains at least one element. * The element is not validated and may contain nulls if the collection allows nulls. * For example, in a constructor: * <pre> * this.values = ArgChecker.notEmpty(values, "values"); * </pre> * * @param <T> the element type of the input collection reflected in the result * @param <C> the type of the input collection, reflected in the result * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static <T, C extends Collection<T>> C notEmpty(C argument, String name) { notNull(argument, name); if (argument.isEmpty()) { throw new IllegalArgumentException(notEmptyCollectionMsg(name)); } return argument; } // extracted to aid inlining performance private static String notEmptyCollectionMsg(String name) { return "Argument collection '" + name + "' must not be empty"; } /** * Checks that the specified argument map is non-null and not empty. * <p> * Given the input argument, this returns only if it is non-null and contains at least one mapping. * The element is not validated and may contain nulls if the collection allows nulls. * For example, in a constructor: * <pre> * this.keyValues = ArgChecker.notEmpty(keyValues, "keyValues"); * </pre> * * @param <K> the key type of the input map key, reflected in the result * @param <V> the value type of the input map value, reflected in the result * @param <M> the type of the input map, reflected in the result * @param argument the argument to check, null or empty throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or empty */ public static <K, V, M extends Map<K, V>> M notEmpty(M argument, String name) { notNull(argument, name); if (argument.isEmpty()) { throw new IllegalArgumentException(notEmptyMapMsg(name)); } return argument; } // extracted to aid inlining performance private static String notEmptyMapMsg(String name) { return "Argument map '" + name + "' must not be empty"; } //------------------------------------------------------------------------- /** * Checks that the specified argument array is non-null and contains no nulls. * <p> * Given the input argument, this returns only if it is non-null and contains no nulls. * For example, in a constructor: * <pre> * this.values = ArgChecker.noNulls(values, "values"); * </pre> * * @param <T> the type of the input array reflected in the result * @param argument the argument to check, null or contains null throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or contains nulls */ public static <T> T[] noNulls(T[] argument, String name) { notNull(argument, name); for (int i = 0; i < argument.length; i++) { if (argument[i] == null) { throw new IllegalArgumentException("Argument array '" + name + "' must not contain null at index " + i); } } return argument; } /** * Checks that the specified argument collection is non-null and contains no nulls. * <p> * Given the input argument, this returns only if it is non-null and contains no nulls. * For example, in a constructor: * <pre> * this.values = ArgChecker.noNulls(values, "values"); * </pre> * * @param <T> the element type of the input iterable reflected in the result * @param <I> the type of the input iterable, reflected in the result * @param argument the argument to check, null or contains null throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or contains nulls */ public static <T, I extends Iterable<T>> I noNulls(I argument, String name) { notNull(argument, name); for (Object obj : argument) { if (obj == null) { throw new IllegalArgumentException("Argument iterable '" + name + "' must not contain null"); } } return argument; } /** * Checks that the specified argument map is non-null and contains no nulls. * <p> * Given the input argument, this returns only if it is non-null and contains no nulls. * For example, in a constructor: * <pre> * this.keyValues = ArgChecker.noNulls(keyValues, "keyValues"); * </pre> * * @param <K> the key type of the input map key, reflected in the result * @param <V> the value type of the input map value, reflected in the result * @param <M> the type of the input map, reflected in the result * @param argument the argument to check, null or contains null throws an exception * @param name the name of the argument to use in the error message, not null * @return the input {@code argument}, not null * @throws IllegalArgumentException if the input is null or contains nulls */ public static <K, V, M extends Map<K, V>> M noNulls(M argument, String name) { notNull(argument, name); for (Entry<K, V> entry : argument.entrySet()) { if (entry.getKey() == null) { throw new IllegalArgumentException("Argument map '" + name + "' must not contain a null key"); } if (entry.getValue() == null) { throw new IllegalArgumentException("Argument map '" + name + "' must not contain a null value"); } } return argument; } //------------------------------------------------------------------------- /** * Checks that the argument is not negative. * <p> * Given the input argument, this returns only if it is zero or greater. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegative(amount, "amount"); * </pre> * * @param argument the argument to check * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the input is negative */ public static int notNegative(int argument, String name) { if (argument < 0) { throw new IllegalArgumentException(notNegativeMsg(name)); } return argument; } // extracted to aid inlining performance private static String notNegativeMsg(String name) { return "Argument '" + name + "' must not be negative"; } /** * Checks that the argument is not negative. * <p> * Given the input argument, this returns only if it is zero or greater. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegative(amount, "amount"); * </pre> * * @param argument the argument to check * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the input is negative */ public static long notNegative(long argument, String name) { if (argument < 0) { throw new IllegalArgumentException(notNegativeMsg(name)); } return argument; } /** * Checks that the argument is not negative. * <p> * Given the input argument, this returns only if it is zero or greater. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegative(amount, "amount"); * </pre> * * @param argument the argument to check * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the input is negative */ public static double notNegative(double argument, String name) { if (argument < 0) { throw new IllegalArgumentException(notNegativeMsg(name)); } return argument; } //------------------------------------------------------------------------- /** * Checks that the argument is not negative or zero. * <p> * Given the input argument, this returns only if it is greater than zero. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegativeOrZero(amount, "amount"); * </pre> * * @param argument the argument to check * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the input is negative or zero */ public static int notNegativeOrZero(int argument, String name) { if (argument <= 0) { throw new IllegalArgumentException(notNegativeOrZeroMsg(name, argument)); } return argument; } // extracted to aid inlining performance private static String notNegativeOrZeroMsg(String name, double argument) { return "Argument '" + name + "' must not be negative or zero but has value " + argument; } /** * Checks that the argument is not negative or zero. * <p> * Given the input argument, this returns only if it is greater than zero. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegativeOrZero(amount, "amount"); * </pre> * * @param argument the argument to check * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the input is negative or zero */ public static long notNegativeOrZero(long argument, String name) { if (argument <= 0) { throw new IllegalArgumentException(notNegativeOrZeroMsg(name, argument)); } return argument; } /** * Checks that the argument is not negative or zero. * <p> * Given the input argument, this returns only if it is greater than zero. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegativeOrZero(amount, "amount"); * </pre> * * @param argument the argument to check * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the input is negative or zero */ public static double notNegativeOrZero(double argument, String name) { if (argument <= 0) { throw new IllegalArgumentException(notNegativeOrZeroMsg(name, argument)); } return argument; } /** * Checks that the argument is greater than zero to within a given accuracy. * <p> * Given the input argument, this returns only if it is greater than zero * using the {@code eps} accuracy for zero. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notNegativeOrZero(amount, 0.0001d, "amount"); * </pre> * * @param argument the value to check * @param tolerance the tolerance to use for zero * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the absolute value of the argument is less than eps */ public static double notNegativeOrZero(double argument, double tolerance, String name) { if (DoubleMath.fuzzyEquals(argument, 0, tolerance)) { throw new IllegalArgumentException("Argument '" + name + "' must not be zero"); } if (argument < 0) { throw new IllegalArgumentException("Argument '" + name + "' must be greater than zero but has value " + argument); } return argument; } //------------------------------------------------------------------------- /** * Checks that the argument is not equal to zero to within a given accuracy. * <p> * Given the input argument, this returns only if it is not zero comparing * using the {@code eps} accuracy. * For example, in a constructor: * <pre> * this.amount = ArgChecker.notZero(amount, 0.0001d, "amount"); * </pre> * * @param argument the value to check * @param tolerance the tolerance to use for zero * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the absolute value of the argument is less than the tolerance */ public static double notZero(double argument, double tolerance, String name) { if (DoubleMath.fuzzyEquals(argument, 0d, tolerance)) { throw new IllegalArgumentException("Argument '" + name + "' must not be zero"); } return argument; } //------------------------------------------------------------------------- /** * Checks that the argument is within the range defined by {@code low <= x < high}. * <p> * Given a value, this returns true if it is within the specified range including the * lower boundary but excluding the upper boundary. * For example, in a constructor: * <pre> * this.amount = ArgChecker.inRange(amount, 0d, 1d, "amount"); * </pre> * * @param argument the value to check * @param lowInclusive the low value of the range * @param highExclusive the high value of the range * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the argument is outside the valid range */ public static double inRange(double argument, double lowInclusive, double highExclusive, String name) { if (argument < lowInclusive || argument >= highExclusive) { throw new IllegalArgumentException( Messages.format("Expected {} <= '{}' < {}, but found {}", lowInclusive, name, highExclusive, argument)); } return argument; } /** * Checks that the argument is within the range defined by {@code low <= x <= high}. * <p> * Given a value, this returns true if it is within the specified range including both boundaries. * For example, in a constructor: * <pre> * this.amount = ArgChecker.inRangeInclusive(amount, 0d, 1d, "amount"); * </pre> * * @param argument the value to check * @param lowInclusive the low value of the range * @param highInclusive the high value of the range * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the argument is outside the valid range */ public static double inRangeInclusive(double argument, double lowInclusive, double highInclusive, String name) { if (argument < lowInclusive || argument > highInclusive) { throw new IllegalArgumentException( Messages.format("Expected {} <= '{}' <= {}, but found {}", lowInclusive, name, highInclusive, argument)); } return argument; } /** * Checks that the argument is within the range defined by {@code low < x < high}. * <p> * Given a value, this returns true if it is within the specified range excluding both boundaries. * For example, in a constructor: * <pre> * this.amount = ArgChecker.inRangeExclusive(amount, 0d, 1d, "amount"); * </pre> * * @param argument the value to check * @param lowExclusive the low value of the range * @param highExclusive the high value of the range * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the argument is outside the valid range */ public static double inRangeExclusive(double argument, double lowExclusive, double highExclusive, String name) { if (argument <= lowExclusive || argument >= highExclusive) { throw new IllegalArgumentException( Messages.format("Expected {} < '{}' < {}, but found {}", lowExclusive, name, highExclusive, argument)); } return argument; } //------------------------------------------------------------------------- /** * Checks that the argument is within the range defined by {@code low <= x < high}. * <p> * Given a value, this returns true if it is within the specified range including the * lower boundary but excluding the upper boundary. * For example, in a constructor: * <pre> * this.amount = ArgChecker.inRange(amount, 0d, 1d, "amount"); * </pre> * * @param argument the value to check * @param lowInclusive the low value of the range * @param highExclusive the high value of the range * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the argument is outside the valid range */ public static int inRange(int argument, int lowInclusive, int highExclusive, String name) { if (argument < lowInclusive || argument >= highExclusive) { throw new IllegalArgumentException( Messages.format("Expected {} <= '{}' < {}, but found {}", lowInclusive, name, highExclusive, argument)); } return argument; } /** * Checks that the argument is within the range defined by {@code low <= x <= high}. * <p> * Given a value, this returns true if it is within the specified range including both boundaries. * For example, in a constructor: * <pre> * this.amount = ArgChecker.inRangeInclusive(amount, 0d, 1d, "amount"); * </pre> * * @param argument the value to check * @param lowInclusive the low value of the range * @param highInclusive the high value of the range * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the argument is outside the valid range */ public static int inRangeInclusive(int argument, int lowInclusive, int highInclusive, String name) { if (argument < lowInclusive || argument > highInclusive) { throw new IllegalArgumentException( Messages.format("Expected {} <= '{}' <= {}, but found {}", lowInclusive, name, highInclusive, argument)); } return argument; } /** * Checks that the argument is within the range defined by {@code low < x < high}. * <p> * Given a value, this returns true if it is within the specified range excluding both boundaries. * For example, in a constructor: * <pre> * this.amount = ArgChecker.inRangeExclusive(amount, 0d, 1d, "amount"); * </pre> * * @param argument the value to check * @param lowExclusive the low value of the range * @param highExclusive the high value of the range * @param name the name of the argument to use in the error message, not null * @return the input {@code argument} * @throws IllegalArgumentException if the argument is outside the valid range */ public static int inRangeExclusive(int argument, int lowExclusive, int highExclusive, String name) { if (argument <= lowExclusive || argument >= highExclusive) { throw new IllegalArgumentException( Messages.format("Expected {} < '{}' < {}, but found {}", lowExclusive, name, highExclusive, argument)); } return argument; } //------------------------------------------------------------------------- /** * Checks that the two values are in order and not equal. * <p> * Given two comparable instances, this checks that the first is "less than" the second. * Two equal values also throw the exception. * * @param <T> the type * @param obj1 the first object, null throws an exception * @param obj2 the second object, null throws an exception * @param name1 the first argument name, not null * @param name2 the second argument name, not null * @throws IllegalArgumentException if either input is null or they are not in order */ public static <T> void inOrderNotEqual(Comparable<? super T> obj1, T obj2, String name1, String name2) { notNull(obj1, name1); notNull(obj2, name2); if (obj1.compareTo(obj2) >= 0) { throw new IllegalArgumentException( Messages.format("Invalid order: Expected '{}' < '{}', but found: '{}' >= '{}", name1, name2, obj1, obj2)); } } /** * Checks that the two values are in order or equal. * <p> * Given two comparable instances, this checks that the first is "less than" or "equal to" the second. * * @param <T> the type * @param obj1 the first object, null throws an exception * @param obj2 the second object, null throws an exception * @param name1 the first argument name, not null * @param name2 the second argument name, not null * @throws IllegalArgumentException if either input is null or they are not in order */ public static <T> void inOrderOrEqual(Comparable<? super T> obj1, T obj2, String name1, String name2) { notNull(obj1, name1); notNull(obj2, name2); if (obj1.compareTo(obj2) > 0) { throw new IllegalArgumentException( Messages.format("Invalid order: Expected '{}' <= '{}', but found: '{}' > '{}", name1, name2, obj1, obj2)); } } }