Class QualificationCascade
The two #574 qualification arms — ws:add's add-time
qualification and the scaffold-publish self-heal — rewrote only the
subproject root POM's own <version>. A multi-module
subproject was left internally split: every child's
<parent><version> still named the unqualified version, so the
children either built against a stale external parent resolved from a
repository (inheriting the unqualified version) or failed parent
resolution outright. Observed 2026-08-18 adding ikm-reasoner
(21 child modules, two aggregator levels) to the incremental-reasoner
sibling.
This cascade applies one version move old → new to the whole
tree, precisely:
- every tree POM whose own literal
<version>isold(the root's own version; a child that redundantly declares its own version) is rewritten tonew; - every tree POM whose
<parent>names an in-tree POM by full groupId:artifactId and whose parent version isoldis rewritten tonewvia the OpenRewrite-LST editor (PomModel.updateParentVersion(String, String, String, String)) — never string replacement.
What it never touches: an external <parent> (GA not produced
by the tree — e.g. ikm-reasoner's java-parent), and dependency
versions that merely coincide with old literally. GA matching,
not literal string matching, is the precision guarantee (#241 set the
precedent for full-GA matching).
De-qualification already cascades on the finish side
(FeatureFinishSupport.setAllVersions +
stripAllBranchQualifiedVersions), so the round trip is
symmetric once both #574 arms route through here.
-
Method Summary
Modifier and TypeMethodDescriptionstatic intApply the version moveoldVersion → newVersionacross the member's whole module tree, as described in the class javadoc.static booleanhasStaleTree(Path memberDir, String baseVersion, org.apache.maven.api.plugin.Log log) Whether the member's tree still referencesbaseVersion— an in-tree<parent>at that version, or a POM's own literal<version>at it.static StringspliceOwnVersion(String content, String oldVersion, String newVersion) Rewrite a POM's own<version>incontent, searching past the</parent>block so a parent version that coincidentally equalsoldVersionis never mistaken for the project's own (the project<version>precedes<dependencies>, so the first match after</parent>is the project's own).
-
Method Details
-
apply
public static int apply(Path memberDir, String oldVersion, String newVersion, org.apache.maven.api.plugin.Log log) throws IOException Apply the version moveoldVersion → newVersionacross the member's whole module tree, as described in the class javadoc.Failures on individual POMs (unreadable, unparseable) are logged and skipped rather than failing the move — matching the non-fatal posture of both #574 arms, whose callers treat qualification as self-healable on the next scaffold-publish.
- Parameters:
memberDir- the subproject root directoryoldVersion- the version currently in the treenewVersion- the version the tree should carrylog- Maven logger for per-file debug and warnings- Returns:
- the number of POM files rewritten
- Throws:
IOException- if the root POM cannot be rewritten
-
hasStaleTree
public static boolean hasStaleTree(Path memberDir, String baseVersion, org.apache.maven.api.plugin.Log log) Whether the member's tree still referencesbaseVersion— an in-tree<parent>at that version, or a POM's own literal<version>at it. This is the reconciler's detection arm for trees whose root is already qualified but whose children were left behind by a pre-#1051 qualification (the state the reconciler's root-only read could not see).- Parameters:
memberDir- the subproject root directorybaseVersion- the unqualified version to look forlog- Maven logger for warnings on unreadable POMs- Returns:
truewhen at least one tree POM still carriesbaseVersionas described
-
spliceOwnVersion
Rewrite a POM's own<version>incontent, searching past the</parent>block so a parent version that coincidentally equalsoldVersionis never mistaken for the project's own (the project<version>precedes<dependencies>, so the first match after</parent>is the project's own). The single own-version splice of the cascade — successor of the retired root-onlyFeatureVersionReconciler.rewriteOwnVersion(#1051).- Parameters:
content- the POM textoldVersion- the current project versionnewVersion- the replacement version- Returns:
- the updated text, or
contentunchanged when the old version is absent outside the parent block
-