Skip to content

Commit 4bb8375

Browse files
committed
Support for static field access on non-public enums
Issue: SPR-16284 (cherry picked from commit 9beb978)
1 parent 3368dca commit 4bb8375

File tree

3 files changed

+79
-19
lines changed

3 files changed

+79
-19
lines changed

spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -35,6 +35,7 @@
3535
import org.springframework.core.convert.TypeDescriptor;
3636
import org.springframework.util.ClassUtils;
3737
import org.springframework.util.NumberUtils;
38+
import org.springframework.util.ReflectionUtils;
3839
import org.springframework.util.StringUtils;
3940

4041
/**
@@ -353,6 +354,7 @@ private Object attemptToConvertStringToEnum(Class<?> requiredType, String trimme
353354
// to be checked, hence we don't return it right away.
354355
try {
355356
Field enumField = requiredType.getField(trimmedValue);
357+
ReflectionUtils.makeAccessible(enumField);
356358
convertedValue = enumField.get(null);
357359
}
358360
catch (Throwable ex) {

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

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -31,35 +31,35 @@
3131
* @author Juergen Hoeller
3232
* @author Chris Beams
3333
*/
34-
public final class BeanWrapperEnumTests {
34+
public class BeanWrapperEnumTests {
3535

3636
@Test
3737
public void testCustomEnum() {
38-
GenericBean<?> gb = new GenericBean<Object>();
38+
GenericBean<?> gb = new GenericBean<>();
3939
BeanWrapper bw = new BeanWrapperImpl(gb);
4040
bw.setPropertyValue("customEnum", "VALUE_1");
4141
assertEquals(CustomEnum.VALUE_1, gb.getCustomEnum());
4242
}
4343

4444
@Test
4545
public void testCustomEnumWithNull() {
46-
GenericBean<?> gb = new GenericBean<Object>();
46+
GenericBean<?> gb = new GenericBean<>();
4747
BeanWrapper bw = new BeanWrapperImpl(gb);
4848
bw.setPropertyValue("customEnum", null);
4949
assertEquals(null, gb.getCustomEnum());
5050
}
5151

5252
@Test
5353
public void testCustomEnumWithEmptyString() {
54-
GenericBean<?> gb = new GenericBean<Object>();
54+
GenericBean<?> gb = new GenericBean<>();
5555
BeanWrapper bw = new BeanWrapperImpl(gb);
5656
bw.setPropertyValue("customEnum", "");
5757
assertEquals(null, gb.getCustomEnum());
5858
}
5959

6060
@Test
6161
public void testCustomEnumArrayWithSingleValue() {
62-
GenericBean<?> gb = new GenericBean<Object>();
62+
GenericBean<?> gb = new GenericBean<>();
6363
BeanWrapper bw = new BeanWrapperImpl(gb);
6464
bw.setPropertyValue("customEnumArray", "VALUE_1");
6565
assertEquals(1, gb.getCustomEnumArray().length);
@@ -68,7 +68,7 @@ public void testCustomEnumArrayWithSingleValue() {
6868

6969
@Test
7070
public void testCustomEnumArrayWithMultipleValues() {
71-
GenericBean<?> gb = new GenericBean<Object>();
71+
GenericBean<?> gb = new GenericBean<>();
7272
BeanWrapper bw = new BeanWrapperImpl(gb);
7373
bw.setPropertyValue("customEnumArray", new String[] {"VALUE_1", "VALUE_2"});
7474
assertEquals(2, gb.getCustomEnumArray().length);
@@ -78,7 +78,7 @@ public void testCustomEnumArrayWithMultipleValues() {
7878

7979
@Test
8080
public void testCustomEnumArrayWithMultipleValuesAsCsv() {
81-
GenericBean<?> gb = new GenericBean<Object>();
81+
GenericBean<?> gb = new GenericBean<>();
8282
BeanWrapper bw = new BeanWrapperImpl(gb);
8383
bw.setPropertyValue("customEnumArray", "VALUE_1,VALUE_2");
8484
assertEquals(2, gb.getCustomEnumArray().length);
@@ -88,7 +88,7 @@ public void testCustomEnumArrayWithMultipleValuesAsCsv() {
8888

8989
@Test
9090
public void testCustomEnumSetWithSingleValue() {
91-
GenericBean<?> gb = new GenericBean<Object>();
91+
GenericBean<?> gb = new GenericBean<>();
9292
BeanWrapper bw = new BeanWrapperImpl(gb);
9393
bw.setPropertyValue("customEnumSet", "VALUE_1");
9494
assertEquals(1, gb.getCustomEnumSet().size());
@@ -97,7 +97,7 @@ public void testCustomEnumSetWithSingleValue() {
9797

9898
@Test
9999
public void testCustomEnumSetWithMultipleValues() {
100-
GenericBean<?> gb = new GenericBean<Object>();
100+
GenericBean<?> gb = new GenericBean<>();
101101
BeanWrapper bw = new BeanWrapperImpl(gb);
102102
bw.setPropertyValue("customEnumSet", new String[] {"VALUE_1", "VALUE_2"});
103103
assertEquals(2, gb.getCustomEnumSet().size());
@@ -107,7 +107,7 @@ public void testCustomEnumSetWithMultipleValues() {
107107

108108
@Test
109109
public void testCustomEnumSetWithMultipleValuesAsCsv() {
110-
GenericBean<?> gb = new GenericBean<Object>();
110+
GenericBean<?> gb = new GenericBean<>();
111111
BeanWrapper bw = new BeanWrapperImpl(gb);
112112
bw.setPropertyValue("customEnumSet", "VALUE_1,VALUE_2");
113113
assertEquals(2, gb.getCustomEnumSet().size());
@@ -117,7 +117,7 @@ public void testCustomEnumSetWithMultipleValuesAsCsv() {
117117

118118
@Test
119119
public void testCustomEnumSetWithGetterSetterMismatch() {
120-
GenericBean<?> gb = new GenericBean<Object>();
120+
GenericBean<?> gb = new GenericBean<>();
121121
BeanWrapper bw = new BeanWrapperImpl(gb);
122122
bw.setPropertyValue("customEnumSetMismatch", new String[] {"VALUE_1", "VALUE_2"});
123123
assertEquals(2, gb.getCustomEnumSet().size());
@@ -127,7 +127,7 @@ public void testCustomEnumSetWithGetterSetterMismatch() {
127127

128128
@Test
129129
public void testStandardEnumSetWithMultipleValues() {
130-
GenericBean<?> gb = new GenericBean<Object>();
130+
GenericBean<?> gb = new GenericBean<>();
131131
BeanWrapper bw = new BeanWrapperImpl(gb);
132132
bw.setConversionService(new DefaultConversionService());
133133
assertNull(gb.getStandardEnumSet());
@@ -139,7 +139,7 @@ public void testStandardEnumSetWithMultipleValues() {
139139

140140
@Test
141141
public void testStandardEnumSetWithAutoGrowing() {
142-
GenericBean<?> gb = new GenericBean<Object>();
142+
GenericBean<?> gb = new GenericBean<>();
143143
BeanWrapper bw = new BeanWrapperImpl(gb);
144144
bw.setAutoGrowNestedPaths(true);
145145
assertNull(gb.getStandardEnumSet());
@@ -149,11 +149,11 @@ public void testStandardEnumSetWithAutoGrowing() {
149149

150150
@Test
151151
public void testStandardEnumMapWithMultipleValues() {
152-
GenericBean<?> gb = new GenericBean<Object>();
152+
GenericBean<?> gb = new GenericBean<>();
153153
BeanWrapper bw = new BeanWrapperImpl(gb);
154154
bw.setConversionService(new DefaultConversionService());
155155
assertNull(gb.getStandardEnumMap());
156-
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
156+
Map<String, Integer> map = new LinkedHashMap<>();
157157
map.put("VALUE_1", 1);
158158
map.put("VALUE_2", 2);
159159
bw.setPropertyValue("standardEnumMap", map);
@@ -164,7 +164,7 @@ public void testStandardEnumMapWithMultipleValues() {
164164

165165
@Test
166166
public void testStandardEnumMapWithAutoGrowing() {
167-
GenericBean<?> gb = new GenericBean<Object>();
167+
GenericBean<?> gb = new GenericBean<>();
168168
BeanWrapper bw = new BeanWrapperImpl(gb);
169169
bw.setAutoGrowNestedPaths(true);
170170
assertNull(gb.getStandardEnumMap());
@@ -173,4 +173,32 @@ public void testStandardEnumMapWithAutoGrowing() {
173173
assertEquals(new Integer(1), gb.getStandardEnumMap().get(CustomEnum.VALUE_1));
174174
}
175175

176+
@Test
177+
public void testNonPublicEnum() {
178+
NonPublicEnumHolder holder = new NonPublicEnumHolder();
179+
BeanWrapper bw = new BeanWrapperImpl(holder);
180+
bw.setPropertyValue("nonPublicEnum", "VALUE_1");
181+
assertEquals(NonPublicEnum.VALUE_1, holder.getNonPublicEnum());
182+
}
183+
184+
185+
enum NonPublicEnum {
186+
187+
VALUE_1, VALUE_2;
188+
}
189+
190+
191+
static class NonPublicEnumHolder {
192+
193+
private NonPublicEnum nonPublicEnum;
194+
195+
public NonPublicEnum getNonPublicEnum() {
196+
return nonPublicEnum;
197+
}
198+
199+
public void setNonPublicEnum(NonPublicEnum nonPublicEnum) {
200+
this.nonPublicEnum = nonPublicEnum;
201+
}
202+
}
203+
176204
}

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -2735,6 +2735,16 @@ public void emptyJavaUtilOptionalBean() {
27352735
assertSame(Optional.empty(), bf.getBean(Optional.class));
27362736
}
27372737

2738+
@Test
2739+
public void testNonPublicEnum() {
2740+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
2741+
RootBeanDefinition bd = new RootBeanDefinition(NonPublicEnumHolder.class);
2742+
bd.getConstructorArgumentValues().addGenericArgumentValue("VALUE_1");
2743+
bf.registerBeanDefinition("holderBean", bd);
2744+
NonPublicEnumHolder holder = (NonPublicEnumHolder) bf.getBean("holderBean");
2745+
assertEquals(NonPublicEnum.VALUE_1, holder.getNonPublicEnum());
2746+
}
2747+
27382748
/**
27392749
* Test that by-type bean lookup caching is working effectively by searching for a
27402750
* bean of type B 10K times within a container having 1K additional beans of type A.
@@ -3262,4 +3272,24 @@ public boolean isSingleton() {
32623272
}
32633273
}
32643274

3275+
3276+
enum NonPublicEnum {
3277+
3278+
VALUE_1, VALUE_2;
3279+
}
3280+
3281+
3282+
static class NonPublicEnumHolder {
3283+
3284+
final NonPublicEnum nonPublicEnum;
3285+
3286+
public NonPublicEnumHolder(NonPublicEnum nonPublicEnum) {
3287+
this.nonPublicEnum = nonPublicEnum;
3288+
}
3289+
3290+
public NonPublicEnum getNonPublicEnum() {
3291+
return nonPublicEnum;
3292+
}
3293+
}
3294+
32653295
}

0 commit comments

Comments
 (0)