DATAMONGO-1660 - Adapt to moved CustomConversions to Spring Data Commons.
Introduce MongoCustomConversions extending o.s.d.convert.CustomConversions. Remove o.s.d.mongo.core.convert.CustomConversions implementation code and utility classes and let it extend MongoCustomConversions. Replace references to o.s.d.m.c.c.CustomConversions with o.s.d.convert.CustomConversions. Adapt tests and MappingMongoConverter to MongoCustomConversions. Related ticket: DATACMNS-1035.
This commit is contained in:
@@ -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 <converter> must specify 'ref' or contain a bean definition for the converter", element);
|
||||
parserContext.getReaderContext()
|
||||
.error("Element <converter> 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)) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<ConvertiblePair> readingPairs;
|
||||
private final Set<ConvertiblePair> writingPairs;
|
||||
private final Set<Class<?>> customSimpleTypes;
|
||||
private final SimpleTypeHolder simpleTypeHolder;
|
||||
|
||||
private final List<Object> converters;
|
||||
|
||||
private final Map<ConvertiblePair, Optional<Class<?>>> customReadTargetTypes;
|
||||
private final Map<ConvertiblePair, Optional<Class<?>>> customWriteTargetTypes;
|
||||
private final Map<Class<?>, Optional<Class<?>>> rawWriteTargetTypes;
|
||||
@Deprecated
|
||||
public class CustomConversions extends MongoCustomConversions {
|
||||
|
||||
/**
|
||||
* Creates an empty {@link CustomConversions} object.
|
||||
*/
|
||||
CustomConversions() {
|
||||
this(new ArrayList<Object>());
|
||||
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<Object> toRegister = new ArrayList<Object>();
|
||||
|
||||
// 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<Class<?>> getCustomTarget(Class<?> sourceType, Class<?> requestedTargetType,
|
||||
Collection<ConvertiblePair> 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<ConvertiblePair> getConvertibleTypes() {
|
||||
|
||||
ConvertiblePair localeToString = new ConvertiblePair(Locale.class, String.class);
|
||||
ConvertiblePair booleanToString = new ConvertiblePair(Character.class, String.class);
|
||||
|
||||
return new HashSet<ConvertiblePair>(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Class<?>> 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<Class<?>> 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<Class<?>> 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<Object> objects = bulkReadAndConvertDBRefs((List<DBRef>) sourceValue, componentType, path,
|
||||
rawComponentType);
|
||||
List<Object> objects = bulkReadAndConvertDBRefs((List<DBRef>) 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<Class<?>> 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<Object, Object> converted = new LinkedHashMap<>(((Map)obj).size(), 1);
|
||||
Map<Object, Object> converted = new LinkedHashMap<>(((Map) obj).size(), 1);
|
||||
Document result = new Document();
|
||||
|
||||
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) 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
|
||||
*/
|
||||
|
||||
@@ -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<Object> STORE_CONVERTERS;
|
||||
|
||||
static {
|
||||
|
||||
List<Object> 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<ConvertiblePair> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
|
||||
List<Converter<?, ?>> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.<Converter<?, ?>> asList(ageWriteConverter(), ageReadConverter()));
|
||||
return new MongoCustomConversions(Arrays.asList(ageWriteConverter(), ageReadConverter()));
|
||||
}
|
||||
|
||||
Converter<Age, org.bson.Document> ageWriteConverter() {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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<ObjectId, String>() {
|
||||
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<Format, String> {
|
||||
INSTANCE;
|
||||
|
||||
public String convert(Format source) {
|
||||
return source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
enum StringToFormatConverter implements Converter<String, Format> {
|
||||
INSTANCE;
|
||||
public Format convert(String source) {
|
||||
return DateFormat.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
enum NumberToStringConverter implements Converter<Number, String> {
|
||||
INSTANCE;
|
||||
public String convert(Number source) {
|
||||
return source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
enum StringToNumberConverter implements Converter<String, Number> {
|
||||
INSTANCE;
|
||||
public Number convert(String source) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
enum StringToIntegerConverter implements Converter<String, Integer> {
|
||||
INSTANCE;
|
||||
public Integer convert(String source) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum DateTimeToStringConverter implements Converter<DateTime, String> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String convert(DateTime source) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
enum CustomDateTimeConverter implements Converter<DateTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Date convert(DateTime source) {
|
||||
return new Date(0);
|
||||
}
|
||||
}
|
||||
|
||||
enum CustomObjectToStringConverter implements Converter<Object, String> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String convert(Object source) {
|
||||
return source != null ? source.toString() : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@WritingConverter
|
||||
static class FormatConverterFactory implements ConverterFactory<String, Format> {
|
||||
|
||||
@Override
|
||||
public <T extends Format> Converter<String, T> getConverter(Class<T> targetType) {
|
||||
return new StringToFormat<T>(targetType);
|
||||
}
|
||||
|
||||
private static final class StringToFormat<T extends Format> implements Converter<String, T> {
|
||||
|
||||
private final Class<T> targetType;
|
||||
|
||||
public StringToFormat(Class<T> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<Foo> fooEntity;
|
||||
MongoPersistentEntity<Bar> 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();
|
||||
|
||||
@@ -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<String, Object>();
|
||||
entity.mapOfObjects.put("foo", person);
|
||||
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(new Converter<Person, org.bson.Document>() {
|
||||
CustomConversions conversions = new MongoCustomConversions(
|
||||
Arrays.asList(new Converter<Person, org.bson.Document>() {
|
||||
|
||||
@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<org.bson.Document, Person>() {
|
||||
}, new Converter<org.bson.Document, Person>() {
|
||||
|
||||
@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<org.bson.Document> points = (List<org.bson.Document>) polygonDoc.get("points");
|
||||
|
||||
assertThat(points, hasSize(3));
|
||||
assertThat(points, Matchers.<org.bson.Document>hasItems(toDocument(object.polygon.getPoints().get(0)),
|
||||
assertThat(points, Matchers.<org.bson.Document> 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.<String>empty()));
|
||||
assertThat(read.string, is(Optional.<String> 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"));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
|
||||
|
||||
<bean class="org.springframework.data.mongodb.core.TestMongoConfiguration"/>
|
||||
|
||||
<mongo:db-factory dbname="database"/>
|
||||
|
||||
<mongo:db-factory dbname="database"/>
|
||||
|
||||
<bean id="mappingConverter1" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
|
||||
<constructor-arg ref="mongoDbFactory" />
|
||||
@@ -20,8 +20,8 @@
|
||||
<bean factory-bean="conversions" factory-method="getSimpleTypeHolder" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="conversions" class="org.springframework.data.mongodb.core.convert.CustomConversions">
|
||||
|
||||
<bean id="conversions" class="org.springframework.data.mongodb.core.convert.MongoCustomConversions">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.data.mongodb.core.PersonReadConverter" />
|
||||
@@ -44,7 +44,7 @@
|
||||
<bean class="org.springframework.data.mongodb.core.PersonWriteConverter"/>
|
||||
</mongo:converter>
|
||||
</mongo:custom-converters>
|
||||
</mongo:mapping-converter>
|
||||
</mongo:mapping-converter>
|
||||
|
||||
<bean id="mongoTemplate2" class="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
|
||||
|
||||
Reference in New Issue
Block a user