6666import org .apache .maven .api .model .Exclusion ;
6767import org .apache .maven .api .model .InputLocation ;
6868import org .apache .maven .api .model .InputSource ;
69+ import org .apache .maven .api .model .Mixin ;
6970import org .apache .maven .api .model .Model ;
7071import org .apache .maven .api .model .Parent ;
7172import org .apache .maven .api .model .Profile ;
@@ -851,12 +852,11 @@ void buildEffectiveModel(Collection<String> importIds) throws ModelBuilderExcept
851852 }
852853 }
853854
854- Model readParent (Model childModel , DefaultProfileActivationContext profileActivationContext ) {
855+ Model readParent (Model childModel , Parent parent , DefaultProfileActivationContext profileActivationContext ) {
855856 Model parentModel ;
856857
857- Parent parent = childModel .getParent ();
858858 if (parent != null ) {
859- parentModel = resolveParent (childModel , profileActivationContext );
859+ parentModel = resolveParent (childModel , parent , profileActivationContext );
860860
861861 if (!"pom" .equals (parentModel .getPackaging ())) {
862862 add (
@@ -881,23 +881,26 @@ Model readParent(Model childModel, DefaultProfileActivationContext profileActiva
881881 return parentModel ;
882882 }
883883
884- private Model resolveParent (Model childModel , DefaultProfileActivationContext profileActivationContext )
884+ private Model resolveParent (
885+ Model childModel , Parent parent , DefaultProfileActivationContext profileActivationContext )
885886 throws ModelBuilderException {
886887 Model parentModel = null ;
887888 if (isBuildRequest ()) {
888- parentModel = readParentLocally (childModel , profileActivationContext );
889+ parentModel = readParentLocally (childModel , parent , profileActivationContext );
889890 }
890891 if (parentModel == null ) {
891- parentModel = resolveAndReadParentExternally (childModel , profileActivationContext );
892+ parentModel = resolveAndReadParentExternally (childModel , parent , profileActivationContext );
892893 }
893894 return parentModel ;
894895 }
895896
896- private Model readParentLocally (Model childModel , DefaultProfileActivationContext profileActivationContext )
897+ private Model readParentLocally (
898+ Model childModel , Parent parent , DefaultProfileActivationContext profileActivationContext )
897899 throws ModelBuilderException {
898900 ModelSource candidateSource ;
899901
900- Parent parent = childModel .getParent ();
902+ boolean isParentOrSimpleMixin =
903+ !(parent instanceof Mixin mixin ) || (mixin .getClassifier () == null && mixin .getExtension () == null );
901904 String parentPath = parent .getRelativePath ();
902905 if (request .getRequestType () == ModelBuilderRequest .RequestType .BUILD_PROJECT ) {
903906 if (parentPath != null && !parentPath .isEmpty ()) {
@@ -906,14 +909,16 @@ private Model readParentLocally(Model childModel, DefaultProfileActivationContex
906909 wrongParentRelativePath (childModel );
907910 return null ;
908911 }
909- } else {
912+ } else if ( isParentOrSimpleMixin ) {
910913 candidateSource =
911914 resolveReactorModel (parent .getGroupId (), parent .getArtifactId (), parent .getVersion ());
912915 if (candidateSource == null && parentPath == null ) {
913916 candidateSource = request .getSource ().resolve (modelProcessor ::locateExistingPom , ".." );
914917 }
918+ } else {
919+ candidateSource = null ;
915920 }
916- } else {
921+ } else if ( isParentOrSimpleMixin ) {
917922 candidateSource = resolveReactorModel (parent .getGroupId (), parent .getArtifactId (), parent .getVersion ());
918923 if (candidateSource == null ) {
919924 if (parentPath == null ) {
@@ -923,6 +928,8 @@ private Model readParentLocally(Model childModel, DefaultProfileActivationContex
923928 candidateSource = request .getSource ().resolve (modelProcessor ::locateExistingPom , parentPath );
924929 }
925930 }
931+ } else {
932+ candidateSource = null ;
926933 }
927934
928935 if (candidateSource == null ) {
@@ -938,11 +945,10 @@ private Model readParentLocally(Model childModel, DefaultProfileActivationContex
938945 String version = getVersion (candidateModel );
939946
940947 // Ensure that relative path and GA match, if both are provided
941- if (groupId == null
942- || !groupId .equals (parent .getGroupId ())
943- || artifactId == null
944- || !artifactId .equals (parent .getArtifactId ())) {
945- mismatchRelativePathAndGA (childModel , groupId , artifactId );
948+ if (parent .getGroupId () != null && (groupId == null || !groupId .equals (parent .getGroupId ()))
949+ || parent .getArtifactId () != null
950+ && (artifactId == null || !artifactId .equals (parent .getArtifactId ()))) {
951+ mismatchRelativePathAndGA (childModel , parent , groupId , artifactId );
946952 return null ;
947953 }
948954
@@ -981,8 +987,7 @@ private Model readParentLocally(Model childModel, DefaultProfileActivationContex
981987 return candidateModel ;
982988 }
983989
984- private void mismatchRelativePathAndGA (Model childModel , String groupId , String artifactId ) {
985- Parent parent = childModel .getParent ();
990+ private void mismatchRelativePathAndGA (Model childModel , Parent parent , String groupId , String artifactId ) {
986991 StringBuilder buffer = new StringBuilder (256 );
987992 buffer .append ("'parent.relativePath'" );
988993 if (childModel != getRootModel ()) {
@@ -1013,16 +1018,17 @@ private void wrongParentRelativePath(Model childModel) {
10131018 add (Severity .FATAL , Version .BASE , buffer .toString (), parent .getLocation ("" ));
10141019 }
10151020
1016- Model resolveAndReadParentExternally (Model childModel , DefaultProfileActivationContext profileActivationContext )
1021+ Model resolveAndReadParentExternally (
1022+ Model childModel , Parent parent , DefaultProfileActivationContext profileActivationContext )
10171023 throws ModelBuilderException {
10181024 ModelBuilderRequest request = this .request ;
10191025 setSource (childModel );
10201026
1021- Parent parent = childModel .getParent ();
1022-
10231027 String groupId = parent .getGroupId ();
10241028 String artifactId = parent .getArtifactId ();
10251029 String version = parent .getVersion ();
1030+ String classifier = parent instanceof Mixin mixin ? mixin .getClassifier () : null ;
1031+ String extension = parent instanceof Mixin mixin ? mixin .getExtension () : null ;
10261032
10271033 // add repositories specified by the current model so that we can resolve the parent
10281034 if (!childModel .getRepositories ().isEmpty ()) {
@@ -1040,12 +1046,23 @@ Model resolveAndReadParentExternally(Model childModel, DefaultProfileActivationC
10401046
10411047 ModelSource modelSource ;
10421048 try {
1043- modelSource = resolveReactorModel (parent .getGroupId (), parent .getArtifactId (), parent .getVersion ());
1049+ modelSource = classifier == null && extension == null
1050+ ? resolveReactorModel (parent .getGroupId (), parent .getArtifactId (), parent .getVersion ())
1051+ : null ;
10441052 if (modelSource == null ) {
1045- AtomicReference <Parent > modified = new AtomicReference <>();
1046- modelSource = modelResolver .resolveModel (request .getSession (), repositories , parent , modified );
1047- if (modified .get () != null ) {
1048- parent = modified .get ();
1053+ ModelResolver .ModelResolverRequest req = new ModelResolver .ModelResolverRequest (
1054+ request .getSession (),
1055+ null ,
1056+ repositories ,
1057+ parent .getGroupId (),
1058+ parent .getArtifactId (),
1059+ parent .getVersion (),
1060+ classifier ,
1061+ extension != null ? extension : "pom" );
1062+ ModelResolver .ModelResolverResult result = modelResolver .resolveModel (req );
1063+ modelSource = result .source ();
1064+ if (result .version () != null ) {
1065+ parent = parent .withVersion (result .version ());
10491066 }
10501067 }
10511068 } catch (ModelResolverException e ) {
@@ -1161,7 +1178,8 @@ private Model readEffectiveModel() throws ModelBuilderException {
11611178 profileActivationContext .setUserProperties (profileProps );
11621179 }
11631180
1164- Model parentModel = readParent (activatedFileModel , profileActivationContext );
1181+ Model parentModel =
1182+ readParent (activatedFileModel , activatedFileModel .getParent (), profileActivationContext );
11651183
11661184 // Now that we have read the parent, we can set the relative
11671185 // path correctly if it was not set in the input model
@@ -1183,6 +1201,12 @@ private Model readEffectiveModel() throws ModelBuilderException {
11831201
11841202 Model model = inheritanceAssembler .assembleModelInheritance (inputModel , parentModel , request , this );
11851203
1204+ // Mixins
1205+ for (Mixin mixin : model .getMixins ()) {
1206+ Model parent = resolveParent (model , mixin , profileActivationContext );
1207+ model = inheritanceAssembler .assembleModelInheritance (model , parent , request , this );
1208+ }
1209+
11861210 // model normalization
11871211 model = modelNormalizer .mergeDuplicates (model , request , this );
11881212
@@ -1367,7 +1391,7 @@ Model doReadFileModel() throws ModelBuilderException {
13671391 .version (parentVersion )
13681392 .build ());
13691393 } else {
1370- mismatchRelativePathAndGA (model , parentGroupId , parentArtifactId );
1394+ mismatchRelativePathAndGA (model , parent , parentGroupId , parentArtifactId );
13711395 }
13721396 } else {
13731397 if (!MODEL_VERSION_4_0_0 .equals (model .getModelVersion ()) && path != null ) {
@@ -1555,8 +1579,9 @@ Model readAsParentModel(DefaultProfileActivationContext profileActivationContext
15551579 private Model doReadAsParentModel (DefaultProfileActivationContext profileActivationContext )
15561580 throws ModelBuilderException {
15571581 Model raw = readRawModel ();
1558- Model parentData = readParent (raw , profileActivationContext );
1559- Model parent = new DefaultInheritanceAssembler (new DefaultInheritanceAssembler .InheritanceModelMerger () {
1582+ Model parentData = readParent (raw , raw .getParent (), profileActivationContext );
1583+ DefaultInheritanceAssembler defaultInheritanceAssembler =
1584+ new DefaultInheritanceAssembler (new DefaultInheritanceAssembler .InheritanceModelMerger () {
15601585 @ Override
15611586 protected void mergeModel_Modules (
15621587 Model .Builder builder ,
@@ -1572,8 +1597,12 @@ protected void mergeModel_Subprojects(
15721597 Model source ,
15731598 boolean sourceDominant ,
15741599 Map <Object , Object > context ) {}
1575- })
1576- .assembleModelInheritance (raw , parentData , request , this );
1600+ });
1601+ Model parent = defaultInheritanceAssembler .assembleModelInheritance (raw , parentData , request , this );
1602+ for (Mixin mixin : parent .getMixins ()) {
1603+ Model parentModel = resolveParent (parent , mixin , profileActivationContext );
1604+ parent = defaultInheritanceAssembler .assembleModelInheritance (parent , parentModel , request , this );
1605+ }
15771606
15781607 // activate profiles
15791608 List <Profile > parentActivePomProfiles = getActiveProfiles (parent .getProfiles (), profileActivationContext );
0 commit comments