You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/10/19 08:32:07 UTC

[causeway] 01/02: CAUSEWAY-3637: adds (flat)mapSuccessWhenPresent(..) for Try

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 7773222924757bc411da5113136b953cf670377a
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Oct 19 10:31:41 2023 +0200

    CAUSEWAY-3637: adds (flat)mapSuccessWhenPresent(..) for Try<T>
---
 .../apache/causeway/commons/functional/Try.java    | 44 +++++++++++++++++++++-
 .../grid/spi/LayoutResourceLoaderDefault.java      | 12 +++---
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/Try.java b/commons/src/main/java/org/apache/causeway/commons/functional/Try.java
index 539f053e80..ae7c239266 100644
--- a/commons/src/main/java/org/apache/causeway/commons/functional/Try.java
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/Try.java
@@ -148,6 +148,17 @@ public interface Try<T> {
      *      the success value - as passed over to the successMapper - is guaranteed non-null.
      */
     <R> Try<R> mapSuccessAsNullable(@NonNull ThrowingFunction<T, R> successMapper);
+    /**
+     * If this {@link Try} holds a non-null {@code value} (and hence is also a {@link Success}),
+     * maps this {@link Try} to another,
+     * by calling the successMapper with the {@code value} (which is non-null).
+     * Otherwise acts as identity operator, that is,
+     * either stay an empty {@link Success} or stay a {@link Failure},
+     * though implementations may return a new instance.
+     * <p>
+     * If given successMapper throws an exception, a failed {@link Try} is returned.
+     */
+    <R> Try<R> mapSuccessWhenPresent(@NonNull ThrowingFunction<T, R> successMapper);
     /**
      * If this is a {@link Failure}, maps this {@link Try} to another.
      * Otherwise if this is a {@link Success} acts as identity operator,
@@ -182,7 +193,7 @@ public interface Try<T> {
             final @NonNull ThrowingFunction<Throwable, L> failureMapper,
             final @NonNull ThrowingFunction<Optional<T>, R> successMapper);
 
-    // -- FLAT MAPPING
+    // -- FLAT MAPPING / FUNCTION COMPOSITION
 
     /**
      * Variant of {@link #mapSuccess(ThrowingFunction)},
@@ -198,6 +209,13 @@ public interface Try<T> {
      */
     <R> Try<R> flatMapSuccessAsNullable(@NonNull ThrowingFunction<T, Try<R>> successMapper);
 
+    /**
+     * Variant of {@link #mapSuccessWhenPresent(ThrowingFunction)},
+     * utilizing a different successMapper, one that returns a {@link Try}.
+     * @see #mapSuccessWhenPresent(ThrowingFunction)
+     */
+    <R> Try<R> flatMapSuccessWhenPresent(@NonNull ThrowingFunction<T, Try<R>> successMapper);
+
     // -- ACCEPT
 
     /**
@@ -329,6 +347,12 @@ public interface Try<T> {
             return Try.call(()->successMapper.apply(getValue().orElse(null)));
         }
         @Override
+        public <R> Try<R> mapSuccessWhenPresent(final @NonNull ThrowingFunction<T, R> successMapper) {
+            return getValue()
+                    .map(value->Try.call(()->successMapper.apply(value)))
+                    .orElseGet(Try::empty);
+        }
+        @Override
         public <R> Try<R> flatMapSuccess(final @NonNull ThrowingFunction<Optional<T>, Try<R>> successMapper) {
             try {
                 return successMapper.apply(getValue());
@@ -344,6 +368,16 @@ public interface Try<T> {
                 return Try.failure(ex);
             }
         }
+        @Override
+        public <R> Try<R> flatMapSuccessWhenPresent(final @NonNull ThrowingFunction<T, Try<R>> successMapper) {
+            var value = getValue().orElse(null);
+            if(value==null) return Try.empty();
+            try {
+                return successMapper.apply(value);
+            } catch (Throwable ex) {
+                return Try.failure(ex);
+            }
+        }
 
         @Override
         public Success<T> mapFailure(final @NonNull ThrowingFunction<Throwable, Throwable> failureMapper){
@@ -466,6 +500,10 @@ public interface Try<T> {
             return new Failure<>(throwable); // railway pattern:  once failed, stays failed
         }
         @Override
+        public <R> Failure<R> mapSuccessWhenPresent(final @NonNull ThrowingFunction<T, R> successMapper) {
+            return new Failure<>(throwable); // railway pattern:  once failed, stays failed
+        }
+        @Override
         public <R> Failure<R> flatMapSuccess(final @NonNull ThrowingFunction<Optional<T>, Try<R>> successMapper) {
             return new Failure<>(throwable); // railway pattern:  once failed, stays failed
         }
@@ -473,6 +511,10 @@ public interface Try<T> {
         public <R> Failure<R> flatMapSuccessAsNullable(final @NonNull ThrowingFunction<T, Try<R>> successMapper) {
             return new Failure<>(throwable); // railway pattern:  once failed, stays failed
         }
+        @Override
+        public <R> Failure<R> flatMapSuccessWhenPresent(final @NonNull ThrowingFunction<T, Try<R>> successMapper) {
+            return new Failure<>(throwable); // railway pattern:  once failed, stays failed
+        }
 
         @Override
         public Failure<T> mapFailure(final @NonNull ThrowingFunction<Throwable, Throwable> failureMapper){
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
index 839db05dea..feb737ffbe 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
@@ -35,13 +35,11 @@ public class LayoutResourceLoaderDefault implements LayoutResourceLoader {
 
         return DataSource.ofResource(type, candidateResourceName)
             .tryReadAsStringUtf8()
-            .mapSuccess(fileContent->fileContent
-                .map(layoutSource->
-                    new LayoutResource(
-                            candidateResourceName,
-                            NamedWithMimeType.CommonMimeType.valueOfFileName(candidateResourceName).orElseThrow(),
-                            layoutSource))
-                .orElse(null));
+            .mapSuccessWhenPresent(fileContent->
+                new LayoutResource(
+                        candidateResourceName,
+                        NamedWithMimeType.CommonMimeType.valueOfFileName(candidateResourceName).orElseThrow(),
+                        fileContent));
     }
 
 }