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 in hierarchy 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: notifications-unsubscr...@ignite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org