Skip to content

Commit 564090e

Browse files
committed
Add support for enum values in @ConfigProperties
1 parent f9a9bf4 commit 564090e

File tree

3 files changed

+48
-31
lines changed

3 files changed

+48
-31
lines changed

extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/ClassConfigPropertiesUtil.java

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -267,26 +267,37 @@ private static ResultHandle populateConfigObject(ClassLoader classLoader, ClassI
267267
*/
268268
DotName fieldTypeDotName = fieldType.name();
269269
ClassInfo fieldTypeClassInfo = applicationIndex.getClassByName(fieldType.name());
270+
ResultHandle mpConfig = methodCreator.getMethodParam(0);
270271
if (fieldTypeClassInfo != null) {
271-
if (!fieldTypeClassInfo.hasNoArgsConstructor()) {
272-
throw new IllegalArgumentException(
273-
"Nested configuration class '" + fieldTypeClassInfo + "' must contain a no-args constructor ");
274-
}
275-
276-
if (!Modifier.isPublic(fieldTypeClassInfo.flags())) {
277-
throw new IllegalArgumentException(
278-
"Nested configuration class '" + fieldTypeClassInfo + "' must be public ");
279-
}
272+
if (DotNames.ENUM.equals(fieldTypeClassInfo.superName())) {
273+
// just read the value from MP Config normally
274+
ResultHandle value = methodCreator.invokeInterfaceMethod(
275+
MethodDescriptor.ofMethod(Config.class, "getValue", Object.class, String.class, Class.class),
276+
mpConfig,
277+
methodCreator.load(getFullConfigName(prefixStr, namingStrategy, field)),
278+
methodCreator.loadClass(fieldTypeDotName.toString()));
279+
280+
createWriteValue(methodCreator, configObject, field, setter, useFieldAccess, value);
281+
} else {
282+
if (!fieldTypeClassInfo.hasNoArgsConstructor()) {
283+
throw new IllegalArgumentException(
284+
"Nested configuration class '" + fieldTypeClassInfo
285+
+ "' must contain a no-args constructor ");
286+
}
280287

281-
ResultHandle nestedConfigObject = populateConfigObject(classLoader, fieldTypeClassInfo,
282-
prefixStr + "." + namingStrategy.getName(field.name()), namingStrategy, failOnMismatchingMember,
283-
methodCreator,
284-
applicationIndex, configProperties);
285-
createWriteValue(methodCreator, configObject, field, setter, useFieldAccess, nestedConfigObject);
288+
if (!Modifier.isPublic(fieldTypeClassInfo.flags())) {
289+
throw new IllegalArgumentException(
290+
"Nested configuration class '" + fieldTypeClassInfo + "' must be public ");
291+
}
286292

293+
ResultHandle nestedConfigObject = populateConfigObject(classLoader, fieldTypeClassInfo,
294+
getFullConfigName(prefixStr, namingStrategy, field), namingStrategy, failOnMismatchingMember,
295+
methodCreator,
296+
applicationIndex, configProperties);
297+
createWriteValue(methodCreator, configObject, field, setter, useFieldAccess, nestedConfigObject);
298+
}
287299
} else {
288-
String fullConfigName = prefixStr + "." + namingStrategy.getName(field.name());
289-
ResultHandle config = methodCreator.getMethodParam(0);
300+
String fullConfigName = getFullConfigName(prefixStr, namingStrategy, field);
290301
if (DotNames.OPTIONAL.equals(fieldTypeDotName)) {
291302
Type genericType = determineSingleGenericType(field.type(),
292303
field.declaringClass().name());
@@ -296,14 +307,14 @@ private static ResultHandle populateConfigObject(ClassLoader classLoader, ClassI
296307
ResultHandle setterValue = methodCreator.invokeInterfaceMethod(
297308
MethodDescriptor.ofMethod(Config.class, "getOptionalValue", Optional.class, String.class,
298309
Class.class),
299-
config, methodCreator.load(fullConfigName),
310+
mpConfig, methodCreator.load(fullConfigName),
300311
methodCreator.loadClass(genericType.name().toString()));
301312
createWriteValue(methodCreator, configObject, field, setter, useFieldAccess, setterValue);
302313
} else {
303314
// convert the String value and populate an Optional with it
304315
ReadOptionalResponse readOptionalResponse = createReadOptionalValueAndConvertIfNeeded(
305316
fullConfigName,
306-
genericType, field.declaringClass().name(), methodCreator, config);
317+
genericType, field.declaringClass().name(), methodCreator, mpConfig);
307318
createWriteValue(readOptionalResponse.getIsPresentTrue(), configObject, field, setter,
308319
useFieldAccess,
309320
readOptionalResponse.getIsPresentTrue().invokeStaticMethod(
@@ -329,7 +340,7 @@ private static ResultHandle populateConfigObject(ClassLoader classLoader, ClassI
329340

330341
ReadOptionalResponse readOptionalResponse = createReadOptionalValueAndConvertIfNeeded(
331342
fullConfigName,
332-
fieldType, field.declaringClass().name(), methodCreator, config);
343+
fieldType, field.declaringClass().name(), methodCreator, mpConfig);
333344

334345
// call the setter if the optional contained data
335346
createWriteValue(readOptionalResponse.getIsPresentTrue(), configObject, field, setter,
@@ -342,7 +353,7 @@ private static ResultHandle populateConfigObject(ClassLoader classLoader, ClassI
342353
*/
343354
ResultHandle setterValue = createReadMandatoryValueAndConvertIfNeeded(
344355
fullConfigName, fieldType,
345-
field.declaringClass().name(), methodCreator, config);
356+
field.declaringClass().name(), methodCreator, mpConfig);
346357
createWriteValue(methodCreator, configObject, field, setter, useFieldAccess, setterValue);
347358

348359
}
@@ -382,6 +393,10 @@ private static ResultHandle populateConfigObject(ClassLoader classLoader, ClassI
382393
return configObject;
383394
}
384395

396+
private static String getFullConfigName(String prefixStr, ConfigProperties.NamingStrategy namingStrategy, FieldInfo field) {
397+
return prefixStr + "." + namingStrategy.getName(field.name());
398+
}
399+
385400
private static void createWriteValue(BytecodeCreator bytecodeCreator, ResultHandle configObject, FieldInfo field,
386401
MethodInfo setter, boolean useFieldAccess, ResultHandle value) {
387402
if (useFieldAccess) {

extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/DotNames.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ private DotNames() {
2222
static final DotName LIST = DotName.createSimple(List.class.getName());
2323
static final DotName SET = DotName.createSimple(Set.class.getName());
2424
static final DotName COLLECTION = DotName.createSimple(Collection.class.getName());
25+
static final DotName ENUM = DotName.createSimple(Enum.class.getName());
2526
static final DotName CONFIG_PROPERTIES = DotName.createSimple(ConfigProperties.class.getName());
2627
static final DotName CONFIG_PREFIX = DotName.createSimple(ConfigPrefix.class.getName());
2728
static final DotName CONFIG_PROPERTY = DotName.createSimple(ConfigProperty.class.getName());

extensions/arc/deployment/src/test/java/io/quarkus/arc/test/configproperties/ClassWithoutGettersConfigPropertiesTest.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,32 @@ public class ClassWithoutGettersConfigPropertiesTest {
2424
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
2525
.addClasses(DummyBean.class, DummyProperties.class)
2626
.addAsResource(new StringAsset(
27-
"dummy.name=quarkus\ndummy.numbers=1,2,3,4\ndummy.unused=whatever"),
27+
"dummy.name=quarkus\ndummy.my-enum=OPTIONAL\ndummy.numbers=1,2,3,4\ndummy.unused=whatever"),
2828
"application.properties"));
2929

3030
@Inject
3131
DummyBean dummyBean;
3232

3333
@Test
3434
public void testConfiguredValues() {
35-
assertEquals("quarkus", dummyBean.getName());
36-
assertEquals(Arrays.asList(1, 2, 3, 4), dummyBean.getNumbers());
35+
DummyProperties dummyProperties = dummyBean.dummyProperties;
36+
assertEquals("quarkus", dummyProperties.name);
37+
assertEquals(Arrays.asList(1, 2, 3, 4), dummyProperties.numbers);
38+
assertEquals(MyEnum.OPTIONAL, dummyProperties.myEnum);
3739
}
3840

3941
@Singleton
4042
public static class DummyBean {
4143
@Inject
4244
DummyProperties dummyProperties;
43-
44-
String getName() {
45-
return dummyProperties.name;
46-
}
47-
48-
List<Integer> getNumbers() {
49-
return dummyProperties.numbers;
50-
}
5145
}
5246

5347
@ConfigProperties(prefix = "dummy")
5448
public static class DummyProperties {
5549

5650
public String name;
5751
public List<Integer> numbers;
52+
public MyEnum myEnum;
5853

5954
public void setName(String name) {
6055
this.name = name;
@@ -64,4 +59,10 @@ public void setNumbers(List<Integer> numbers) {
6459
this.numbers = numbers;
6560
}
6661
}
62+
63+
public enum MyEnum {
64+
OPTIONAL,
65+
ENUM_ONE,
66+
Enum_Two
67+
}
6768
}

0 commit comments

Comments
 (0)