in build-systems/src/commonMain/kotlin/org/jetbrains/packagesearch/maven/PomResolver.kt [107:184]
public suspend fun resolve(model: ProjectObjectModel): ProjectObjectModel {
// Initialize the mergedPom with the given model.
var mergedPom = model
// Start by retrieving the parent of the given model.
var currentParent = mergedPom.parent
// Initialize a count variable to ensure that the loop does not run indefinitely.
var count = 0
// Loop to merge parent POMs until a max of 10 parent POMs or until there's no parent.
while (count < 10) {
count++
// If there's no parent, break out of the loop.
val parent = currentParent ?: break
// Attempt to retrieve the POM for the parent. If it fails or if it's null, break out of the loop.
val parentPom = runCatching { getPom(parent) }.getOrNull() ?: break
// Merge the current mergedPom with its parent. This includes merging the dependencies,
// dependencyManagement, and properties.
// Note: The 'distinct()' function ensures that there are no duplicate items.
mergedPom =
mergedPom.copy(
groupId = mergedPom.groupId ?: parentPom.groupId,
artifactId = mergedPom.artifactId ?: parentPom.artifactId,
dependencies = parentPom.dependencies.plus(mergedPom.dependencies).distinct(),
dependencyManagement = parentPom.dependencyManagement.plus(mergedPom.dependencyManagement).distinct(),
properties = parentPom.properties + mergedPom.properties,
)
// Update the currentParent for the next iteration.
currentParent = parentPom.parent
}
// Convert the mergedPom to a JSON object for easier property value resolution.
val accessor = Json.encodeToJsonElement(mergedPom).jsonObject
// Resolve the versions in the dependencyManagement section of the mergedPom.
// This creates a map with keys as DependencyKey and values as the corresponding dependency with resolved version.
val resolvedDependencyManagement =
mergedPom.dependencyManagement
.map { it.copy(version = it.version?.resolve(mergedPom.properties, accessor)) }
.associateBy { DependencyKey(it.groupId, it.artifactId) }
// Resolve the versions in the dependencies section of the mergedPom.
// If the version is present in resolvedDependencyManagement, use that. Otherwise, resolve it using properties.
val resolvedDependencies =
mergedPom.dependencies
.map {
it.copy(
version =
resolvedDependencyManagement[DependencyKey(it.groupId, it.artifactId)]
?.takeIf { it.version != null }
?.version
?: it.version?.resolve(mergedPom.properties, accessor),
)
}
// Return the final mergedPom with all resolved properties, dependencies, and dependencyManagement.
return mergedPom.copy(
groupId = mergedPom.groupId?.resolve(mergedPom.properties, accessor),
artifactId = mergedPom.artifactId?.resolve(mergedPom.properties, accessor),
dependencies = resolvedDependencies,
dependencyManagement = resolvedDependencyManagement.values.toList(),
properties = mergedPom.properties.mapValues { it.value.resolve(mergedPom.properties, accessor) },
name = mergedPom.name?.resolve(mergedPom.properties, accessor),
description = mergedPom.description?.resolve(mergedPom.properties, accessor),
scm =
mergedPom.scm?.copy(
connection = mergedPom.scm?.connection?.resolve(mergedPom.properties, accessor),
developerConnection = mergedPom.scm?.developerConnection?.resolve(mergedPom.properties, accessor),
url = mergedPom.scm?.url?.resolve(mergedPom.properties, accessor),
tag = mergedPom.scm?.tag?.resolve(mergedPom.properties, accessor),
),
)
}