-
Notifications
You must be signed in to change notification settings - Fork 38.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 'Throwable' variants of the `Consumer`, `Function`, `BiFunction` and `Supplier` interfaces that wrap checked exceptions or allow calls to be made that throw them. Closes gh-28417
- Loading branch information
Showing
8 changed files
with
851 additions
and
0 deletions.
There are no files selected for viewing
135 changes: 135 additions & 0 deletions
135
spring-core/src/main/java/org/springframework/util/function/ThrowingBiFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright 2002-2022 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.util.function; | ||
|
||
import java.util.function.BiFunction; | ||
|
||
/** | ||
* A {@link BiFunction} that allows invocation of code that throws a checked | ||
* exception. | ||
* | ||
* @author Stephane Nicoll | ||
* @author Phillip Webb | ||
* @since 6.0 | ||
* @param <T> the type of the first argument to the function | ||
* @param <U> the type of the second argument to the function | ||
* @param <R> the type of the result of the function | ||
*/ | ||
public interface ThrowingBiFunction<T, U, R> extends BiFunction<T, U, R> { | ||
|
||
/** | ||
* Applies this function to the given argument, possibly throwing a checked | ||
* exception. | ||
* @param t the first function argument | ||
* @param u the second function argument | ||
* @return the function result | ||
* @throws Exception on error | ||
*/ | ||
R applyWithException(T t, U u) throws Exception; | ||
|
||
/** | ||
* Default {@link BiFunction#apply(Object, Object)} that wraps any thrown | ||
* checked exceptions (by default in a {@link RuntimeException}). | ||
* @param t the first function argument | ||
* @param u the second function argument | ||
* @return the function result | ||
* @see java.util.function.BiFunction#apply(Object, Object) | ||
*/ | ||
@Override | ||
default R apply(T t, U u) { | ||
return apply(t, u, RuntimeException::new); | ||
} | ||
|
||
/** | ||
* Applies this function to the given argument, wrapping any thrown checked | ||
* exceptions using the given {@code exceptionWrapper}. | ||
* @param t the first function argument | ||
* @param u the second function argument | ||
* @param exceptionWrapper {@link BiFunction} that wraps the given message | ||
* and checked exception into a runtime exception | ||
* @return a result | ||
*/ | ||
default R apply(T t, U u, BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
try { | ||
return applyWithException(t, u); | ||
} | ||
catch (RuntimeException ex) { | ||
throw ex; | ||
} | ||
catch (Exception ex) { | ||
throw exceptionWrapper.apply(ex.getMessage(), ex); | ||
} | ||
} | ||
|
||
/** | ||
* Return a new {@link ThrowingBiFunction} where the | ||
* {@link #apply(Object, Object)} method wraps any thrown checked exceptions | ||
* using the given {@code exceptionWrapper}. | ||
* @param exceptionWrapper {@link BiFunction} that wraps the given message | ||
* and checked exception into a runtime exception | ||
* @return the replacement {@link ThrowingBiFunction} instance | ||
*/ | ||
default ThrowingBiFunction<T, U, R> throwing(BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
return new ThrowingBiFunction<>() { | ||
|
||
@Override | ||
public R applyWithException(T t, U u) throws Exception { | ||
return ThrowingBiFunction.this.applyWithException(t, u); | ||
} | ||
|
||
@Override | ||
public R apply(T t, U u) { | ||
return apply(t, u, exceptionWrapper); | ||
} | ||
|
||
}; | ||
} | ||
|
||
/** | ||
* Lambda friendly convenience method that can be used to create | ||
* {@link ThrowingBiFunction} where the {@link #apply(Object, Object)} | ||
* method wraps any thrown checked exceptions using the given | ||
* {@code exceptionWrapper}. | ||
* @param <T> the type of the first argument to the function | ||
* @param <U> the type of the second argument to the function | ||
* @param <R> the type of the result of the function | ||
* @param function the source function | ||
* @return a new {@link ThrowingFunction} instance | ||
*/ | ||
static <T, U, R> ThrowingBiFunction<T, U, R> of(ThrowingBiFunction<T, U, R> function) { | ||
return function; | ||
} | ||
|
||
/** | ||
* Lambda friendly convenience method that can be used to create | ||
* {@link ThrowingBiFunction} where the {@link #apply(Object, Object)} | ||
* method wraps any thrown checked exceptions using the given | ||
* {@code exceptionWrapper}. | ||
* @param <T> the type of the first argument to the function | ||
* @param <U> the type of the second argument to the function | ||
* @param <R> the type of the result of the function | ||
* @param function the source function | ||
* @param exceptionWrapper the exception wrapper to use | ||
* @return a new {@link ThrowingFunction} instance | ||
*/ | ||
static <T, U, R> ThrowingBiFunction<T, U, R> of(ThrowingBiFunction<T, U, R> function, | ||
BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
|
||
return function.throwing(exceptionWrapper); | ||
} | ||
|
||
} |
121 changes: 121 additions & 0 deletions
121
spring-core/src/main/java/org/springframework/util/function/ThrowingConsumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* Copyright 2002-2022 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.util.function; | ||
|
||
import java.util.function.BiFunction; | ||
import java.util.function.Consumer; | ||
|
||
/** | ||
* A {@link Consumer} that allows invocation of code that throws a checked | ||
* exception. | ||
* | ||
* @author Stephane Nicoll | ||
* @author Phillip Webb | ||
* @since 6.0 | ||
* @param <T> the type of the input to the operation | ||
*/ | ||
@FunctionalInterface | ||
public interface ThrowingConsumer<T> extends Consumer<T> { | ||
|
||
/** | ||
* Performs this operation on the given argument, possibly throwing a | ||
* checked exception. | ||
* @param t the input argument | ||
* @throws Exception on error | ||
*/ | ||
void acceptWithException(T t) throws Exception; | ||
|
||
/** | ||
* Default {@link Consumer#accept(Object)} that wraps any thrown checked | ||
* exceptions (by default in a {@link RuntimeException}). | ||
* @see java.util.function.Consumer#accept(Object) | ||
*/ | ||
@Override | ||
default void accept(T t) { | ||
accept(t, RuntimeException::new); | ||
} | ||
|
||
/** | ||
* Performs this operation on the given argument, wrapping any thrown | ||
* checked exceptions using the given {@code exceptionWrapper}. | ||
* @param exceptionWrapper {@link BiFunction} that wraps the given message | ||
* and checked exception into a runtime exception | ||
*/ | ||
default void accept(T t,BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
try { | ||
acceptWithException(t); | ||
} | ||
catch (RuntimeException ex) { | ||
throw ex; | ||
} | ||
catch (Exception ex) { | ||
throw exceptionWrapper.apply(ex.getMessage(), ex); | ||
} | ||
} | ||
|
||
/** | ||
* Return a new {@link ThrowingConsumer} where the {@link #accept(Object)} | ||
* method wraps any thrown checked exceptions using the given | ||
* {@code exceptionWrapper}. | ||
* @param exceptionWrapper {@link BiFunction} that wraps the given message | ||
* and checked exception into a runtime exception | ||
* @return the replacement {@link ThrowingConsumer} instance | ||
*/ | ||
default ThrowingConsumer<T> throwing(BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
return new ThrowingConsumer<>() { | ||
|
||
@Override | ||
public void acceptWithException(T t) throws Exception { | ||
ThrowingConsumer.this.acceptWithException(t); | ||
} | ||
|
||
@Override | ||
public void accept(T t) { | ||
accept(t, exceptionWrapper); | ||
} | ||
|
||
}; | ||
} | ||
|
||
/** | ||
* Lambda friendly convenience method that can be used to create | ||
* {@link ThrowingConsumer} where the {@link #accept(Object)} method wraps | ||
* any thrown checked exceptions using the given {@code exceptionWrapper}. | ||
* @param <T> the type of the input to the operation | ||
* @param consumer the source consumer | ||
* @return a new {@link ThrowingConsumer} instance | ||
*/ | ||
static <T> ThrowingConsumer<T> of(ThrowingConsumer<T> consumer) { | ||
return consumer; | ||
} | ||
|
||
/** | ||
* Lambda friendly convenience method that can be used to create | ||
* {@link ThrowingConsumer} where the {@link #accept(Object)} method wraps | ||
* any thrown checked exceptions using the given {@code exceptionWrapper}. | ||
* @param <T> the type of the input to the operation | ||
* @param consumer the source consumer | ||
* @param exceptionWrapper the exception wrapper to use | ||
* @return a new {@link ThrowingConsumer} instance | ||
*/ | ||
static <T> ThrowingConsumer<T> of(ThrowingConsumer<T> consumer, | ||
BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
|
||
return consumer.throwing(exceptionWrapper); | ||
} | ||
|
||
} |
126 changes: 126 additions & 0 deletions
126
spring-core/src/main/java/org/springframework/util/function/ThrowingFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* Copyright 2002-2022 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.util.function; | ||
|
||
import java.util.function.BiFunction; | ||
import java.util.function.Function; | ||
|
||
/** | ||
* A {@link Function} that allows invocation of code that throws a checked | ||
* exception. | ||
* | ||
* @author Stephane Nicoll | ||
* @author Phillip Webb | ||
* @since 6.0 | ||
* @param <T> the type of the input to the function | ||
* @param <R> the type of the result of the function | ||
*/ | ||
@FunctionalInterface | ||
public interface ThrowingFunction<T, R> extends Function<T, R> { | ||
|
||
/** | ||
* Applies this function to the given argument, possibly throwing a checked | ||
* exception. | ||
* @param t the function argument | ||
* @return the function result | ||
* @throws Exception on error | ||
*/ | ||
R applyWithException(T t) throws Exception; | ||
|
||
/** | ||
* Default {@link Function#apply(Object)} that wraps any thrown checked | ||
* exceptions (by default in a {@link RuntimeException}). | ||
* @see java.util.function.Function#apply(java.lang.Object) | ||
*/ | ||
@Override | ||
default R apply(T t) { | ||
return apply(t, RuntimeException::new); | ||
} | ||
|
||
/** | ||
* Applies this function to the given argument, wrapping any thrown checked | ||
* exceptions using the given {@code exceptionWrapper}. | ||
* @param exceptionWrapper {@link BiFunction} that wraps the given message | ||
* and checked exception into a runtime exception | ||
* @return a result | ||
*/ | ||
default R apply(T t, BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
try { | ||
return applyWithException(t); | ||
} | ||
catch (RuntimeException ex) { | ||
throw ex; | ||
} | ||
catch (Exception ex) { | ||
throw exceptionWrapper.apply(ex.getMessage(), ex); | ||
} | ||
} | ||
|
||
/** | ||
* Return a new {@link ThrowingFunction} where the {@link #apply(Object)} | ||
* method wraps any thrown checked exceptions using the given | ||
* {@code exceptionWrapper}. | ||
* @param exceptionWrapper {@link BiFunction} that wraps the given message | ||
* and checked exception into a runtime exception | ||
* @return the replacement {@link ThrowingFunction} instance | ||
*/ | ||
default ThrowingFunction<T, R> throwing(BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
return new ThrowingFunction<>() { | ||
|
||
@Override | ||
public R applyWithException(T t) throws Exception { | ||
return ThrowingFunction.this.applyWithException(t); | ||
} | ||
|
||
@Override | ||
public R apply(T t) { | ||
return apply(t, exceptionWrapper); | ||
} | ||
|
||
}; | ||
} | ||
|
||
/** | ||
* Lambda friendly convenience method that can be used to create | ||
* {@link ThrowingFunction} where the {@link #apply(Object)} method wraps | ||
* any thrown checked exceptions using the given {@code exceptionWrapper}. | ||
* @param <T> the type of the input to the function | ||
* @param <R> the type of the result of the function | ||
* @param function the source function | ||
* @return a new {@link ThrowingFunction} instance | ||
*/ | ||
static <T, R> ThrowingFunction<T, R> of(ThrowingFunction<T, R> function) { | ||
return function; | ||
} | ||
|
||
/** | ||
* Lambda friendly convenience method that can be used to create | ||
* {@link ThrowingFunction} where the {@link #apply(Object)} method wraps | ||
* any thrown checked exceptions using the given {@code exceptionWrapper}. | ||
* @param <T> the type of the input to the function | ||
* @param <R> the type of the result of the function | ||
* @param function the source function | ||
* @param exceptionWrapper the exception wrapper to use | ||
* @return a new {@link ThrowingFunction} instance | ||
*/ | ||
static <T, R> ThrowingFunction<T, R> of(ThrowingFunction<T, R> function, | ||
BiFunction<String, Exception, RuntimeException> exceptionWrapper) { | ||
|
||
return function.throwing(exceptionWrapper); | ||
} | ||
|
||
} |
Oops, something went wrong.