Browse Source

Fixed ConversionService handling in SimpleMongoConverter.

Removed possibility to use custom ConversionService and rather provide a setter to allow registering custom Converter and ConverterFactory instances. This way we can use a custom ConversionService our own that does not regard the ObjectToStringConverter registered by default. This way ConversionService.canConvert(…, String.class) will not return true by default.
pull/1/head
Oliver Gierke 15 years ago
parent
commit
b6c3760e78
  1. 79
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/SimpleMongoConverter.java

79
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/SimpleMongoConverter.java

@ -32,8 +32,12 @@ import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.core.CollectionFactory; import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.Converter; 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.ConversionServiceFactory; import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor; import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor;
@ -108,18 +112,8 @@ public class SimpleMongoConverter implements MongoConverter {
* Creates a {@link SimpleMongoConverter}. * Creates a {@link SimpleMongoConverter}.
*/ */
public SimpleMongoConverter() { public SimpleMongoConverter() {
this.conversionService = ConversionServiceFactory.createDefaultConversionService(); this.conversionService = new SimpleToStringSuppressingGenericConversionService();
initializeConverters(); ConversionServiceFactory.addDefaultConverters(conversionService);
}
/**
* Creates a new {@link SimpleMongoConverter} for the given {@link ConversionService}.
*
* @param conversionService
*/
public SimpleMongoConverter(GenericConversionService conversionService) {
Assert.notNull(conversionService);
this.conversionService = conversionService;
initializeConverters(); initializeConverters();
} }
@ -129,14 +123,33 @@ public class SimpleMongoConverter implements MongoConverter {
*/ */
protected void initializeConverters() { protected void initializeConverters() {
if (!conversionService.canConvert(ObjectId.class, String.class)) {
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE); conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
conversionService.addConverter(StringToObjectIdConverter.INSTANCE); conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE); conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
conversionService.addConverter(BigIntegerToIdConverter.INSTANCE); conversionService.addConverter(BigIntegerToIdConverter.INSTANCE);
}
/**
* Sets custom {@link Converter} or {@link ConverterFactory} instances to be used.
*
* @param converters
*/
public void setConverters(Set<?> converters) {
for (Object converter : converters) {
boolean added = false;
if (converter instanceof Converter) {
this.conversionService.addConverter((Converter<?, ?>) converter);
added = true;
}
if (converter instanceof ConverterFactory) {
this.conversionService.addConverterFactory((ConverterFactory<?, ?>) converter);
added = true;
}
if (!added) {
throw new IllegalArgumentException("Given set contains element that is neither Converter nor ConverterFactory!");
}
} }
} }
@ -178,7 +191,7 @@ public class SimpleMongoConverter implements MongoConverter {
} }
} else { } else {
if (!"class".equals(descriptor.getName())) { if (!"class".equals(descriptor.getName())) {
LOG.warn("Unable to map property " + descriptor.getName() + ". Skipping."); LOG.debug("Skipping property " + descriptor.getName() + " as it's not a mappable one.");
} }
} }
} }
@ -223,6 +236,12 @@ public class SimpleMongoConverter implements MongoConverter {
writeArray(dbo, keyToUse, (Object[]) value); writeArray(dbo, keyToUse, (Object[]) value);
return; return;
} }
if (conversionService.canConvert(value.getClass(), String.class)) {
dbo.put(keyToUse, conversionService.convert(value, String.class));
return;
}
DBObject nestedDbo = new BasicDBObject(); DBObject nestedDbo = new BasicDBObject();
write(value, nestedDbo); write(value, nestedDbo);
dbo.put(keyToUse, nestedDbo); dbo.put(keyToUse, nestedDbo);
@ -492,6 +511,30 @@ public class SimpleMongoConverter implements MongoConverter {
return conversionService.convert(id, ObjectId.class); return conversionService.convert(id, ObjectId.class);
} }
private static class SimpleToStringSuppressingGenericConversionService extends GenericConversionService {
private static final Set<ConvertiblePair> REFERENCE = Collections.singleton(new ConvertiblePair(Object.class, String.class));
/* (non-Javadoc)
* @see org.springframework.core.convert.support.GenericConversionService#getConverter(org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor)
*/
@Override
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
GenericConverter converter = super.getConverter(sourceType, targetType);
if (converter instanceof ConditionalGenericConverter) {
Set<ConvertiblePair> convertibleTypes = ((ConditionalGenericConverter) converter).getConvertibleTypes();
if (REFERENCE.equals(convertibleTypes)) {
return null;
}
}
return converter;
}
}
/** /**
* Simple singleton to convert {@link ObjectId}s to their {@link String} representation. * Simple singleton to convert {@link ObjectId}s to their {@link String} representation.
* *

Loading…
Cancel
Save