Fix GenericConversionService search algorithm
Previously the algorithm used by GenericConversionService to find
converters incorrectly searched for interfaces working up from the
base class. This caused particular problems with custom List
converters as as the Collection interface would be considered before
the List interface giving CollectionToObjectConverter precedence
over the custom converter.
The updated algorithm restores the class search order to behave in the
same way as Spring 3.1.
Issue: SPR-10116
Backport-Issue: SPR-10117
Backport-Commit: aa914497dc
This commit is contained in:
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.math.BigDecimal;
|
||||
@@ -506,6 +502,21 @@ public class DefaultConversionTests {
|
||||
assertEquals(source, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertCollectionToObjectWithCustomConverter() throws Exception {
|
||||
List<String> source = new ArrayList<String>();
|
||||
source.add("A");
|
||||
source.add("B");
|
||||
conversionService.addConverter(new Converter<List, ListWrapper>() {
|
||||
@Override
|
||||
public ListWrapper convert(List source) {
|
||||
return new ListWrapper(source);
|
||||
}
|
||||
});
|
||||
ListWrapper result = conversionService.convert(source, ListWrapper.class);
|
||||
assertSame(source, result.getList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertObjectToCollection() {
|
||||
List<String> result = (List<String>) conversionService.convert(3L, List.class);
|
||||
@@ -777,4 +788,17 @@ public class DefaultConversionTests {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListWrapper {
|
||||
|
||||
private List<?> list;
|
||||
|
||||
public ListWrapper(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -48,6 +47,7 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@@ -696,14 +696,11 @@ public class GenericConversionServiceTests {
|
||||
MyConditionalGenericConverter converter = new MyConditionalGenericConverter();
|
||||
conversionService.addConverter(converter);
|
||||
assertEquals((Integer) 3, conversionService.convert(3, Integer.class));
|
||||
assertThat(converter.getSourceTypes().size(), greaterThan(2));
|
||||
Iterator<TypeDescriptor> iterator = converter.getSourceTypes().iterator();
|
||||
assertEquals(Integer.class, iterator.next().getType());
|
||||
assertEquals(Number.class, iterator.next().getType());
|
||||
TypeDescriptor last = null;
|
||||
while (iterator.hasNext()) {
|
||||
last = iterator.next();
|
||||
while(iterator.hasNext()) {
|
||||
assertEquals(Integer.class, iterator.next().getType());
|
||||
}
|
||||
assertEquals(Object.class, last.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -784,7 +781,7 @@ public class GenericConversionServiceTests {
|
||||
private static class MyConditionalGenericConverter implements GenericConverter,
|
||||
ConditionalConverter {
|
||||
|
||||
private Set<TypeDescriptor> sourceTypes = new LinkedHashSet<TypeDescriptor>();
|
||||
private List<TypeDescriptor> sourceTypes = new ArrayList<TypeDescriptor>();
|
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
return null;
|
||||
@@ -800,7 +797,7 @@ public class GenericConversionServiceTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<TypeDescriptor> getSourceTypes() {
|
||||
public List<TypeDescriptor> getSourceTypes() {
|
||||
return sourceTypes;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user