From 2d94269f1b8baacacd2f30a26306425abc438fcb Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Mon, 29 Jul 2019 07:07:57 -0600 Subject: [PATCH] Add Converter.andThen Fixes: gh-22381 --- .../core/convert/converter/Converter.java | 18 ++++++++++++ .../convert/converter/ConverterTests.java | 28 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 spring-core/src/test/java/org/springframework/core/convert/converter/ConverterTests.java diff --git a/spring-core/src/main/java/org/springframework/core/convert/converter/Converter.java b/spring-core/src/main/java/org/springframework/core/convert/converter/Converter.java index d7cf51432d6e..a9c893b12d57 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/converter/Converter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/converter/Converter.java @@ -17,6 +17,7 @@ package org.springframework.core.convert.converter; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * A converter converts a source object of type {@code S} to a target of type {@code T}. @@ -26,6 +27,7 @@ *

Implementations may additionally implement {@link ConditionalConverter}. * * @author Keith Donald + * @author Josh Cummings * @since 3.0 * @param the source type * @param the target type @@ -42,4 +44,20 @@ public interface Converter { @Nullable T convert(S source); + /** + * Construct a composed {@link Converter} that first applies this {@link Converter} to + * its input, and then applies the {@code after} {@link Converter} to the result. + * + * @since 5.2 + * @param the type of output of both the {@code after} {@link Converter} and the + * composed {@link Converter} + * @param after the {@link Converter} to apply after this {@link Converter} + * is applied + * @return a composed {@link Converter} that first applies this {@link Converter} and then + * applies the {@code after} {@link Converter} + */ + default Converter andThen(Converter after) { + Assert.notNull(after, "after cannot be null"); + return (S s) -> after.convert(convert(s)); + } } diff --git a/spring-core/src/test/java/org/springframework/core/convert/converter/ConverterTests.java b/spring-core/src/test/java/org/springframework/core/convert/converter/ConverterTests.java new file mode 100644 index 000000000000..076ef507a9e5 --- /dev/null +++ b/spring-core/src/test/java/org/springframework/core/convert/converter/ConverterTests.java @@ -0,0 +1,28 @@ +package org.springframework.core.convert.converter; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Tests for {@link Converter} + * + * @author Josh Cummings + */ +public class ConverterTests { + Converter moduloTwo = number -> number % 2; + + @Test + public void andThenWhenGivenANullConverterThenThrowsException() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> this.moduloTwo.andThen(null)); + } + + @Test + public void andThenWhenGivenConverterThenComposesInOrder() { + Converter addOne = number-> number + 1; + assertThat(this.moduloTwo.andThen(addOne).convert(13)).isEqualTo(2); + assertThat(addOne.andThen(this.moduloTwo).convert(13)).isEqualTo(0); + } +} \ No newline at end of file