ibessonov commented on code in PR #6325: URL: https://github.com/apache/ignite-3/pull/6325#discussion_r2238986734
########## 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: I don't think it's allowed right now, but relying on a hierarchy of Java classes instead of a hierarchy of "logical" configuration schema representation might not be a good idea, IF I understood your point correctly -- 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