From 1100d3300145ea730b9c3389d3b72f3fa1fdadd2 Mon Sep 17 00:00:00 2001 From: Matt Benson Date: Fri, 26 Apr 2024 15:16:07 -0500 Subject: [PATCH] [MNG-8081] interpolate available properties during default profile selection (Maven 3.9.x) --- .../model/building/DefaultModelBuilder.java | 105 ++++++++++++------ 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java index 6ad8b8ee3407..15c0e7f3deb4 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java @@ -32,17 +32,21 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Properties; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Activation; -import org.apache.maven.model.ActivationFile; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputLocationTracker; import org.apache.maven.model.InputSource; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; @@ -78,6 +82,7 @@ import org.apache.maven.model.validation.ModelValidator; import org.codehaus.plexus.interpolation.InterpolationException; import org.codehaus.plexus.interpolation.MapBasedValueSource; +import org.codehaus.plexus.interpolation.RegexBasedInterpolator; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.codehaus.plexus.util.StringUtils; import org.eclipse.sisu.Nullable; @@ -299,14 +304,19 @@ protected ModelBuildingResult build(ModelBuildingRequest request, Collection activePomProfiles = - profileSelector.getActiveProfiles(rawModel.getProfiles(), profileActivationContext, problems); - currentData.setActiveProfiles(activePomProfiles); - Map interpolatedActivations = getInterpolatedActivations(rawModel, profileActivationContext, problems); injectProfileActivations(tmpModel, interpolatedActivations); + List activePomProfiles = + profileSelector.getActiveProfiles(tmpModel.getProfiles(), profileActivationContext, problems); + + Set activeProfileIds = + activePomProfiles.stream().map(Profile::getId).collect(Collectors.toSet()); + currentData.setActiveProfiles(rawModel.getProfiles().stream() + .filter(p -> activeProfileIds.contains(p.getId())) + .collect(Collectors.toList())); + // profile injection for (Profile activeProfile : activePomProfiles) { profileInjector.injectProfile(tmpModel, activeProfile, request, problems); @@ -413,40 +423,69 @@ protected ModelBuildingResult build(ModelBuildingRequest request, Collection getInterpolatedActivations( Model rawModel, DefaultProfileActivationContext context, DefaultModelProblemCollector problems) { - Map interpolatedActivations = getProfileActivations(rawModel, true); - for (Activation activation : interpolatedActivations.values()) { - if (activation.getFile() != null) { - replaceWithInterpolatedValue(activation.getFile(), context, problems); + RegexBasedInterpolator interpolator = new RegexBasedInterpolator(); + + interpolator.addValueSource(new MapBasedValueSource(context.getProjectProperties())); + interpolator.addValueSource(new MapBasedValueSource(context.getUserProperties())); + interpolator.addValueSource(new MapBasedValueSource(context.getSystemProperties())); + + class Interpolation { + final InputLocationTracker target; + + final InterpolateString impl; + + Interpolation(InputLocationTracker target, InterpolateString impl) { + this.target = target; + this.impl = impl; } - } - return interpolatedActivations; - } - private void replaceWithInterpolatedValue( - ActivationFile activationFile, ProfileActivationContext context, DefaultModelProblemCollector problems) { - try { - if (StringUtils.isNotEmpty(activationFile.getExists())) { - String path = activationFile.getExists(); - String absolutePath = profileActivationFilePathInterpolator.interpolate(path, context); - activationFile.setExists(absolutePath); - } else if (StringUtils.isNotEmpty(activationFile.getMissing())) { - String path = activationFile.getMissing(); - String absolutePath = profileActivationFilePathInterpolator.interpolate(path, context); - activationFile.setMissing(absolutePath); + void performFor(String value, String locationKey, Consumer mutator) { + if (StringUtils.isEmpty(value)) { + return; + } + try { + mutator.accept(impl.apply(value)); + } catch (InterpolationException e) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage("Failed to interpolate value " + value + ": " + e.getMessage()) + .setLocation(target.getLocation(locationKey)) + .setException(e)); + } } - } catch (InterpolationException e) { - String path = StringUtils.isNotEmpty(activationFile.getExists()) - ? activationFile.getExists() - : activationFile.getMissing(); - - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) - .setMessage("Failed to interpolate file location " + path + ": " + e.getMessage()) - .setLocation(activationFile.getLocation( - StringUtils.isNotEmpty(activationFile.getExists()) ? "exists" : "missing")) - .setException(e)); } + + Map interpolatedActivations = getProfileActivations(rawModel, true); + for (Activation activation : interpolatedActivations.values()) { + Optional a = Optional.of(activation); + a.map(Activation::getFile).ifPresent(fa -> { + Interpolation nt = + new Interpolation(fa, s -> profileActivationFilePathInterpolator.interpolate(s, context)); + nt.performFor(fa.getExists(), "exists", fa::setExists); + nt.performFor(fa.getMissing(), "missing", fa::setMissing); + }); + a.map(Activation::getOs).ifPresent(oa -> { + Interpolation nt = new Interpolation(oa, interpolator::interpolate); + nt.performFor(oa.getArch(), "arch", oa::setArch); + nt.performFor(oa.getFamily(), "family", oa::setFamily); + nt.performFor(oa.getName(), "name", oa::setName); + nt.performFor(oa.getVersion(), "version", oa::setVersion); + }); + a.map(Activation::getProperty).ifPresent(pa -> { + Interpolation nt = new Interpolation(pa, interpolator::interpolate); + nt.performFor(pa.getName(), "name", pa::setName); + nt.performFor(pa.getValue(), "value", pa::setValue); + }); + a.map(Activation::getJdk).ifPresent(ja -> new Interpolation(activation, interpolator::interpolate) + .performFor(ja, "jdk", activation::setJdk)); + } + return interpolatedActivations; } @Override