From 525c38db5d7d905d11e0935b4541a8225908aeb3 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 26 Feb 2025 22:31:53 +0100 Subject: [PATCH] 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 }