1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.interpolation;
20
21 import java.io.File;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import javax.inject.Inject;
26 import javax.inject.Named;
27 import javax.inject.Singleton;
28 import org.apache.maven.api.model.Model;
29 import org.apache.maven.model.building.ModelBuildingRequest;
30 import org.apache.maven.model.building.ModelProblem.Severity;
31 import org.apache.maven.model.building.ModelProblem.Version;
32 import org.apache.maven.model.building.ModelProblemCollector;
33 import org.apache.maven.model.building.ModelProblemCollectorRequest;
34 import org.apache.maven.model.path.PathTranslator;
35 import org.apache.maven.model.path.UrlNormalizer;
36 import org.apache.maven.model.v4.MavenTransformer;
37 import org.codehaus.plexus.interpolation.InterpolationException;
38 import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
39 import org.codehaus.plexus.interpolation.RecursionInterceptor;
40 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
41 import org.codehaus.plexus.interpolation.ValueSource;
42
43
44
45
46
47
48 @Named
49 @Singleton
50 public class StringVisitorModelInterpolator extends AbstractStringBasedModelInterpolator {
51 @Inject
52 public StringVisitorModelInterpolator(PathTranslator pathTranslator, UrlNormalizer urlNormalizer) {
53 super(pathTranslator, urlNormalizer);
54 }
55
56 interface InnerInterpolator {
57 String interpolate(String value);
58 }
59
60 @Override
61 public Model interpolateModel(
62 Model model, File projectDir, ModelBuildingRequest config, ModelProblemCollector problems) {
63 List<? extends ValueSource> valueSources = createValueSources(model, projectDir, config);
64 List<? extends InterpolationPostProcessor> postProcessors = createPostProcessors(model, projectDir, config);
65
66 InnerInterpolator innerInterpolator = createInterpolator(valueSources, postProcessors, problems);
67
68 return new MavenTransformer(innerInterpolator::interpolate).visit(model);
69 }
70
71 private InnerInterpolator createInterpolator(
72 List<? extends ValueSource> valueSources,
73 List<? extends InterpolationPostProcessor> postProcessors,
74 final ModelProblemCollector problems) {
75 final Map<String, String> cache = new HashMap<>();
76 final StringSearchInterpolator interpolator = new StringSearchInterpolator();
77 interpolator.setCacheAnswers(true);
78 for (ValueSource vs : valueSources) {
79 interpolator.addValueSource(vs);
80 }
81 for (InterpolationPostProcessor postProcessor : postProcessors) {
82 interpolator.addPostProcessor(postProcessor);
83 }
84 final RecursionInterceptor recursionInterceptor = createRecursionInterceptor();
85 return value -> {
86 if (value != null && value.contains("${")) {
87 String c = cache.get(value);
88 if (c == null) {
89 try {
90 c = interpolator.interpolate(value, recursionInterceptor);
91 } catch (InterpolationException e) {
92 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
93 .setMessage(e.getMessage())
94 .setException(e));
95 }
96 cache.put(value, c);
97 }
98 return c;
99 }
100 return value;
101 };
102 }
103 }