From 5d9eb9cf2f1dacd38c2956eb05958018524288ea Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Fri, 21 Feb 2025 14:57:51 +0100 Subject: [PATCH 1/6] [MNG-8588] Add activated profiles to Project interface --- .../java/org/apache/maven/api/Project.java | 14 ++++++ .../maven/internal/impl/DefaultProject.java | 6 +++ .../DefaultMavenProjectBuilderTest.java | 31 +++++++++++++ .../projects/pom-with-profiles/pom.xml | 46 +++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 impl/maven-core/src/test/resources/projects/pom-with-profiles/pom.xml diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java index 27cf17908cae..0e608b0ded33 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java @@ -20,6 +20,7 @@ import java.nio.file.Path; import java.util.List; +import java.util.Map; import java.util.Optional; import org.apache.maven.api.annotations.Experimental; @@ -237,4 +238,17 @@ default String getId() { */ @Nonnull Optional getParent(); + + /** + * Gets the identifiers of all profiles that contributed to this project's effective model. This includes active + * profiles from the project's POM and all its parent POMs as well as from external sources like the + * {@code settings.xml}. The profile identifiers are grouped by the identifier of their source, e.g. + * {@code ::} for a POM profile or {@code external} for profiles from the + * {@code settings.xml}. + * + * @return The identifiers of all activated profiles, indexed by the source from which the profiles originated, never + * {@code null}. + */ + @Nonnull + Map> getActivatedProfileIdsBySource(); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java index 6b7903b6d6ca..277b04701d6e 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import org.apache.maven.RepositoryUtils; @@ -165,6 +166,11 @@ public Optional getParent() { return Optional.ofNullable(session.getProject(parent)); } + @Override + public Map> getActivatedProfileIdsBySource() { + return project.getInjectedProfileIds(); + } + @Nonnull private DependencyCoordinates toDependency(org.apache.maven.api.model.Dependency dependency) { return new DependencyCoordinates() { diff --git a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index 60994b8213f4..09f3f085e9a0 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -345,6 +345,37 @@ void rereadPom_mng7063() throws Exception { assertThat(project.getName(), is("PROJECT NAME")); } + @Test + void testActivatedProfileIsResolved() throws Exception { + File testPom = getTestFile("src/test/resources/projects/pom-with-profiles/pom.xml"); + + ProjectBuildingRequest request = newBuildingRequest(); + request.setLocalRepository(getLocalRepository()); + request.setActiveProfileIds(List.of("profile1")); + + MavenProject project = projectBuilder.build(testPom, request).getProject(); + + assertEquals(1, project.getActiveProfiles().size()); + assertTrue(project.getActiveProfiles().stream().anyMatch(p -> "profile1".equals(p.getId()))); + assertTrue(project.getActiveProfiles().stream().noneMatch(p -> "profile2".equals(p.getId()))); + assertTrue(project.getActiveProfiles().stream().noneMatch(p -> "active-by-default".equals(p.getId()))); + } + + @Test + void testActivatedProfileByDefaultIsResolved() throws Exception { + File testPom = getTestFile("src/test/resources/projects/pom-with-profiles/pom.xml"); + + ProjectBuildingRequest request = newBuildingRequest(); + request.setLocalRepository(getLocalRepository()); + + MavenProject project = projectBuilder.build(testPom, request).getProject(); + + assertEquals(1, project.getActiveProfiles().size()); + assertTrue(project.getActiveProfiles().stream().noneMatch(p -> "profile1".equals(p.getId()))); + assertTrue(project.getActiveProfiles().stream().noneMatch(p -> "profile2".equals(p.getId()))); + assertTrue(project.getActiveProfiles().stream().anyMatch(p -> "active-by-default".equals(p.getId()))); + } + /** * Tests whether external version range parent references are build correctly. * diff --git a/impl/maven-core/src/test/resources/projects/pom-with-profiles/pom.xml b/impl/maven-core/src/test/resources/projects/pom-with-profiles/pom.xml new file mode 100644 index 000000000000..fdf4e9b47d4c --- /dev/null +++ b/impl/maven-core/src/test/resources/projects/pom-with-profiles/pom.xml @@ -0,0 +1,46 @@ + + + + + + 4.0.0 + + maven + maven-core + 2.0-SNAPSHOT + + Maven + + + + active-by-default + + true + + + + profile1 + + + profile2 + + + From 5308f551d9acd7ebb01dd088d96f60e9a63f32b5 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Fri, 21 Feb 2025 20:54:11 +0100 Subject: [PATCH 2/6] [MNG-8588] Add tests for getInjectedProfileIds() --- .../DefaultMavenProjectBuilderTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index 09f3f085e9a0..baaf5a00478a 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -29,6 +29,7 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.impl.InternalSession; import org.apache.maven.internal.impl.InternalMavenSession; +import org.apache.maven.model.Profile; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -345,6 +346,61 @@ void rereadPom_mng7063() throws Exception { assertThat(project.getName(), is("PROJECT NAME")); } + @Test + void testActivatedProfileBySource() throws Exception { + File testPom = getTestFile("src/test/resources/projects/pom-with-profiles/pom.xml"); + + ProjectBuildingRequest request = newBuildingRequest(); + request.setLocalRepository(getLocalRepository()); + request.setActiveProfileIds(List.of("profile1")); + + MavenProject project = projectBuilder.build(testPom, request).getProject(); + + assertTrue(project.getInjectedProfileIds().keySet().containsAll(List.of("external", project.getId()))); + assertTrue(project.getInjectedProfileIds().get("external").isEmpty()); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().anyMatch("profile1"::equals)); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile2"::equals)); + assertTrue( + project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("active-by-default"::equals)); + } + + @Test + void testActivatedDefaultProfileBySource() throws Exception { + File testPom = getTestFile("src/test/resources/projects/pom-with-profiles/pom.xml"); + + ProjectBuildingRequest request = newBuildingRequest(); + request.setLocalRepository(getLocalRepository()); + + MavenProject project = projectBuilder.build(testPom, request).getProject(); + + assertTrue(project.getInjectedProfileIds().keySet().containsAll(List.of("external", project.getId()))); + assertTrue(project.getInjectedProfileIds().get("external").isEmpty()); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile1"::equals)); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile2"::equals)); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().anyMatch("active-by-default"::equals)); + } + + @Test + void testActivatedExternalProfileBySource() throws Exception { + File testPom = getTestFile("src/test/resources/projects/pom-with-profiles/pom.xml"); + + ProjectBuildingRequest request = newBuildingRequest(); + request.setLocalRepository(getLocalRepository()); + + final Profile externalProfile = new Profile(); + externalProfile.setId("external-profile"); + request.addProfile(externalProfile); + request.setActiveProfileIds(List.of(externalProfile.getId())); + + MavenProject project = projectBuilder.build(testPom, request).getProject(); + + assertTrue(project.getInjectedProfileIds().keySet().containsAll(List.of("external", project.getId()))); + assertTrue(project.getInjectedProfileIds().get("external").stream().anyMatch("external-profile"::equals)); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile1"::equals)); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile2"::equals)); + assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().anyMatch("active-by-default"::equals)); + } + @Test void testActivatedProfileIsResolved() throws Exception { File testPom = getTestFile("src/test/resources/projects/pom-with-profiles/pom.xml"); From d7c1fc4c22d0af3af909be4cbec870f89c0b1ad5 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 26 Feb 2025 17:44:35 +0100 Subject: [PATCH 3/6] Define getActiveProfiles() instead --- .../java/org/apache/maven/api/Project.java | 26 +++++++---- .../maven/internal/impl/DefaultProject.java | 10 +++-- .../DefaultMavenProjectBuilderTest.java | 43 +++++++++++++++++++ 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java index 0e608b0ded33..d03c1a7fb91a 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java @@ -20,13 +20,13 @@ import java.nio.file.Path; import java.util.List; -import java.util.Map; import java.util.Optional; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.model.Build; import org.apache.maven.api.model.Model; +import org.apache.maven.api.model.Profile; /** * Interface representing a Maven project which can be created using the @@ -240,15 +240,23 @@ default String getId() { Optional getParent(); /** - * Gets the identifiers of all profiles that contributed to this project's effective model. This includes active - * profiles from the project's POM and all its parent POMs as well as from external sources like the - * {@code settings.xml}. The profile identifiers are grouped by the identifier of their source, e.g. - * {@code ::} for a POM profile or {@code external} for profiles from the - * {@code settings.xml}. + * Returns all active profiles for the current project build. + *

+ * Active profiles are those that have been explicitly activated through one of the following means: + *

    + *
  • Command line activation using the -P flag
  • + *
  • Maven settings activation in settings.xml via <activeProfiles>
  • + *
  • Automatic activation via <activation> conditions
  • + *
  • The default active profile (marked with <activeByDefault>true</activeByDefault>)
  • + *
+ *

+ * The active profiles control various aspects of the build configuration including but not + * limited to dependencies, plugins, properties, and build resources. * - * @return The identifiers of all activated profiles, indexed by the source from which the profiles originated, never - * {@code null}. + * @return a non-null, possibly empty list of active profiles for this project + * @since 4.0.0 + * @see Profile */ @Nonnull - Map> getActivatedProfileIdsBySource(); + List getActiveProfiles(); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java index 277b04701d6e..e66d50c6c969 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java @@ -23,7 +23,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; import org.apache.maven.RepositoryUtils; @@ -39,6 +38,7 @@ import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.model.DependencyManagement; import org.apache.maven.api.model.Model; +import org.apache.maven.api.model.Profile; import org.apache.maven.impl.MappedCollection; import org.apache.maven.impl.MappedList; import org.apache.maven.project.MavenProject; @@ -167,8 +167,12 @@ public Optional getParent() { } @Override - public Map> getActivatedProfileIdsBySource() { - return project.getInjectedProfileIds(); + @Nonnull + public List getActiveProfiles() { + List activeProfiles = project.getActiveProfiles(); + return activeProfiles != null + ? new MappedList<>(activeProfiles, org.apache.maven.model.Profile::getDelegate) + : List.of(); } @Nonnull diff --git a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index baaf5a00478a..8547a9268433 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -25,21 +25,26 @@ import java.nio.file.StandardCopyOption; import java.util.List; +import org.apache.maven.api.model.InputLocation; +import org.apache.maven.api.model.InputSource; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.impl.InternalSession; +import org.apache.maven.internal.impl.DefaultProject; import org.apache.maven.internal.impl.InternalMavenSession; import org.apache.maven.model.Profile; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.mockito.Mockito; import static org.apache.maven.project.ProjectBuildingResultWithProblemMessageMatcher.projectBuildingResultWithProblemMessage; import static org.codehaus.plexus.testing.PlexusExtension.getTestFile; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -378,6 +383,19 @@ void testActivatedDefaultProfileBySource() throws Exception { assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile1"::equals)); assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile2"::equals)); assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().anyMatch("active-by-default"::equals)); + + InternalMavenSession session = Mockito.mock(InternalMavenSession.class); + List activeProfiles = + new DefaultProject(session, project).getActiveProfiles(); + assertEquals(1, activeProfiles.size()); + org.apache.maven.api.model.Profile profile = activeProfiles.get(0); + assertEquals("active-by-default", profile.getId()); + InputLocation location = profile.getLocation(""); + assertNotNull(location); + assertThat(location.getLineNumber(), greaterThan(0)); + assertThat(location.getColumnNumber(), greaterThan(0)); + assertNotNull(location.getSource()); + assertThat(location.getSource().getLocation(), containsString("pom-with-profiles/pom.xml")); } @Test @@ -388,6 +406,10 @@ void testActivatedExternalProfileBySource() throws Exception { request.setLocalRepository(getLocalRepository()); final Profile externalProfile = new Profile(); + externalProfile.setLocation( + "", + new org.apache.maven.model.InputLocation( + 1, 1, new org.apache.maven.model.InputSource(new InputSource(null, "settings.xml", null)))); externalProfile.setId("external-profile"); request.addProfile(externalProfile); request.setActiveProfileIds(List.of(externalProfile.getId())); @@ -399,6 +421,27 @@ void testActivatedExternalProfileBySource() throws Exception { assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile1"::equals)); assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().noneMatch("profile2"::equals)); assertTrue(project.getInjectedProfileIds().get(project.getId()).stream().anyMatch("active-by-default"::equals)); + + InternalMavenSession session = Mockito.mock(InternalMavenSession.class); + List activeProfiles = + new DefaultProject(session, project).getActiveProfiles(); + assertEquals(2, activeProfiles.size()); + org.apache.maven.api.model.Profile profile = activeProfiles.get(0); + assertEquals("active-by-default", profile.getId()); + InputLocation location = profile.getLocation(""); + assertNotNull(location); + assertThat(location.getLineNumber(), greaterThan(0)); + assertThat(location.getColumnNumber(), greaterThan(0)); + assertNotNull(location.getSource()); + assertThat(location.getSource().getLocation(), containsString("pom-with-profiles/pom.xml")); + profile = activeProfiles.get(1); + assertEquals("external-profile", profile.getId()); + location = profile.getLocation(""); + assertNotNull(location); + assertThat(location.getLineNumber(), greaterThan(0)); + assertThat(location.getColumnNumber(), greaterThan(0)); + assertNotNull(location.getSource()); + assertThat(location.getSource().getLocation(), containsString("settings.xml")); } @Test From 525c38db5d7d905d11e0935b4541a8225908aeb3 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 26 Feb 2025 22:31:53 +0100 Subject: [PATCH 4/6] Add getProfiles methods and fix location tracking on settings --- .../java/org/apache/maven/api/Project.java | 45 ++++++++++++++- .../maven/internal/impl/DefaultProject.java | 39 +++++++++++-- .../apache/maven/impl/SettingsUtilsV4.java | 56 +++++++++++++++++++ src/mdo/model.vm | 41 +------------- 4 files changed, 136 insertions(+), 45 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java index d03c1a7fb91a..9eb87bc103c6 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java @@ -239,6 +239,33 @@ default String getId() { @Nonnull Optional getParent(); + /** + * Returns all profiles defined in this project. + *

+ * This method returns only the profiles defined directly in the current project's POM + * and does not include profiles from parent projects. + * + * @return a non-null, possibly empty list of profiles defined in this project + * @see Profile + * @see #getAllProfiles() + */ + @Nonnull + List getProfiles(); + + /** + * Returns all profiles defined in this project and all of its parent projects. + *

+ * This method traverses the parent hierarchy and includes profiles defined in parent POMs. + * The returned list contains profiles from the current project and all of its ancestors in + * the project inheritance chain. + * + * @return a non-null, possibly empty list of all profiles from this project and its parents + * @see Profile + * @see #getProfiles() + */ + @Nonnull + List getAllProfiles(); + /** * Returns all active profiles for the current project build. *

@@ -254,9 +281,25 @@ default String getId() { * limited to dependencies, plugins, properties, and build resources. * * @return a non-null, possibly empty list of active profiles for this project - * @since 4.0.0 * @see Profile */ @Nonnull List getActiveProfiles(); + + /** + * Returns all active profiles for this project and all of its parent projects. + *

+ * This method traverses the parent hierarchy and collects all active profiles from + * the current project and its ancestors. Active profiles are those that meet the + * activation criteria through explicit activation or automatic conditions. + *

+ * The combined set of active profiles from the entire project hierarchy affects + * the effective build configuration. + * + * @return a non-null, possibly empty list of all active profiles from this project and its parents + * @see Profile + * @see #getActiveProfiles() + */ + @Nonnull + List getAllActiveProfiles(); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java index e66d50c6c969..d507b188208b 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java @@ -166,13 +166,44 @@ public Optional getParent() { return Optional.ofNullable(session.getProject(parent)); } + @Override + @Nonnull + public List getProfiles() { + return getModel().getProfiles(); + } + + @Override + @Nonnull + public List getAllProfiles() { + List activeProfiles = new ArrayList<>(); + for (MavenProject project = this.project; project != null; project = project.getParent()) { + activeProfiles.addAll(project.getModel().getProfiles()); + } + return activeProfiles.stream() + .map(org.apache.maven.model.Profile::getDelegate) + .toList(); + } + @Override @Nonnull public List getActiveProfiles() { - List activeProfiles = project.getActiveProfiles(); - return activeProfiles != null - ? new MappedList<>(activeProfiles, org.apache.maven.model.Profile::getDelegate) - : List.of(); + List activeProfiles = + project.getActiveProfiles() != null ? project.getActiveProfiles() : List.of(); + return activeProfiles.stream() + .map(org.apache.maven.model.Profile::getDelegate) + .toList(); + } + + @Override + @Nonnull + public List getAllActiveProfiles() { + List activeProfiles = new ArrayList<>(); + for (MavenProject project = this.project; project != null; project = project.getParent()) { + activeProfiles.addAll(project.getActiveProfiles()); + } + return activeProfiles.stream() + .map(org.apache.maven.model.Profile::getDelegate) + .toList(); } @Nonnull diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java index a4f2ba618f11..8a5d1e81a2bb 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java @@ -79,16 +79,23 @@ public static Settings merge(Settings dominant, Settings recessive) { public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profile modelProfile) { Profile.Builder profile = Profile.newBuilder(); + profile.location("", toLocation(modelProfile.getLocation(""))); + profile.id(modelProfile.getId()); + profile.location("id", toLocation(modelProfile.getLocation("id"))); org.apache.maven.api.model.Activation modelActivation = modelProfile.getActivation(); if (modelActivation != null) { Activation.Builder activation = Activation.newBuilder(); + activation.location("", toLocation(modelActivation.getLocation(""))); + activation.activeByDefault(modelActivation.isActiveByDefault()); + activation.location("activeByDefault", toLocation(modelActivation.getLocation("activeByDefault"))); activation.jdk(modelActivation.getJdk()); + activation.location("jdk", toLocation(modelActivation.getLocation("jdk"))); org.apache.maven.api.model.ActivationProperty modelProp = modelActivation.getProperty(); @@ -96,6 +103,9 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil ActivationProperty prop = ActivationProperty.newBuilder() .name(modelProp.getName()) .value(modelProp.getValue()) + .location("", toLocation(modelProp.getLocation(""))) + .location("name", toLocation(modelProp.getLocation("name"))) + .location("value", toLocation(modelProp.getLocation("value"))) .build(); activation.property(prop); } @@ -108,6 +118,11 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil .family(modelOs.getFamily()) .name(modelOs.getName()) .version(modelOs.getVersion()) + .location("", toLocation(modelOs.getLocation(""))) + .location("arch", toLocation(modelOs.getLocation("arch"))) + .location("family", toLocation(modelOs.getLocation("family"))) + .location("name", toLocation(modelOs.getLocation("name"))) + .location("version", toLocation(modelOs.getLocation("version"))) .build(); activation.os(os); @@ -120,14 +135,19 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil org.apache.maven.api.settings.ActivationFile.newBuilder() .exists(modelFile.getExists()) .missing(modelFile.getMissing()) + .location("", toLocation(modelFile.getLocation(""))) + .location("exists", toLocation(modelFile.getLocation("exists"))) + .location("missing", toLocation(modelFile.getLocation("missing"))) .build(); activation.file(file); } activation.packaging(modelActivation.getPackaging()); + activation.location("packaging", toLocation(modelActivation.getLocation("packaging"))); activation.condition(modelActivation.getCondition()); + activation.location("condition", toLocation(modelActivation.getLocation("condition"))); profile.activation(activation.build()); } @@ -135,6 +155,7 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil profile.properties(modelProfile.getProperties().entrySet().stream() .collect(Collectors.toMap( e -> e.getKey().toString(), e -> e.getValue().toString()))); + profile.location("properties", toLocation(modelProfile.getLocation("properties"))); List repos = modelProfile.getRepositories(); if (repos != null) { @@ -143,6 +164,7 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil repositories.add(convertToSettingsRepository(repo)); } profile.repositories(repositories); + profile.location("repositories", toLocation(modelProfile.getLocation("repositories"))); } List pluginRepos = modelProfile.getPluginRepositories(); @@ -152,6 +174,7 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil repositories.add(convertToSettingsRepository(pluginRepo)); } profile.pluginRepositories(repositories); + profile.location("pluginRepositories", toLocation(modelProfile.getLocation("pluginRepositories"))); } return profile.build(); @@ -164,7 +187,10 @@ public static Profile convertToSettingsProfile(org.apache.maven.api.model.Profil public static org.apache.maven.api.model.Profile convertFromSettingsProfile(Profile settingsProfile) { org.apache.maven.api.model.Profile.Builder profile = org.apache.maven.api.model.Profile.newBuilder(); + profile.location("", toLocation(settingsProfile.getLocation(""))); + profile.id(settingsProfile.getId()); + profile.location("id", toLocation(settingsProfile.getLocation("id"))); Activation settingsActivation = settingsProfile.getActivation(); @@ -183,6 +209,7 @@ public static org.apache.maven.api.model.Profile convertFromSettingsProfile(Prof activation.property(org.apache.maven.api.model.ActivationProperty.newBuilder() .name(settingsProp.getName()) .value(settingsProp.getValue()) + .location("", toLocation(settingsProp.getLocation(""))) .location("name", toLocation(settingsProp.getLocation("name"))) .location("value", toLocation(settingsProp.getLocation("value"))) .build()); @@ -195,6 +222,7 @@ public static org.apache.maven.api.model.Profile convertFromSettingsProfile(Prof .family(settingsOs.getFamily()) .name(settingsOs.getName()) .version(settingsOs.getVersion()) + .location("", toLocation(settingsOs.getLocation(""))) .location("arch", toLocation(settingsOs.getLocation("arch"))) .location("family", toLocation(settingsOs.getLocation("family"))) .location("name", toLocation(settingsOs.getLocation("name"))) @@ -207,14 +235,17 @@ public static org.apache.maven.api.model.Profile convertFromSettingsProfile(Prof activation.file(ActivationFile.newBuilder() .exists(settingsFile.getExists()) .missing(settingsFile.getMissing()) + .location("", toLocation(settingsFile.getLocation(""))) .location("exists", toLocation(settingsFile.getLocation("exists"))) .location("missing", toLocation(settingsFile.getLocation("missing"))) .build()); } activation.packaging(settingsActivation.getPackaging()); + activation.location("packaging", toLocation(settingsActivation.getLocation("packaging"))); activation.condition(settingsActivation.getCondition()); + activation.location("condition", toLocation(settingsActivation.getLocation("condition"))); profile.activation(activation.build()); } @@ -297,6 +328,11 @@ private static Repository convertToSettingsRepository(org.apache.maven.api.model .url(modelRepo.getUrl()) .snapshots(modelRepo.getSnapshots() != null ? convertRepositoryPolicy(modelRepo.getSnapshots()) : null) .releases(modelRepo.getReleases() != null ? convertRepositoryPolicy(modelRepo.getReleases()) : null) + .location("", toLocation(modelRepo.getLocation(""))) + .location("id", toLocation(modelRepo.getLocation("id"))) + .location("layout", toLocation(modelRepo.getLocation("layout"))) + .location("name", toLocation(modelRepo.getLocation("name"))) + .location("url", toLocation(modelRepo.getLocation("url"))) .build(); return repo; @@ -311,10 +347,30 @@ private static RepositoryPolicy convertRepositoryPolicy(org.apache.maven.api.mod .enabled(modelPolicy.isEnabled()) .updatePolicy(modelPolicy.getUpdatePolicy()) .checksumPolicy(modelPolicy.getChecksumPolicy()) + .location("", toLocation(modelPolicy.getLocation(""))) + .location("enabled", toLocation(modelPolicy.getLocation("enabled"))) + .location("updatePolicy", toLocation(modelPolicy.getLocation("updatePolicy"))) + .location("checksumPolicy", toLocation(modelPolicy.getLocation("checksumPolicy"))) .build(); return policy; } + private static org.apache.maven.api.settings.InputLocation toLocation( + org.apache.maven.api.model.InputLocation location) { + if (location != null) { + org.apache.maven.api.model.InputSource source = location.getSource(); + Map locs = location.getLocations().entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> toLocation(e.getValue()))); + return new org.apache.maven.api.settings.InputLocation( + location.getLineNumber(), + location.getColumnNumber(), + source != null ? new org.apache.maven.api.settings.InputSource(source.getLocation()) : null, + locs); + } else { + return null; + } + } + private static org.apache.maven.api.model.InputLocation toLocation( org.apache.maven.api.settings.InputLocation location) { if (location != null) { diff --git a/src/mdo/model.vm b/src/mdo/model.vm index 8e4c46243c9d..1a6e923a870f 100644 --- a/src/mdo/model.vm +++ b/src/mdo/model.vm @@ -173,11 +173,7 @@ public class ${class.name} #end #end #if ( $locationTracking && ! $class.superClass ) - #if ( ! $class.getFields($version).isEmpty() ) this.locations = builder.computeLocations(); - #else - this.locations = Map.of(); - #end this.importedFrom = builder.importedFrom; #end } @@ -243,55 +239,24 @@ public class ${class.name} * Gets the location of the specified field in the input source. */ public InputLocation getLocation(Object key) { - #if ( $class.getFields($version).isEmpty() ) - #if ( $class.superClass ) - return super.getLocation(key); - #else - return null; - #end - #elseif ( $class.superClass ) - return locations.containsKey(key) ? locations.get(key) : super.getLocation(key); - #else return locations.get(key); - #end } /** * Gets the keys of the locations of the input source. */ public Set getLocationKeys() { - #if ( $class.getFields($version).isEmpty() ) - #if ( $class.superClass ) - return super.getLocationKeys(); - #else - return Set.of(); - #end - #elseif ( $class.superClass ) - return getLocationKeyStream().collect(Collectors.toUnmodifiableSet()); - #else return locations.keySet(); - #end } protected Stream getLocationKeyStream() { - #if ( $class.getFields($version).isEmpty() ) - #if ( $class.superClass ) - return super.getLocationKeyStream(); - #else - return Stream.empty(); - #end - #elseif ( $class.superClass ) - return Stream.concat(locations.keySet().stream(), super.getLocationKeyStream()); - #else return locations.keySet().stream(); - #end } /** * Gets the input location that caused this model to be read. */ - public InputLocation getImportedFrom() - { + public InputLocation getImportedFrom() { return importedFrom; } @@ -534,7 +499,6 @@ public class ${class.name} #if ( $locationTracking && ! $class.superClass ) Map computeLocations() { - #if ( ! $class.getFields($version).isEmpty() ) Map newlocs = locations != null ? locations : Map.of(); Map oldlocs = base != null ? base.locations : Map.of(); if (newlocs.isEmpty()) { @@ -546,9 +510,6 @@ public class ${class.name} return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream()) // Keep value from newlocs in case of duplicates .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1)); - #else - return Map.of(); - #end } #end } From 616b0b43ae631ba8a64ae485d53240b8ca97a446 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 26 Feb 2025 23:25:11 +0100 Subject: [PATCH 5/6] Update impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java Co-authored-by: Giovanni van der Schelde <27761321+Giovds@users.noreply.github.com> --- .../java/org/apache/maven/internal/impl/DefaultProject.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java index d507b188208b..bf78a65294d8 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java @@ -175,11 +175,11 @@ public List getProfiles() { @Override @Nonnull public List getAllProfiles() { - List activeProfiles = new ArrayList<>(); + List profiles = new ArrayList<>(); for (MavenProject project = this.project; project != null; project = project.getParent()) { - activeProfiles.addAll(project.getModel().getProfiles()); + profiles.addAll(project.getModel().getProfiles()); } - return activeProfiles.stream() + return profiles.stream() .map(org.apache.maven.model.Profile::getDelegate) .toList(); } From f5fce8d51bec11665ffd91105b62338da8a5a64e Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 26 Feb 2025 23:45:20 +0100 Subject: [PATCH 6/6] Rename methods and use streams --- .../java/org/apache/maven/api/Project.java | 15 +++++----- .../maven/internal/impl/DefaultProject.java | 29 +++++++------------ .../DefaultMavenProjectBuilderTest.java | 4 +-- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java index 9eb87bc103c6..8e989ad4ae98 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java @@ -247,10 +247,10 @@ default String getId() { * * @return a non-null, possibly empty list of profiles defined in this project * @see Profile - * @see #getAllProfiles() + * @see #getEffectiveProfiles() */ @Nonnull - List getProfiles(); + List getDeclaredProfiles(); /** * Returns all profiles defined in this project and all of its parent projects. @@ -261,10 +261,10 @@ default String getId() { * * @return a non-null, possibly empty list of all profiles from this project and its parents * @see Profile - * @see #getProfiles() + * @see #getDeclaredProfiles() */ @Nonnull - List getAllProfiles(); + List getEffectiveProfiles(); /** * Returns all active profiles for the current project build. @@ -282,9 +282,10 @@ default String getId() { * * @return a non-null, possibly empty list of active profiles for this project * @see Profile + * @see #getEffectiveActiveProfiles() */ @Nonnull - List getActiveProfiles(); + List getDeclaredActiveProfiles(); /** * Returns all active profiles for this project and all of its parent projects. @@ -298,8 +299,8 @@ default String getId() { * * @return a non-null, possibly empty list of all active profiles from this project and its parents * @see Profile - * @see #getActiveProfiles() + * @see #getDeclaredActiveProfiles() */ @Nonnull - List getAllActiveProfiles(); + List getEffectiveActiveProfiles(); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java index bf78a65294d8..8cbfeaddc15e 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java @@ -23,7 +23,9 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Stream; import org.apache.maven.RepositoryUtils; import org.apache.maven.api.DependencyCoordinates; @@ -168,40 +170,31 @@ public Optional getParent() { @Override @Nonnull - public List getProfiles() { + public List getDeclaredProfiles() { return getModel().getProfiles(); } @Override @Nonnull - public List getAllProfiles() { - List profiles = new ArrayList<>(); - for (MavenProject project = this.project; project != null; project = project.getParent()) { - profiles.addAll(project.getModel().getProfiles()); - } - return profiles.stream() - .map(org.apache.maven.model.Profile::getDelegate) + public List getEffectiveProfiles() { + return Stream.iterate(this.project, Objects::nonNull, MavenProject::getParent) + .flatMap(project -> project.getModel().getDelegate().getProfiles().stream()) .toList(); } @Override @Nonnull - public List getActiveProfiles() { - List activeProfiles = - project.getActiveProfiles() != null ? project.getActiveProfiles() : List.of(); - return activeProfiles.stream() + public List getDeclaredActiveProfiles() { + return project.getActiveProfiles().stream() .map(org.apache.maven.model.Profile::getDelegate) .toList(); } @Override @Nonnull - public List getAllActiveProfiles() { - List activeProfiles = new ArrayList<>(); - for (MavenProject project = this.project; project != null; project = project.getParent()) { - activeProfiles.addAll(project.getActiveProfiles()); - } - return activeProfiles.stream() + public List getEffectiveActiveProfiles() { + return Stream.iterate(this.project, Objects::nonNull, MavenProject::getParent) + .flatMap(project -> project.getActiveProfiles().stream()) .map(org.apache.maven.model.Profile::getDelegate) .toList(); } diff --git a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index 8547a9268433..d41697d6a548 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -386,7 +386,7 @@ void testActivatedDefaultProfileBySource() throws Exception { InternalMavenSession session = Mockito.mock(InternalMavenSession.class); List activeProfiles = - new DefaultProject(session, project).getActiveProfiles(); + new DefaultProject(session, project).getDeclaredActiveProfiles(); assertEquals(1, activeProfiles.size()); org.apache.maven.api.model.Profile profile = activeProfiles.get(0); assertEquals("active-by-default", profile.getId()); @@ -424,7 +424,7 @@ void testActivatedExternalProfileBySource() throws Exception { InternalMavenSession session = Mockito.mock(InternalMavenSession.class); List activeProfiles = - new DefaultProject(session, project).getActiveProfiles(); + new DefaultProject(session, project).getDeclaredActiveProfiles(); assertEquals(2, activeProfiles.size()); org.apache.maven.api.model.Profile profile = activeProfiles.get(0); assertEquals("active-by-default", profile.getId());