Skip to content

Commit 8a8abf7

Browse files
authored
Collect nested ConfigMappingClass entries in getConfigMappingsMetadata (#1551)
1 parent 9458d40 commit 8a8abf7

4 files changed

Lines changed: 64 additions & 1 deletion

File tree

implementation/src/main/java/io/smallrye/config/ConfigMappingInterface.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ String getClassInternalName() {
188188
return className.replace('.', '/');
189189
}
190190

191-
List<ConfigMappingInterface> getNested() {
191+
public List<ConfigMappingInterface> getNested() {
192192
Set<ConfigMappingInterface> nested = new LinkedHashSet<>();
193193
getNested(properties, nested);
194194
return new ArrayList<>(nested);

implementation/src/main/java/io/smallrye/config/ConfigMappingLoader.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
import java.lang.invoke.MethodHandle;
66
import java.lang.invoke.MethodHandles;
7+
import java.lang.reflect.Field;
78
import java.lang.reflect.InvocationTargetException;
89
import java.lang.reflect.Modifier;
10+
import java.lang.reflect.ParameterizedType;
911
import java.lang.reflect.UndeclaredThrowableException;
1012
import java.util.ArrayList;
1113
import java.util.Collection;
@@ -43,6 +45,7 @@ public static List<ConfigMappingMetadata> getConfigMappingsMetadata(final Class<
4345
ConfigMappingClass configMappingClass = ConfigMappingClass.getConfigurationClass(type);
4446
if (configMappingClass != null) {
4547
mappings.add(configMappingClass);
48+
mappings.addAll(configMappingClass.getNested());
4649
mappings.addAll(getConfigMappingsMetadata(getConfigMapping(type).getInterfaceType()));
4750
}
4851
return List.copyOf(mappings);
@@ -336,5 +339,37 @@ public String getClassName() {
336339
public byte[] getClassBytes() {
337340
return ConfigMappingGenerator.generate(classType, interfaceName);
338341
}
342+
343+
public List<ConfigMappingClass> getNested() {
344+
List<ConfigMappingClass> nested = new ArrayList<>();
345+
collectNested(classType, nested);
346+
return nested;
347+
}
348+
349+
private static void collectNested(final Class<?> type, final List<ConfigMappingClass> nested) {
350+
for (Field field : type.getDeclaredFields()) {
351+
Class<?> fieldType = field.getType();
352+
if (Collection.class.isAssignableFrom(fieldType) || Map.class.isAssignableFrom(fieldType)) {
353+
java.lang.reflect.Type genericType = field.getGenericType();
354+
if (genericType instanceof ParameterizedType parameterizedType) {
355+
for (java.lang.reflect.Type typeArg : parameterizedType.getActualTypeArguments()) {
356+
if (typeArg instanceof Class<?> argClass) {
357+
addNested(argClass, nested);
358+
}
359+
}
360+
}
361+
} else {
362+
addNested(fieldType, nested);
363+
}
364+
}
365+
}
366+
367+
private static void addNested(final Class<?> type, final List<ConfigMappingClass> nested) {
368+
ConfigMappingClass configClass = getConfigurationClass(type);
369+
if (configClass != null) {
370+
nested.add(configClass);
371+
collectNested(type, nested);
372+
}
373+
}
339374
}
340375
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package io.smallrye.config;
22

3+
import java.util.List;
4+
35
public interface ConfigMappingMetadata {
46
Class<?> getInterfaceType();
57

68
String getClassName();
79

810
byte[] getClassBytes();
11+
12+
default List<? extends ConfigMappingMetadata> getNested() {
13+
return List.of();
14+
}
915
}

implementation/src/test/java/io/smallrye/config/ConfigMappingClassTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
import static org.junit.jupiter.api.Assertions.assertTrue;
66

77
import java.util.HashMap;
8+
import java.util.List;
89
import java.util.Map;
910
import java.util.Optional;
1011
import java.util.OptionalInt;
12+
import java.util.Set;
13+
import java.util.stream.Collectors;
1114

1215
import org.eclipse.microprofile.config.spi.Converter;
1316
import org.junit.jupiter.api.Assertions;
@@ -259,6 +262,25 @@ void mapNestedWithFieldInitializerIgnored() {
259262
assertEquals(8080, mapping.servers.get("one").port);
260263
}
261264

265+
@Test
266+
void nestedMetadataCollection() {
267+
List<ConfigMappingMetadata> metadata = ConfigMappingLoader.getConfigMappingsMetadata(MapNestedClass.class);
268+
Set<String> names = metadata.stream()
269+
.map(ConfigMappingMetadata::getClassName)
270+
.collect(Collectors.toSet());
271+
272+
// ConfigMappingClass entries (generated interface names)
273+
assertTrue(names
274+
.contains(ConfigMappingLoader.ConfigMappingClass.getConfigurationClass(MapNestedClass.class).getClassName()));
275+
assertTrue(names.contains(
276+
ConfigMappingLoader.ConfigMappingClass.getConfigurationClass(MapNestedClass.ServerEntry.class).getClassName()));
277+
// ConfigMappingInterface entries (implementation class names)
278+
assertTrue(names.contains(ConfigMappingInterface.getImplementationClassName(
279+
ConfigMappingLoader.getConfigMapping(MapNestedClass.class).getInterfaceType())));
280+
assertTrue(names.contains(ConfigMappingInterface.getImplementationClassName(
281+
ConfigMappingLoader.getConfigMapping(MapNestedClass.ServerEntry.class).getInterfaceType())));
282+
}
283+
262284
static class MapNestedClass {
263285
Map<String, ServerEntry> servers = new HashMap<>();
264286

0 commit comments

Comments
 (0)