/** * A convenient variant of {@link #mustExist(Object, Supplier)} that throws a * {@link NullArgumentException} with the supplied {@code message}. * * @param <T> Value type. * @param value The value to check. * @param message The message to the {@link NullArgumentException}. * @return The verified value. * @throws NullArgumentException If the given value is {@code null}. */ public static <T> T mustExist(T value, String message) throws NullArgumentException { return mustExist(value, withMessage(message, NullArgumentException::new)); }
private static void ensureNotEmpty(Collection<?> array) { mustBeTrue(! array.isEmpty(), withMessage("No elements to search", IllegalArgumentException::new)); }
TaskScheduler getBackgroundScheduler() { return mustExist(backgroundScheduler, withMessage("Background scheduler is not in use", IllegalStateException::new)); }
private void checkAllowNonLinearTasks() { mustBeTrue(allowNonLinearTasks, withMessage("Non-linear tasks are not allowed", RejectedExecutionException::new)); }
TaskScheduler getTimeoutScheduler() { return mustExist(timeoutScheduler, withMessage("Timeout scheduler is not in use", IllegalStateException::new)); }
/** * Ensures that the given {@code map} contains the specified {@code key} and returns the * mapped value. Otherwise, an exception specified by the given {@code exceptionMaker} is * thrown. * * @param <K> Key type. * @param <V> Value type. * @param <X> Exception type. * @param map The map to query. * @param key The key that must be present. * @param errorTemplate The template for forming the error, where the single format specifier * '%s' is substituted for the missing key. * @param exceptionMaker A way of creating the exception for a missing value. * @return The value. * @throws X If the mapping wasn't present. */ public static <K, V, X extends Throwable> V mustExist(Map<K, V> map, K key, String errorTemplate, Function<String, ? extends X> exceptionMaker) throws X { return mustExist(map.get(key), withMessage(() -> String.format(errorTemplate, key), exceptionMaker)); }
/** * Attempts the transition {@code from} -> {@code to}, returning the {@code to} state * if allowed. * * @param from The <i>from</i> state. * @param to The <i>to</i> state. * @return The <i>to</i> state. * @throws IllegalTransitionException If the transition is not permitted. */ public S guard(S from, S to) throws IllegalTransitionException { mustBeTrue(isAllowed(from, to), withMessage("Cannot transition " + from + " -> " + to, IllegalTransitionException::new)); return to; }
/** * Locates an enum among the given array of enums, where it is assumed that the enum must be * present. Returns the index of the enum, or throws an {@link IllegalArgumentException} if it * couldn't be found. * * @param <E> Enum type. * @param en The enum to find. * @param enums The enums to search in. * @return The index. * @throws IllegalArgumentException If the enum could not be found. */ public static <E extends Enum<E>> int indexOfMandatory(E en, E[] enums) { final int index = indexOf(en, enums); mustBeTrue(index != -1, withMessage(() -> en + " is not among " + Arrays.toString(enums), IllegalArgumentException::new)); return index; } }
withMessage(() -> "Classes are not mutually comparable: " + x.getClass().getName() + " and " + y.getClass().getName(), IllegalArgumentException::new));
/** * Creates a concrete ordering of an enum type using the given {@code orderedEnums} array. <p> * * The number of elements specified must equal to the number of elements defined in the enum. * Duplicate elements are not permitted. * * @param <E> Enum type. * @param enumType The enum type. * @param orderedEnums The intended order. * @return The corresponding {@link EnumOrder}. */ @SuppressWarnings("unchecked") public static <E extends Enum<E>> EnumOrder<E> capture(Class<E> enumType, E... orderedEnums) { final E[] world = enumType.getEnumConstants(); mustBeEqual(world.length, orderedEnums.length, withMessage("Order omits one or more required enums", IllegalArgumentException::new)); final int[] order = new int[world.length]; for (int i = 0; i < world.length; i++) { // every element in the enum's world must be present in orderedEnums, otherwise an exception is thrown final int index = indexOfMandatory(world[i], orderedEnums); order[i] = index; } return new EnumOrder<>(enumType, order); }
mustBeTrue(rangeFromIncl >= 1024, withMessage(() -> "Lower port range must include 1024 or higher", IllegalArgumentException::new)); mustBeTrue(rangeFromIncl < rangeToExcl, withMessage(() -> "Port range cannot overlap", IllegalArgumentException::new)); mustBeTrue(rangeToExcl <= 65536, withMessage(() -> "Upper port range must exclude 65536 or lower", IllegalArgumentException::new)); final int randomPort = randomInRange(rangeFromIncl, rangeToExcl);