|
24 | 24 |
|
25 | 25 | import java.io.File;
|
26 | 26 | import java.util.Arrays;
|
| 27 | +import java.util.Deque; |
27 | 28 | import java.util.HashMap;
|
28 | 29 | import java.util.HashSet;
|
| 30 | +import java.util.Iterator; |
| 31 | +import java.util.LinkedList; |
29 | 32 | import java.util.List;
|
30 | 33 | import java.util.Map;
|
31 | 34 | import java.util.Objects;
|
| 35 | +import java.util.Optional; |
32 | 36 | import java.util.Set;
|
| 37 | +import java.util.function.Consumer; |
| 38 | +import java.util.function.Supplier; |
33 | 39 | import java.util.regex.Matcher;
|
34 | 40 | import java.util.regex.Pattern;
|
| 41 | +import java.util.stream.Collectors; |
| 42 | +import java.util.stream.StreamSupport; |
35 | 43 |
|
36 | 44 | import org.apache.maven.model.Activation;
|
37 |
| -import org.apache.maven.model.ActivationFile; |
38 | 45 | import org.apache.maven.model.Build;
|
39 | 46 | import org.apache.maven.model.BuildBase;
|
40 | 47 | import org.apache.maven.model.Dependency;
|
@@ -236,42 +243,97 @@ public void validateRawModel(Model m, ModelBuildingRequest request, ModelProblem
|
236 | 243 | }
|
237 | 244 |
|
238 | 245 | private void validate30RawProfileActivation(ModelProblemCollector problems, Activation activation, String prefix) {
|
239 |
| - if (activation == null || activation.getFile() == null) { |
| 246 | + if (activation == null) { |
240 | 247 | return;
|
241 | 248 | }
|
| 249 | + class ActivationFrame { |
| 250 | + String location; |
| 251 | + Optional<? extends InputLocationTracker> parent; |
242 | 252 |
|
243 |
| - ActivationFile file = activation.getFile(); |
244 |
| - |
245 |
| - String path; |
246 |
| - String location; |
247 |
| - |
248 |
| - if (file.getExists() != null && !file.getExists().isEmpty()) { |
249 |
| - path = file.getExists(); |
250 |
| - location = "exists"; |
251 |
| - } else if (file.getMissing() != null && !file.getMissing().isEmpty()) { |
252 |
| - path = file.getMissing(); |
253 |
| - location = "missing"; |
254 |
| - } else { |
255 |
| - return; |
| 253 | + ActivationFrame(String location, Optional<? extends InputLocationTracker> parent) { |
| 254 | + this.location = location; |
| 255 | + this.parent = parent; |
| 256 | + } |
256 | 257 | }
|
257 |
| - |
258 |
| - if (hasProjectExpression(path)) { |
259 |
| - Matcher matcher = EXPRESSION_PROJECT_NAME_PATTERN.matcher(path); |
260 |
| - while (matcher.find()) { |
261 |
| - String propertyName = matcher.group(0); |
262 |
| - if (!"${project.basedir}".equals(propertyName)) { |
| 258 | + final Deque<ActivationFrame> stk = new LinkedList<>(); |
| 259 | + |
| 260 | + final Supplier<String> pathSupplier = () -> { |
| 261 | + final boolean parallel = false; |
| 262 | + return StreamSupport.stream(((Iterable<ActivationFrame>) stk::descendingIterator).spliterator(), parallel) |
| 263 | + .map(f -> f.location) |
| 264 | + .collect(Collectors.joining(".")); |
| 265 | + }; |
| 266 | + final Supplier<InputLocation> locationSupplier = () -> { |
| 267 | + if (stk.size() < 2) { |
| 268 | + return null; |
| 269 | + } |
| 270 | + Iterator<ActivationFrame> f = stk.iterator(); |
| 271 | + |
| 272 | + String location = f.next().location; |
| 273 | + ActivationFrame parent = f.next(); |
| 274 | + |
| 275 | + return parent.parent.map(p -> p.getLocation(location)).orElse(null); |
| 276 | + }; |
| 277 | + final Consumer<String> validator = s -> { |
| 278 | + if (hasProjectExpression(s)) { |
| 279 | + String path = pathSupplier.get(); |
| 280 | + Matcher matcher = EXPRESSION_PROJECT_NAME_PATTERN.matcher(s); |
| 281 | + while (matcher.find()) { |
| 282 | + String propertyName = matcher.group(0); |
| 283 | + |
| 284 | + if (path.startsWith("activation.file.") && "${project.basedir}".equals(propertyName)) { |
| 285 | + continue; |
| 286 | + } |
263 | 287 | addViolation(
|
264 | 288 | problems,
|
265 | 289 | Severity.WARNING,
|
266 | 290 | Version.V30,
|
267 |
| - prefix + "activation.file." + location, |
| 291 | + prefix + path, |
268 | 292 | null,
|
269 |
| - "Failed to interpolate file location " + path + ": " + propertyName |
| 293 | + "Failed to interpolate profile activation property " + s + ": " + propertyName |
270 | 294 | + " expressions are not supported during profile activation.",
|
271 |
| - file.getLocation(location)); |
| 295 | + locationSupplier.get()); |
272 | 296 | }
|
273 | 297 | }
|
274 |
| - } |
| 298 | + }; |
| 299 | + Optional<Activation> root = Optional.of(activation); |
| 300 | + stk.push(new ActivationFrame("activation", root)); |
| 301 | + root.map(Activation::getFile).ifPresent(fa -> { |
| 302 | + stk.push(new ActivationFrame("file", Optional.of(fa))); |
| 303 | + stk.push(new ActivationFrame("exists", Optional.empty())); |
| 304 | + validator.accept(fa.getExists()); |
| 305 | + stk.peek().location = "missing"; |
| 306 | + validator.accept(fa.getMissing()); |
| 307 | + stk.pop(); |
| 308 | + stk.pop(); |
| 309 | + }); |
| 310 | + root.map(Activation::getOs).ifPresent(oa -> { |
| 311 | + stk.push(new ActivationFrame("os", Optional.of(oa))); |
| 312 | + stk.push(new ActivationFrame("arch", Optional.empty())); |
| 313 | + validator.accept(oa.getArch()); |
| 314 | + stk.peek().location = "family"; |
| 315 | + validator.accept(oa.getFamily()); |
| 316 | + stk.peek().location = "name"; |
| 317 | + validator.accept(oa.getName()); |
| 318 | + stk.peek().location = "version"; |
| 319 | + validator.accept(oa.getVersion()); |
| 320 | + stk.pop(); |
| 321 | + stk.pop(); |
| 322 | + }); |
| 323 | + root.map(Activation::getProperty).ifPresent(pa -> { |
| 324 | + stk.push(new ActivationFrame("property", Optional.of(pa))); |
| 325 | + stk.push(new ActivationFrame("name", Optional.empty())); |
| 326 | + validator.accept(pa.getName()); |
| 327 | + stk.peek().location = "value"; |
| 328 | + validator.accept(pa.getValue()); |
| 329 | + stk.pop(); |
| 330 | + stk.pop(); |
| 331 | + }); |
| 332 | + root.map(Activation::getJdk).ifPresent(jdk -> { |
| 333 | + stk.push(new ActivationFrame("jdk", Optional.empty())); |
| 334 | + validator.accept(jdk); |
| 335 | + stk.pop(); |
| 336 | + }); |
275 | 337 | }
|
276 | 338 |
|
277 | 339 | private void validate20RawPlugins(
|
|
0 commit comments