Skip to content

Commit 965d15e

Browse files
committed
[MNG-5102] Add support for POM mixins
1 parent 3c02ad0 commit 965d15e

File tree

17 files changed

+428
-233
lines changed

17 files changed

+428
-233
lines changed

api/maven-api-model/src/main/mdo/maven.mdo

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,20 @@
112112
</association>
113113
</field>
114114

115+
<!-- ====================================================================== -->
116+
<!-- Mixins -->
117+
<!-- ====================================================================== -->
118+
119+
<field xdoc.separator="blank">
120+
<name>mixins</name>
121+
<version>4.1.0+</version>
122+
<description>Mixins...</description>
123+
<association>
124+
<type>Parent</type>
125+
<multiplicity>*</multiplicity>
126+
</association>
127+
</field>
128+
115129
<!-- ====================================================================== -->
116130
<!-- groupId/artifactId/Version/Packaging -->
117131
<!-- ====================================================================== -->

compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FileToRawModelMerger.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ protected void mergeModel_Profiles(
138138
.collect(Collectors.toList()));
139139
}
140140

141+
@Override
142+
protected void mergeModel_Mixins(
143+
Model.Builder builder, Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
144+
// don't merge
145+
}
146+
141147
@Override
142148
protected void mergeModelBase_Dependencies(
143149
ModelBase.Builder builder,

impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ static Model transformNonPom(Model model, MavenProject project) {
210210
.preserveModelVersion(false)
211211
.root(false)
212212
.parent(null)
213+
.mixins(null)
213214
.build(null),
214215
model)
215216
.mailingLists(null)

impl/maven-impl/src/main/java/org/apache/maven/api/services/model/ModelResolver.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ record ModelResolverRequest(
8787
@Nonnull String version,
8888
@Nullable String classifier)
8989
implements Request<Session> {
90+
public ModelResolverRequest {
91+
Objects.requireNonNull(session, "session cannot be null");
92+
Objects.requireNonNull(groupId, "groupId cannot be null");
93+
Objects.requireNonNull(artifactId, "artifactId cannot be null");
94+
Objects.requireNonNull(version, "version cannot be null");
95+
}
96+
9097
@Nonnull
9198
@Override
9299
public Session getSession() {

impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultInheritanceAssembler.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ private void concatPath(StringBuilder url, String path) {
194194
}
195195
}
196196

197+
@Override
198+
protected void mergeModel_Mixins(
199+
Model.Builder builder,
200+
Model target,
201+
Model source,
202+
boolean sourceDominant,
203+
Map<Object, Object> context) {
204+
// do not merge
205+
}
206+
197207
@Override
198208
protected void mergeModelBase_Properties(
199209
ModelBase.Builder builder,

impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -840,12 +840,11 @@ void buildEffectiveModel(Collection<String> importIds) throws ModelBuilderExcept
840840
}
841841
}
842842

843-
Model readParent(Model childModel, DefaultProfileActivationContext profileActivationContext) {
843+
Model readParent(Model childModel, Parent parent, DefaultProfileActivationContext profileActivationContext) {
844844
Model parentModel;
845845

846-
Parent parent = childModel.getParent();
847846
if (parent != null) {
848-
parentModel = resolveParent(childModel, profileActivationContext);
847+
parentModel = resolveParent(childModel, parent, profileActivationContext);
849848

850849
if (!"pom".equals(parentModel.getPackaging())) {
851850
add(
@@ -870,23 +869,24 @@ Model readParent(Model childModel, DefaultProfileActivationContext profileActiva
870869
return parentModel;
871870
}
872871

873-
private Model resolveParent(Model childModel, DefaultProfileActivationContext profileActivationContext)
872+
private Model resolveParent(
873+
Model childModel, Parent parent, DefaultProfileActivationContext profileActivationContext)
874874
throws ModelBuilderException {
875875
Model parentModel = null;
876876
if (isBuildRequest()) {
877-
parentModel = readParentLocally(childModel, profileActivationContext);
877+
parentModel = readParentLocally(childModel, parent, profileActivationContext);
878878
}
879879
if (parentModel == null) {
880-
parentModel = resolveAndReadParentExternally(childModel, profileActivationContext);
880+
parentModel = resolveAndReadParentExternally(childModel, parent, profileActivationContext);
881881
}
882882
return parentModel;
883883
}
884884

885-
private Model readParentLocally(Model childModel, DefaultProfileActivationContext profileActivationContext)
885+
private Model readParentLocally(
886+
Model childModel, Parent parent, DefaultProfileActivationContext profileActivationContext)
886887
throws ModelBuilderException {
887888
ModelSource candidateSource;
888889

889-
Parent parent = childModel.getParent();
890890
String parentPath = parent.getRelativePath();
891891
if (request.getRequestType() == ModelBuilderRequest.RequestType.BUILD_PROJECT) {
892892
if (parentPath != null && !parentPath.isEmpty()) {
@@ -927,10 +927,9 @@ private Model readParentLocally(Model childModel, DefaultProfileActivationContex
927927
String version = getVersion(candidateModel);
928928

929929
// Ensure that relative path and GA match, if both are provided
930-
if (groupId == null
931-
|| !groupId.equals(parent.getGroupId())
932-
|| artifactId == null
933-
|| !artifactId.equals(parent.getArtifactId())) {
930+
if (parent.getGroupId() != null && (groupId == null || !groupId.equals(parent.getGroupId()))
931+
|| parent.getArtifactId() != null
932+
&& (artifactId == null || !artifactId.equals(parent.getArtifactId()))) {
934933
mismatchRelativePathAndGA(childModel, groupId, artifactId);
935934
return null;
936935
}
@@ -1002,13 +1001,12 @@ private void wrongParentRelativePath(Model childModel) {
10021001
add(Severity.FATAL, Version.BASE, buffer.toString(), parent.getLocation(""));
10031002
}
10041003

1005-
Model resolveAndReadParentExternally(Model childModel, DefaultProfileActivationContext profileActivationContext)
1004+
Model resolveAndReadParentExternally(
1005+
Model childModel, Parent parent, DefaultProfileActivationContext profileActivationContext)
10061006
throws ModelBuilderException {
10071007
ModelBuilderRequest request = this.request;
10081008
setSource(childModel);
10091009

1010-
Parent parent = childModel.getParent();
1011-
10121010
String groupId = parent.getGroupId();
10131011
String artifactId = parent.getArtifactId();
10141012
String version = parent.getVersion();
@@ -1150,7 +1148,8 @@ private Model readEffectiveModel() throws ModelBuilderException {
11501148
profileActivationContext.setUserProperties(profileProps);
11511149
}
11521150

1153-
Model parentModel = readParent(activatedFileModel, profileActivationContext);
1151+
Model parentModel =
1152+
readParent(activatedFileModel, activatedFileModel.getParent(), profileActivationContext);
11541153

11551154
// Now that we have read the parent, we can set the relative
11561155
// path correctly if it was not set in the input model
@@ -1172,6 +1171,12 @@ private Model readEffectiveModel() throws ModelBuilderException {
11721171

11731172
Model model = inheritanceAssembler.assembleModelInheritance(inputModel, parentModel, request, this);
11741173

1174+
// Mixins
1175+
for (Parent mixin : model.getMixins()) {
1176+
Model parent = resolveParent(model, mixin, profileActivationContext);
1177+
model = inheritanceAssembler.assembleModelInheritance(model, parent, request, this);
1178+
}
1179+
11751180
// model normalization
11761181
model = modelNormalizer.mergeDuplicates(model, request, this);
11771182

@@ -1544,7 +1549,7 @@ Model readAsParentModel(DefaultProfileActivationContext profileActivationContext
15441549
private Model doReadAsParentModel(DefaultProfileActivationContext profileActivationContext)
15451550
throws ModelBuilderException {
15461551
Model raw = readRawModel();
1547-
Model parentData = readParent(raw, profileActivationContext);
1552+
Model parentData = readParent(raw, raw.getParent(), profileActivationContext);
15481553
Model parent = new DefaultInheritanceAssembler(new DefaultInheritanceAssembler.InheritanceModelMerger() {
15491554
@Override
15501555
protected void mergeModel_Modules(

impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,11 @@ public void validateFileModel(Model m, int validationLevel, ModelProblemCollecto
356356
}
357357
}
358358

359+
for (Parent mixin : m.getMixins()) {
360+
// TODO: validate mixin
361+
mixin.getId();
362+
}
363+
359364
if (validationLevel == ModelValidator.VALIDATION_LEVEL_MINIMAL) {
360365
// profiles: they are essential for proper model building (may contribute profiles, dependencies...)
361366
HashSet<String> minProfileIds = new HashSet<>();

0 commit comments

Comments
 (0)