generic collection type resolution respects upper bound as well

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@624 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Juergen Hoeller 2009-02-13 09:09:56 +00:00
parent cd9cbabb4d
commit 613f744990
4 changed files with 42 additions and 14 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,8 +16,6 @@
package org.springframework.beans; package org.springframework.beans;
import static org.junit.Assert.*;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -31,18 +29,18 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import junit.framework.Assert; import junit.framework.Assert;
import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import test.beans.GenericBean; import test.beans.GenericBean;
import test.beans.GenericIntegerBean; import test.beans.GenericIntegerBean;
import test.beans.GenericSetOfIntegerBean; import test.beans.GenericSetOfIntegerBean;
import test.beans.TestBean; import test.beans.TestBean;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
/** /**
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams * @author Chris Beams
@ -62,6 +60,19 @@ public final class BeanWrapperGenericsTests {
assertTrue(gb.getIntegerSet().contains(new Integer(5))); assertTrue(gb.getIntegerSet().contains(new Integer(5)));
} }
@Test
public void testGenericLowerBoundedSet() {
GenericBean<?> gb = new GenericBean<Object>();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, true));
Set<String> input = new HashSet<String>();
input.add("4");
input.add("5");
bw.setPropertyValue("numberSet", input);
assertTrue(gb.getNumberSet().contains(new Integer(4)));
assertTrue(gb.getNumberSet().contains(new Integer(5)));
}
@Test @Test
public void testGenericSetWithConversionFailure() { public void testGenericSetWithConversionFailure() {
GenericBean<?> gb = new GenericBean<Object>(); GenericBean<?> gb = new GenericBean<Object>();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -34,6 +34,8 @@ public class GenericBean<T> {
private Set<Integer> integerSet; private Set<Integer> integerSet;
private Set<? extends Number> numberSet;
private List<Resource> resourceList; private List<Resource> resourceList;
private List<List<Integer>> listOfLists; private List<List<Integer>> listOfLists;
@ -105,6 +107,14 @@ public class GenericBean<T> {
this.integerSet = integerSet; this.integerSet = integerSet;
} }
public Set<? extends Number> getNumberSet() {
return numberSet;
}
public void setNumberSet(Set<? extends Number> numberSet) {
this.numberSet = numberSet;
}
public List<Resource> getResourceList() { public List<Resource> getResourceList() {
return resourceList; return resourceList;
} }

View File

@ -341,11 +341,18 @@ public abstract class GenericCollectionTypeResolver {
} }
} }
if (paramType instanceof WildcardType) { if (paramType instanceof WildcardType) {
Type[] lowerBounds = ((WildcardType) paramType).getLowerBounds(); WildcardType wildcardType = (WildcardType) paramType;
if (lowerBounds != null && lowerBounds.length > 0) { Type[] upperBounds = wildcardType.getUpperBounds();
if (upperBounds != null && upperBounds.length > 0 && !Object.class.equals(upperBounds[0])) {
paramType = upperBounds[0];
}
else {
Type[] lowerBounds = wildcardType.getLowerBounds();
if (lowerBounds != null && lowerBounds.length > 0 && !Object.class.equals(lowerBounds[0])) {
paramType = lowerBounds[0]; paramType = lowerBounds[0];
} }
} }
}
if (paramType instanceof ParameterizedType) { if (paramType instanceof ParameterizedType) {
paramType = ((ParameterizedType) paramType).getRawType(); paramType = ((ParameterizedType) paramType).getRawType();
} }

View File

@ -40,7 +40,7 @@ public class GenericCollectionTypeResolverTests extends AbstractGenericsTests {
this.targetClass = Foo.class; this.targetClass = Foo.class;
this.methods = new String[] {"a", "b", "b2", "b3", "c", "d", "d2", "d3", "e", "e2", "e3"}; this.methods = new String[] {"a", "b", "b2", "b3", "c", "d", "d2", "d3", "e", "e2", "e3"};
this.expectedResults = new Class[] { this.expectedResults = new Class[] {
Integer.class, null, null, Set.class, null, Integer.class, Integer.class, null, Set.class, Set.class, null, Integer.class,
Integer.class, Integer.class, Integer.class, Integer.class, Integer.class}; Integer.class, Integer.class, Integer.class, Integer.class, Integer.class};
} }