Skip to content

Commit 6403479

Browse files
committed
TypeDescriptor's nested type traversal leniently returns null in case of unresolvable nested type
Issue: SPR-11898 (cherry picked from commit d663580)
1 parent 5af1a69 commit 6403479

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

spring-beans/src/test/java/org/springframework/beans/BeanWrapperGenericsTests.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@
2828
import java.util.Map;
2929
import java.util.Set;
3030

31-
import static org.junit.Assert.*;
3231
import org.junit.Test;
3332

3433
import org.springframework.beans.propertyeditors.CustomNumberEditor;
@@ -40,6 +39,8 @@
4039
import org.springframework.tests.sample.beans.GenericSetOfIntegerBean;
4140
import org.springframework.tests.sample.beans.TestBean;
4241

42+
import static org.junit.Assert.*;
43+
4344
/**
4445
* @author Juergen Hoeller
4546
* @author Chris Beams
@@ -485,6 +486,29 @@ public void testSettingLongPropertyWithGenericInterface() {
485486
assertEquals(new Long(10), bean.getId());
486487
}
487488

489+
@Test
490+
public void testUntypedPropertyWithMapAtRuntime() {
491+
class Holder<D> {
492+
private final D data;
493+
public Holder(D data) {
494+
this.data = data;
495+
}
496+
public D getData() {
497+
return this.data;
498+
}
499+
}
500+
501+
Map<String, Object> data = new HashMap<String, Object>();
502+
data.put("x", "y");
503+
Holder<Map<String, Object>> context = new Holder<Map<String,Object>>(data);
504+
505+
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(context);
506+
assertEquals("y", bw.getPropertyValue("data['x']"));
507+
508+
bw.setPropertyValue("data['message']", "it works!");
509+
assertEquals(data.get("message"), "it works!");
510+
}
511+
488512

489513
private static abstract class BaseGenericCollectionBean {
490514

spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,7 @@ private static TypeDescriptor nested(TypeDescriptor typeDescriptor, int nestingL
701701
}
702702
}
703703
if (nested == ResolvableType.NONE) {
704-
throw new IllegalStateException(
705-
"Unable to obtain nested generic from " + typeDescriptor + " at level " + nestingLevel);
704+
return null;
706705
}
707706
return getRelatedIfResolvable(typeDescriptor, nested);
708707
}

spring-core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
3636
import java.util.Set;
3737

3838
import org.junit.Test;
39+
3940
import org.springframework.core.MethodParameter;
4041
import org.springframework.util.LinkedMultiValueMap;
4142
import org.springframework.util.MultiValueMap;
@@ -69,6 +70,7 @@ public class TypeDescriptorTests {
6970

7071
public Map<String, List<Integer>> nestedMapField = new HashMap<String, List<Integer>>();
7172

73+
7274
@Test
7375
public void parameterPrimitive() throws Exception {
7476
TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterPrimitive", int.class), 0));
@@ -555,15 +557,16 @@ public void nestedMethodParameterNot1NestedLevel() throws Exception {
555557
TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0, 2), 2);
556558
}
557559

558-
@Test(expected=IllegalStateException.class)
560+
@Test
559561
public void nestedTooManyLevels() throws Exception {
560562
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 3);
561-
assertEquals(String.class, t1.getType());
563+
assertNull(t1);
562564
}
563565

564-
@Test(expected=IllegalStateException.class)
566+
@Test
565567
public void nestedMethodParameterTypeNotNestable() throws Exception {
566-
TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0), 2);
568+
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0), 2);
569+
assertNull(t1);
567570
}
568571

569572
@Test(expected=IllegalArgumentException.class)
@@ -941,4 +944,5 @@ public void getSource() throws Exception {
941944
assertThat(new TypeDescriptor(methodParameter).getSource(), equalTo((Object) methodParameter));
942945
assertThat(TypeDescriptor.valueOf(Integer.class).getSource(), equalTo((Object) Integer.class));
943946
}
947+
944948
}

0 commit comments

Comments
 (0)