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. 93
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/SimpleMongoConverter.java

93
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;
@ -42,7 +46,7 @@ import org.springframework.util.comparator.CompoundComparator;
/** /**
* Basic {@link MongoConverter} implementation to convert between domain classes and {@link DBObject}s. * Basic {@link MongoConverter} implementation to convert between domain classes and {@link DBObject}s.
* *
* @author Mark Pollack * @author Mark Pollack
* @author Thomas Risberg * @author Thomas Risberg
* @author Oliver Gierke * @author Oliver Gierke
@ -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);
} conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
conversionService.addConverter(BigIntegerToIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) { /**
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE); * Sets custom {@link Converter} or {@link ConverterFactory} instances to be used.
conversionService.addConverter(BigIntegerToIdConverter.INSTANCE); *
* @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.");
} }
} }
} }
@ -186,7 +199,7 @@ public class SimpleMongoConverter implements MongoConverter {
/** /**
* Writes the given value to the given {@link DBObject}. Will skip {@literal null} values. * Writes the given value to the given {@link DBObject}. Will skip {@literal null} values.
* *
* @param dbo * @param dbo
* @param keyToUse * @param keyToUse
* @param value * @param value
@ -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);
@ -231,7 +250,7 @@ public class SimpleMongoConverter implements MongoConverter {
/** /**
* Writes the given {@link Map} to the given {@link DBObject}. * Writes the given {@link Map} to the given {@link DBObject}.
* *
* @param dbo * @param dbo
* @param mapKey * @param mapKey
* @param map * @param map
@ -491,10 +510,34 @@ public class SimpleMongoConverter implements MongoConverter {
public ObjectId convertObjectId(Object id) { public ObjectId convertObjectId(Object id) {
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.
* *
* @author Oliver Gierke * @author Oliver Gierke
*/ */
public static enum ObjectIdToStringConverter implements Converter<ObjectId, String> { public static enum ObjectIdToStringConverter implements Converter<ObjectId, String> {

Loading…
Cancel
Save