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/02/28 07:16:19 UTC

[causeway] branch master updated: CAUSEWAY-3304: Railway: opposed to Try, non of the consumer/mapper exceptions are catched

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


The following commit(s) were added to refs/heads/master by this push:
     new a75d2ca0a9 CAUSEWAY-3304: Railway: opposed to Try, non of the consumer/mapper exceptions are catched
a75d2ca0a9 is described below

commit a75d2ca0a9beffb2d66cb6f506534cfc31114b50
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Feb 28 08:16:14 2023 +0100

    CAUSEWAY-3304: Railway: opposed to Try, non of the consumer/mapper
    exceptions are catched
---
 .../causeway/commons/functional/Railway.java       | 73 ++++++++++++----------
 .../commons/functional/ThrowingConsumer.java       |  4 +-
 .../commons/functional/ThrowingFunction.java       |  2 +-
 .../commons/functional/ThrowingRunnable.java       |  2 +-
 .../commons/functional/ThrowingSupplier.java       |  4 +-
 .../apache/causeway/commons/functional/Try.java    | 35 ++++++-----
 .../interactions/managed/InteractionRailway.java   |  4 +-
 7 files changed, 66 insertions(+), 58 deletions(-)

diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/Railway.java b/commons/src/main/java/org/apache/causeway/commons/functional/Railway.java
index c9c847e633..735f7475cf 100644
--- a/commons/src/main/java/org/apache/causeway/commons/functional/Railway.java
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/Railway.java
@@ -20,7 +20,6 @@ package org.apache.causeway.commons.functional;
 
 import java.io.Serializable;
 import java.util.Optional;
-import java.util.function.Consumer;
 import java.util.function.Function;
 
 import org.springframework.lang.Nullable;
@@ -85,36 +84,41 @@ public interface Railway<F, S> {
     // -- PEEKING
 
     /**
-     * Peeks into the contained {@code success} if this is a {@link Success}.
+     * If this is a {@link Success}, peeks into the contained {@code success}.
+     * @apiNote Any exceptions thrown by given successConsumer are propagated without catching.
      */
-    Railway<F, S> ifSuccess(final @NonNull Consumer<S> successConsumer);
+    Railway<F, S> ifSuccess(final @NonNull ThrowingConsumer<S> successConsumer);
     /**
-     * Peeks into the contained {@code failure} if this is a {@link Failure}.
+     * If this is a {@link Failure}, peeks into the contained {@code failure}.
+     * @apiNote Any exceptions thrown by given failureConsumer are propagated without catching.
      */
-    Railway<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer);
+    Railway<F, S> ifFailure(final @NonNull ThrowingConsumer<F> failureConsumer);
 
     // -- MAPPING
 
     /**
-     * Maps this {@link Railway} to another if this is a {@link Success}.
+     * If this is a {@link Success}, maps this {@link Railway} to another (success).
      * Otherwise if this is a {@link Failure} acts as identity operator.
+     * @apiNote Any exceptions thrown by given successMapper are propagated without catching.
      */
-    <R> Railway<F, R> mapSuccess(final @NonNull Function<S, R> successMapper);
+    <R> Railway<F, R> mapSuccess(final @NonNull ThrowingFunction<S, R> successMapper);
     /**
      * Maps this {@link Railway} to another if this is a {@link Failure}.
      * Otherwise if this is a {@link Success} acts as identity operator.
+     * @apiNote Any exceptions thrown by given failureMapper are propagated without catching.
      */
-    <R> Railway<R, S> mapFailure(final @NonNull Function<F, R> failureMapper);
+    <R> Railway<R, S> mapFailure(final @NonNull ThrowingFunction<F, R> failureMapper);
 
     // -- FOLDING
 
     /**
-     * Maps the contained {@code success} or {@code failure} to a new value of type {@code R}
-     * using according mapping function {@code successMapper} or {@code failureMapper}.
+     * Maps the contained {@code failure} or {@code success} to a new value of type {@code R}
+     * using according mapping function {@code failureMapper} or {@code successMapper}.
+     * @apiNote Any exceptions thrown by given failureMapper or successMapper are propagated without catching.
      */
     <R> R fold(
-            final @NonNull Function<F, R> failureMapper,
-            final @NonNull Function<S, R> successMapper);
+            final @NonNull ThrowingFunction<F, R> failureMapper,
+            final @NonNull ThrowingFunction<S, R> successMapper);
 
     // -- CHAINING
 
@@ -126,8 +130,9 @@ public interface Railway<F, S> {
      * the chainingFunction is not executed.
      * <p>
      * In other words: if once failed stays failed
+     * @apiNote Any exceptions thrown by given chainingFunction are propagated without catching.
      */
-    Railway<F, S> chain(@NonNull Function<S, Railway<F, S>> chainingFunction);
+    Railway<F, S> chain(@NonNull ThrowingFunction<S, Railway<F, S>> chainingFunction);
 
     // -- SUCCESS
 
@@ -145,35 +150,35 @@ public interface Railway<F, S> {
         @Override public Optional<F> getFailure() { return Optional.empty(); }
 
         @Override
-        public Success<F, S> ifSuccess(final @NonNull Consumer<S> successConsumer) {
+        public Success<F, S> ifSuccess(final @NonNull ThrowingConsumer<S> successConsumer) {
             successConsumer.accept(success);
             return this;
         }
 
         @Override
-        public Success<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer) {
+        public Success<F, S> ifFailure(final @NonNull ThrowingConsumer<F> failureConsumer) {
             return this;
         }
 
         @Override
-        public <R> Success<F, R> mapSuccess(final @NonNull Function<S, R> successMapper) {
+        public <R> Success<F, R> mapSuccess(final @NonNull ThrowingFunction<S, R> successMapper) {
             return Railway.success(successMapper.apply(success));
         }
 
         @Override
-        public <R> Success<R, S> mapFailure(final @NonNull Function<F, R> failureMapper) {
+        public <R> Success<R, S> mapFailure(final @NonNull ThrowingFunction<F, R> failureMapper) {
             return Railway.success(success);
         }
 
         @Override
         public <R> R fold(
-                final @NonNull Function<F, R> failureMapper,
-                final @NonNull Function<S, R> successMapper) {
+                final @NonNull ThrowingFunction<F, R> failureMapper,
+                final @NonNull ThrowingFunction<S, R> successMapper) {
             return successMapper.apply(success);
         }
 
         @Override
-        public Railway<F, S> chain(final @NonNull Function<S, Railway<F, S>> chainingFunction){
+        public Railway<F, S> chain(final @NonNull ThrowingFunction<S, Railway<F, S>> chainingFunction){
             return chainingFunction.apply(success);
         }
 
@@ -195,35 +200,35 @@ public interface Railway<F, S> {
         @Override public Optional<F> getFailure() { return Optional.of(failure); }
 
         @Override
-        public Failure<F, S> ifSuccess(final @NonNull Consumer<S> successConsumer) {
+        public Failure<F, S> ifSuccess(final @NonNull ThrowingConsumer<S> successConsumer) {
             return this;
         }
 
         @Override
-        public Failure<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer) {
+        public Failure<F, S> ifFailure(final @NonNull ThrowingConsumer<F> failureConsumer) {
             failureConsumer.accept(failure);
             return this;
         }
 
         @Override
-        public <R> Failure<F, R> mapSuccess(final @NonNull Function<S, R> successMapper) {
+        public <R> Failure<F, R> mapSuccess(final @NonNull ThrowingFunction<S, R> successMapper) {
             return Railway.failure(failure);
         }
 
         @Override
-        public <R> Failure<R, S> mapFailure(final @NonNull Function<F, R> failureMapper) {
+        public <R> Failure<R, S> mapFailure(final @NonNull ThrowingFunction<F, R> failureMapper) {
             return Railway.failure(failureMapper.apply(failure));
         }
 
         @Override
         public <R> R fold(
-                final @NonNull Function<F, R> failureMapper,
-                final @NonNull Function<S, R> successMapper) {
+                final @NonNull ThrowingFunction<F, R> failureMapper,
+                final @NonNull ThrowingFunction<S, R> successMapper) {
             return failureMapper.apply(failure);
         }
 
         @Override
-        public Railway<F, S> chain(final @NonNull Function<S, Railway<F, S>> chainingFunction){
+        public Railway<F, S> chain(final @NonNull ThrowingFunction<S, Railway<F, S>> chainingFunction){
             return this;
         }
 
@@ -242,23 +247,23 @@ public interface Railway<F, S> {
         @Override default Optional<S> getSuccess() { return getRailway().getSuccess(); }
         @Override default Optional<F> getFailure() { return getRailway().getFailure(); }
 
-        @Override default Railway<F, S> ifSuccess(final @NonNull Consumer<S> successConsumer) {
+        @Override default Railway<F, S> ifSuccess(final @NonNull ThrowingConsumer<S> successConsumer) {
             return getRailway().ifSuccess(successConsumer); }
-        @Override default Railway<F, S> ifFailure(final @NonNull Consumer<F> failureConsumer) {
+        @Override default Railway<F, S> ifFailure(final @NonNull ThrowingConsumer<F> failureConsumer) {
             return getRailway().ifFailure(failureConsumer); }
 
-        @Override default <R> Railway<F, R> mapSuccess(final @NonNull Function<S, R> successMapper) {
+        @Override default <R> Railway<F, R> mapSuccess(final @NonNull ThrowingFunction<S, R> successMapper) {
             return getRailway().mapSuccess(successMapper); }
-        @Override default <R> Railway<R, S> mapFailure(final @NonNull Function<F, R> failureMapper) {
+        @Override default <R> Railway<R, S> mapFailure(final @NonNull ThrowingFunction<F, R> failureMapper) {
             return getRailway().mapFailure(failureMapper); }
 
         @Override default <R> R fold(
-                final @NonNull Function<F, R> failureMapper,
-                final @NonNull Function<S, R> successMapper) {
+                final @NonNull ThrowingFunction<F, R> failureMapper,
+                final @NonNull ThrowingFunction<S, R> successMapper) {
             return getRailway().fold(failureMapper, successMapper);
         }
 
-        @Override default public Railway<F, S> chain(final @NonNull Function<S, Railway<F, S>> chainingFunction){
+        @Override default public Railway<F, S> chain(final @NonNull ThrowingFunction<S, Railway<F, S>> chainingFunction){
             return getRailway().chain(chainingFunction);
         }
     }
diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingConsumer.java b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingConsumer.java
index 2bc517efc1..5f09e3a19e 100644
--- a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingConsumer.java
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingConsumer.java
@@ -25,11 +25,11 @@ import java.util.function.Consumer;
  * A {@link Consumer} that allows invocation of code that throws a checked
  * {@link Exception}.
  *
- * @since 2.x [@index}
  * @param <T> the type of the input to the operation
  * @apiNote this is a clone from <i>Spring's</i>
- *     org.springframework.util.function.ThrowingConsumer (as was introduced with <i>Spring Framework v6</i>),
+ *     org.springframework.util.function.ThrowingConsumer (as was introduced with <i>Spring Framework v6</i>);
  *     with version 3, the latter is used as a replacement and this interface is removed
+ * @since 2.x {@index}
  */
 @FunctionalInterface
 public interface ThrowingConsumer<T> extends Consumer<T> {
diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingFunction.java b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingFunction.java
index a25c5f87f0..d0a06013a9 100644
--- a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingFunction.java
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingFunction.java
@@ -25,12 +25,12 @@ import java.util.function.Function;
  * A {@link Function} that allows invocation of code that throws a checked
  * {@link Exception}.
  *
- * @since 2.x {index}
  * @param <T> the type of the input to the function
  * @param <R> the type of the result of the function
  * @apiNote this is a clone from <i>Spring's</i>
  *     org.springframework.util.function.ThrowingFunction (as was introduced with <i>Spring Framework v6</i>);
  *     with version 3, the latter is used as a replacement and this interface is removed
+ * @since 2.x {index}
  */
 @FunctionalInterface
 public interface ThrowingFunction<T, R> extends Function<T, R> {
diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingRunnable.java b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingRunnable.java
index 0b378566bb..35372f1d76 100644
--- a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingRunnable.java
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingRunnable.java
@@ -25,7 +25,7 @@ import lombok.NonNull;
 /**
  * Similar to a {@link Runnable}, except that it can also throw a checked {@link Exception}.
  *
- * @since 2.x [@index}
+ * @since 2.x {@index}
  */
 @FunctionalInterface
 public interface ThrowingRunnable {
diff --git a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java
index 5e18620b55..72af94bed0 100644
--- a/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java
+++ b/commons/src/main/java/org/apache/causeway/commons/functional/ThrowingSupplier.java
@@ -25,10 +25,10 @@ import java.util.function.Supplier;
  * A {@link Supplier} that allows invocation of code that throws a checked
  * exception.
  *
- * @param <T> the type of results supplied by this supplier
  * @apiNote this is a clone from <i>Spring's</i>
- *     org.springframework.util.function.ThrowingSupplier (as was introduced with <i>Spring Framework v6</i>),
+ *     org.springframework.util.function.ThrowingSupplier (as was introduced with <i>Spring Framework v6</i>);
  *     with version 3, the latter is used as a replacement and this interface is removed
+ * @since 2.x {@index}
  */
 public interface ThrowingSupplier<T> extends Supplier<T> {
 
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 43c3585521..92c4d0dd09 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
@@ -22,7 +22,6 @@ import java.io.Serializable;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.concurrent.Callable;
-import java.util.function.Function;
 import java.util.function.Supplier;
 
 import org.springframework.lang.Nullable;
@@ -169,19 +168,21 @@ public interface Try<T> {
     /**
      * Maps this {@link Try} to {@link Either}
      * using according mapping function {@code successMapper} or {@code failureMapper}.
+     * <p>
+     * Any exceptions thrown by given failureMapper or successMapper are propagated without catching.
      * @apiNote It is a common functional programming convention, to map the success value <i>right</i>.
      */
     <L, R> Either<L, R> mapToEither(
-            final @NonNull Function<Throwable, L> failureMapper,
-            final @NonNull Function<Optional<T>, R> successMapper);
+            final @NonNull ThrowingFunction<Throwable, L> failureMapper,
+            final @NonNull ThrowingFunction<Optional<T>, R> successMapper);
 
     // -- ACCEPT
 
     /**
      * Either consumes the success or the failure.
      * <p>
-     * If any of given failureConsumer or successConsumer throws an exception, a failed {@link Try} is returned.
-     * @apiNote Order of arguments conforms to {@link #mapToEither(Function, Function)}
+     * However, if any of given failureConsumer or successConsumer throws an exception, a failed {@link Try} is returned.
+     * @apiNote Order of arguments conforms to {@link #mapToEither(ThrowingFunction, ThrowingFunction)}
      */
     Try<T> accept(
             final @NonNull ThrowingConsumer<Throwable> failureConsumer,
@@ -192,11 +193,13 @@ public interface Try<T> {
     /**
      * Maps the contained {@code value} or {@code failure} to a new value of type {@code R}
      * using according mapping function {@code successMapper} or {@code failureMapper}.
-     * @apiNote Order of arguments conforms to {@link #mapToEither(Function, Function)}
+     * <p>
+     * Any exceptions thrown by given failureMapper or successMapper are propagated without catching.
+     * @apiNote Order of arguments conforms to {@link #mapToEither(ThrowingFunction, ThrowingFunction)}
      */
     <R> R fold(
-            final @NonNull Function<Throwable, R> failureMapper,
-            final @NonNull Function<Optional<T>, R> successMapper);
+            final @NonNull ThrowingFunction<Throwable, R> failureMapper,
+            final @NonNull ThrowingFunction<Optional<T>, R> successMapper);
 
     // -- CONCATENATION
 
@@ -358,15 +361,15 @@ public interface Try<T> {
 
         @Override
         public <R> R fold(
-                final @NonNull Function<Throwable, R> failureMapper,
-                final @NonNull Function<Optional<T>, R> successMapper) {
+                final @NonNull ThrowingFunction<Throwable, R> failureMapper,
+                final @NonNull ThrowingFunction<Optional<T>, R> successMapper) {
             return successMapper.apply(getValue());
         }
 
         @Override
         public <L, R> Either<L, R> mapToEither(
-                final @NonNull Function<Throwable, L> failureMapper,
-                final @NonNull Function<Optional<T>, R> successMapper) {
+                final @NonNull ThrowingFunction<Throwable, L> failureMapper,
+                final @NonNull ThrowingFunction<Optional<T>, R> successMapper) {
             return Either.right(successMapper.apply(getValue()));
         }
 
@@ -477,15 +480,15 @@ public interface Try<T> {
 
         @Override
         public <R> R fold(
-                final @NonNull Function<Throwable, R> failureMapper,
-                final @NonNull Function<Optional<T>, R> successMapper) {
+                final @NonNull ThrowingFunction<Throwable, R> failureMapper,
+                final @NonNull ThrowingFunction<Optional<T>, R> successMapper) {
             return failureMapper.apply(throwable);
         }
 
         @Override
         public <L, R> Either<L, R> mapToEither(
-                final @NonNull Function<Throwable, L> failureMapper,
-                final @NonNull Function<Optional<T>, R> successMapper) {
+                final @NonNull ThrowingFunction<Throwable, L> failureMapper,
+                final @NonNull ThrowingFunction<Optional<T>, R> successMapper) {
             return Either.left(failureMapper.apply(throwable));
         }
 
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/InteractionRailway.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/InteractionRailway.java
index 3a954ca34e..a4fbc4f620 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/InteractionRailway.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/InteractionRailway.java
@@ -19,10 +19,10 @@
 package org.apache.causeway.core.metamodel.interactions.managed;
 
 import java.io.Serializable;
-import java.util.function.Function;
 
 import org.apache.causeway.commons.functional.Railway;
 import org.apache.causeway.commons.functional.Railway.HasRailway;
+import org.apache.causeway.commons.functional.ThrowingFunction;
 
 import lombok.AccessLevel;
 import lombok.EqualsAndHashCode;
@@ -55,7 +55,7 @@ implements
     @Getter private final Railway<InteractionVeto, T> railway;
 
     @Override // type-safe override
-    public InteractionRailway<T> chain(final @NonNull Function<T, Railway<InteractionVeto, T>> chainingFunction) {
+    public InteractionRailway<T> chain(final @NonNull ThrowingFunction<T, Railway<InteractionVeto, T>> chainingFunction) {
         val railway = HasRailway.super.chain(chainingFunction);
         return railway instanceof InteractionRailway
             ? (InteractionRailway<T>) railway