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