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
23 import java.io.File;
24 import java.nio.file.Path;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Map;
32
33 import org.apache.maven.api.model.Model;
34 import org.apache.maven.model.building.ModelBuildingRequest;
35 import org.apache.maven.model.building.ModelProblemCollector;
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.codehaus.plexus.interpolation.AbstractValueSource;
40 import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
41 import org.codehaus.plexus.interpolation.MapBasedValueSource;
42 import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
43 import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
44 import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
45 import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper;
46 import org.codehaus.plexus.interpolation.RecursionInterceptor;
47 import org.codehaus.plexus.interpolation.ValueSource;
48
49
50
51
52
53
54 public abstract class AbstractStringBasedModelInterpolator implements ModelInterpolator {
55 private static final String PREFIX_PROJECT = "project.";
56 private static final String PREFIX_POM = "pom.";
57 private static final List<String> PROJECT_PREFIXES_3_1 = Arrays.asList(PREFIX_POM, PREFIX_PROJECT);
58 private static final List<String> PROJECT_PREFIXES_4_0 = Collections.singletonList(PREFIX_PROJECT);
59
60 private static final Collection<String> TRANSLATED_PATH_EXPRESSIONS;
61
62 static {
63 Collection<String> translatedPrefixes = new HashSet<>();
64
65
66
67
68
69
70 translatedPrefixes.add("build.directory");
71 translatedPrefixes.add("build.outputDirectory");
72 translatedPrefixes.add("build.testOutputDirectory");
73 translatedPrefixes.add("build.sourceDirectory");
74 translatedPrefixes.add("build.testSourceDirectory");
75 translatedPrefixes.add("build.scriptSourceDirectory");
76 translatedPrefixes.add("reporting.outputDirectory");
77
78 TRANSLATED_PATH_EXPRESSIONS = translatedPrefixes;
79 }
80
81 private final PathTranslator pathTranslator;
82 private final UrlNormalizer urlNormalizer;
83
84 private final RootLocator rootLocator;
85
86 @Inject
87 public AbstractStringBasedModelInterpolator(
88 PathTranslator pathTranslator, UrlNormalizer urlNormalizer, RootLocator rootLocator) {
89 this.pathTranslator = pathTranslator;
90 this.urlNormalizer = urlNormalizer;
91 this.rootLocator = rootLocator;
92 }
93
94 @Override
95 public org.apache.maven.model.Model interpolateModel(
96 org.apache.maven.model.Model model,
97 File projectDir,
98 ModelBuildingRequest request,
99 ModelProblemCollector problems) {
100 return new org.apache.maven.model.Model(interpolateModel(model.getDelegate(), projectDir, request, problems));
101 }
102
103 protected List<String> getProjectPrefixes(ModelBuildingRequest config) {
104 return config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_4_0
105 ? PROJECT_PREFIXES_4_0
106 : PROJECT_PREFIXES_3_1;
107 }
108
109 protected List<ValueSource> createValueSources(
110 final Model model,
111 final File projectDir,
112 final ModelBuildingRequest config,
113 ModelProblemCollector problems) {
114 Map<String, String> modelProperties = model.getProperties();
115
116 ValueSource projectPrefixValueSource;
117 ValueSource prefixlessObjectBasedValueSource;
118 if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_4_0) {
119 projectPrefixValueSource = new PrefixedObjectValueSource(PROJECT_PREFIXES_4_0, model, false);
120 prefixlessObjectBasedValueSource = new ObjectBasedValueSource(model);
121 } else {
122 projectPrefixValueSource = new PrefixedObjectValueSource(PROJECT_PREFIXES_3_1, model, false);
123 if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
124 projectPrefixValueSource =
125 new ProblemDetectingValueSource(projectPrefixValueSource, PREFIX_POM, PREFIX_PROJECT, problems);
126 }
127
128 prefixlessObjectBasedValueSource = new ObjectBasedValueSource(model);
129 if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
130 prefixlessObjectBasedValueSource =
131 new ProblemDetectingValueSource(prefixlessObjectBasedValueSource, "", PREFIX_PROJECT, problems);
132 }
133 }
134
135
136 List<ValueSource> valueSources = new ArrayList<>(9);
137
138 if (projectDir != null) {
139 ValueSource basedirValueSource = new PrefixedValueSourceWrapper(
140 new AbstractValueSource(false) {
141 @Override
142 public Object getValue(String expression) {
143 if ("basedir".equals(expression)) {
144 return projectDir.getAbsolutePath();
145 }
146 return null;
147 }
148 },
149 getProjectPrefixes(config),
150 true);
151 valueSources.add(basedirValueSource);
152
153 ValueSource baseUriValueSource = new PrefixedValueSourceWrapper(
154 new AbstractValueSource(false) {
155 @Override
156 public Object getValue(String expression) {
157 if ("baseUri".equals(expression)) {
158 return projectDir
159 .getAbsoluteFile()
160 .toPath()
161 .toUri()
162 .toASCIIString();
163 }
164 return null;
165 }
166 },
167 getProjectPrefixes(config),
168 false);
169 valueSources.add(baseUriValueSource);
170 valueSources.add(new BuildTimestampValueSource(config.getBuildStartTime(), modelProperties));
171 }
172
173 valueSources.add(new PrefixedValueSourceWrapper(
174 new AbstractValueSource(false) {
175 @Override
176 public Object getValue(String expression) {
177 if ("rootDirectory".equals(expression)) {
178 Path base = projectDir != null ? projectDir.toPath() : null;
179 Path root = rootLocator.findMandatoryRoot(base);
180 return root.toFile().getPath();
181 }
182 return null;
183 }
184 },
185 getProjectPrefixes(config)));
186
187 valueSources.add(projectPrefixValueSource);
188
189 valueSources.add(new MapBasedValueSource(config.getUserProperties()));
190
191 valueSources.add(new MapBasedValueSource(modelProperties));
192
193 valueSources.add(new MapBasedValueSource(config.getSystemProperties()));
194
195 valueSources.add(new AbstractValueSource(false) {
196 @Override
197 public Object getValue(String expression) {
198 return config.getSystemProperties().getProperty("env." + expression);
199 }
200 });
201
202 valueSources.add(prefixlessObjectBasedValueSource);
203
204 return valueSources;
205 }
206
207 protected List<? extends InterpolationPostProcessor> createPostProcessors(
208 final Model model, final File projectDir, final ModelBuildingRequest config) {
209 List<InterpolationPostProcessor> processors = new ArrayList<>(2);
210 if (projectDir != null) {
211 processors.add(new PathTranslatingPostProcessor(
212 getProjectPrefixes(config), TRANSLATED_PATH_EXPRESSIONS, projectDir, pathTranslator));
213 }
214 processors.add(new UrlNormalizingPostProcessor(urlNormalizer));
215 return processors;
216 }
217
218 protected RecursionInterceptor createRecursionInterceptor(ModelBuildingRequest config) {
219 return new PrefixAwareRecursionInterceptor(getProjectPrefixes(config));
220 }
221 }