Browse Source

DATAMONGO-462 - Added custom converters for URL.

So far URL instances were treated as entities and serialized as nested document. As there was no custom converter registered to re-instantiate the objects and URL does not contain a no-arg constructor, reading the instances back in resulted in an ugly exception in ReflectionEntityInstantiator. We now register a custom Converter to serialize URL instances as their plain toString() representation. This causes the reading working out of the box as the StringToObjectConverter registered by default uses the constructor taking a String on URL accidentally. To make sure this still works we added an explicit StringToURLConverter to implement symmetric conversions.
1.0.x
Oliver Gierke 14 years ago
parent
commit
25a94bc45e
  1. 4
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java
  2. 28
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
  3. 20
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java
  4. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

4
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java

@ -38,6 +38,8 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalT
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.URLToStringConverter;
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -89,6 +91,8 @@ public class CustomConversions {
this.converters.add(StringToBigDecimalConverter.INSTANCE); this.converters.add(StringToBigDecimalConverter.INSTANCE);
this.converters.add(BigIntegerToStringConverter.INSTANCE); this.converters.add(BigIntegerToStringConverter.INSTANCE);
this.converters.add(StringToBigIntegerConverter.INSTANCE); this.converters.add(StringToBigIntegerConverter.INSTANCE);
this.converters.add(URLToStringConverter.INSTANCE);
this.converters.add(StringToURLConverter.INSTANCE);
this.converters.addAll(converters); this.converters.addAll(converters);
for (Object c : this.converters) { for (Object c : this.converters) {

28
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java

@ -17,8 +17,12 @@ package org.springframework.data.mongodb.core.convert;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -119,4 +123,28 @@ abstract class MongoConverters {
return StringUtils.hasText(source) ? new BigInteger(source) : null; return StringUtils.hasText(source) ? new BigInteger(source) : null;
} }
} }
public static enum URLToStringConverter implements Converter<URL, String> {
INSTANCE;
public String convert(URL source) {
return source == null ? null : source.toString();
}
}
public static enum StringToURLConverter implements Converter<String, URL> {
INSTANCE;
private static final TypeDescriptor SOURCE = TypeDescriptor.valueOf(String.class);
private static final TypeDescriptor TARGET = TypeDescriptor.valueOf(URL.class);
public URL convert(String source) {
try {
return source == null ? null : new URL(source);
} catch (MalformedURLException e) {
throw new ConversionFailedException(SOURCE, TARGET, source, e);
}
}
}
} }

20
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomConversionsUnitTests.java

@ -3,6 +3,7 @@ package org.springframework.data.mongodb.core.convert;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.net.URL;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.Format; import java.text.Format;
import java.util.Arrays; import java.util.Arrays;
@ -152,6 +153,25 @@ public class CustomConversionsUnitTests {
assertThat(conversions.isSimpleType(Binary.class), is(true)); assertThat(conversions.isSimpleType(Binary.class), is(true));
} }
/**
* @see DATAMONGO-462
*/
@Test
public void hasWriteConverterForURL() {
CustomConversions conversions = new CustomConversions();
assertThat(conversions.hasCustomWriteTarget(URL.class), is(true));
}
/**
* @see DATAMONGO-462
*/
@Test
public void readTargetForURL() {
CustomConversions conversions = new CustomConversions();
assertThat(conversions.hasCustomReadTarget(String.class, URL.class), is(true));
}
enum FormatToStringConverter implements Converter<Format, String> { enum FormatToStringConverter implements Converter<Format, String> {
INSTANCE; INSTANCE;

29
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

@ -21,6 +21,7 @@ import static org.junit.Assert.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -1034,6 +1035,30 @@ public class MappingMongoConverterUnitTests {
assertThat(readResult.iterator().next(), is(Map.class)); assertThat(readResult.iterator().next(), is(Map.class));
} }
/**
* @see DATAMONGO-462
*/
@Test
public void readsURLsAsStringsByDefault() throws Exception {
DBObject dbObject = new BasicDBObject("url", new URL("http://springsource.org"));
URLWrapper result = converter.read(URLWrapper.class, dbObject);
assertThat(result.url, is(new URL("http://springsource.org")));
}
/**
* @see DATAMONGO-462
*/
@Test
public void writesURLsAsStringsByDefault() throws Exception {
URLWrapper wrapper = new URLWrapper();
wrapper.url = new URL("http://springsource.org");
DBObject sink = new BasicDBObject();
converter.write(wrapper, sink);
assertThat(sink.get("url"), is((Object) "http://springsource.org"));
}
static class GenericType<T> { static class GenericType<T> {
T content; T content;
} }
@ -1165,6 +1190,10 @@ public class MappingMongoConverterUnitTests {
Object value; Object value;
} }
static class URLWrapper {
URL url;
}
private class LocalDateToDateConverter implements Converter<LocalDate, Date> { private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
public Date convert(LocalDate source) { public Date convert(LocalDate source) {

Loading…
Cancel
Save