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