diff --git a/pom.xml b/pom.xml
index bec5ffa86..355d30a49 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,8 +17,8 @@
2.11.7
- 2.5.0.M41.4.8
+ 5.0.0.BUILD-SNAPSHOT
@@ -114,6 +114,20 @@
true
+
+ io.reactivex
+ rxjava-reactive-streams
+ ${rxjava-reactive-streams}
+ true
+
+
+
+ io.reactivex.rxjava2
+ rxjava
+ ${rxjava2}
+ true
+
+
diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java
index 1596b67e4..6e1806908 100644
--- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java
+++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java
@@ -43,6 +43,7 @@ import org.springframework.util.StringUtils;
* {@link #getModulePrefix()}). Stubs out the post-processing methods as they might not be needed by default.
*
* @author Oliver Gierke
+ * @author Mark Paluch
*/
public abstract class RepositoryConfigurationExtensionSupport implements RepositoryConfigurationExtension {
@@ -293,7 +294,7 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit
* @param loader must not be {@literal null}.
* @return the repository interface or {@literal null} if it can't be loaded.
*/
- private Class> loadRepositoryInterface(RepositoryConfiguration> configuration, ResourceLoader loader) {
+ protected Class> loadRepositoryInterface(RepositoryConfiguration> configuration, ResourceLoader loader) {
String repositoryInterface = configuration.getRepositoryInterface();
ClassLoader classLoader = loader.getClassLoader();
diff --git a/src/main/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformation.java b/src/main/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformation.java
index 3d3eac6b6..da8a5bc0f 100644
--- a/src/main/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformation.java
+++ b/src/main/java/org/springframework/data/repository/core/support/ReactiveRepositoryInformation.java
@@ -33,6 +33,7 @@ import org.springframework.util.Assert;
* converted for invocation of implementation methods.
*
* @author Mark Paluch
+ * @since 2.0
*/
public class ReactiveRepositoryInformation extends DefaultRepositoryInformation {
@@ -75,7 +76,7 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
boolean wantsWrappers = wantsMethodUsingReactiveWrapperParameters(method);
if (wantsWrappers) {
- Method candidate = getMethodCandidate(method, baseClass, new ExactWrapperMatch(method));
+ Method candidate = getMethodCandidate(method, baseClass, new AssignableWrapperMatch(method));
if (candidate != null) {
return candidate;
@@ -171,6 +172,11 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
&& !QueryExecutionConverters.supportsUnwrapping(parameterType);
}
+ /**
+ * {@link BiPredicate} to check whether a method parameter is a {@link #isNonunwrappingWrapper(Class)} and can be
+ * converted into a different wrapper. Usually {@link rx.Observable} to {@link org.reactivestreams.Publisher}
+ * conversion.
+ */
static class WrapperConversionMatch implements BiPredicate, Integer> {
final Method declaredMethod;
@@ -187,7 +193,6 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
@Override
public boolean test(Class> candidateParameterType, Integer index) {
- // TODO: should check for component type
if (isNonunwrappingWrapper(candidateParameterType) && isNonunwrappingWrapper(declaredParameterTypes[index])) {
if (conversionService.canConvert(declaredParameterTypes[index], candidateParameterType)) {
@@ -197,15 +202,19 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
return false;
}
-
}
- static class ExactWrapperMatch implements BiPredicate, Integer> {
+ /**
+ * {@link BiPredicate} to check parameter assignability between a {@link #isNonunwrappingWrapper(Class)} parameter and
+ * a declared parameter. Usually {@link reactor.core.publisher.Flux} vs. {@link org.reactivestreams.Publisher}
+ * conversion.
+ */
+ static class AssignableWrapperMatch implements BiPredicate, Integer> {
final Method declaredMethod;
final Class>[] declaredParameterTypes;
- public ExactWrapperMatch(Method declaredMethod) {
+ public AssignableWrapperMatch(Method declaredMethod) {
this.declaredMethod = declaredMethod;
this.declaredParameterTypes = declaredMethod.getParameterTypes();
@@ -214,7 +223,6 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
@Override
public boolean test(Class> candidateParameterType, Integer index) {
- // TODO: should check for component type
if (isNonunwrappingWrapper(candidateParameterType) && isNonunwrappingWrapper(declaredParameterTypes[index])) {
if (declaredParameterTypes[index].isAssignableFrom(candidateParameterType)) {
@@ -224,9 +232,14 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
return false;
}
-
}
+ /**
+ * {@link BiPredicate} to check parameter assignability between a parameters in which the declared parameter may be
+ * wrapped but supports unwrapping. Usually types like {@link java.util.Optional} or {@link java.util.stream.Stream}.
+ *
+ * @see QueryExecutionConverters
+ */
static class MatchParameterOrComponentType implements BiPredicate, Integer> {
final Method declaredMethod;
@@ -253,7 +266,5 @@ public class ReactiveRepositoryInformation extends DefaultRepositoryInformation
return true;
}
-
}
-
}
diff --git a/src/main/java/org/springframework/data/repository/query/ReactiveWrapperConverters.java b/src/main/java/org/springframework/data/repository/query/ReactiveWrapperConverters.java
deleted file mode 100644
index 6012f194b..000000000
--- a/src/main/java/org/springframework/data/repository/query/ReactiveWrapperConverters.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2016 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
- *
- * http://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.data.repository.query;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-import org.reactivestreams.Publisher;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.core.convert.support.GenericConversionService;
-import org.springframework.data.repository.util.QueryExecutionConverters;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import rx.Observable;
-import rx.Single;
-
-/**
- * Conversion support for reactive wrapper types.
- *
- * @author Mark Paluch
- * @since 2.0
- */
-public abstract class ReactiveWrapperConverters {
-
- private static final boolean PROJECT_REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.converter.DependencyUtils",
- QueryExecutionConverters.class.getClassLoader());
- private static final boolean RXJAVA_SINGLE_PRESENT = ClassUtils.isPresent("rx.Single",
- QueryExecutionConverters.class.getClassLoader());
- private static final boolean RXJAVA_OBSERVABLE_PRESENT = ClassUtils.isPresent("rx.Observable",
- QueryExecutionConverters.class.getClassLoader());
-
- private static final List> REACTIVE_WRAPPERS = new ArrayList<>();
- private static final GenericConversionService GENERIC_CONVERSION_SERVICE = new GenericConversionService();
-
- static {
-
- if (PROJECT_REACTOR_PRESENT) {
- REACTIVE_WRAPPERS.add(FluxWrapper.INSTANCE);
- REACTIVE_WRAPPERS.add(MonoWrapper.INSTANCE);
- REACTIVE_WRAPPERS.add(PublisherWrapper.INSTANCE);
- }
-
- if (RXJAVA_SINGLE_PRESENT) {
- REACTIVE_WRAPPERS.add(SingleWrapper.INSTANCE);
- }
-
- if (RXJAVA_OBSERVABLE_PRESENT) {
- REACTIVE_WRAPPERS.add(ObservableWrapper.INSTANCE);
- }
-
- QueryExecutionConverters.registerConvertersIn(GENERIC_CONVERSION_SERVICE);
- }
-
- private ReactiveWrapperConverters() {
-
- }
-
- /**
- * Returns whether the given type is a supported wrapper type.
- *
- * @param type must not be {@literal null}.
- * @return
- */
- public static boolean supports(Class> type) {
- return assignableStream(type).isPresent();
- }
-
- /**
- * Returns whether the type is a single-like wrapper.
- *
- * @param type must not be {@literal null}.
- * @return
- * @see Single
- * @see Mono
- */
- public static boolean isSingleLike(Class> type) {
- return assignableStream(type).map(wrapper -> wrapper.getMultiplicity() == Multiplicity.ONE).orElse(false);
- }
-
- /**
- * Returns whether the type is a collection/multi-element-like wrapper.
- *
- * @param type must not be {@literal null}.
- * @return
- * @see Observable
- * @see Flux
- * @see Publisher
- */
- public static boolean isCollectionLike(Class> type) {
- return assignableStream(type).map(wrapper -> wrapper.getMultiplicity() == Multiplicity.MANY).orElse(false);
- }
-
- /**
- * Casts or converts the given wrapper type into a different wrapper type.
- *
- * @param stream the stream, must not be {@literal null}.
- * @param expectedWrapperType must not be {@literal null}.
- * @return
- */
- public static T toWrapper(Object stream, Class extends T> expectedWrapperType) {
-
- Assert.notNull(stream, "Stream must not be null!");
- Assert.notNull(expectedWrapperType, "Converter must not be null!");
-
- if (expectedWrapperType.isAssignableFrom(stream.getClass())) {
- return (T) stream;
- }
-
- return GENERIC_CONVERSION_SERVICE.convert(stream, expectedWrapperType);
- }
-
- /**
- * Maps elements of a reactive element stream to other elements.
- *
- * @param stream must not be {@literal null}.
- * @param converter must not be {@literal null}.
- * @return
- */
- public static T map(Object stream, Converter