From f997c3e59022ecbdad553ebb8e659d4f832a1775 Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 13 Jan 2021 21:13:06 -0800 Subject: [PATCH] Add overloaded doOperationSafely(:ExceptionThrowingOperation, :Supplier) method to the ObjectUtils class. Edit Javadoc. --- .../geode/core/util/ObjectUtils.java | 98 ++++++++++++------- .../geode/core/util/ObjectUtilsUnitTests.java | 31 +++++- 2 files changed, 93 insertions(+), 36 deletions(-) diff --git a/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java b/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java index b21c31b7..66d1e10f 100644 --- a/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java +++ b/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java @@ -87,68 +87,96 @@ public abstract class ObjectUtils extends org.springframework.util.ObjectUtils { } /** - * Executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} thrown during - * the normal execution of the operation by rethrowing an {@link IllegalStateException} wrapping - * the checked {@link Exception}. + * Safely executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} + * thrown during the normal execution of the operation by rethrowing an {@link IllegalStateException} + * wrapping the original checked {@link Exception}. * - * @param {@link Class type} of value returned from the operation execution. - * @param operation {@link ExceptionThrowingOperation} to execute. - * @return the result of the given {@link ExceptionThrowingOperation} or throw an {@link IllegalStateException} - * wrapping the checked {@link Exception} thrown by the operation. + * @param {@link Class type} of {@link Object value} returned from the execution of the operation. + * @param operation {@link ExceptionThrowingOperation} to execute; must not be {@literal null}. + * @return the result of the {@link ExceptionThrowingOperation}. + * @throws IllegalStateException wrapping any checked {@link Exception} thrown by the operation. * @see org.springframework.geode.core.util.ObjectUtils.ExceptionThrowingOperation * @see #doOperationSafely(ExceptionThrowingOperation, Object) */ @Nullable - public static T doOperationSafely(ExceptionThrowingOperation operation) { + public static T doOperationSafely(@NonNull ExceptionThrowingOperation operation) { return doOperationSafely(operation, (T) null); } /** - * Executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} thrown - * during the normal execution of the operation, returning the {@link Object default value} in its place - * or throwing a {@link RuntimeException} if the {@link Object default value} is {@literal null}. + * Safely executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} + * thrown during the normal execution of the operation by returning the given {@link Object default value} + * or throwing an {@link IllegalStateException} if the {@link Object default value} is {@literal null}. * - * @param {@link Class type} of value returned from the operation execution as well as - * the {@link Object default value}. - * @param operation {@link ExceptionThrowingOperation} to execute. - * @param defaultValue {@link Object value} to return if the operation results in a checked {@link Exception}. - * @return the result of the given {@link ExceptionThrowingOperation}, returning the {@link Object default value} - * if the operation throws a checked {@link Exception} or throws an {@link IllegalStateException} wrapping - * the checked {@link Exception} if the {@link Object default value} is {@literal null}. - * @throws IllegalStateException if the {@link ExceptionThrowingOperation} throws a checked {@link Exception} - * and {@link Object default value} is {@literal null}. + * @param {@link Class type} of {@link Object value} returned from the execution of the operation + * as well as the {@link Class type} of the {@link Object default value}. + * @param operation {@link ExceptionThrowingOperation} to execute; must not be {@literal null}. + * @param defaultValue {@link Object value} to return if the execution of the operation + * results in a checked {@link Exception}. + * @return the result of the {@link ExceptionThrowingOperation}, returning the {@link Object default value} + * if the execution of the operation throws a checked {@link Exception} + * @throws IllegalStateException wrapping any checked {@link Exception} thrown by the operation + * when the {@link Object default value} is {@literal null}. * @see org.springframework.geode.core.util.ObjectUtils.ExceptionThrowingOperation - * @see #doOperationSafely(ExceptionThrowingOperation, Function) + * @see #doOperationSafely(ExceptionThrowingOperation, Supplier) * @see #returnValueThrowOnNull(Object, RuntimeException) */ @Nullable - public static T doOperationSafely(ExceptionThrowingOperation operation, T defaultValue) { + public static T doOperationSafely(@NonNull ExceptionThrowingOperation operation, @NonNull T defaultValue) { + + Supplier valueSupplier = () -> defaultValue; + + return doOperationSafely(operation, valueSupplier); + } + + /** + * Safely executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} + * thrown during the normal execution of the operation by returning a {@link Object default value} + * supplied by the given {@link Supplier}, or throws an {@link IllegalStateException} + * if the {@link Supplier supplied value} is {@literal null}. + * + * @param {@link Class type} of {@link Object value} returned from the execution of the operation + * as well as the {@link Class type} of the {@link Object default value}. + * @param operation {@link ExceptionThrowingOperation} to execute; must not be {@literal null}. + * @param valueSupplier {@link Supplier} of the {@link Object value} to return if the execution of the operation + * results in a checked {@link Exception}; must not be {@literal null}. + * @return the result of the {@link ExceptionThrowingOperation}, returning the {@link Supplier supplied value} + * if the execution of the operation throws a checked {@link Exception} + * @throws IllegalStateException wrapping any checked {@link Exception} thrown by the operation + * when the {@link Supplier supplied value} is {@literal null}. + * @see org.springframework.geode.core.util.ObjectUtils.ExceptionThrowingOperation + * @see #doOperationSafely(ExceptionThrowingOperation, Function) + * @see #returnValueThrowOnNull(Object, RuntimeException) + * @see java.util.function.Supplier + */ + public static T doOperationSafely(@NonNull ExceptionThrowingOperation operation, + @NonNull Supplier valueSupplier) { Function exceptionHandlingFunction = cause -> - returnValueThrowOnNull(defaultValue, newIllegalStateException(cause, "Failed to execute operation")); + returnValueThrowOnNull(valueSupplier.get(), newIllegalStateException(cause, "Failed to execute operation")); return doOperationSafely(operation, exceptionHandlingFunction); } /** - * Executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} thrown - * during the normal execution of the operation by invoking the provided {@link Exception} handling - * {@link Function}. + * Safely executes the given {@link ExceptionThrowingOperation} handling any checked {@link Exception} + * thrown during the normal execution of the operation by invoking the provided {@link Exception} + * handling {@link Function}. * - * @param {@link Class type} of value returned from the operation execution. - * @param operation {@link ExceptionThrowingOperation} to execute. - * @param exceptionHandlingFunction {@link Function} used to handle any {@link Exception} thrown by - * the {@link ExceptionThrowingOperation operation}. - * @return the result of executing the given {@link ExceptionThrowingOperation}. + * @param {@link Class type} of {@link Object value} returned from the execution of the operation. + * @param operation {@link ExceptionThrowingOperation} to execute; must not be {@literal null}. + * @param exceptionHandlingFunction {@link Function} used to handle any checked {@link Exception} + * thrown by {@link ExceptionThrowingOperation}; must not be {@literal null}. + * @return the result of the {@link ExceptionThrowingOperation}. * @see org.springframework.geode.core.util.ObjectUtils.ExceptionThrowingOperation * @see java.util.function.Function * @see java.lang.Throwable */ - public static T doOperationSafely(ExceptionThrowingOperation operation, - Function exceptionHandlingFunction) { + public static T doOperationSafely(@NonNull ExceptionThrowingOperation operation, + @NonNull Function exceptionHandlingFunction) { try { - return operation.doExceptionThrowingOperation(); + return operation.run(); } catch (Exception cause) { @@ -404,6 +432,6 @@ public abstract class ObjectUtils extends org.springframework.util.ObjectUtils { @FunctionalInterface public interface ExceptionThrowingOperation { - T doExceptionThrowingOperation() throws Exception; + T run() throws Exception; } } diff --git a/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java b/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java index 2c3d6a01..06bb9a43 100644 --- a/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java +++ b/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java @@ -25,6 +25,7 @@ import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newR import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Optional; +import java.util.function.Supplier; import org.junit.Test; @@ -162,8 +163,17 @@ public class ObjectUtilsUnitTests { "default value")).isEqualTo("default value"); } + @Test + public void doOperationSafelyReturnsSuppliedValue() { + + Supplier suppliedValue = () -> "supplied value"; + + assertThat(ObjectUtils.doOperationSafely(() -> { throw newRuntimeException("test"); }, suppliedValue)) + .isEqualTo("supplied value"); + } + @Test(expected = IllegalStateException.class) - public void doOperationSafelyThrowsIllegalStateException() { + public void doOperationSafelyWithNullDefaultValueThrowsIllegalStateException() { try { ObjectUtils.doOperationSafely(() -> { throw newRuntimeException("test"); }, (Object) null); @@ -179,6 +189,25 @@ public class ObjectUtilsUnitTests { } } + @Test(expected = IllegalStateException.class) + public void doOperationSafelyWithNullSuppliedValueThrowsIllegalStateException() { + + Supplier suppliedValue = () -> null; + + try { + ObjectUtils.doOperationSafely(() -> { throw newRuntimeException("test"); }, suppliedValue); + } + catch (IllegalStateException expected) { + + assertThat(expected).hasMessage("Failed to execute operation"); + assertThat(expected).hasCauseInstanceOf(RuntimeException.class); + assertThat(expected.getCause()).hasMessage("test"); + assertThat(expected.getCause()).hasNoCause(); + + throw expected; + } + } + @Test public void findMethodUsingExactArguments() {