LinearFutureTask(ActorExecutor executor, FutureTask<V> delegateTask, String key) { mustExist(key, "Key cannot be null"); this.executor = executor; this.delegateTask = delegateTask; this.key = key; }
private void checkAllowNonLinearTasks() { mustBeTrue(allowNonLinearTasks, withMessage("Non-linear tasks are not allowed", RejectedExecutionException::new)); }
/** * 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)); }
/** * 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); }
/** * Ensures that the given value is {@code null}. Otherwise, an * exception specified by the given {@code exceptionMaker} is thrown. * * @param <X> Exception type. * @param value The value to test. * @param exceptionMaker A way of creating the exception for a non-{@code null} value. * @throws X If the value is not {@code null}. */ public static <X extends Throwable> void mustBeNull(Object value, Supplier<? extends X> exceptionMaker) throws X { mustBeTrue(value == null, exceptionMaker); }
/** * A variant of {@link #ifAbsent(Object, CheckedSupplier)} that operates on {@link Optional} values, * returning the encapsulated value if set, or sourcing the value from the given {@code supplier} * otherwise. <p> * * This is similar to {@link Optional#orElseGet(Supplier)}, with two notable differences: <br> * - This method does not create intermediate objects; and <br> * - This method accepts a {@link CheckedSupplier}, permitting exceptions. * * @param <T> Value type. * @param <X> Exception type. * @param value The optional value. * @param supplier Supplier to invoke if the value is empty. * @return The extracted value (as-is) if it is set, or the value produced by the supplier otherwise. * @throws X If an error occurs inside the supplier. */ public static <T, X extends Throwable> T ifAbsentOptional(Optional<T> value, CheckedSupplier<? extends T, X> supplier) throws X { return ifAbsent(value.orElse(null), supplier); }
/** * A variant of {@link #ifEither(Object, CheckedFunction, CheckedSupplier)} that operates on * {@link Optional} values. * * @param <T> Value type. * @param <U> Mapped or supplied type. * @param <X> Exception type. * @param value The optional value. * @param mapperIfPresent The mapping function to invoke if the value is set. * @param supplierIfAbsent The supplier to invoke if the value is empty. * @return The mapped value if the initial value isn't empty, or the value produced by * the supplier otherwise. * @throws X If an error occurs inside either the mapping function or the supplier. */ public static <T, U, X extends Throwable> U ifEitherOptional(Optional<T> value, CheckedFunction<? super T, ? extends U, X> mapperIfPresent, CheckedSupplier<? extends U, X> supplierIfAbsent) throws X { return ifEither(value.orElse(null), mapperIfPresent, supplierIfAbsent); }
/** * A variant of {@link #ifPresent(Object, CheckedFunction)} that operates on {@link Optional} values, * returning the result of applying the given {@code mapper} to the encapsulated value if the * latter is present, or {@code null} otherwise. <p> * * This is similar to {@link Optional#map(Function)}, with two notable differences: <br> * - This method does not create intermediate objects; and <br> * - This method accepts a {@link CheckedFunction}, permitting exceptions. * * @param <T> Value type. * @param <U> Mapped type. * @param <X> Exception type. * @param value The optional value. * @param mapper The mapping function. * @return The mapped value if the initial value isn't empty, or {@code null} otherwise. * @throws X If an error occurs. */ public static <T, U, X extends Throwable> U ifPresentOptional(Optional<T> value, CheckedFunction<? super T, ? extends U, X> mapper) throws X { return ifPresent(value.orElse(null), mapper); }
TaskScheduler getTimeoutScheduler() { return mustExist(timeoutScheduler, withMessage("Timeout scheduler is not in use", IllegalStateException::new)); }
mustBeEqual(x.getClass(), y.getClass(), withMessage(() -> "Classes are not mutually comparable: " + x.getClass().getName() + " and " + y.getClass().getName(), IllegalArgumentException::new));
/** * Ensures that the given {@code expected} and {@code actual} values are equal. Otherwise, an * exception specified by the given {@code exceptionMaker} is thrown. * * @param <X> Exception type. * @param expected The expected value. * @param actual The actual value. * @param exceptionMaker A way of creating the exception for non-equal objects. * @throws X If the two objects are not equal. */ public static <X extends Throwable> void mustBeEqual(Object expected, Object actual, Supplier<? extends X> exceptionMaker) throws X { mustBeTrue(Objects.equals(expected, actual), exceptionMaker); }
/** * A convenient variant of {@link #mustExist(Object, Supplier)} that throws a * {@link NullArgumentException} with no message. * * @param <T> Value type. * @param value The value to check. * @return The verified value. * @throws NullArgumentException If the given value is {@code null}. */ public static <T> T mustExist(T value) throws NullArgumentException { return mustExist(value, NullArgumentException::new); }
TaskScheduler getBackgroundScheduler() { return mustExist(backgroundScheduler, withMessage("Background scheduler is not in use", IllegalStateException::new)); }
private static void ensureNotEmpty(Collection<?> array) { mustBeTrue(! array.isEmpty(), withMessage("No elements to search", IllegalArgumentException::new)); }
/** * Marks a given task as completed. <p> * * Because this method may be called from within the actor system (just after executing the task), * it <em>must not block</em>. (It may also be called by application threads to cancel tasks.) * * @param task The task to complete. */ void markCompleted(LinearFutureTask<?> task) { final boolean removed = pendingTasks.remove(task); mustBeTrue(removed, IllegalStateException::new); final boolean terminated; synchronized (stateLock) { final int currentPendingTaskCount = pendingTaskCount; pendingTaskCount = currentPendingTaskCount - 1; terminated = shuttingDown && currentPendingTaskCount == 1; } if (terminated) { dispose(); } }
/** * 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; }
/** * A helper for decorating an existing {@link Callable} instance * with a {@link LinearTask}, on the basis of the provided key. * * @param <V> Return type. * @param callable The callable to delegate to. * @param key The key used for ordering. * @return A {@link LinearCallable} instance. */ public static <V> LinearCallable<V> decorate(Callable<V> callable, String key) { mustExist(callable, "Callable cannot be null"); mustExist(key, "Key cannot be null"); return new LinearCallable<V>() { @Override public V call() throws Exception { return callable.call(); } @Override public String getKey() { return key; } }; } }