diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/CassandraRepositoryConfigurationExtension.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/CassandraRepositoryConfigurationExtension.java index f8047adbc..4644acc9e 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/CassandraRepositoryConfigurationExtension.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/CassandraRepositoryConfigurationExtension.java @@ -13,30 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.cassandra.repository.config; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Collections; -import java.util.stream.Collectors; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.cassandra.config.xml.ParsingUtils; -import org.springframework.core.io.ResourceLoader; -import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.cassandra.config.DefaultBeanNames; import org.springframework.data.cassandra.mapping.Table; import org.springframework.data.cassandra.repository.CassandraRepository; import org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; -import org.springframework.data.repository.config.RepositoryConfiguration; import org.springframework.data.repository.config.RepositoryConfigurationExtension; import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; -import org.springframework.data.repository.config.RepositoryConfigurationSource; import org.springframework.data.repository.config.XmlRepositoryConfigurationSource; -import org.springframework.data.repository.util.ReactiveWrappers; -import org.springframework.util.ClassUtils; +import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.util.StringUtils; import org.w3c.dom.Element; @@ -116,49 +109,12 @@ public class CassandraRepositoryConfigurationExtension extends RepositoryConfigu return Collections.singleton(CassandraRepository.class); } - /** - * @inheritDoc + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#useRepositoryConfiguration(org.springframework.data.repository.core.RepositoryMetadata) */ @Override - public Collection> getRepositoryConfigurations( - T configSource, ResourceLoader loader, boolean strictMatchesOnly) { - - Collection> repositoryConfigurations = - super.getRepositoryConfigurations(configSource, loader, strictMatchesOnly); - - return (ReactiveWrappers.isAvailable() ? filter(repositoryConfigurations, loader) : repositoryConfigurations); - } - - /* (non-Javadoc) */ - private Collection> filter( - Collection> repositoryConfigurations, ResourceLoader loader) { - - return repositoryConfigurations.stream().filter( - configuration -> isNonReactiveRepository(configuration, loader)).collect(Collectors.toList()); - } - - /* (non-Javadoc) */ - private boolean isNonReactiveRepository(RepositoryConfiguration repositoryConfiguration, ResourceLoader loader) { - return !RepositoryType.isReactiveRepository(loadRepositoryInterface(repositoryConfiguration, loader)); - } - - /** - * TODO replace with {@link org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#loadRepositoryInterface(RepositoryConfiguration, ResourceLoader)} - * Loads the Repository interface specified in the given {@link RepositoryConfiguration} using - * the given {@link ResourceLoader}. - * - * @param configuration must not be {@literal null}. - * @param loader must not be {@literal null}. - * @return the Repository interface. - * @throws InvalidDataAccessApiUsageException if the Repository interface could not loaded. - */ - private Class loadRepositoryInterface(RepositoryConfiguration configuration, ResourceLoader loader) { - try { - return ClassUtils.forName(configuration.getRepositoryInterface(), loader.getClassLoader()); - } - catch (ClassNotFoundException | LinkageError e) { - throw new InvalidDataAccessApiUsageException(String.format( - "Could not find Repository type [%s]", configuration.getRepositoryInterface()), e); - } + protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) { + return !metadata.isReactiveRepository(); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/ReactiveCassandraRepositoryConfigurationExtension.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/ReactiveCassandraRepositoryConfigurationExtension.java index 2110978d3..6b332b697 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/ReactiveCassandraRepositoryConfigurationExtension.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/ReactiveCassandraRepositoryConfigurationExtension.java @@ -13,27 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.cassandra.repository.config; -import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Collections; -import java.util.stream.Collectors; import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.core.io.ResourceLoader; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.cassandra.mapping.Table; import org.springframework.data.cassandra.repository.ReactiveCassandraRepository; import org.springframework.data.cassandra.repository.support.ReactiveCassandraRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; -import org.springframework.data.repository.config.RepositoryConfiguration; import org.springframework.data.repository.config.RepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; -import org.springframework.data.repository.config.RepositoryConfigurationSource; -import org.springframework.data.repository.config.XmlRepositoryConfigurationSource; -import org.springframework.util.ClassUtils; +import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.util.StringUtils; /** @@ -42,7 +32,7 @@ import org.springframework.util.StringUtils; * @author Mark Paluch * @since 2.0 */ -public class ReactiveCassandraRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { +public class ReactiveCassandraRepositoryConfigurationExtension extends CassandraRepositoryConfigurationExtension { /** * @inheritDoc @@ -52,14 +42,6 @@ public class ReactiveCassandraRepositoryConfigurationExtension extends Repositor return "Reactive Cassandra"; } - /** - * @inheritDoc - */ - @Override - protected String getModulePrefix() { - return "cassandra"; - } - /** * @inheritDoc */ @@ -68,12 +50,6 @@ public class ReactiveCassandraRepositoryConfigurationExtension extends Repositor return ReactiveCassandraRepositoryFactoryBean.class.getName(); } - /** - * @inheritDoc - */ - @Override - public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) {} - /** * @inheritDoc */ @@ -87,14 +63,6 @@ public class ReactiveCassandraRepositoryConfigurationExtension extends Repositor } } - /** - * @inheritDoc - */ - @Override - protected Collection> getIdentifyingAnnotations() { - return Collections.singleton(Table.class); - } - /** * @inheritDoc */ @@ -103,38 +71,11 @@ public class ReactiveCassandraRepositoryConfigurationExtension extends Repositor return Collections.singleton(ReactiveCassandraRepository.class); } - /** - * @inheritDoc + /* + * (non-Javadoc) + * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#useRepositoryConfiguration(org.springframework.data.repository.core.RepositoryMetadata) */ - @Override - public Collection> getRepositoryConfigurations( - T configSource, ResourceLoader loader, boolean strictMatchesOnly) { - - Collection> repositoryConfigurations = - super.getRepositoryConfigurations(configSource, loader, strictMatchesOnly); - - return repositoryConfigurations.stream() - .filter(configuration -> RepositoryType.isReactiveRepository(loadRepositoryInterface(configuration, loader))) - .collect(Collectors.toList()); - } - - /** - * TODO replace with {@link org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#loadRepositoryInterface(RepositoryConfiguration, ResourceLoader)} - * Loads the Repository interface specified in the given {@link RepositoryConfiguration} using - * the given {@link ResourceLoader}. - * - * @param configuration must not be {@literal null}. - * @param loader must not be {@literal null}. - * @return the Repository interface. - * @throws InvalidDataAccessApiUsageException if the Repository interface could not loaded. - */ - private Class loadRepositoryInterface(RepositoryConfiguration configuration, ResourceLoader loader) { - try { - return ClassUtils.forName(configuration.getRepositoryInterface(), loader.getClassLoader()); - } - catch (ClassNotFoundException | LinkageError e) { - throw new InvalidDataAccessApiUsageException(String.format( - "Could not find Repository type [%s]", configuration.getRepositoryInterface()), e); - } + protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) { + return metadata.isReactiveRepository(); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/RepositoryType.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/RepositoryType.java deleted file mode 100644 index b8949178a..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/config/RepositoryType.java +++ /dev/null @@ -1,70 +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.cassandra.repository.config; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.repository.util.ReactiveWrappers; -import org.springframework.util.ReflectionUtils; - -import lombok.experimental.UtilityClass; - -/** - * Utility class to discover whether a repository interface uses reactive wrapper types. - * - * @author Mark Paluch - * @since 2.0 - */ -@UtilityClass -class RepositoryType { - - /** - * Check whether {@code repositoryInterface} uses reactive wrapper types as return type or parameter types in its - * methods. - * - * @param repositoryInterface must not be {@literal null}. - * @return {@literal true} if the {@code repositoryInterface} uses reactive wrapper types. - * @see ReactiveWrappers - * @see ReactiveWrappers#isAvailable() - */ - public static boolean isReactiveRepository(Class repositoryInterface) { - - if (repositoryInterface == null || !ReactiveWrappers.isAvailable()) { - return false; - } - - List reactiveMethods = new ArrayList<>(); - ReflectionUtils.doWithMethods(repositoryInterface, reactiveMethods::add, RepositoryType::usesReactiveWrappers); - return !reactiveMethods.isEmpty(); - } - - private static boolean usesReactiveWrappers(Method method) { - - if (ReactiveWrappers.supports(method.getReturnType())) { - return true; - } - - for (Class parameterType : method.getParameterTypes()) { - if (ReactiveWrappers.supports(parameterType)) { - return true; - } - } - - return false; - } -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java index d6a0b2d73..3ac1f478a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java @@ -13,15 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.cassandra.repository.support; import java.io.Serializable; import java.lang.reflect.Method; -import java.util.Arrays; -import org.reactivestreams.Publisher; -import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.cassandra.core.ReactiveCassandraOperations; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; @@ -34,16 +30,13 @@ import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.core.support.RepositoryFactorySupport; +import org.springframework.data.repository.core.support.ReactiveRepositoryFactorySupport; import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.util.ReactiveWrapperConverters; -import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; /** * Factory to create {@link org.springframework.data.cassandra.repository.ReactiveCassandraRepository} instances. @@ -51,7 +44,7 @@ import org.springframework.util.ClassUtils; * @author Mark Paluch * @since 2.0 */ -public class ReactiveCassandraRepositoryFactory extends RepositoryFactorySupport { +public class ReactiveCassandraRepositoryFactory extends ReactiveRepositoryFactorySupport { private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(); @@ -87,8 +80,7 @@ public class ReactiveCassandraRepositoryFactory extends RepositoryFactorySupport @Override protected Object getTargetRepository(RepositoryInformation information) { - CassandraEntityInformation entityInformation = - getEntityInformation(information.getDomainType()); + CassandraEntityInformation entityInformation = getEntityInformation(information.getDomainType()); return getTargetRepositoryViaReflection(information, entityInformation, operations); } @@ -102,53 +94,6 @@ public class ReactiveCassandraRepositoryFactory extends RepositoryFactorySupport return new CassandraQueryLookupStrategy(operations, evaluationContextProvider, mappingContext); } - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#validate(org.springframework.data.repository.core.RepositoryMetadata) - */ - @Override - protected void validate(RepositoryMetadata repositoryMetadata) { - - if (!ReactiveWrappers.isAvailable()) { - throw new InvalidDataAccessApiUsageException( - String.format("Cannot implement Repository %s without reactive library support.", - repositoryMetadata.getRepositoryInterface().getName())); - } - - Arrays.stream(repositoryMetadata.getRepositoryInterface().getMethods()) - .forEach(ReactiveCassandraRepositoryFactory::validate); - } - - /** - * Reactive Cassandra support requires reactive wrapper support. If return type/parameters are reactive wrapper types, - * then it's required to be able to convert these into Publisher. - * - * @param method the method to validate. - */ - private static void validate(Method method) { - - if (ReactiveWrappers.supports(method.getReturnType()) - && !ClassUtils.isAssignable(Publisher.class, method.getReturnType())) { - - if (!ReactiveWrapperConverters.supports(method.getReturnType())) { - - throw new InvalidDataAccessApiUsageException( - String.format("No reactive type converter found for type %s used in %s, method %s.", - method.getReturnType().getName(), method.getDeclaringClass().getName(), method)); - } - } - - Arrays.stream(method.getParameterTypes()) // - .filter(ReactiveWrappers::supports) // - .filter(parameterType -> !ClassUtils.isAssignable(Publisher.class, parameterType)) // - .filter(parameterType -> !ReactiveWrapperConverters.supports(parameterType)) // - .forEach(parameterType -> { - throw new InvalidDataAccessApiUsageException( - String.format("No reactive type converter found for type %s used in %s, method %s.", - parameterType.getName(), method.getDeclaringClass().getName(), method)); - }); - } - /* * (non-Javadoc) * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class) @@ -159,7 +104,7 @@ public class ReactiveCassandraRepositoryFactory extends RepositoryFactorySupport if (entity == null) { throw new MappingException( - String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName())); + String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName())); } return new MappingCassandraEntityInformation<>((CassandraPersistentEntity) entity, operations.getConverter());