From f92ce6ebe854145415e8503000c1ea304e9640b6 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 21 Apr 2017 14:14:52 +0200 Subject: [PATCH] DATACASS-438 - Adapt to moved CustomConversions to Spring Data Commons. Introduce CassandraCustomConversions extending o.s.d.convert.CustomConversions. Remove o.s.d.cassandra.convert.CustomConversions implementation and utility classes, extend CassandraCustomConversions. Replace references to o.s.d.c.c.CustomConversions with o.s.d.convert.CustomConversions. Adapt tests and MappingCassandraConverter to CassandraCustomConversions. Related ticket: DATACMNS-1035. --- .../java/AbstractCassandraConfiguration.java | 5 +- .../convert/AbstractCassandraConverter.java | 9 +- .../cassandra/convert/CassandraConverter.java | 1 + .../convert/CassandraCustomConversions.java | 61 ++++ .../convert/ConverterRegistration.java | 118 ------- .../cassandra/convert/CustomConversions.java | 308 +----------------- .../convert/MappingCassandraConverter.java | 40 ++- .../mapping/BasicCassandraMappingContext.java | 49 ++- .../BasicCassandraPersistentProperty.java | 3 +- .../mapping/CassandraMappingContext.java | 9 +- .../query/AbstractCassandraQuery.java | 2 +- .../query/CassandraReturnedType.java | 7 +- .../ConverterRegistrationUnitTests.java | 66 ---- .../CustomConversionIntegrationTests.java | 3 +- .../convert/CustomConversionsUnitTests.java | 300 ----------------- ...CassandraConverterUDTIntegrationTests.java | 9 +- ...BasicCassandraMappingContextUnitTests.java | 16 +- ...BasicCassandraMappingContextUnitTests.java | 6 +- .../CreateUserTypeIntegrationTests.java | 2 +- .../ParameterConversionTestSupport.java | 5 +- ...yMethodParameterTypesIntegrationTests.java | 5 +- 21 files changed, 157 insertions(+), 867 deletions(-) create mode 100644 spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraCustomConversions.java delete mode 100644 spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/ConverterRegistration.java delete mode 100755 spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/ConverterRegistrationUnitTests.java delete mode 100755 spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionsUnitTests.java diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java index caeeba729..3c93afd5a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java @@ -28,7 +28,7 @@ import org.springframework.data.cassandra.config.CassandraEntityClassScanner; import org.springframework.data.cassandra.config.CassandraSessionFactoryBean; import org.springframework.data.cassandra.config.SchemaAction; import org.springframework.data.cassandra.convert.CassandraConverter; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.cassandra.convert.CassandraCustomConversions; import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.CassandraAdminOperations; import org.springframework.data.cassandra.core.CassandraAdminTemplate; @@ -36,6 +36,7 @@ import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.SimpleUserTypeResolver; import org.springframework.data.cassandra.mapping.Table; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.mapping.context.MappingContext; /** @@ -126,7 +127,7 @@ public abstract class AbstractCassandraConfiguration extends AbstractClusterConf */ @Bean public CustomConversions customConversions() { - return new CustomConversions(Collections.emptyList()); + return new CassandraCustomConversions(Collections.emptyList()); } /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/AbstractCassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/AbstractCassandraConverter.java index ee4ce4fa0..5c7c95d2a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/AbstractCassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/AbstractCassandraConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors + * Copyright 2013-2017 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. @@ -15,10 +15,13 @@ */ package org.springframework.data.cassandra.convert; +import java.util.Collections; + import org.springframework.beans.factory.InitializingBean; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.EntityInstantiators; /** @@ -34,7 +37,9 @@ import org.springframework.data.convert.EntityInstantiators; public abstract class AbstractCassandraConverter implements CassandraConverter, InitializingBean { protected final ConversionService conversionService; - protected CustomConversions conversions = new CustomConversions(); + + protected CustomConversions conversions = new CassandraCustomConversions(Collections.emptyList()); + protected EntityInstantiators instantiators = new EntityInstantiators(); /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java index 81e1f0b55..7955a04b3 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java @@ -20,6 +20,7 @@ import java.util.Optional; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.EntityConverter; import org.springframework.data.util.TypeInformation; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraCustomConversions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraCustomConversions.java new file mode 100644 index 000000000..a4b19e180 --- /dev/null +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraCustomConversions.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017 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.convert; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder; +import org.springframework.data.mapping.model.SimpleTypeHolder; + +/** + * Value object to capture custom conversion. {@link CassandraCustomConversions} also act as factory for + * {@link SimpleTypeHolder} + * + * @author Mark Paluch + * @since 2.0 + * @see org.springframework.data.convert.CustomConversions + * @see SimpleTypeHolder + */ +public class CassandraCustomConversions extends org.springframework.data.convert.CustomConversions { + + private static final StoreConversions STORE_CONVERSIONS; + + private static final List STORE_CONVERTERS; + + static { + + List converters = new ArrayList<>(); + + converters.addAll(CassandraConverters.getConvertersToRegister()); + converters.addAll(CassandraJodaTimeConverters.getConvertersToRegister()); + converters.addAll(CassandraJsr310Converters.getConvertersToRegister()); + converters.addAll(CassandraThreeTenBackPortConverters.getConvertersToRegister()); + + STORE_CONVERTERS = Collections.unmodifiableList(converters); + STORE_CONVERSIONS = StoreConversions.of(new CassandraSimpleTypeHolder(), STORE_CONVERTERS); + } + + /** + * Create a new {@link CassandraCustomConversions} instance registering the given converters. + * + * @param converters must not be {@literal null}. + */ + public CassandraCustomConversions(List converters) { + super(STORE_CONVERSIONS, converters); + } +} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/ConverterRegistration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/ConverterRegistration.java deleted file mode 100644 index 7566bca4e..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/ConverterRegistration.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2016-2017 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.convert; - -import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair; -import org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder; -import org.springframework.util.Assert; - -/** - * Conversion registration information. - * - * @author Mark Paluch - * @since 1.5 - */ -class ConverterRegistration { - - private final ConvertiblePair convertiblePair; - - private final boolean reading; - - private final boolean writing; - - /** - * Create a new {@link ConverterRegistration}. - * - * @param convertiblePair must not be {@literal null}. - * @param isReading whether to force to consider the converter for reading. - * @param isWriting whether to force to consider the converter for reading. - */ - public ConverterRegistration(ConvertiblePair convertiblePair, boolean isReading, boolean isWriting) { - - Assert.notNull(convertiblePair, "ConvertiblePair must not be null"); - - this.convertiblePair = convertiblePair; - this.reading = isReading; - this.writing = isWriting; - } - - /** - * Create a new {@link ConverterRegistration} from the given source and target type and read/write flags. - * - * @param source the source type to be converted from, must not be {@literal null}. - * @param target the target type to be converted to, must not be {@literal null}. - * @param isReading whether to force to consider the converter for reading. - * @param isWriting whether to force to consider the converter for writing. - */ - public ConverterRegistration(Class source, Class target, boolean isReading, boolean isWriting) { - this(new ConvertiblePair(source, target), isReading, isWriting); - } - - /** - * Returns whether the converter shall be used for writing. - * - * @return - */ - public boolean isWriting() { - return writing || (!reading && isSimpleTargetType()); - } - - /** - * Returns whether the converter shall be used for reading. - * - * @return - */ - public boolean isReading() { - return reading || (!writing && isSimpleSourceType()); - } - - /** - * Returns the actual conversion pair. - * - * @return - */ - public ConvertiblePair getConvertiblePair() { - return convertiblePair; - } - - /** - * Returns whether the source type is a Cassandra simple one. - * - * @return - */ - public boolean isSimpleSourceType() { - return isCassandraBasicType(convertiblePair.getSourceType()); - } - - /** - * Returns whether the target type is a Cassandra simple one. - * - * @return - */ - public boolean isSimpleTargetType() { - return isCassandraBasicType(convertiblePair.getTargetType()); - } - - /** - * Returns whether the given type is a type that Cassandra can handle basically. - * - * @param type - * @return - */ - private static boolean isCassandraBasicType(Class type) { - return CassandraSimpleTypeHolder.HOLDER.isSimpleType(type); - } -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java index 1bdda18dd..667cb4439 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java @@ -15,32 +15,9 @@ */ package org.springframework.data.cassandra.convert; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.GenericTypeResolver; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.converter.ConverterFactory; -import org.springframework.core.convert.converter.GenericConverter; -import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair; -import org.springframework.core.convert.support.GenericConversionService; -import org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder; -import org.springframework.data.convert.JodaTimeConverters; -import org.springframework.data.convert.Jsr310Converters; -import org.springframework.data.convert.ReadingConverter; -import org.springframework.data.convert.ThreeTenBackPortConverters; -import org.springframework.data.convert.WritingConverter; import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; /** * Value object to capture custom conversion. That is essentially a {@link List} of converters and some additional logic @@ -50,293 +27,18 @@ import org.springframework.util.Assert; * * @author Mark Paluch * @since 1.5 + * @deprecated since 2.0, use {@link CassandraCustomConversions}. */ -public class CustomConversions { - - private static final Logger LOG = LoggerFactory.getLogger(CustomConversions.class); - private static final String READ_CONVERTER_NOT_SIMPLE = "Registering converter from %s to %s as reading converter although it doesn't convert from a Cassandra supported type! You might wanna check you annotation setup at the converter implementation."; - private static final String WRITE_CONVERTER_NOT_SIMPLE = "Registering converter from %s to %s as writing converter although it doesn't convert to a Cassandra supported type! You might wanna check you annotation setup at the converter implementation."; - - private final Set readingPairs; - private final Set writingPairs; - private final CassandraSimpleTypeHolder simpleTypeHolder; - - private final List converters; - - private final Map>> customReadTargetTypes; - private final Map>> customWriteTargetTypes; - private final Map, Optional>> rawWriteTargetTypes; - - /** - * Creates an empty {@link CustomConversions} object. - */ - CustomConversions() { - this(new ArrayList<>()); - } +@Deprecated +public class CustomConversions extends CassandraCustomConversions { /** * Create a new {@link CustomConversions} instance registering the given converters. * * @param converters */ - public CustomConversions(List converters) { + private CustomConversions(List converters) { + super(converters); - Assert.notNull(converters, "List of converters must not be null"); - - this.readingPairs = new LinkedHashSet<>(); - this.writingPairs = new LinkedHashSet<>(); - this.customReadTargetTypes = new ConcurrentHashMap<>(); - this.customWriteTargetTypes = new ConcurrentHashMap<>(); - this.rawWriteTargetTypes = new ConcurrentHashMap<>(); - - List toRegister = new ArrayList<>(); - - // Add user provided converters to make sure they can override the defaults - toRegister.addAll(converters); - toRegister.addAll(CassandraConverters.getConvertersToRegister()); - - toRegister.addAll(CassandraJodaTimeConverters.getConvertersToRegister()); - toRegister.addAll(CassandraJsr310Converters.getConvertersToRegister()); - toRegister.addAll(CassandraThreeTenBackPortConverters.getConvertersToRegister()); - - toRegister.addAll(JodaTimeConverters.getConvertersToRegister()); - toRegister.addAll(Jsr310Converters.getConvertersToRegister()); - toRegister.addAll(ThreeTenBackPortConverters.getConvertersToRegister()); - - toRegister.forEach(this::registerConversion); - - Collections.reverse(toRegister); - - this.converters = Collections.unmodifiableList(toRegister); - this.simpleTypeHolder = new CassandraSimpleTypeHolder(); - } - - /** - * Returns the underlying {@link SimpleTypeHolder}. - * - * @return - */ - public SimpleTypeHolder getSimpleTypeHolder() { - return simpleTypeHolder; - } - - /** - * Returns whether the given type is considered to be simple. That means it's either a general simple type or we have - * a writing {@link Converter} registered for a particular type. - * - * @see SimpleTypeHolder#isSimpleType(Class) - * @param type - * @return - */ - public boolean isSimpleType(Class type) { - return simpleTypeHolder.isSimpleType(type); - } - - /** - * Populates the given {@link GenericConversionService} with the registered converters. - * - * @param conversionService - */ - public void registerConvertersIn(GenericConversionService conversionService) { - - for (Object converter : converters) { - - boolean added = false; - - if (converter instanceof Converter) { - conversionService.addConverter((Converter) converter); - added = true; - } - - if (converter instanceof ConverterFactory) { - conversionService.addConverterFactory((ConverterFactory) converter); - added = true; - } - - if (converter instanceof GenericConverter) { - conversionService.addConverter((GenericConverter) converter); - added = true; - } - - if (!added) { - throw new IllegalArgumentException( - "Given set contains element that is neither Converter nor ConverterFactory!"); - } - } - } - - /** - * Registers a conversion for the given converter. Inspects either generics of {@link Converter} and - * {@link ConverterFactory} or the {@link ConvertiblePair}s returned by a {@link GenericConverter}. - * - * @param converter - */ - private void registerConversion(Object converter) { - - Class type = converter.getClass(); - - boolean isReading = type.isAnnotationPresent(ReadingConverter.class); - boolean isWriting = type.isAnnotationPresent(WritingConverter.class); - - if (converter instanceof GenericConverter) { - GenericConverter genericConverter = (GenericConverter) converter; - - for (ConvertiblePair pair : genericConverter.getConvertibleTypes()) { - register(new ConverterRegistration(pair, isReading, isWriting)); - } - } else if (converter instanceof ConverterFactory) { - Class[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), ConverterFactory.class); - register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting)); - } else if (converter instanceof Converter) { - Class[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class); - register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting)); - } else { - throw new IllegalArgumentException("Unsupported Converter type!"); - } - } - - /** - * Registers the given {@link ConvertiblePair} as reading or writing pair depending on the type sides being basic - * Cassandra types. - * - * @param converterRegistration - */ - private void register(ConverterRegistration converterRegistration) { - - ConvertiblePair pair = converterRegistration.getConvertiblePair(); - - if (converterRegistration.isReading()) { - - readingPairs.add(pair); - - if (LOG.isWarnEnabled() && !converterRegistration.isSimpleSourceType()) { - LOG.warn(String.format(READ_CONVERTER_NOT_SIMPLE, pair.getSourceType(), pair.getTargetType())); - } - } - - if (converterRegistration.isWriting()) { - - writingPairs.add(pair); - - if (LOG.isWarnEnabled() && !converterRegistration.isSimpleTargetType()) { - LOG.warn(String.format(WRITE_CONVERTER_NOT_SIMPLE, pair.getSourceType(), pair.getTargetType())); - } - } - } - - /** - * Returns the target type to convert to in case we have a custom conversion registered to convert the given source - * type into a Cassandra native one. - * - * @param sourceType must not be {@literal null} - * @return - */ - public Class getCustomWriteTarget(final Class sourceType) { - - return rawWriteTargetTypes.computeIfAbsent(sourceType, it -> getCustomTarget(sourceType, null, writingPairs)) - .orElse(null); - } - - /** - * Returns the target type we can inject of the given source type to. The returned type might be a subclass of the - * given expected type though. If {@code expectedTargetType} is {@literal null} we will simply return the first target - * type matching or {@literal null} if no conversion can be found. - * - * @param sourceType must not be {@literal null} - * @param requestedTargetType - * @return - */ - public Class getCustomWriteTarget(final Class sourceType, final Class requestedTargetType) { - - if (requestedTargetType == null) { - return getCustomWriteTarget(sourceType); - } - - return customWriteTargetTypes.computeIfAbsent(new ConvertiblePair(sourceType, requestedTargetType), - it -> getCustomTarget(sourceType, requestedTargetType, writingPairs)).orElse(null); - } - - /** - * Returns whether we have a custom conversion registered into a Cassandra native type. The returned type might be a - * subclass of the given expected type though. - * - * @param sourceType must not be {@literal null} - * @return - */ - public boolean hasCustomWriteTarget(Class sourceType) { - return hasCustomWriteTarget(sourceType, null); - } - - /** - * Returns whether we have a custom conversion registered to an object of the given source type into an object of the - * given Cassandra native target type. - * - * @param sourceType must not be {@literal null}. - * @param requestedTargetType - * @return - */ - public boolean hasCustomWriteTarget(Class sourceType, Class requestedTargetType) { - return getCustomWriteTarget(sourceType, requestedTargetType) != null; - } - - /** - * Returns whether we have a custom conversion registered to the given source into the given target type. - * - * @param sourceType must not be {@literal null} - * @param requestedTargetType must not be {@literal null} - * @return - */ - public boolean hasCustomReadTarget(Class sourceType, Class requestedTargetType) { - return getCustomReadTarget(sourceType, requestedTargetType) != null; - } - - /** - * Returns the actual target type for the given {@code sourceType} and {@code requestedTargetType}. Note that the - * returned {@link Class} could be an assignable type to the given {@code requestedTargetType}. - * - * @param sourceType must not be {@literal null}. - * @param requestedTargetType can be {@literal null}. - * @return - */ - private Class getCustomReadTarget(final Class sourceType, final Class requestedTargetType) { - - if (requestedTargetType == null) { - return null; - } - - return customReadTargetTypes.computeIfAbsent(new ConvertiblePair(sourceType, requestedTargetType), - it -> getCustomTarget(sourceType, requestedTargetType, readingPairs)).orElse(null); - - } - - /** - * Inspects the given {@link ConvertiblePair}s for ones that have a source compatible type as source. Additionally - * checks assignability of the target type if one is given. - * - * @param sourceType must not be {@literal null}. - * @param requestedTargetType can be {@literal null}. - * @param pairs must not be {@literal null}. - * @return - */ - private static Optional> getCustomTarget(Class sourceType, Class requestedTargetType, - Collection pairs) { - - Assert.notNull(sourceType, "Source Class must not be null"); - Assert.notNull(pairs, "Collection of ConvertiblePair must not be null"); - - if (requestedTargetType != null && pairs.contains(new ConvertiblePair(sourceType, requestedTargetType))) { - return Optional.of(requestedTargetType); - } - - for (ConvertiblePair typePair : pairs) { - if (typePair.getSourceType().isAssignableFrom(sourceType)) { - Class targetType = typePair.getTargetType(); - if (requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType)) { - return Optional.of(targetType); - } - } - } - - return Optional.empty(); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java index dd52f406c..22e59b578 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java @@ -605,21 +605,21 @@ public class MappingCassandraConverter extends AbstractCassandraConverter private Class getTargetType(CassandraPersistentProperty property) { - if (getCustomConversions().hasCustomWriteTarget(property.getType())) { - return getCustomConversions().getCustomWriteTarget(property.getType()); - } + return getCustomConversions().getCustomWriteTarget(property.getType()).orElseGet(() -> { + + if (property.findAnnotation(CassandraType.class).isPresent()) { + return getPropertyTargetType(property); + } + + if (property.isCompositePrimaryKey() || getCustomConversions().isSimpleType(property.getType()) + || property.isCollectionLike()) { + + return property.getType(); + } - if (property.findAnnotation(CassandraType.class).isPresent()) { return getPropertyTargetType(property); - } + }); - if (property.isCompositePrimaryKey() || getCustomConversions().isSimpleType(property.getType()) - || property.isCollectionLike()) { - - return property.getType(); - } - - return getPropertyTargetType(property); } private Class getPropertyTargetType(CassandraPersistentProperty property) { @@ -673,8 +673,10 @@ public class MappingCassandraConverter extends AbstractCassandraConverter if (getCustomConversions().hasCustomWriteTarget(value.getClass())) { - return Optional.ofNullable(getConversionService().convert(value, - (Class) getCustomConversions().getCustomWriteTarget(value.getClass()))); + return getCustomConversions().getCustomWriteTarget(value.getClass()).map(it -> { + + return getConversionService().convert(value, (Class) it); + }); } TypeInformation type = (typeInformation != null ? typeInformation : ClassTypeInformation.from(value.getClass())); @@ -726,9 +728,13 @@ public class MappingCassandraConverter extends AbstractCassandraConverter if (optionalValue.isPresent()) { Object value = optionalValue.get(); - if (getCustomConversions().hasCustomWriteTarget(value.getClass(), requestedTargetType)) { - return Optional.ofNullable((O) getConversionService().convert(value, - getCustomConversions().getCustomWriteTarget(value.getClass(), requestedTargetType))); + + if (getCustomConversions().hasCustomWriteTarget(value.getClass())) { + + return getCustomConversions().getCustomWriteTarget(value.getClass()).map(it -> { + + return getConversionService().convert(value, (Class) it); + }); } // Cassandra has no default enum handling - convert it either to string diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java index ec868d40e..460104c83 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java @@ -35,8 +35,9 @@ import org.springframework.cassandra.core.keyspace.CreateUserTypeSpecification; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.cassandra.convert.CassandraCustomConversions; import org.springframework.data.cassandra.mapping.UserTypeUtil.FrozenLiteralDataType; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.context.AbstractMappingContext; @@ -93,7 +94,7 @@ public class BasicCassandraMappingContext */ public BasicCassandraMappingContext() { - setCustomConversions(new CustomConversions(Collections.EMPTY_LIST)); + setCustomConversions(new CassandraCustomConversions(Collections.EMPTY_LIST)); setSimpleTypeHolder(CassandraSimpleTypeHolder.HOLDER); } @@ -304,11 +305,6 @@ public class BasicCassandraMappingContext @Override protected CassandraPersistentProperty createPersistentProperty(Property property, CassandraPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - return createPersistentProperty(property, owner, (CassandraSimpleTypeHolder) simpleTypeHolder); - } - - public CassandraPersistentProperty createPersistentProperty(Property property, CassandraPersistentEntity owner, - CassandraSimpleTypeHolder simpleTypeHolder) { return new BasicCassandraPersistentProperty(property, owner, simpleTypeHolder, userTypeResolver); } @@ -468,29 +464,26 @@ public class BasicCassandraMappingContext } } - if (customConversions.hasCustomWriteTarget(property.getType())) { - return getDataTypeFor(customConversions.getCustomWriteTarget(property.getType())); - } + return customConversions.getCustomWriteTarget(property.getType()) // + .map(CassandraSimpleTypeHolder::getDataTypeFor) // + .orElseGet(() -> customConversions.getCustomWriteTarget(property.getActualType()) // + .map(it -> { - if (customConversions.hasCustomWriteTarget(property.getActualType())) { + if (property.isCollectionLike()) { - Class targetType = customConversions.getCustomWriteTarget(property.getActualType()); + if (List.class.isAssignableFrom(property.getType())) { + return DataType.list(getDataTypeFor(it)); + } - if (property.isCollectionLike()) { + if (Set.class.isAssignableFrom(property.getType())) { + return DataType.set(getDataTypeFor(it)); + } + } - if (List.class.isAssignableFrom(property.getType())) { - return DataType.list(getDataTypeFor(targetType)); - } + return getDataTypeFor(it); + }).orElseGet(property::getDataType) - if (Set.class.isAssignableFrom(property.getType())) { - return DataType.set(getDataTypeFor(targetType)); - } - } - - return getDataTypeFor(targetType); - } - - return property.getDataType(); + ); } private DataType getUserDataType(CassandraPersistentProperty property, DataTypeProvider dataTypeProvider, @@ -521,8 +514,10 @@ public class BasicCassandraMappingContext */ @Override public DataType getDataType(Class type) { - return (customConversions.hasCustomWriteTarget(type) ? getDataTypeFor(customConversions.getCustomWriteTarget(type)) - : getDataTypeFor(type)); + + return customConversions.getCustomWriteTarget(type) // + .map(CassandraSimpleTypeHolder::getDataTypeFor) // + .orElseGet(() -> getDataTypeFor(type)); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java index f57b56d0f..4d92a2c8d 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java @@ -39,6 +39,7 @@ import org.springframework.data.mapping.Association; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.Property; +import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -105,7 +106,7 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP * @param userTypeResolver resolver for user-defined types. */ public BasicCassandraPersistentProperty(Property property, CassandraPersistentEntity owner, - CassandraSimpleTypeHolder simpleTypeHolder, UserTypeResolver userTypeResolver) { + SimpleTypeHolder simpleTypeHolder, UserTypeResolver userTypeResolver) { super(property, owner, simpleTypeHolder); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java index 24605077d..af47ae9ff 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraMappingContext.java @@ -19,7 +19,6 @@ import java.util.Collection; import org.springframework.cassandra.core.keyspace.CreateTableSpecification; import org.springframework.cassandra.core.keyspace.CreateUserTypeSpecification; -import org.springframework.data.cassandra.convert.CustomConversions; import org.springframework.data.mapping.context.MappingContext; import com.datastax.driver.core.DataType; @@ -137,11 +136,11 @@ public interface CassandraMappingContext /** * Retrieve the data type of the property. Cassandra {@link DataType types} are determined using simple types and - * configured {@link CustomConversions}. + * configured {@link org.springframework.data.convert.CustomConversions}. * * @param property must not be {@literal null}. * @return the Cassandra {@link DataType type}. - * @see CustomConversions + * @see org.springframework.data.convert.CustomConversions * @see CassandraSimpleTypeHolder * @since 1.5 */ @@ -149,11 +148,11 @@ public interface CassandraMappingContext /** * Retrieve the data type based on the given {@code type}. Cassandra {@link DataType types} are determined using - * simple types and configured {@link CustomConversions}. + * simple types and configured {@link org.springframework.data.convert.CustomConversions}. * * @param type must not be {@literal null}. * @return the Cassandra {@link DataType type}. - * @see CustomConversions + * @see org.springframework.data.convert.CustomConversions * @see CassandraSimpleTypeHolder * @since 1.5 */ diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java index 0cbf29322..765be3b85 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java @@ -31,7 +31,6 @@ import org.slf4j.LoggerFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.convert.CassandraConverter; -import org.springframework.data.cassandra.convert.CustomConversions; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.CollectionExecution; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ResultProcessingConverter; @@ -39,6 +38,7 @@ import org.springframework.data.cassandra.repository.query.CassandraQueryExecuti import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ResultSetQuery; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.SingleEntityExecution; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.StreamExecution; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.EntityInstantiators; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.RepositoryQuery; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraReturnedType.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraReturnedType.java index 2b21eb1f6..4662283db 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraReturnedType.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraReturnedType.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 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. @@ -17,18 +17,19 @@ package org.springframework.data.cassandra.repository.query; import java.util.Map; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.repository.query.ReturnedType; import org.springframework.util.ClassUtils; /** * Represents a {@link ReturnedType} in the context of Spring Data Cassandra. - * + * * @author Mark Paluch */ class CassandraReturnedType { private final ReturnedType returnedType; + private final CustomConversions customConversions; CassandraReturnedType(ReturnedType returnedType, CustomConversions customConversions) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/ConverterRegistrationUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/ConverterRegistrationUnitTests.java deleted file mode 100755 index 62bcb51e0..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/ConverterRegistrationUnitTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016-2017 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.convert; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.Test; -import org.springframework.data.cassandra.domain.Person; - -/** - * Unit tests for {@link ConverterRegistration}. - * - * @author Mark Paluch - */ -public class ConverterRegistrationUnitTests { - - @Test // DATACASS-280 - public void considersNotExplicitlyReadingDependingOnTypes() { - - ConverterRegistration context = new ConverterRegistration(Person.class, String.class, false, false); - assertThat(context.isWriting()).isTrue(); - assertThat(context.isReading()).isFalse(); - - context = new ConverterRegistration(String.class, Person.class, false, false); - assertThat(context.isWriting()).isFalse(); - assertThat(context.isReading()).isTrue(); - - context = new ConverterRegistration(String.class, Class.class, false, false); - assertThat(context.isWriting()).isTrue(); - assertThat(context.isReading()).isTrue(); - } - - @Test // DATACASS-280 - public void forcesReadWriteOnlyIfAnnotated() { - - ConverterRegistration context = new ConverterRegistration(String.class, Class.class, false, true); - assertThat(context.isWriting()).isTrue(); - assertThat(context.isReading()).isFalse(); - - context = new ConverterRegistration(String.class, Class.class, true, false); - assertThat(context.isWriting()).isFalse(); - assertThat(context.isReading()).isTrue(); - } - - @Test // DATACASS-280 - public void considersConverterForReadAndWriteIfBothAnnotated() { - - ConverterRegistration context = new ConverterRegistration(String.class, Class.class, true, true); - assertThat(context.isWriting()).isTrue(); - assertThat(context.isReading()).isTrue(); - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java index 1cf453653..76f8901d6 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java @@ -37,6 +37,7 @@ import org.springframework.data.cassandra.core.CassandraTemplate; import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; import org.springframework.data.cassandra.mapping.Table; import org.springframework.data.cassandra.test.integration.support.SchemaTestUtils; +import org.springframework.data.convert.CustomConversions; import org.springframework.util.StringUtils; import com.datastax.driver.core.Row; @@ -59,7 +60,7 @@ public class CustomConversionIntegrationTests extends AbstractKeyspaceCreatingIn List> converters = new ArrayList<>(); converters.add(new PersonReadConverter()); converters.add(new PersonWriteConverter()); - CustomConversions customConversions = new CustomConversions(converters); + CustomConversions customConversions = new CassandraCustomConversions(converters); BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); mappingContext.setCustomConversions(customConversions); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionsUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionsUnitTests.java deleted file mode 100755 index e66ccdfe1..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionsUnitTests.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2016-2017 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.convert; - -import static org.assertj.core.api.Assertions.*; - -import java.net.InetAddress; -import java.text.DateFormat; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.Locale; -import java.util.UUID; - -import org.joda.time.DateTime; -import org.junit.Test; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.converter.ConverterFactory; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.core.convert.support.GenericConversionService; -import org.springframework.data.convert.WritingConverter; - -import com.datastax.driver.core.Row; - -/** - * Unit tests for {@link CustomConversions}. - * - * @soundtrack Atc - Why Oh Why (Extended Version) - * @author Mark Paluch - */ -public class CustomConversionsUnitTests { - - @Test // DATACASS-280 - public void findsBasicReadAndWriteConversions() { - - CustomConversions conversions = new CustomConversions( - Arrays.asList(FormatToStringConverter.INSTANCE, StringToFormatConverter.INSTANCE)); - - assertThat(conversions.getCustomWriteTarget(Format.class, null)).isAssignableFrom(String.class); - assertThat(conversions.getCustomWriteTarget(String.class, null)).isNull(); - - assertThat(conversions.hasCustomReadTarget(String.class, Format.class)).isTrue(); - assertThat(conversions.hasCustomReadTarget(String.class, Locale.class)).isFalse(); - } - - @Test // DATACASS-280 - public void considersSubtypesCorrectly() { - - CustomConversions conversions = new CustomConversions( - Arrays.asList(NumberToStringConverter.INSTANCE, StringToNumberConverter.INSTANCE)); - - assertThat(conversions.getCustomWriteTarget(Long.class, null)).isAssignableFrom(String.class); - assertThat(conversions.hasCustomReadTarget(String.class, Long.class)).isTrue(); - } - - @Test // DATACASS-280 - public void considersTypesWeRegisteredConvertersForAsSimple() { - - CustomConversions conversions = new CustomConversions(Collections.singletonList(FormatToStringConverter.INSTANCE)); - assertThat(conversions.isSimpleType(UUID.class)).isTrue(); - } - - @Test // DATACASS-280 - public void populatesConversionServiceCorrectly() { - - GenericConversionService conversionService = new DefaultConversionService(); - - CustomConversions conversions = new CustomConversions(Collections.singletonList(StringToFormatConverter.INSTANCE)); - conversions.registerConvertersIn(conversionService); - - assertThat(conversionService.canConvert(String.class, Format.class)).isTrue(); - } - - @Test // DATACASS-280 - public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() { - - CustomConversions conversions = new CustomConversions(Collections.singletonList(StringToFormatConverter.INSTANCE)); - assertThat(conversions.isSimpleType(Format.class)).isFalse(); - } - - @Test // DATACASS-280 - public void discoversConvertersForSubtypesOfCassandraTypes() { - - CustomConversions conversions = new CustomConversions(Collections.singletonList(StringToIntegerConverter.INSTANCE)); - assertThat(conversions.hasCustomReadTarget(String.class, Integer.class)).isTrue(); - assertThat(conversions.hasCustomWriteTarget(String.class, Integer.class)).isTrue(); - } - - @Test // DATACASS-280 - public void considersUUIDASimpleType() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.isSimpleType(UUID.class)).isTrue(); - } - - @Test // DATACASS-280 - public void considersInetAddressASimpleType() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.isSimpleType(InetAddress.class)).isTrue(); - } - - @Test // DATACASS-280 - public void considersRowASimpleType() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.isSimpleType(Row.class)).isTrue(); - } - - @Test // DATACASS-280 - @SuppressWarnings("rawtypes") - public void favorsCustomConverterForIndeterminedTargetType() { - - CustomConversions conversions = new CustomConversions( - Collections.singletonList(DateTimeToStringConverter.INSTANCE)); - assertThat(conversions.getCustomWriteTarget(DateTime.class, null)).isEqualTo((Class) String.class); - } - - @Test // DATACASS-280 - public void customConverterOverridesDefault() { - - CustomConversions conversions = new CustomConversions(Collections.singletonList(CustomDateTimeConverter.INSTANCE)); - GenericConversionService conversionService = new DefaultConversionService(); - conversions.registerConvertersIn(conversionService); - - assertThat(conversionService.convert(new DateTime(), Date.class)).isEqualTo(new Date(0)); - } - - @Test // DATACASS-280 - public void shouldSelectPropertCustomWriteTargetForCglibProxiedType() { - - CustomConversions conversions = new CustomConversions(Collections.singletonList(FormatToStringConverter.INSTANCE)); - assertThat(conversions.getCustomWriteTarget(createProxyTypeFor(Format.class))).isAssignableFrom(String.class); - } - - @Test // DATACASS-280 - public void shouldSelectPropertyCustomReadTargetForCglibProxiedType() { - - CustomConversions conversions = new CustomConversions( - Collections.singletonList(CustomObjectToStringConverter.INSTANCE)); - assertThat(conversions.hasCustomReadTarget(createProxyTypeFor(Object.class), String.class)).isTrue(); - } - - @Test // DATACASS-280 - public void registersConverterFactoryCorrectly() { - - CustomConversions customConversions = new CustomConversions( - Collections.singletonList(new FormatConverterFactory())); - - assertThat(customConversions.getCustomWriteTarget(String.class, SimpleDateFormat.class)).isNotNull(); - } - - @Test // DATACASS-296 - public void registersConvertersForJsr310() { - - CustomConversions customConversions = new CustomConversions(); - - assertThat(customConversions.hasCustomWriteTarget(java.time.LocalDateTime.class)).isTrue(); - } - - @Test // DATACASS-296 - public void registersConvertersForThreeTenBackPort() { - - CustomConversions customConversions = new CustomConversions(); - - assertThat(customConversions.hasCustomWriteTarget(org.threeten.bp.LocalDateTime.class)).isTrue(); - } - - @Test // DATACASS-296 - public void registersConvertersForJoda() { - - CustomConversions customConversions = new CustomConversions(); - - assertThat(customConversions.hasCustomWriteTarget(org.joda.time.LocalDate.class)).isTrue(); - } - - private static Class createProxyTypeFor(Class type) { - - ProxyFactory factory = new ProxyFactory(); - factory.setProxyTargetClass(true); - factory.setTargetClass(type); - - return factory.getProxy().getClass(); - } - - enum FormatToStringConverter implements Converter { - INSTANCE; - - public String convert(Format source) { - return source.toString(); - } - } - - enum StringToFormatConverter implements Converter { - INSTANCE; - public Format convert(String source) { - return DateFormat.getInstance(); - } - } - - enum NumberToStringConverter implements Converter { - INSTANCE; - public String convert(Number source) { - return source.toString(); - } - } - - enum StringToNumberConverter implements Converter { - INSTANCE; - public Number convert(String source) { - return 0L; - } - } - - enum StringToIntegerConverter implements Converter { - INSTANCE; - public Integer convert(String source) { - return 0; - } - } - - enum DateTimeToStringConverter implements Converter { - INSTANCE; - - @Override - public String convert(DateTime source) { - return ""; - } - } - - enum CustomDateTimeConverter implements Converter { - - INSTANCE; - - @Override - public Date convert(DateTime source) { - return new Date(0); - } - } - - enum CustomObjectToStringConverter implements Converter { - - INSTANCE; - - @Override - public String convert(Object source) { - return source != null ? source.toString() : null; - } - - } - - @WritingConverter - static class FormatConverterFactory implements ConverterFactory { - - @Override - public Converter getConverter(Class targetType) { - return new StringToFormat<>(targetType); - } - - private static final class StringToFormat implements Converter { - - private final Class targetType; - - public StringToFormat(Class targetType) { - this.targetType = targetType; - } - - @Override - public T convert(String source) { - - if (source.length() == 0) { - return null; - } - - try { - return targetType.newInstance(); - } catch (Exception e) { - throw new IllegalArgumentException(e.getMessage(), e); - } - } - } - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java index c31c8b65f..928fda7ea 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java @@ -44,6 +44,7 @@ import org.springframework.data.cassandra.mapping.UserDefinedType; import org.springframework.data.cassandra.mapping.UserTypeResolver; import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; import org.springframework.data.cassandra.test.integration.support.IntegrationTestConfig; +import org.springframework.data.convert.CustomConversions; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -83,7 +84,7 @@ public class MappingCassandraConverterUDTIntegrationTests extends AbstractSpring @Override public CustomConversions customConversions() { - return new CustomConversions(Arrays.asList(new UDTToCurrencyConverter(), + return new CassandraCustomConversions(Arrays.asList(new UDTToCurrencyConverter(), new CurrencyToUDTConverter(new SimpleUserTypeResolver(cluster().getObject(), getKeyspaceName())))); } } @@ -301,8 +302,7 @@ public class MappingCassandraConverterUDTIntegrationTests extends AbstractSpring Insert insert = QueryBuilder.insertInto("bank"); converter.write(bank, insert); - assertThat(insert.toString()) - .isEqualTo("INSERT INTO bank (currency) VALUES ({currency:'EUR'});"); + assertThat(insert.toString()).isEqualTo("INSERT INTO bank (currency) VALUES ({currency:'EUR'});"); } @Test // DATACASS-172 @@ -360,8 +360,7 @@ public class MappingCassandraConverterUDTIntegrationTests extends AbstractSpring Insert insert = QueryBuilder.insertInto("bank"); converter.write(bank, insert); - assertThat(insert.toString()) - .isEqualTo("INSERT INTO bank (othercurrencies) VALUES ([{currency:'EUR'}]);"); + assertThat(insert.toString()).isEqualTo("INSERT INTO bank (othercurrencies) VALUES ([{currency:'EUR'}]);"); } @Test // DATACASS-172 diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java index 6a0b9bf68..af21dc638 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java @@ -35,7 +35,7 @@ import org.springframework.cassandra.core.keyspace.CreateTableSpecification; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.cassandra.convert.CassandraCustomConversions; import org.springframework.data.convert.WritingConverter; import org.springframework.data.util.ClassTypeInformation; @@ -305,15 +305,15 @@ public class BasicCassandraMappingContextUnitTests { @Test // DATACASS-296 public void shouldCreatePersistentEntityIfNoConversionRegistered() { - mappingContext.setCustomConversions(new CustomConversions(Collections.EMPTY_LIST)); + mappingContext.setCustomConversions(new CassandraCustomConversions(Collections.EMPTY_LIST)); assertThat(mappingContext.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class))).isTrue(); } @Test // DATACASS-296 public void shouldNotCreateEntitiesForCustomConvertedTypes() { - mappingContext - .setCustomConversions(new CustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE))); + mappingContext.setCustomConversions( + new CassandraCustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE))); assertThat(mappingContext.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class))).isFalse(); } @@ -321,8 +321,8 @@ public class BasicCassandraMappingContextUnitTests { @Test // DATACASS-349 public void propertyTypeShouldConsiderRegisteredConverterForPropertyType() { - mappingContext - .setCustomConversions(new CustomConversions(Collections.singletonList(StringMapToStringConverter.INSTANCE))); + mappingContext.setCustomConversions( + new CassandraCustomConversions(Collections.singletonList(StringMapToStringConverter.INSTANCE))); CassandraPersistentEntity persistentEntity = mappingContext .getRequiredPersistentEntity(TypeWithCustomConvertedMap.class); @@ -337,8 +337,8 @@ public class BasicCassandraMappingContextUnitTests { @Test // DATACASS-349 public void propertyTypeShouldConsiderRegisteredConverterForCollectionComponentType() { - mappingContext - .setCustomConversions(new CustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE))); + mappingContext.setCustomConversions( + new CassandraCustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE))); CassandraPersistentEntity persistentEntity = mappingContext .getRequiredPersistentEntity(TypeWithListOfHumans.class); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java index aaecf2796..80aaefb15 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java @@ -36,7 +36,7 @@ import org.springframework.cassandra.core.keyspace.ColumnSpecification; import org.springframework.cassandra.core.keyspace.CreateTableSpecification; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.cassandra.convert.CassandraCustomConversions; import org.springframework.data.cassandra.domain.AllPossibleTypes; import org.springframework.util.StringUtils; @@ -64,7 +64,7 @@ public class CreateTableSpecificationBasicCassandraMappingContextUnitTests { converters.add(new PersonReadConverter()); converters.add(new PersonWriteConverter()); - CustomConversions customConversions = new CustomConversions(converters); + CassandraCustomConversions customConversions = new CassandraCustomConversions(converters); ctx.setCustomConversions(customConversions); } @@ -299,7 +299,7 @@ public class CreateTableSpecificationBasicCassandraMappingContextUnitTests { private CreateTableSpecification getCreateTableSpecificationFor(Class persistentEntityClass) { - CustomConversions customConversions = new CustomConversions(Collections.EMPTY_LIST); + CassandraCustomConversions customConversions = new CassandraCustomConversions(Collections.EMPTY_LIST); ctx.setCustomConversions(customConversions); CassandraPersistentEntity persistentEntity = ctx.getRequiredPersistentEntity(persistentEntityClass); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateUserTypeIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateUserTypeIntegrationTests.java index fea1cde36..cf4c28f47 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateUserTypeIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateUserTypeIntegrationTests.java @@ -31,9 +31,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.convert.CustomConversions; import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; import org.springframework.data.cassandra.test.integration.support.IntegrationTestConfig; +import org.springframework.data.convert.CustomConversions; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/conversion/ParameterConversionTestSupport.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/conversion/ParameterConversionTestSupport.java index bd1ea663b..17c33ce86 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/conversion/ParameterConversionTestSupport.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/conversion/ParameterConversionTestSupport.java @@ -26,7 +26,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.config.CassandraSessionFactoryBean; import org.springframework.data.cassandra.config.SchemaAction; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.cassandra.convert.CassandraCustomConversions; import org.springframework.data.cassandra.core.CassandraAdminOperations; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.mapping.SimpleUserTypeResolver; @@ -34,6 +34,7 @@ import org.springframework.data.cassandra.mapping.UserTypeResolver; import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; import org.springframework.data.cassandra.test.integration.support.IntegrationTestConfig; +import org.springframework.data.convert.CustomConversions; import org.springframework.util.StringUtils; import com.datastax.driver.core.Cluster; @@ -76,7 +77,7 @@ abstract class ParameterConversionTestSupport extends AbstractSpringDataEmbedded @Override public CustomConversions customConversions() { - return new CustomConversions( + return new CassandraCustomConversions( Arrays.asList(AddressReadConverter.INSTANCE, AddressWriteConverter.INSTANCE, PhoneReadConverter.INSTANCE, new PhoneWriteConverter(new SimpleUserTypeResolver(cluster().getObject(), getKeyspaceName())))); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java index 13992389e..14ca160c8 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java @@ -35,7 +35,7 @@ import org.springframework.cassandra.support.exception.CassandraInvalidQueryExce import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.config.SchemaAction; -import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.cassandra.convert.CassandraCustomConversions; import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.domain.AllPossibleTypes; import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; @@ -44,6 +44,7 @@ import org.springframework.data.cassandra.repository.Query; import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; import org.springframework.data.cassandra.test.integration.support.IntegrationTestConfig; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.repository.CrudRepository; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -109,7 +110,7 @@ public class RepositoryQueryMethodParameterTypesIntegrationTests @Test // DATACASS-296 public void shouldFindByAnnotatedDateParameter() { - CustomConversions customConversions = new CustomConversions( + CustomConversions customConversions = new CassandraCustomConversions( Collections.singletonList(new DateToLocalDateConverter())); mappingContext.setCustomConversions(customConversions);