diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java index 06fcef41f..68d53208f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java @@ -53,8 +53,8 @@ import org.springframework.data.annotation.Persistent; import org.springframework.data.config.BeanComponentDefinitionBuilder; import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; -import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator; import org.springframework.data.mongodb.core.mapping.Document; @@ -122,12 +122,15 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { converterBuilder.addPropertyValue("customConversions", conversionsDefinition); } - if(!registry.containsBeanDefinition("indexOperationsProvider")){ + if (!registry.containsBeanDefinition("indexOperationsProvider")) { - BeanDefinitionBuilder indexOperationsProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.data.mongodb.core.DefaultIndexOperationsProvider"); + BeanDefinitionBuilder indexOperationsProviderBuilder = BeanDefinitionBuilder + .genericBeanDefinition("org.springframework.data.mongodb.core.DefaultIndexOperationsProvider"); indexOperationsProviderBuilder.addConstructorArgReference(dbFactoryRef); - indexOperationsProviderBuilder.addConstructorArgValue(BeanDefinitionBuilder.genericBeanDefinition(QueryMapper.class).addConstructorArgReference(id).getBeanDefinition()); - parserContext.registerBeanComponent(new BeanComponentDefinition(indexOperationsProviderBuilder.getBeanDefinition(), "indexOperationsProvider")); + indexOperationsProviderBuilder.addConstructorArgValue(BeanDefinitionBuilder + .genericBeanDefinition(QueryMapper.class).addConstructorArgReference(id).getBeanDefinition()); + parserContext.registerBeanComponent( + new BeanComponentDefinition(indexOperationsProviderBuilder.getBeanDefinition(), "indexOperationsProvider")); } try { @@ -140,15 +143,15 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { indexHelperBuilder.addConstructorArgReference("indexOperationsProvider"); indexHelperBuilder.addDependsOn(ctxRef); - parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(), - INDEX_HELPER_BEAN_NAME)); + parserContext.registerBeanComponent( + new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(), INDEX_HELPER_BEAN_NAME)); } BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext); if (validatingMongoEventListener != null) { - parserContext.registerBeanComponent(new BeanComponentDefinition(validatingMongoEventListener, - VALIDATING_EVENT_LISTENER_BEAN_NAME)); + parserContext.registerBeanComponent( + new BeanComponentDefinition(validatingMongoEventListener, VALIDATING_EVENT_LISTENER_BEAN_NAME)); } parserContext.registerBeanComponent(new BeanComponentDefinition(converterBuilder.getBeanDefinition(), id)); @@ -287,7 +290,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { } } - BeanDefinitionBuilder conversionsBuilder = BeanDefinitionBuilder.rootBeanDefinition(CustomConversions.class); + BeanDefinitionBuilder conversionsBuilder = BeanDefinitionBuilder.rootBeanDefinition(MongoCustomConversions.class); conversionsBuilder.addConstructorArgValue(converterBeans); AbstractBeanDefinition conversionsBean = conversionsBuilder.getBeanDefinition(); @@ -335,8 +338,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { return beanDef; } - parserContext.getReaderContext().error( - "Element must specify 'ref' or contain a bean definition for the converter", element); + parserContext.getReaderContext() + .error("Element must specify 'ref' or contain a bean definition for the converter", element); return null; } @@ -348,8 +351,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { mappingContextStrategyFactoryBuilder.addConstructorArgReference(mappingContextRef); BeanComponentDefinitionBuilder builder = new BeanComponentDefinitionBuilder(element, context); - context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder, - IS_NEW_STRATEGY_FACTORY_BEAN_NAME)); + context.registerBeanComponent( + builder.getComponent(mappingContextStrategyFactoryBuilder, IS_NEW_STRATEGY_FACTORY_BEAN_NAME)); return IS_NEW_STRATEGY_FACTORY_BEAN_NAME; } @@ -379,7 +382,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser { * (non-Javadoc) * @see org.springframework.core.type.filter.TypeFilter#match(org.springframework.core.type.classreading.MetadataReader, org.springframework.core.type.classreading.MetadataReaderFactory) */ - public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { + public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) + throws IOException { for (TypeFilter delegate : delegates) { if (delegate.match(metadataReader, metadataReaderFactory)) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java index 27c8088cb..e46f7697a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.config; import java.util.Arrays; @@ -28,20 +27,14 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen import org.springframework.core.convert.converter.Converter; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.data.annotation.Persistent; -import org.springframework.data.authentication.UserCredentials; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory; import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; import org.springframework.data.mapping.model.FieldNamingStrategy; import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; -import org.springframework.data.mongodb.MongoDbFactory; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.SimpleMongoDbFactory; -import org.springframework.data.mongodb.core.convert.CustomConversions; -import org.springframework.data.mongodb.core.convert.DbRefResolver; -import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; -import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.support.CachingIsNewStrategyFactory; @@ -49,9 +42,6 @@ import org.springframework.data.support.IsNewStrategyFactory; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; -import com.mongodb.Mongo; -import com.mongodb.MongoClient; - /** * Base class for Spring Data MongoDB to be extended for JavaConfiguration usage. * @@ -117,13 +107,13 @@ public abstract class MongoConfigurationSupport { /** * Register custom {@link Converter}s in a {@link CustomConversions} object if required. These * {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and - * {@link #mongoMappingContext()}. Returns an empty {@link CustomConversions} instance by default. + * {@link #mongoMappingContext()}. Returns an empty {@link MongoCustomConversions} instance by default. * * @return must not be {@literal null}. */ @Bean public CustomConversions customConversions() { - return new CustomConversions(Collections.emptyList()); + return new MongoCustomConversions(Collections.emptyList()); } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java index 8416d0fdc..f9f35b520 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-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. @@ -22,6 +22,7 @@ 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; import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToObjectIdConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.ObjectIdToBigIntegerConverter; @@ -34,11 +35,12 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToObj * * @author Jon Brisbin * @author Oliver Gierke + * @author Mark Paluch */ public abstract class AbstractMongoConverter implements MongoConverter, InitializingBean { protected final GenericConversionService conversionService; - protected CustomConversions conversions = new CustomConversions(); + protected CustomConversions conversions = new MongoCustomConversions(); protected EntityInstantiators instantiators = new EntityInstantiators(); /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ConverterRegistration.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ConverterRegistration.java deleted file mode 100644 index 133d778a5..000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ConverterRegistration.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2011-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.mongodb.core.convert; - -import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair; -import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; -import org.springframework.util.Assert; - -/** - * Conversion registration information. - * - * @author Oliver Gierke - * @author Mark Paluch - */ -class ConverterRegistration { - - private final ConvertiblePair convertiblePair; - private final boolean reading; - private final boolean writing; - - /** - * Creates a new {@link ConverterRegistration}. - * - * @param convertiblePair must not be {@literal null}. - * @param isReading whether to force to consider the converter for reading. - * @param isWritingwhether 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; - } - - /** - * Creates 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 == true || (!reading && isSimpleTargetType()); - } - - /** - * Returns whether the converter shall be used for reading. - * - * @return - */ - public boolean isReading() { - return reading == true || (!writing && isSimpleSourceType()); - } - - /** - * Returns the actual conversion pair. - * - * @return - */ - public ConvertiblePair getConvertiblePair() { - return convertiblePair; - } - - /** - * Returns whether the source type is a Mongo simple one. - * - * @return - */ - public boolean isSimpleSourceType() { - return isMongoBasicType(convertiblePair.getSourceType()); - } - - /** - * Returns whether the target type is a Mongo simple one. - * - * @return - */ - public boolean isSimpleTargetType() { - return isMongoBasicType(convertiblePair.getTargetType()); - } - - /** - * Returns whether the given type is a type that Mongo can handle basically. - * - * @param type - * @return - */ - private static boolean isMongoBasicType(Class type) { - return MongoSimpleTypes.HOLDER.isSimpleType(type); - } -} \ No newline at end of file diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java index f29ca67fd..f74ebb45f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java @@ -16,35 +16,9 @@ package org.springframework.data.mongodb.core.convert; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Locale; -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.TypeDescriptor; -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.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.data.mongodb.core.mapping.MongoSimpleTypes; -import org.springframework.util.Assert; /** * Value object to capture custom conversion. That is essentially a {@link List} of converters and some additional logic @@ -52,325 +26,30 @@ import org.springframework.util.Assert; * can be converted into and from. These types will be considered simple ones (which means they neither need deeper * inspection nor nested conversion. Thus the {@link CustomConversions} also act as factory for {@link SimpleTypeHolder} * . - * + * * @author Oliver Gierke * @author Thomas Darimont * @author Christoph Strobl * @author Mark Paluch + * @deprecated since 2.0, use {@link MongoCustomConversions}. */ -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 Mongo 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 Mongo supported type! You might wanna check you annotation setup at the converter implementation."; - - private final Set readingPairs; - private final Set writingPairs; - private final Set> customSimpleTypes; - private final SimpleTypeHolder simpleTypeHolder; - - private final List converters; - - private final Map>> customReadTargetTypes; - private final Map>> customWriteTargetTypes; - private final Map, Optional>> rawWriteTargetTypes; +@Deprecated +public class CustomConversions extends MongoCustomConversions { /** * Creates an empty {@link CustomConversions} object. */ CustomConversions() { - this(new ArrayList()); + this(new ArrayList<>()); } /** * Creates a new {@link CustomConversions} instance registering the given converters. - * + * * @param converters */ public CustomConversions(List converters) { - - Assert.notNull(converters, "List of converters must not be null!"); - - this.readingPairs = new LinkedHashSet<>(); - this.writingPairs = new LinkedHashSet<>(); - this.customSimpleTypes = new HashSet<>(); - 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.add(CustomToStringConverter.INSTANCE); - toRegister.addAll(MongoConverters.getConvertersToRegister()); - toRegister.addAll(JodaTimeConverters.getConvertersToRegister()); - toRegister.addAll(GeoConverters.getConvertersToRegister()); - toRegister.addAll(Jsr310Converters.getConvertersToRegister()); - toRegister.addAll(ThreeTenBackPortConverters.getConvertersToRegister()); - - for (Object c : toRegister) { - registerConversion(c); - } - - Collections.reverse(toRegister); - - this.converters = Collections.unmodifiableList(toRegister); - this.simpleTypeHolder = new SimpleTypeHolder(customSimpleTypes, MongoSimpleTypes.HOLDER); + super(converters); } - /** - * 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 convertes registered. - * - * @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 isWriting = type.isAnnotationPresent(WritingConverter.class); - boolean isReading = type.isAnnotationPresent(ReadingConverter.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 - * Mongo types. - * - * @param pair - */ - 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); - customSimpleTypes.add(pair.getSourceType()); - - 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 Mongo 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 readTargetWriteLocl an 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 to readTargetWriteLocl into a Mongo 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 readTargetWriteLocl an object of the given source type - * into an object of the given Mongo 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 readTargetReadLock 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(); - } - - @WritingConverter - private enum CustomToStringConverter implements GenericConverter { - - INSTANCE; - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.GenericConverter#getConvertibleTypes() - */ - public Set getConvertibleTypes() { - - ConvertiblePair localeToString = new ConvertiblePair(Locale.class, String.class); - ConvertiblePair booleanToString = new ConvertiblePair(Character.class, String.class); - - return new HashSet(Arrays.asList(localeToString, booleanToString)); - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.GenericConverter#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) - */ - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - return source.toString(); - } - } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index e3d187097..5ba341bdd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -15,23 +15,13 @@ */ package org.springframework.data.mongodb.core.convert; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import org.bson.Document; import org.bson.conversions.Bson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -40,7 +30,6 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.convert.EntityInstantiator; import org.springframework.data.convert.TypeMapper; -import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PreferredConstructor.Parameter; @@ -77,7 +66,7 @@ import com.mongodb.DBRef; /** * {@link MongoConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to * {@link Document}. - * + * * @author Oliver Gierke * @author Jon Brisbin * @author Patrik Wasik @@ -105,7 +94,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Creates a new {@link MappingMongoConverter} given the new {@link DbRefResolver} and {@link MappingContext}. - * + * * @param dbRefResolver must not be {@literal null}. * @param mappingContext must not be {@literal null}. */ @@ -127,7 +116,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Creates a new {@link MappingMongoConverter} given the new {@link MongoDbFactory} and {@link MappingContext}. - * + * * @deprecated use the constructor taking a {@link DbRefResolver} instead. * @param mongoDbFactory must not be {@literal null}. * @param mappingContext must not be {@literal null}. @@ -143,7 +132,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * converter and how to lookup type information from {@link Document}s when reading them. Uses a * {@link DefaultMongoTypeMapper} by default. Setting this to {@literal null} will reset the {@link TypeMapper} to the * default one. - * + * * @param typeMapper the typeMapper to set */ public void setTypeMapper(MongoTypeMapper typeMapper) { @@ -165,7 +154,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * any translation but rather reject a {@link Map} with keys containing dots causing the conversion for the entire * object to fail. If further customization of the translation is needed, have a look at * {@link #potentiallyEscapeMapKey(String)} as well as {@link #potentiallyUnescapeMapKey(String)}. - * + * * @param mapKeyDotReplacement the mapKeyDotReplacement to set */ public void setMapKeyDotReplacement(String mapKeyDotReplacement) { @@ -311,8 +300,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App DBRef dbref = value instanceof DBRef ? (DBRef) value : null; - DbRefProxyHandler handler = new DefaultDbRefProxyHandler(spELContext, mappingContext, - MappingMongoConverter.this); + DbRefProxyHandler handler = new DefaultDbRefProxyHandler(spELContext, mappingContext, MappingMongoConverter.this); DbRefResolverCallback callback = new DefaultDbRefResolverCallback(bson, currentPath, evaluator, MappingMongoConverter.this); @@ -346,7 +334,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Root entry method into write conversion. Adds a type discriminator to the {@link Document}. Shouldn't be called for * nested conversions. - * + * * @see org.springframework.data.mongodb.core.convert.MongoWriter#write(java.lang.Object, com.mongodb.Document) */ public void write(final Object obj, final Bson bson) { @@ -365,7 +353,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App removeFromMap(bson, "_id"); } - boolean handledByCustomConverter = conversions.getCustomWriteTarget(entityType, Document.class) != null; + boolean handledByCustomConverter = conversions.hasCustomWriteTarget(entityType, Document.class); if (!handledByCustomConverter && !(bson instanceof Collection)) { typeMapper.writeType(type, bson); } @@ -373,7 +361,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Internal write conversion method which should be used for nested invocations. - * + * * @param obj * @param bson */ @@ -385,9 +373,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } Class entityType = obj.getClass(); - Class customTarget = conversions.getCustomWriteTarget(entityType, Document.class); + Optional> customTarget = conversions.getCustomWriteTarget(entityType, Document.class); - if (customTarget != null) { + if (customTarget.isPresent()) { Document result = conversionService.convert(obj, Document.class); addAllToMap(bson, result); return; @@ -501,10 +489,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } // Lookup potential custom target type - Class basicTargetType = conversions.getCustomWriteTarget(obj.getClass(), null); + Optional> basicTargetType = conversions.getCustomWriteTarget(obj.getClass()); - if (basicTargetType != null) { - accessor.put(prop, conversionService.convert(obj, basicTargetType)); + if (basicTargetType.isPresent()) { + + accessor.put(prop, conversionService.convert(obj, basicTargetType.get())); return; } @@ -527,7 +516,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * Returns given object as {@link Collection}. Will return the {@link Collection} as is if the source is a * {@link Collection} already, will convert an array into a {@link Collection} or simply create a single element * collection for everything else. - * + * * @param source * @return */ @@ -542,7 +531,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Writes the given {@link Collection} using the given {@link MongoPersistentProperty} information. - * + * * @param collection must not be {@literal null}. * @param property must not be {@literal null}. * @return @@ -570,7 +559,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Writes the given {@link Map} using the given {@link MongoPersistentProperty} information. - * + * * @param map must not {@literal null}. * @param property must not be {@literal null}. * @return @@ -606,7 +595,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Populates the given {@link BasicDBList} with values from the given {@link Collection}. - * + * * @param source the collection to create a {@link BasicDBList} for, must not be {@literal null}. * @param type the {@link TypeInformation} to consider or {@literal null} if unknown. * @param sink the {@link BasicDBList} to write to. @@ -637,7 +626,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Writes the given {@link Map} to the given {@link Document} considering the given {@link TypeInformation}. - * + * * @param obj must not be {@literal null}. * @param bson must not be {@literal null}. * @param propertyType must not be {@literal null}. @@ -676,7 +665,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Prepares the given {@link Map} key to be converted into a {@link String}. Will invoke potentially registered custom * conversions and escape dots from the result as they're not supported as {@link Map} key in MongoDB. - * + * * @param key must not be {@literal null}. * @return */ @@ -691,7 +680,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Potentially replaces dots in the given map key with the configured map key replacement if configured or aborts * conversion if none is configured. - * + * * @see #setMapKeyDotReplacement(String) * @param source * @return @@ -714,7 +703,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Returns a {@link String} representation of the given {@link Map} key - * + * * @param key * @return */ @@ -731,7 +720,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Translates the map key replacements in the given key just read with a dot in case a map key replacement has been * configured. - * + * * @param source * @return */ @@ -761,7 +750,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Writes the given simple value to the given {@link Document}. Will store enum names for enum values. - * + * * @param value * @param bson must not be {@literal null}. * @param key must not be {@literal null}. @@ -778,7 +767,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Checks whether we have a custom conversion registered for the given value into an arbitrary simple Mongo type. * Returns the converted value if so. If not, we perform special enum handling or simply return the value as is. - * + * * @param value * @return */ @@ -788,27 +777,26 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return null; } - Class customTarget = conversions.getCustomWriteTarget(value.getClass(), null); + Optional> customTarget = conversions.getCustomWriteTarget(value.getClass()); - if (customTarget != null) { - return conversionService.convert(value, customTarget); - } else if (ObjectUtils.isArray(value)) { + return customTarget.map(it -> (Object) conversionService.convert(value, it)).orElseGet(() -> { - if (value instanceof byte[]) { - return value; + if (ObjectUtils.isArray(value)) { + + if (value instanceof byte[]) { + return value; + } + return asCollection(value); } - return asCollection(value); - } - else { return Enum.class.isAssignableFrom(value.getClass()) ? ((Enum) value).name() : value; - } + }); } /** * Checks whether we have a custom conversion for the given simple object. Converts the given value if so, applies * {@link Enum} handling or returns the value as is. - * + * * @param value * @param target must not be {@literal null}. * @return @@ -877,7 +865,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Reads the given {@link BasicDBList} into a collection of the given {@link TypeInformation}. - * + * * @param targetType must not be {@literal null}. * @param sourceValue must not be {@literal null}. * @param path must not be {@literal null}. @@ -904,8 +892,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App if (!DBRef.class.equals(rawComponentType) && isCollectionOfDbRefWhereBulkFetchIsPossible(sourceValue)) { - List objects = bulkReadAndConvertDBRefs((List) sourceValue, componentType, path, - rawComponentType); + List objects = bulkReadAndConvertDBRefs((List) sourceValue, componentType, path, rawComponentType); return getPotentiallyConvertedSimpleRead(objects, targetType.getType()); } @@ -940,7 +927,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Reads the given {@link Document} into a {@link Map}. will recursively resolve nested {@link Map}s as well. - * + * * @param type the {@link Map} {@link TypeInformation} to be used to unmarshall this {@link Document}. * @param bson must not be {@literal null} * @param path must not be {@literal null} @@ -1071,9 +1058,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return null; } - Class target = conversions.getCustomWriteTarget(obj.getClass()); - if (target != null) { - return conversionService.convert(obj, target); + Optional> target = conversions.getCustomWriteTarget(obj.getClass()); + if (target.isPresent()) { + return conversionService.convert(obj, target.get()); } if (conversions.isSimpleType(obj.getClass())) { @@ -1111,7 +1098,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App if (obj instanceof Map) { - Map converted = new LinkedHashMap<>(((Map)obj).size(), 1); + Map converted = new LinkedHashMap<>(((Map) obj).size(), 1); Document result = new Document(); for (Map.Entry entry : ((Map) obj).entrySet()) { @@ -1254,7 +1241,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Extension of {@link SpELExpressionParameterValueProvider} to recursively trigger value conversion on the raw * resolved SpEL value. - * + * * @author Oliver Gierke */ private class ConverterAwareSpELExpressionParameterValueProvider @@ -1264,7 +1251,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Creates a new {@link ConverterAwareSpELExpressionParameterValueProvider}. - * + * * @param evaluator must not be {@literal null}. * @param conversionService must not be {@literal null}. * @param delegate must not be {@literal null}. @@ -1383,7 +1370,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Performs the fetch operation for the given {@link DBRef}. - * + * * @param ref * @return */ @@ -1433,7 +1420,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Marker class used to indicate we have a non root document object here that might be used within an update - so we * need to preserve type hints for potential nested elements but need to remove it on top level. - * + * * @author Christoph Strobl * @since 1.8 */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java new file mode 100644 index 000000000..915183e16 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java @@ -0,0 +1,101 @@ +/* + * 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.mongodb.core.convert; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.data.convert.JodaTimeConverters; +import org.springframework.data.convert.WritingConverter; +import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; + +/** + * Value object to capture custom conversion. {@link MongoCustomConversions} also act as factory for + * {@link org.springframework.data.mapping.model.SimpleTypeHolder} + * + * @author Mark Paluch + * @since 2.0 + * @see org.springframework.data.convert.CustomConversions + * @see org.springframework.data.mapping.model.SimpleTypeHolder + * @see MongoSimpleTypes + */ +public class MongoCustomConversions extends org.springframework.data.convert.CustomConversions { + + private static final StoreConversions STORE_CONVERSIONS; + private static final List STORE_CONVERTERS; + + static { + + List converters = new ArrayList<>(); + + converters.add(CustomToStringConverter.INSTANCE); + converters.addAll(MongoConverters.getConvertersToRegister()); + converters.addAll(JodaTimeConverters.getConvertersToRegister()); + converters.addAll(GeoConverters.getConvertersToRegister()); + + STORE_CONVERTERS = Collections.unmodifiableList(converters); + STORE_CONVERSIONS = StoreConversions.of(MongoSimpleTypes.HOLDER, STORE_CONVERTERS); + } + + /** + * Creates an empty {@link MongoCustomConversions} object. + */ + MongoCustomConversions() { + this(Collections.emptyList()); + } + + /** + * Create a new {@link MongoCustomConversions} instance registering the given converters. + * + * @param converters must not be {@literal null}. + */ + public MongoCustomConversions(List converters) { + super(STORE_CONVERSIONS, converters); + } + + @WritingConverter + private enum CustomToStringConverter implements GenericConverter { + + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.GenericConverter#getConvertibleTypes() + */ + public Set getConvertibleTypes() { + + ConvertiblePair localeToString = new ConvertiblePair(Locale.class, String.class); + ConvertiblePair booleanToString = new ConvertiblePair(Character.class, String.class); + + return new HashSet<>(Arrays.asList(localeToString, booleanToString)); + } + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.GenericConverter#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) + */ + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + return source.toString(); + } + } +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java index 275536910..db0b1a5f7 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java @@ -35,8 +35,8 @@ import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.io.ClassPathResource; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; -import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.MongoTypeMapper; import org.springframework.data.mongodb.core.mapping.Account; @@ -45,7 +45,7 @@ import org.springframework.stereotype.Component; /** * Integration tests for {@link MappingMongoConverterParser}. - * + * * @author Oliver Gierke * @author Thomas Darimont * @author Christoph Strobl diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 5f946e6b4..3d208270a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -29,18 +29,7 @@ import lombok.NoArgsConstructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; +import java.util.*; import org.bson.types.ObjectId; import org.hamcrest.collection.IsMapContaining; @@ -61,17 +50,18 @@ import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.Version; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.data.mongodb.MongoDbFactory; -import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.LazyLoadingProxy; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.index.Index; import org.springframework.data.mongodb.core.index.IndexField; @@ -149,7 +139,7 @@ public class MongoTemplateTests { @Autowired public void setMongo(Mongo mongo) throws Exception { - CustomConversions conversions = new CustomConversions( + CustomConversions conversions = new MongoCustomConversions( Arrays.asList(DateToDateTimeConverter.INSTANCE, DateTimeToDateConverter.INSTANCE)); MongoMappingContext mappingContext = new MongoMappingContext(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java index 91302f057..41266089f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java @@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; import static org.springframework.data.mongodb.test.util.IsBsonObject.*; import java.math.BigInteger; @@ -26,7 +27,6 @@ import java.util.List; import java.util.Optional; import java.util.regex.Pattern; -import com.mongodb.MongoClient; import org.bson.Document; import org.bson.conversions.Bson; import org.bson.types.ObjectId; @@ -49,13 +49,14 @@ import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.domain.Sort; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.aggregation.Aggregation; -import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; @@ -70,7 +71,7 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.test.util.ReflectionTestUtils; import com.mongodb.DB; -import com.mongodb.Mongo; +import com.mongodb.MongoClient; import com.mongodb.MongoException; import com.mongodb.ReadPreference; import com.mongodb.client.FindIterable; @@ -188,7 +189,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @Test // DATAMONGO-374 public void convertsUpdateConstraintsUsingConverters() { - CustomConversions conversions = new CustomConversions(Collections.singletonList(MyConverter.INSTANCE)); + CustomConversions conversions = new MongoCustomConversions(Collections.singletonList(MyConverter.INSTANCE)); this.converter.setCustomConversions(conversions); this.converter.afterPropertiesSet(); @@ -341,7 +342,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { public void aggregateShouldHonorReadPreferenceWhenSet() { when(db.runCommand(Mockito.any(org.bson.Document.class), Mockito.any(ReadPreference.class), eq(Document.class))) - .thenReturn(mock(Document.class)); + .thenReturn(mock(Document.class)); template.setReadPreference(ReadPreference.secondary()); template.aggregate(Aggregation.newAggregation(Aggregation.unwind("foo")), "collection-1", Wrapper.class); @@ -365,7 +366,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { public void geoNearShouldHonorReadPreferenceWhenSet() { when(db.runCommand(Mockito.any(org.bson.Document.class), Mockito.any(ReadPreference.class), eq(Document.class))) - .thenReturn(mock(Document.class)); + .thenReturn(mock(Document.class)); template.setReadPreference(ReadPreference.secondary()); NearQuery query = NearQuery.near(new Point(1, 1)); @@ -378,8 +379,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @Test // DATAMONGO-1166 public void geoNearShouldIgnoreReadPreferenceWhenNotSet() { - when(db.runCommand(Mockito.any(Document.class), eq(Document.class))).thenReturn( - mock(Document.class)); + when(db.runCommand(Mockito.any(Document.class), eq(Document.class))).thenReturn(mock(Document.class)); NearQuery query = NearQuery.near(new Point(1, 1)); template.geoNear(query, Wrapper.class); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java index 4bfd2be45..273b435b2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java @@ -20,8 +20,9 @@ import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.mongodb.config.AbstractMongoConfiguration; -import org.springframework.data.mongodb.core.convert.CustomConversions; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import com.mongodb.MongoClient; @@ -47,9 +48,9 @@ public class TestMongoConfiguration extends AbstractMongoConfiguration { @Override public CustomConversions customConversions() { - List> converters = new ArrayList>(); + List> converters = new ArrayList<>(2); converters.add(new org.springframework.data.mongodb.core.PersonReadConverter()); converters.add(new org.springframework.data.mongodb.core.PersonWriteConverter()); - return new CustomConversions(converters); + return new MongoCustomConversions(converters); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java index 6e1193155..24210332b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java @@ -36,21 +36,22 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; -import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.Criteria; /** * Unit tests for {@link TypeBasedAggregationOperationContext}. - * + * * @author Oliver Gierke * @author Thomas Darimont * @author Mark Paluch @@ -362,7 +363,7 @@ public class TypeBasedAggregationOperationContextUnitTests { } public CustomConversions customAgeConversions() { - return new CustomConversions(Arrays.> asList(ageWriteConverter(), ageReadConverter())); + return new MongoCustomConversions(Arrays.asList(ageWriteConverter(), ageReadConverter())); } Converter ageWriteConverter() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ConverterRegistrationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ConverterRegistrationUnitTests.java deleted file mode 100644 index 069540006..000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ConverterRegistrationUnitTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011 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.mongodb.core.convert; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import org.junit.Test; -import org.springframework.data.mongodb.core.mapping.Person; - -/** - * Unit tests for {@link ConverterRegistration}. - * - * @author Oliver Gierke - */ -public class ConverterRegistrationUnitTests { - - @Test - public void considersNotExplicitlyReadingDependingOnTypes() { - - ConverterRegistration context = new ConverterRegistration(Person.class, String.class, false, false); - assertThat(context.isWriting(), is(true)); - assertThat(context.isReading(), is(false)); - - context = new ConverterRegistration(String.class, Person.class, false, false); - assertThat(context.isWriting(), is(false)); - assertThat(context.isReading(), is(true)); - - context = new ConverterRegistration(String.class, Class.class, false, false); - assertThat(context.isWriting(), is(true)); - assertThat(context.isReading(), is(true)); - } - - @Test - public void forcesReadWriteOnlyIfAnnotated() { - - ConverterRegistration context = new ConverterRegistration(String.class, Class.class, false, true); - assertThat(context.isWriting(), is(true)); - assertThat(context.isReading(), is(false)); - - context = new ConverterRegistration(String.class, Class.class, true, false); - assertThat(context.isWriting(), is(false)); - assertThat(context.isReading(), is(true)); - } - - @Test - public void considersConverterForReadAndWriteIfBothAnnotated() { - - ConverterRegistration context = new ConverterRegistration(String.class, Class.class, true, true); - assertThat(context.isWriting(), is(true)); - assertThat(context.isReading(), is(true)); - } -} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java deleted file mode 100644 index 8cbbbca43..000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2011-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.mongodb.core.convert; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import java.net.URL; -import java.text.DateFormat; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Collections; -import java.util.Currency; -import java.util.Date; -import java.util.Locale; -import java.util.UUID; - -import org.bson.types.Binary; -import org.bson.types.ObjectId; -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 org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; -import org.threeten.bp.LocalDateTime; - -import com.mongodb.DBRef; - -/** - * Unit tests for {@link CustomConversions}. - * - * @author Oliver Gierke - * @author Christoph Strobl - */ -public class CustomConversionsUnitTests { - - @Test - public void findsBasicReadAndWriteConversions() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE, - StringToFormatConverter.INSTANCE)); - - assertThat(conversions.getCustomWriteTarget(Format.class, null), is(typeCompatibleWith(String.class))); - assertThat(conversions.getCustomWriteTarget(String.class, null), is(nullValue())); - - assertThat(conversions.hasCustomReadTarget(String.class, Format.class), is(true)); - assertThat(conversions.hasCustomReadTarget(String.class, Locale.class), is(false)); - } - - @Test - public void considersSubtypesCorrectly() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(NumberToStringConverter.INSTANCE, - StringToNumberConverter.INSTANCE)); - - assertThat(conversions.getCustomWriteTarget(Long.class, null), is(typeCompatibleWith(String.class))); - assertThat(conversions.hasCustomReadTarget(String.class, Long.class), is(true)); - } - - @Test - public void considersTypesWeRegisteredConvertersForAsSimple() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE)); - assertThat(conversions.isSimpleType(UUID.class), is(true)); - } - - @Test // DATAMONGO-240 - public void considersObjectIdToBeSimpleType() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.isSimpleType(ObjectId.class), is(true)); - assertThat(conversions.hasCustomWriteTarget(ObjectId.class), is(false)); - - } - - @Test // DATAMONGO-240 - public void considersCustomConverterForSimpleType() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(new Converter() { - public String convert(ObjectId source) { - return source == null ? null : source.toString(); - } - })); - - assertThat(conversions.isSimpleType(ObjectId.class), is(true)); - assertThat(conversions.hasCustomWriteTarget(ObjectId.class), is(true)); - assertThat(conversions.hasCustomReadTarget(ObjectId.class, String.class), is(true)); - assertThat(conversions.hasCustomReadTarget(ObjectId.class, Object.class), is(false)); - } - - @Test - public void considersDBRefsToBeSimpleTypes() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.isSimpleType(DBRef.class), is(true)); - } - - @Test - public void populatesConversionServiceCorrectly() { - - GenericConversionService conversionService = new DefaultConversionService(); - - CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE)); - conversions.registerConvertersIn(conversionService); - - assertThat(conversionService.canConvert(String.class, Format.class), is(true)); - } - - @Test // DATAMONGO-259 - public void doesNotConsiderTypeSimpleIfOnlyReadConverterIsRegistered() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(StringToFormatConverter.INSTANCE)); - assertThat(conversions.isSimpleType(Format.class), is(false)); - } - - @Test // DATAMONGO-298 - public void discoversConvertersForSubtypesOfMongoTypes() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(StringToIntegerConverter.INSTANCE)); - assertThat(conversions.hasCustomReadTarget(String.class, Integer.class), is(true)); - assertThat(conversions.hasCustomWriteTarget(String.class, Integer.class), is(true)); - } - - @Test // DATAMONGO-342 - public void doesNotHaveConverterForStringToBigIntegerByDefault() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.hasCustomWriteTarget(String.class), is(false)); - assertThat(conversions.getCustomWriteTarget(String.class), is(nullValue())); - - conversions = new CustomConversions(Arrays.asList(StringToBigIntegerConverter.INSTANCE)); - assertThat(conversions.hasCustomWriteTarget(String.class), is(false)); - assertThat(conversions.getCustomWriteTarget(String.class), is(nullValue())); - } - - @Test // DATAMONGO-390 - public void considersBinaryASimpleType() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.isSimpleType(Binary.class), is(true)); - } - - @Test // DATAMONGO-462 - public void hasWriteConverterForURL() { - - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.hasCustomWriteTarget(URL.class), is(true)); - } - - @Test // DATAMONGO-462 - public void readTargetForURL() { - CustomConversions conversions = new CustomConversions(); - assertThat(conversions.hasCustomReadTarget(String.class, URL.class), is(true)); - } - - @Test // DATAMONGO-795 - @SuppressWarnings("rawtypes") - public void favorsCustomConverterForIndeterminedTargetType() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(DateTimeToStringConverter.INSTANCE)); - assertThat(conversions.getCustomWriteTarget(DateTime.class, null), is(equalTo((Class) String.class))); - } - - @Test // DATAMONGO-881 - public void customConverterOverridesDefault() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(CustomDateTimeConverter.INSTANCE)); - GenericConversionService conversionService = new DefaultConversionService(); - conversions.registerConvertersIn(conversionService); - - assertThat(conversionService.convert(new DateTime(), Date.class), is(new Date(0))); - } - - @Test // DATAMONGO-1001 - public void shouldSelectPropertCustomWriteTargetForCglibProxiedType() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(FormatToStringConverter.INSTANCE)); - assertThat(conversions.getCustomWriteTarget(createProxyTypeFor(Format.class)), is(typeCompatibleWith(String.class))); - } - - @Test // DATAMONGO-1001 - public void shouldSelectPropertCustomReadTargetForCglibProxiedType() { - - CustomConversions conversions = new CustomConversions(Arrays.asList(CustomObjectToStringConverter.INSTANCE)); - assertThat(conversions.hasCustomReadTarget(createProxyTypeFor(Object.class), String.class), is(true)); - } - - @Test // DATAMONGO-1131 - public void registersConvertersForJsr310() { - - CustomConversions customConversions = new CustomConversions(); - - assertThat(customConversions.hasCustomWriteTarget(java.time.LocalDateTime.class), is(true)); - } - - @Test // DATAMONGO-1131 - public void registersConvertersForThreeTenBackPort() { - - CustomConversions customConversions = new CustomConversions(); - - assertThat(customConversions.hasCustomWriteTarget(LocalDateTime.class), is(true)); - } - - @Test // DATAMONGO-1302 - public void registersConverterFactoryCorrectly() { - - CustomConversions customConversions = new CustomConversions(Collections.singletonList(new FormatConverterFactory())); - - assertThat(customConversions.getCustomWriteTarget(String.class, SimpleDateFormat.class), notNullValue()); - } - - @Test // DATAMONGO-1372 - public void registersConvertersForCurrency() { - - CustomConversions customConversions = new CustomConversions(); - - assertThat(customConversions.hasCustomWriteTarget(Currency.class), is(true)); - assertThat(customConversions.hasCustomReadTarget(String.class, Currency.class), is(true)); - } - - 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-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConvertersUnitTests.java index 998bb2d47..00f4597ba 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConvertersUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConvertersUnitTests.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2011-2016 by the original author(s). + * Copyright 2011-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 + * 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, @@ -30,13 +30,13 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; /** * Test case to verify correct usage of custom {@link Converter} implementations to be used. - * + * * @author Oliver Gierke */ @RunWith(MockitoJUnitRunner.class) @@ -49,8 +49,6 @@ public class CustomConvertersUnitTests { @Mock MongoDbFactory mongoDbFactory; MongoMappingContext context; - MongoPersistentEntity fooEntity; - MongoPersistentEntity barEntity; @Before @SuppressWarnings("unchecked") @@ -59,7 +57,7 @@ public class CustomConvertersUnitTests { when(barToDocumentConverter.convert(any(Bar.class))).thenReturn(new Document()); when(documentToBarConverter.convert(any(Document.class))).thenReturn(new Bar()); - CustomConversions conversions = new CustomConversions( + CustomConversions conversions = new MongoCustomConversions( Arrays.asList(barToDocumentConverter, documentToBarConverter)); context = new MongoMappingContext(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index 02dfe7c9b..3774e9131 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -25,22 +25,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.*; import org.bson.types.ObjectId; import org.hamcrest.Matcher; @@ -63,6 +48,7 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.geo.Box; @@ -93,10 +79,11 @@ import com.mongodb.DBRef; /** * Unit tests for {@link MappingMongoConverter}. - * + * * @author Oliver Gierke * @author Patrik Wasik * @author Christoph Strobl + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class MappingMongoConverterUnitTests { @@ -1145,24 +1132,25 @@ public class MappingMongoConverterUnitTests { entity.mapOfObjects = new HashMap(); entity.mapOfObjects.put("foo", person); - CustomConversions conversions = new CustomConversions(Arrays.asList(new Converter() { + CustomConversions conversions = new MongoCustomConversions( + Arrays.asList(new Converter() { - @Override - public org.bson.Document convert(Person source) { - return new org.bson.Document().append("firstname", source.firstname)// - .append("_class", Person.class.getName()); - } + @Override + public org.bson.Document convert(Person source) { + return new org.bson.Document().append("firstname", source.firstname)// + .append("_class", Person.class.getName()); + } - }, new Converter() { + }, new Converter() { - @Override - public Person convert(org.bson.Document source) { - Person person = new Person(); - person.firstname = source.get("firstname").toString(); - person.lastname = "converter"; - return person; - } - })); + @Override + public Person convert(org.bson.Document source) { + Person person = new Person(); + person.firstname = source.get("firstname").toString(); + person.lastname = "converter"; + return person; + } + })); MongoMappingContext context = new MongoMappingContext(); context.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); @@ -1385,7 +1373,7 @@ public class MappingMongoConverterUnitTests { List points = (List) polygonDoc.get("points"); assertThat(points, hasSize(3)); - assertThat(points, Matchers.hasItems(toDocument(object.polygon.getPoints().get(0)), + assertThat(points, Matchers. hasItems(toDocument(object.polygon.getPoints().get(0)), toDocument(object.polygon.getPoints().get(1)), toDocument(object.polygon.getPoints().get(2)))); } @@ -1704,7 +1692,7 @@ public class MappingMongoConverterUnitTests { TypeWithOptional read = converter.read(TypeWithOptional.class, result); - assertThat(read.string, is(Optional.empty())); + assertThat(read.string, is(Optional. empty())); assertThat(read.localDateTime, is(Optional.of(now))); } @@ -1713,7 +1701,7 @@ public class MappingMongoConverterUnitTests { MappingMongoConverter converter = new MappingMongoConverter(resolver, mappingContext); converter.setCustomConversions( - new CustomConversions(Arrays.asList(new FooBarEnumToStringConverter(), new StringToFooNumConverter()))); + new MongoCustomConversions(Arrays.asList(new FooBarEnumToStringConverter(), new StringToFooNumConverter()))); converter.afterPropertiesSet(); ClassWithMapUsingEnumAsKey source = new ClassWithMapUsingEnumAsKey(); @@ -1730,7 +1718,7 @@ public class MappingMongoConverterUnitTests { public void writesMapKeyUsingCustomConverter() { MappingMongoConverter converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(new CustomConversions(Arrays.asList(new FooBarEnumToStringConverter()))); + converter.setCustomConversions(new MongoCustomConversions(Arrays.asList(new FooBarEnumToStringConverter()))); converter.afterPropertiesSet(); ClassWithMapUsingEnumAsKey source = new ClassWithMapUsingEnumAsKey(); @@ -1751,7 +1739,7 @@ public class MappingMongoConverterUnitTests { public void readsMapKeyUsingCustomConverter() { MappingMongoConverter converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(new CustomConversions(Arrays.asList(new StringToFooNumConverter()))); + converter.setCustomConversions(new MongoCustomConversions(Arrays.asList(new StringToFooNumConverter()))); converter.afterPropertiesSet(); org.bson.Document source = new org.bson.Document("map", new org.bson.Document("foo-enum-value", "spring")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java index 74e2d2a17..d378ae86f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java @@ -40,6 +40,7 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; +import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.WritingConverter; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; @@ -80,7 +81,7 @@ public class UpdateMapperUnitTests { public void setUp() { this.writingConverterSpy = Mockito.spy(new NestedEntityWriteConverter()); - CustomConversions conversions = new CustomConversions(Arrays.asList(writingConverterSpy)); + CustomConversions conversions = new MongoCustomConversions(Collections.singletonList(writingConverterSpy)); this.context = new MongoMappingContext(); this.context.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); @@ -739,7 +740,7 @@ public class UpdateMapperUnitTests { @SuppressWarnings("unchecked") public void mapsUpdateWithBothReadingAndWritingConverterRegistered() { - CustomConversions conversions = new CustomConversions(Arrays.asList( + CustomConversions conversions = new MongoCustomConversions(Arrays.asList( ClassWithEnum.AllocationToStringConverter.INSTANCE, ClassWithEnum.StringToAllocationConverter.INSTANCE)); MongoMappingContext mappingContext = new MongoMappingContext(); @@ -857,7 +858,7 @@ public class UpdateMapperUnitTests { @SuppressWarnings("unchecked") public void mappingShouldConsiderCustomConvertersForEnumMapKeys() { - CustomConversions conversions = new CustomConversions(Arrays.asList( + CustomConversions conversions = new MongoCustomConversions(Arrays.asList( ClassWithEnum.AllocationToStringConverter.INSTANCE, ClassWithEnum.StringToAllocationConverter.INSTANCE)); MongoMappingContext mappingContext = new MongoMappingContext(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java index 92c58c3c4..766d55e81 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java @@ -42,7 +42,7 @@ import org.springframework.util.ReflectionUtils; /** * Unit test for {@link BasicMongoPersistentProperty}. - * + * * @author Oliver Gierke * @author Christoph Strobl * @author Mark Paluch @@ -101,12 +101,12 @@ public class BasicMongoPersistentPropertyUnitTests { Field field = ReflectionUtils.findField(Person.class, "lastname"); MongoPersistentProperty property = new BasicMongoPersistentProperty(Property.of(field), entity, - new SimpleTypeHolder(), UppercaseFieldNamingStrategy.INSTANCE); + SimpleTypeHolder.DEFAULT, UppercaseFieldNamingStrategy.INSTANCE); assertThat(property.getFieldName(), is("LASTNAME")); field = ReflectionUtils.findField(Person.class, "firstname"); - property = new BasicMongoPersistentProperty(Property.of(field), entity, new SimpleTypeHolder(), + property = new BasicMongoPersistentProperty(Property.of(field), entity, SimpleTypeHolder.DEFAULT, UppercaseFieldNamingStrategy.INSTANCE); assertThat(property.getFieldName(), is("foo")); } @@ -116,7 +116,7 @@ public class BasicMongoPersistentPropertyUnitTests { Field field = ReflectionUtils.findField(Person.class, "lastname"); MongoPersistentProperty property = new BasicMongoPersistentProperty(Property.of(field), entity, - new SimpleTypeHolder(), InvalidFieldNamingStrategy.INSTANCE); + SimpleTypeHolder.DEFAULT, InvalidFieldNamingStrategy.INSTANCE); exception.expect(MappingException.class); exception.expectMessage(InvalidFieldNamingStrategy.class.getName()); @@ -196,7 +196,7 @@ public class BasicMongoPersistentPropertyUnitTests { } private MongoPersistentProperty getPropertyFor(MongoPersistentEntity persistentEntity, Field field) { - return new BasicMongoPersistentProperty(Property.of(field), persistentEntity, new SimpleTypeHolder(), + return new BasicMongoPersistentProperty(Property.of(field), persistentEntity, SimpleTypeHolder.DEFAULT, PropertyNameFieldNamingStrategy.INSTANCE); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java index 4a49c0708..6e39ebf75 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java @@ -19,8 +19,8 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.springframework.data.mongodb.core.DocumentTestUtils.*; -import java.util.List; import java.util.Collections; +import java.util.List; import org.bson.Document; import org.bson.types.ObjectId; @@ -32,10 +32,10 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.WritingConverter; -import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.MongoConverter; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.repository.Person.Sex; @@ -52,9 +52,10 @@ import com.querydsl.core.types.dsl.StringPath; /** * Unit tests for {@link SpringDataMongodbSerializer}. - * + * * @author Oliver Gierke * @author Christoph Strobl + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class SpringDataMongodbSerializerUnitTests { @@ -171,7 +172,7 @@ public class SpringDataMongodbSerializerUnitTests { MongoMappingContext context = new MongoMappingContext(); MappingMongoConverter converter = new MappingMongoConverter(dbFactory, context); - converter.setCustomConversions(new CustomConversions(Collections.singletonList(new SexTypeWriteConverter()))); + converter.setCustomConversions(new MongoCustomConversions(Collections.singletonList(new SexTypeWriteConverter()))); converter.afterPropertiesSet(); this.converter = converter; diff --git a/spring-data-mongodb/src/test/resources/template-mapping.xml b/spring-data-mongodb/src/test/resources/template-mapping.xml index 2e952b4aa..f9b8073b2 100644 --- a/spring-data-mongodb/src/test/resources/template-mapping.xml +++ b/spring-data-mongodb/src/test/resources/template-mapping.xml @@ -6,8 +6,8 @@ http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd"> - - + + @@ -20,8 +20,8 @@ - - + + @@ -44,7 +44,7 @@ - +