private ObjectNode convertToObjectNode()

in log4j-converter-config/src/main/java/org/apache/logging/converter/config/internal/v2/AbstractJacksonConfigurationMapper.java [119:176]


    private ObjectNode convertToObjectNode(
            ConfigurationNode configurationNode, JsonNodeFactory nodeFactory, boolean explicitTypeAttribute) {
        ObjectNode objectNode = nodeFactory.objectNode();
        if (explicitTypeAttribute || requiresExplicitTypeAttribute(configurationNode)) {
            objectNode.set(TYPE_ATTRIBUTE, nodeFactory.textNode(configurationNode.getPluginName()));
        }
        configurationNode.getAttributes().forEach(objectNode::put);
        // If multiple nodes have the same name, we need to use JSON arrays or explicit type attributes.
        // For a given plugin type, the strategy is:
        // * For the first group of nodes with the given type we use an array.
        // * If there is a second group of nodes with the same plugin name, we use an explicit type attribute.
        //
        // This strategy does not require us to reorder the children elements, which is not a functionally neutral
        // operation
        // (e.g., for filters).
        Iterator<? extends ConfigurationNode> childrenIterator =
                configurationNode.getChildren().iterator();
        Collection<String> visitedPluginNames = new HashSet<>();
        Collection<ConfigurationNode> similarChildren = new ArrayList<>();
        @Nullable String similarChildrenPluginName = null;
        int counter = 1;
        while (childrenIterator.hasNext()) {
            ConfigurationNode child = childrenIterator.next();
            String childPluginName = child.getPluginName();
            // If the plugin name is the same, add to the current group
            if (childPluginName.equals(similarChildrenPluginName)) {
                similarChildren.add(child);
                continue;
            }
            // We have a new group
            if (!similarChildren.isEmpty()) {
                // Flush the previous group
                JsonNode childNode = convertToJsonNode(similarChildren, nodeFactory);
                String childKey = childNode instanceof ObjectNode && childNode.get(TYPE_ATTRIBUTE) != null
                        ? "id" + counter++
                        : similarChildrenPluginName;
                objectNode.set(childKey, convertToJsonNode(similarChildren, nodeFactory));
            }
            if (visitedPluginNames.add(childPluginName)) {
                // 1. This is the first group with the given plugin name:
                similarChildrenPluginName = childPluginName;
                similarChildren.clear();
                similarChildren.add(child);
            } else {
                // 2. Use an explicit type attribute
                objectNode.set("id" + counter++, convertToObjectNode(child, nodeFactory, true));
            }
        }
        // Flush the last group
        if (!similarChildren.isEmpty()) {
            JsonNode childNode = convertToJsonNode(similarChildren, nodeFactory);
            String childKey = childNode instanceof ObjectNode && childNode.get(TYPE_ATTRIBUTE) != null
                    ? "id" + counter
                    : similarChildrenPluginName;
            objectNode.set(childKey, convertToJsonNode(similarChildren, nodeFactory));
        }
        return objectNode;
    }