AMashenkov commented on code in PR #6325:
URL: https://github.com/apache/ignite-3/pull/6325#discussion_r2237092816
##########
modules/runner/src/test/java/org/apache/ignite/internal/configuration/compatibility/framework/ConfigurationTreeScanner.java:
##########
@@ -83,33 +81,75 @@ public class ConfigurationTreeScanner {
* @param context The context containing dependency information.
*/
public static void scan(ConfigNode currentNode, Class<?> schemaClass,
ScanContext context) {
+ scan(currentNode, schemaClass, context, Set.of());
+ }
+
+ private static void scan(ConfigNode currentNode, Class<?> schemaClass,
ScanContext context, Set<String> skipFields) {
assert schemaClass != null &&
schemaClass.getName().startsWith("org.apache.ignite");
Collection<Class<?>> extensions = context.getExtensions(schemaClass);
if (!extensions.isEmpty()) {
extensions.stream()
.sorted(Comparator.comparing(Class::getName)) // Sort for
test stability.
- .forEach(ext -> scan(currentNode, ext, context));
+ .forEach(ext -> scan(currentNode, ext, context,
skipFields));
return;
}
- List<ConfigNode> children = new ArrayList<>();
+ Map<Field, Set<Class<?>>> instancesPerField = new HashMap<>();
+ String[] defaultInstanceId = new String[1];
+
+ // Non-polymorphic fields
configurationClasses(schemaClass).stream()
.flatMap(c -> Arrays.stream(c.getDeclaredFields()))
.filter(field -> !Modifier.isStatic(field.getModifiers()))
+ .filter(field -> !skipFields.contains(field.getName()))
.sorted(Comparator.comparing(Field::getName)) // Sort for test
stability.
.forEach(field -> {
- ConfigNode node = createNodeForField(currentNode, field);
+ Class<?> type = field.getType();
+ Set<Class<?>> instanceClasses =
context.getPolymorphicInstances(type);
+
+ // Field itself
+ ConfigNode node = createNodeForField(currentNode, field,
type);
+
+ if (instanceClasses.isEmpty()) {
+ // Single node
+ if (!node.isValue()) {
+ scan(node, type, context, skipFields);
+ }
- children.add(node);
- if (!node.isValue()) {
- scan(node, field.getType(), context);
+ currentNode.addChildNodes(List.of(node));
+ } else {
+ defaultInstanceId[0] =
extractDefaultPolymorphicId(field, type);
+
+ instancesPerField.put(field, instanceClasses);
}
});
- currentNode.addChildNodes(children);
+ // Polymorphic fields
+ for (Entry<Field, Set<Class<?>>> e : instancesPerField.entrySet()) {
+ Field field = e.getKey();
+ Set<Class<?>> instanceClasses = e.getValue();
+ Map<String, ConfigNode> polymorphicInstances = new HashMap<>();
+
+ Set<String> baseClassFields =
Arrays.stream(field.getType().getDeclaredFields())
+ .map(Field::getName)
+ .collect(Collectors.toSet());
+
+ // Collect nodes that correspond to polymorphic instances
+ for (Class<?> instanceClass : instanceClasses) {
+ ConfigNode instanceTypeNode = createNodeForField(currentNode,
field, instanceClass);
+
polymorphicInstances.put(instanceTypeNode.polymorphicInstanceId(),
instanceTypeNode);
+
+ // Each polymorphic instance includes fields from the base
class
+ scan(instanceTypeNode, field.getType(), context);
+ // And its own fields ignoring base class fields.
+ scan(instanceTypeNode, instanceClass, context,
baseClassFields);
Review Comment:
Should we scan all PolymorphicInstance class parents instead?
E.g. there can be intermediate classes between field.getType and
instanceClass.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]