Skip to content

Commit

Permalink
interpolate profile activations in DefaultModelBuilder#interpolateAct…
Browse files Browse the repository at this point in the history
…ivations
  • Loading branch information
mbenson committed Mar 26, 2024
1 parent a5ea944 commit 18a1b24
Showing 1 changed file with 69 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.maven.api.VersionRange;
import org.apache.maven.api.feature.Features;
import org.apache.maven.api.model.ActivationFile;
import org.apache.maven.api.model.Exclusion;
import org.apache.maven.api.model.InputSource;
import org.apache.maven.api.services.VersionParserException;
Expand All @@ -57,6 +60,7 @@
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.Profile;
import org.apache.maven.model.building.ModelProblem.Severity;
import org.apache.maven.model.building.ModelProblem.Version;
import org.apache.maven.model.composition.DependencyManagementImporter;
import org.apache.maven.model.inheritance.InheritanceAssembler;
import org.apache.maven.model.interpolation.ModelInterpolator;
Expand All @@ -82,11 +86,14 @@
import org.apache.maven.model.resolution.UnresolvableModelException;
import org.apache.maven.model.resolution.WorkspaceModelResolver;
import org.apache.maven.model.superpom.SuperPomProvider;
import org.apache.maven.model.v4.MavenTransformer;
import org.apache.maven.model.validation.DefaultModelValidator;
import org.apache.maven.model.validation.ModelValidator;
import org.apache.maven.model.version.ModelVersionParser;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.Interpolator;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.eclipse.sisu.Nullable;

Expand Down Expand Up @@ -897,69 +904,89 @@ private List<org.apache.maven.api.model.Profile> interpolateActivations(
List<org.apache.maven.api.model.Profile> profiles,
DefaultProfileActivationContext context,
DefaultModelProblemCollector problems) {
List<org.apache.maven.api.model.Profile> newProfiles = null;
for (int index = 0; index < profiles.size(); index++) {
org.apache.maven.api.model.Profile profile = profiles.get(index);
org.apache.maven.api.model.Activation activation = profile.getActivation();
if (activation != null) {
org.apache.maven.api.model.ActivationFile file = activation.getFile();
if (file != null) {
String oldExists = file.getExists();
if (isNotEmpty(oldExists)) {
if (profiles.stream()
.map(org.apache.maven.api.model.Profile::getActivation)
.filter(Objects::nonNull)
.findFirst()
.isEmpty()) {
return profiles;
}
final Interpolator xform = new RegexBasedInterpolator();
xform.setCacheAnswers(true);
Stream.of(context.getUserProperties(), context.getSystemProperties())
.map(MapBasedValueSource::new)
.forEach(xform::addValueSource);

class ProfileInterpolator extends MavenTransformer
implements UnaryOperator<org.apache.maven.api.model.Profile> {
ProfileInterpolator() {
super(s -> {
if (isNotEmpty(s)) {
try {
String newExists = interpolate(oldExists, context);
if (!Objects.equals(oldExists, newExists)) {
if (newProfiles == null) {
newProfiles = new ArrayList<>(profiles);
}
newProfiles.set(
index, profile.withActivation(activation.withFile(file.withExists(newExists))));
}
return xform.interpolate(s);
} catch (InterpolationException e) {
addInterpolationProblem(problems, file, oldExists, e, "exists");
}
} else {
String oldMissing = file.getMissing();
if (isNotEmpty(oldMissing)) {
try {
String newMissing = interpolate(oldMissing, context);
if (!Objects.equals(oldMissing, newMissing)) {
if (newProfiles == null) {
newProfiles = new ArrayList<>(profiles);
}
newProfiles.set(
index,
profile.withActivation(activation.withFile(file.withMissing(newMissing))));
}
} catch (InterpolationException e) {
addInterpolationProblem(problems, file, oldMissing, e, "missing");
}
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage(e.getMessage())
.setException(e));
}
}
return s;
});
}

@Override
public org.apache.maven.api.model.Profile apply(org.apache.maven.api.model.Profile p) {
return org.apache.maven.api.model.Profile.newBuilder(p)
.activation(transformActivation(p.getActivation()))
.build();
}

@Override
protected void transformActivationFile_Missing(ActivationFile.Builder builder, ActivationFile target) {
final String path = target.getMissing();
final String xformed = transformPath(path, target, "missing");
if (xformed != path) {
builder.missing(xformed);
}
}

@Override
protected void transformActivationFile_Exists(ActivationFile.Builder builder, ActivationFile target) {
final String path = target.getExists();
final String xformed = transformPath(path, target, "exists");
if (xformed != path) {
builder.exists(xformed);
}
}

private String transformPath(String path, ActivationFile target, String locationKey) {
if (isNotEmpty(path)) {
try {
return profileActivationFilePathInterpolator.interpolate(path, context);
} catch (InterpolationException e) {
addInterpolationProblem(problems, target, path, e, locationKey);
}
}
return path;
}
}
return newProfiles != null ? newProfiles : profiles;
return profiles.stream().map(new ProfileInterpolator()).toList();
}

private static void addInterpolationProblem(
DefaultModelProblemCollector problems,
org.apache.maven.api.model.ActivationFile file,
org.apache.maven.api.model.InputLocationTracker target,
String path,
InterpolationException e,
String locationKey) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
.setMessage("Failed to interpolate file location " + path + ": " + e.getMessage())
.setLocation(Optional.ofNullable(file.getLocation(locationKey))
.setLocation(Optional.ofNullable(target.getLocation(locationKey))
.map(InputLocation::new)
.orElse(null))
.setException(e));
}

private String interpolate(String path, ProfileActivationContext context) throws InterpolationException {
return isNotEmpty(path) ? profileActivationFilePathInterpolator.interpolate(path, context) : path;
}

private static boolean isNotEmpty(String string) {
return string != null && !string.isEmpty();
}
Expand Down

0 comments on commit 18a1b24

Please sign in to comment.