diff --git a/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java b/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java index 2d5a20384..6a9f2282c 100644 --- a/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java +++ b/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java @@ -15,6 +15,8 @@ */ package org.springframework.data.repository.support; +import static org.springframework.data.util.Optionals.*; + import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -24,8 +26,6 @@ import org.springframework.core.convert.ConversionService; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.core.RepositoryInformation; -import org.springframework.data.util.Optionals; -import org.springframework.data.util.Pair; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.util.Assert; @@ -87,11 +87,10 @@ public class DefaultRepositoryInvokerFactory implements RepositoryInvokerFactory */ private RepositoryInvoker prepareInvokers(Class domainType) { - Optional> repositoryAndInformation = Optionals - .withBoth(repositories.getRepositoryFor(domainType), repositories.getRepositoryInformationFor(domainType)); + Optional information = repositories.getRepositoryInformationFor(domainType); + Optional repository = repositories.getRepositoryFor(domainType); - return repositoryAndInformation// - .map(it -> createInvoker(it.getSecond(), it.getFirst())) // + return mapIfAllPresent(information, repository, (left, right) -> createInvoker(left, right))// .orElseThrow( () -> new IllegalArgumentException(String.format("No repository found for domain type: %s", domainType))); } diff --git a/src/main/java/org/springframework/data/util/Optionals.java b/src/main/java/org/springframework/data/util/Optionals.java index 41ebd5438..fe57165d2 100644 --- a/src/main/java/org/springframework/data/util/Optionals.java +++ b/src/main/java/org/springframework/data/util/Optionals.java @@ -20,6 +20,8 @@ import lombok.experimental.UtilityClass; import java.util.Arrays; import java.util.Iterator; import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; @@ -34,6 +36,8 @@ import org.springframework.util.Assert; @UtilityClass public class Optionals { + private static final Object SUCCESS = new Object(); + /** * Returns whether any of the given {@link Optional}s is present. * @@ -152,4 +156,49 @@ public class Optionals { public static Optional> withBoth(Optional left, Optional right) { return left.flatMap(l -> right.map(r -> Pair.of(l, r))); } + + /** + * Invokes the given {@link BiConsumer} if all given {@link Optional} are present. + * + * @param left must not be {@literal null}. + * @param right must not be {@literal null}. + * @param consumer must not be {@literal null}. + */ + public static Optional ifAllPresent(Optional left, Optional right, BiConsumer consumer) { + + Assert.notNull(left, "Optional must not be null!"); + Assert.notNull(right, "Optional must not be null!"); + Assert.notNull(consumer, "Consumer must not be null!"); + + return mapIfAllPresent(left, right, (l, r) -> { + consumer.accept(l, r); + return SUCCESS; + }); + } + + /** + * Maps the values contained in the given {@link Optional} if both of them are present. + * + * @param left must not be {@literal null}. + * @param right must not be {@literal null}. + * @param function must not be {@literal null}. + * @return + */ + public static Optional mapIfAllPresent(Optional left, Optional right, + BiFunction function) { + + Assert.notNull(left, "Optional must not be null!"); + Assert.notNull(right, "Optional must not be null!"); + Assert.notNull(function, "BiFunctionmust not be null!"); + + return left.flatMap(l -> right.map(r -> function.apply(l, r))); + } + + public static void ifBothAbsent(Optional left, Optional right, Supplier supplier) + throws T { + + if (!left.isPresent() && !right.isPresent()) { + throw supplier.get(); + } + } } diff --git a/src/test/java/org/springframework/data/projection/DefaultProjectionInformationUnitTests.java b/src/test/java/org/springframework/data/projection/DefaultProjectionInformationUnitTests.java index 48e4a2ed7..4e51dca42 100755 --- a/src/test/java/org/springframework/data/projection/DefaultProjectionInformationUnitTests.java +++ b/src/test/java/org/springframework/data/projection/DefaultProjectionInformationUnitTests.java @@ -53,7 +53,7 @@ public class DefaultProjectionInformationUnitTests { ProjectionInformation information = new DefaultProjectionInformation(WithDefaultMethod.class); assertThat(information.isClosed()).isTrue(); - assertThat(toNames(information.getInputProperties())).contains("firstname"); + assertThat(toNames(information.getInputProperties())).containsExactly("firstname"); } private static List toNames(List descriptors) { diff --git a/src/test/java/org/springframework/data/repository/query/ReturnedTypeUnitTests.java b/src/test/java/org/springframework/data/repository/query/ReturnedTypeUnitTests.java index 6a1896c20..75b6c5a07 100755 --- a/src/test/java/org/springframework/data/repository/query/ReturnedTypeUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/ReturnedTypeUnitTests.java @@ -153,7 +153,8 @@ public class ReturnedTypeUnitTests { List properties = type.getInputProperties(); - assertThat(properties).hasSize(1).contains("firstname"); + assertThat(properties).hasSize(1); + assertThat(properties).containsExactly("firstname"); } private static ReturnedType getReturnedType(String methodName, Class... parameters) throws Exception {