in modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationFlattener.java [170:266]
public Void doVisitNamedListNode(Field field, String key, NamedListNode<?> newNode) {
boolean isDeprecated = field.isAnnotationPresent(Deprecated.class);
// Read same named list node from old tree.
NamedListNode<?> oldNode =
oldInnerNodesStack.element().traverseChild(key, ConfigurationUtil.namedListNodeVisitor(), true);
// Old keys ordering can be ignored if we either create or delete everything.
Map<String, Integer> oldKeysToOrderIdxMap = singleTreeTraversal ? null : keysToOrderIdx(oldNode);
// New keys ordering can be ignored if we delete everything.
Map<String, Integer> newKeysToOrderIdxMap = deletion ? null : keysToOrderIdx(newNode);
for (String newNodeKey : newNode.namedListKeys()) {
UUID newNodeInternalId = newNode.internalId(newNodeKey);
String namedListFullKey = currentKey();
withTracking(newNodeInternalId.toString(), false, false, () -> {
InnerNode newNamedElement = isDeprecated ? null : newNode.getInnerNode(newNodeKey);
String oldNodeKey = oldNode.keyByInternalId(newNodeInternalId);
InnerNode oldNamedElement = oldNode.getInnerNode(oldNodeKey);
// Deletion of nonexistent element.
if (oldNamedElement == null && newNamedElement == null) {
return null;
}
if (newNamedElement == null) {
visitAsymmetricInnerNode(oldNamedElement, true);
} else if (oldNamedElement == null) {
visitAsymmetricInnerNode(newNamedElement, isDeprecated);
} else if (newNamedElement.schemaType() != oldNamedElement.schemaType()) {
// At the moment, we do not separate the general fields from the fields of
// specific instances of the polymorphic configuration, so we will assume
// that all the fields have changed, perhaps we will fix this later.
visitAsymmetricInnerNode(oldNamedElement, true);
visitAsymmetricInnerNode(newNamedElement, isDeprecated);
} else {
oldInnerNodesStack.push(oldNamedElement);
newNamedElement.traverseChildren(this, true);
oldInnerNodesStack.pop();
}
Integer newIdx = newKeysToOrderIdxMap == null ? null : newKeysToOrderIdxMap.get(newNodeKey);
Integer oldIdx = oldKeysToOrderIdxMap == null ? null : oldKeysToOrderIdxMap.get(newNodeKey);
// We should "persist" changed indexes only.
if (!Objects.equals(newIdx, oldIdx) || singleTreeTraversal || newNamedElement == null) {
String orderKey = currentKey() + NamedListNode.ORDER_IDX;
resMap.put(orderKey, deletion || newNamedElement == null ? null : newIdx);
}
// If it's creation / deletion / rename.
if (singleTreeTraversal || oldNamedElement == null || newNamedElement == null
|| !oldNodeKey.equals(newNodeKey)
) {
String nameKey = currentKey() + NamedListNode.NAME;
resMap.put(nameKey, deletion || newNamedElement == null ? null : newNodeKey);
}
if (singleTreeTraversal) {
if (deletion) {
// Deletion as a part of outer named list element.
resMap.put(idKey(namedListFullKey, oldNodeKey), null);
} else {
// Creation as a part of outer named list's new element.
resMap.put(idKey(namedListFullKey, newNodeKey), newNodeInternalId);
}
} else {
// Regular deletion.
if (newNamedElement == null) {
resMap.put(idKey(namedListFullKey, oldNodeKey), null);
} else if (oldNamedElement == null) {
// Regular creation.
resMap.put(idKey(namedListFullKey, newNodeKey), newNodeInternalId);
} else if (!oldNodeKey.equals(newNodeKey)) {
// Rename. Old value is nullified.
resMap.put(idKey(namedListFullKey, oldNodeKey), null);
// And new value is initialized.
resMap.put(idKey(namedListFullKey, newNodeKey), newNodeInternalId);
}
}
return null;
});
}
return null;
}