1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.impl.model;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.lang.reflect.Field;
24 import java.nio.file.Path;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.LinkedHashSet;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Objects;
33 import java.util.Properties;
34 import java.util.concurrent.Callable;
35 import java.util.concurrent.atomic.AtomicReference;
36 import java.util.function.BiConsumer;
37 import java.util.function.Supplier;
38 import java.util.function.UnaryOperator;
39 import java.util.stream.Collectors;
40 import java.util.stream.Stream;
41
42 import org.apache.maven.api.Session;
43 import org.apache.maven.api.VersionRange;
44 import org.apache.maven.api.annotations.Nullable;
45 import org.apache.maven.api.di.Inject;
46 import org.apache.maven.api.di.Named;
47 import org.apache.maven.api.di.Singleton;
48 import org.apache.maven.api.feature.Features;
49 import org.apache.maven.api.model.Activation;
50 import org.apache.maven.api.model.ActivationFile;
51 import org.apache.maven.api.model.Build;
52 import org.apache.maven.api.model.Dependency;
53 import org.apache.maven.api.model.DependencyManagement;
54 import org.apache.maven.api.model.Exclusion;
55 import org.apache.maven.api.model.InputLocation;
56 import org.apache.maven.api.model.InputLocationTracker;
57 import org.apache.maven.api.model.InputSource;
58 import org.apache.maven.api.model.Model;
59 import org.apache.maven.api.model.Parent;
60 import org.apache.maven.api.model.Plugin;
61 import org.apache.maven.api.model.PluginManagement;
62 import org.apache.maven.api.model.Profile;
63 import org.apache.maven.api.services.BuilderProblem.Severity;
64 import org.apache.maven.api.services.ModelBuilder;
65 import org.apache.maven.api.services.ModelBuilderException;
66 import org.apache.maven.api.services.ModelBuilderRequest;
67 import org.apache.maven.api.services.ModelBuilderResult;
68 import org.apache.maven.api.services.ModelCache;
69 import org.apache.maven.api.services.ModelProblem;
70 import org.apache.maven.api.services.ModelProblemCollector;
71 import org.apache.maven.api.services.ModelResolver;
72 import org.apache.maven.api.services.ModelResolverException;
73 import org.apache.maven.api.services.ModelSource;
74 import org.apache.maven.api.services.ModelTransformer;
75 import org.apache.maven.api.services.ModelTransformerContext;
76 import org.apache.maven.api.services.ModelTransformerContextBuilder;
77 import org.apache.maven.api.services.ModelTransformerException;
78 import org.apache.maven.api.services.Source;
79 import org.apache.maven.api.services.SuperPomProvider;
80 import org.apache.maven.api.services.VersionParserException;
81 import org.apache.maven.api.services.model.*;
82 import org.apache.maven.api.services.xml.XmlReaderException;
83 import org.apache.maven.api.services.xml.XmlReaderRequest;
84 import org.apache.maven.internal.impl.resolver.DefaultModelCache;
85 import org.apache.maven.internal.impl.resolver.DefaultModelRepositoryHolder;
86 import org.apache.maven.internal.impl.resolver.DefaultModelResolver;
87 import org.apache.maven.model.v4.MavenTransformer;
88 import org.codehaus.plexus.interpolation.InterpolationException;
89 import org.codehaus.plexus.interpolation.Interpolator;
90 import org.codehaus.plexus.interpolation.MapBasedValueSource;
91 import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
92 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
95
96
97
98 @Named
99 @Singleton
100 public class DefaultModelBuilder implements ModelBuilder {
101
102 private static final String RAW = "raw";
103 private static final String FILE = "file";
104 private static final String IMPORT = "import";
105
106 private final Logger logger = LoggerFactory.getLogger(getClass());
107
108 private final ModelProcessor modelProcessor;
109 private final ModelValidator modelValidator;
110 private final ModelNormalizer modelNormalizer;
111 private final ModelInterpolator modelInterpolator;
112 private final ModelPathTranslator modelPathTranslator;
113 private final ModelUrlNormalizer modelUrlNormalizer;
114 private final SuperPomProvider superPomProvider;
115 private final InheritanceAssembler inheritanceAssembler;
116 private final ProfileSelector profileSelector;
117 private final ProfileInjector profileInjector;
118 private final PluginManagementInjector pluginManagementInjector;
119 private final DependencyManagementInjector dependencyManagementInjector;
120 private final DependencyManagementImporter dependencyManagementImporter;
121 private final LifecycleBindingsInjector lifecycleBindingsInjector;
122 private final PluginConfigurationExpander pluginConfigurationExpander;
123 private final ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
124 private final ModelTransformer transformer;
125 private final ModelVersionParser versionParser;
126
127 @SuppressWarnings("checkstyle:ParameterNumber")
128 @Inject
129 public DefaultModelBuilder(
130 ModelProcessor modelProcessor,
131 ModelValidator modelValidator,
132 ModelNormalizer modelNormalizer,
133 ModelInterpolator modelInterpolator,
134 ModelPathTranslator modelPathTranslator,
135 ModelUrlNormalizer modelUrlNormalizer,
136 SuperPomProvider superPomProvider,
137 InheritanceAssembler inheritanceAssembler,
138 ProfileSelector profileSelector,
139 ProfileInjector profileInjector,
140 PluginManagementInjector pluginManagementInjector,
141 DependencyManagementInjector dependencyManagementInjector,
142 DependencyManagementImporter dependencyManagementImporter,
143 @Nullable LifecycleBindingsInjector lifecycleBindingsInjector,
144 PluginConfigurationExpander pluginConfigurationExpander,
145 ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator,
146 ModelTransformer transformer,
147 ModelVersionParser versionParser) {
148 this.modelProcessor = modelProcessor;
149 this.modelValidator = modelValidator;
150 this.modelNormalizer = modelNormalizer;
151 this.modelInterpolator = modelInterpolator;
152 this.modelPathTranslator = modelPathTranslator;
153 this.modelUrlNormalizer = modelUrlNormalizer;
154 this.superPomProvider = superPomProvider;
155 this.inheritanceAssembler = inheritanceAssembler;
156 this.profileSelector = profileSelector;
157 this.profileInjector = profileInjector;
158 this.pluginManagementInjector = pluginManagementInjector;
159 this.dependencyManagementInjector = dependencyManagementInjector;
160 this.dependencyManagementImporter = dependencyManagementImporter;
161 this.lifecycleBindingsInjector = lifecycleBindingsInjector;
162 this.pluginConfigurationExpander = pluginConfigurationExpander;
163 this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator;
164 this.transformer = transformer;
165 this.versionParser = versionParser;
166 }
167
168 @Override
169 public ModelTransformerContextBuilder newTransformerContextBuilder() {
170 return new DefaultModelTransformerContextBuilder(this);
171 }
172
173 @Override
174 public ModelBuilderResult build(ModelBuilderRequest request) throws ModelBuilderException {
175 request = fillRequestDefaults(request);
176 if (request.getInterimResult() != null) {
177 return build(request, request.getInterimResult(), new LinkedHashSet<>());
178 } else {
179 return build(request, new LinkedHashSet<>());
180 }
181 }
182
183 private static ModelBuilderRequest fillRequestDefaults(ModelBuilderRequest request) {
184 ModelBuilderRequest.ModelBuilderRequestBuilder builder = ModelBuilderRequest.builder(request);
185 if (request.getModelCache() == null) {
186 builder.modelCache(new DefaultModelCache());
187 }
188 if (request.getModelRepositoryHolder() == null) {
189 builder.modelRepositoryHolder(new DefaultModelRepositoryHolder(
190 request.getSession(),
191 DefaultModelRepositoryHolder.RepositoryMerging.POM_DOMINANT,
192 request.getSession().getRemoteRepositories()));
193 }
194 if (request.getModelResolver() == null) {
195 builder.modelResolver(new DefaultModelResolver());
196 }
197 return builder.build();
198 }
199
200 protected ModelBuilderResult build(ModelBuilderRequest request, Collection<String> importIds)
201 throws ModelBuilderException {
202
203 DefaultModelBuilderResult result = new DefaultModelBuilderResult();
204
205 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
206
207
208 Model fileModel = readFileModel(request, problems);
209 result.setFileModel(fileModel);
210
211 Model activatedFileModel = activateFileModel(fileModel, request, result, problems);
212 result.setActivatedFileModel(activatedFileModel);
213
214 if (!request.isTwoPhaseBuilding()) {
215 return build(request, result, importIds);
216 } else if (hasModelErrors(problems)) {
217 throw problems.newModelBuilderException();
218 }
219
220 return result;
221 }
222
223 private Model activateFileModel(
224 Model inputModel,
225 ModelBuilderRequest request,
226 DefaultModelBuilderResult result,
227 DefaultModelProblemCollector problems)
228 throws ModelBuilderException {
229 problems.setRootModel(inputModel);
230
231
232 DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request, inputModel);
233
234 problems.setSource("(external profiles)");
235 List<Profile> activeExternalProfiles =
236 profileSelector.getActiveProfiles(request.getProfiles(), profileActivationContext, problems);
237
238 result.setActiveExternalProfiles(activeExternalProfiles);
239
240 if (!activeExternalProfiles.isEmpty()) {
241 Properties profileProps = new Properties();
242 for (Profile profile : activeExternalProfiles) {
243 profileProps.putAll(profile.getProperties());
244 }
245 profileProps.putAll(profileActivationContext.getUserProperties());
246 profileActivationContext.setUserProperties(profileProps);
247 }
248
249 profileActivationContext.setProjectProperties(inputModel.getProperties());
250 problems.setSource(inputModel);
251 List<Profile> activePomProfiles =
252 profileSelector.getActiveProfiles(inputModel.getProfiles(), profileActivationContext, problems);
253
254
255 problems.setSource(inputModel);
256 inputModel = modelNormalizer.mergeDuplicates(inputModel, request, problems);
257
258 Map<String, Activation> interpolatedActivations = getProfileActivations(inputModel);
259 inputModel = injectProfileActivations(inputModel, interpolatedActivations);
260
261
262 inputModel = profileInjector.injectProfiles(inputModel, activePomProfiles, request, problems);
263 inputModel = profileInjector.injectProfiles(inputModel, activeExternalProfiles, request, problems);
264
265 return inputModel;
266 }
267
268 @SuppressWarnings("checkstyle:methodlength")
269 private Model readEffectiveModel(
270 final ModelBuilderRequest request,
271 final DefaultModelBuilderResult result,
272 DefaultModelProblemCollector problems)
273 throws ModelBuilderException {
274 Model inputModel = readRawModel(request, problems);
275 if (problems.hasFatalErrors()) {
276 throw problems.newModelBuilderException();
277 }
278
279 inputModel = activateFileModel(inputModel, request, result, problems);
280
281 problems.setRootModel(inputModel);
282
283 ModelData resultData = new ModelData(request.getSource(), inputModel);
284 String superModelVersion = inputModel.getModelVersion() != null ? inputModel.getModelVersion() : "4.0.0";
285 if (!VALID_MODEL_VERSIONS.contains(superModelVersion)) {
286
287
288
289 superModelVersion = "4.0.0";
290 }
291 ModelData superData = new ModelData(null, getSuperModel(superModelVersion));
292
293
294 DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request, inputModel);
295
296 List<Profile> activeExternalProfiles = result.getActiveExternalProfiles();
297
298 if (!activeExternalProfiles.isEmpty()) {
299 Properties profileProps = new Properties();
300 for (Profile profile : activeExternalProfiles) {
301 profileProps.putAll(profile.getProperties());
302 }
303 profileProps.putAll(profileActivationContext.getUserProperties());
304 profileActivationContext.setUserProperties(profileProps);
305 }
306
307 Collection<String> parentIds = new LinkedHashSet<>();
308
309 List<Model> lineage = new ArrayList<>();
310
311 for (ModelData currentData = resultData; ; ) {
312 String modelId = currentData.id();
313 result.addModelId(modelId);
314
315 Model model = currentData.model();
316 result.setRawModel(modelId, model);
317 problems.setSource(model);
318
319
320 model = modelNormalizer.mergeDuplicates(model, request, problems);
321
322
323 profileActivationContext.setProjectProperties(model.getProperties());
324
325 List<Profile> interpolatedProfiles =
326 interpolateActivations(model.getProfiles(), profileActivationContext, problems);
327
328
329 List<Profile> activePomProfiles =
330 profileSelector.getActiveProfiles(interpolatedProfiles, profileActivationContext, problems);
331 result.setActivePomProfiles(modelId, activePomProfiles);
332 model = profileInjector.injectProfiles(model, activePomProfiles, request, problems);
333 if (currentData == resultData) {
334 model = profileInjector.injectProfiles(model, activeExternalProfiles, request, problems);
335 }
336
337 lineage.add(model);
338
339 if (currentData == superData) {
340 break;
341 }
342
343
344 if (!model.getRepositories().isEmpty()) {
345 List<String> oldRepos = request.getModelRepositoryHolder().getRepositories().stream()
346 .map(Object::toString)
347 .toList();
348 request.getModelRepositoryHolder().merge(model.getRepositories(), false);
349 List<String> newRepos = request.getModelRepositoryHolder().getRepositories().stream()
350 .map(Object::toString)
351 .toList();
352 if (!Objects.equals(oldRepos, newRepos)) {
353 logger.debug("Merging repositories from " + model.getId() + "\n"
354 + newRepos.stream().map(s -> " " + s).collect(Collectors.joining("\n")));
355 }
356 }
357
358
359 ModelData parentData = readParent(model, currentData.source(), request, problems);
360
361 if (parentData == null) {
362 currentData = superData;
363 } else if (!parentIds.add(parentData.id())) {
364 StringBuilder message = new StringBuilder("The parents form a cycle: ");
365 for (String parentId : parentIds) {
366 message.append(parentId).append(" -> ");
367 }
368 message.append(parentData.id());
369
370 problems.add(Severity.FATAL, ModelProblem.Version.BASE, message.toString());
371
372 throw problems.newModelBuilderException();
373 } else {
374 currentData = parentData;
375 }
376 }
377
378 Model tmpModel = lineage.get(0);
379
380
381 List<Profile> interpolated = interpolateActivations(tmpModel.getProfiles(), profileActivationContext, problems);
382 if (interpolated != tmpModel.getProfiles()) {
383 tmpModel = tmpModel.withProfiles(interpolated);
384 }
385
386
387 tmpModel = profileInjector.injectProfiles(tmpModel, activeExternalProfiles, request, problems);
388
389 lineage.set(0, tmpModel);
390
391 checkPluginVersions(lineage, request, problems);
392
393
394 Model resultModel = assembleInheritance(lineage, request, problems);
395
396
397
398 problems.setSource(resultModel);
399 problems.setRootModel(resultModel);
400
401
402 resultModel = interpolateModel(resultModel, request, problems);
403
404
405 resultModel = modelUrlNormalizer.normalize(resultModel, request);
406
407 result.setEffectiveModel(resultModel);
408
409
410 if (!resultModel.getRepositories().isEmpty()) {
411 List<String> oldRepos = request.getModelRepositoryHolder().getRepositories().stream()
412 .map(Object::toString)
413 .toList();
414 request.getModelRepositoryHolder().merge(resultModel.getRepositories(), true);
415 List<String> newRepos = request.getModelRepositoryHolder().getRepositories().stream()
416 .map(Object::toString)
417 .toList();
418 if (!Objects.equals(oldRepos, newRepos)) {
419 logger.debug("Replacing repositories from " + resultModel.getId() + "\n"
420 + newRepos.stream().map(s -> " " + s).collect(Collectors.joining("\n")));
421 }
422 }
423
424 return resultModel;
425 }
426
427 private List<Profile> interpolateActivations(
428 List<Profile> profiles, DefaultProfileActivationContext context, DefaultModelProblemCollector problems) {
429 if (profiles.stream()
430 .map(org.apache.maven.api.model.Profile::getActivation)
431 .noneMatch(Objects::nonNull)) {
432 return profiles;
433 }
434 final Interpolator xform = new RegexBasedInterpolator();
435 xform.setCacheAnswers(true);
436 Stream.of(context.getUserProperties(), context.getSystemProperties())
437 .map(MapBasedValueSource::new)
438 .forEach(xform::addValueSource);
439
440 class ProfileInterpolator extends MavenTransformer implements UnaryOperator<Profile> {
441 ProfileInterpolator() {
442 super(s -> {
443 if (isNotEmpty(s)) {
444 try {
445 return xform.interpolate(s);
446 } catch (InterpolationException e) {
447 problems.add(Severity.ERROR, ModelProblem.Version.BASE, e.getMessage(), e);
448 }
449 }
450 return s;
451 });
452 }
453
454 @Override
455 public Profile apply(Profile p) {
456 return Profile.newBuilder(p)
457 .activation(transformActivation(p.getActivation()))
458 .build();
459 }
460
461 @Override
462 protected ActivationFile.Builder transformActivationFile_Missing(
463 Supplier<? extends ActivationFile.Builder> creator,
464 ActivationFile.Builder builder,
465 ActivationFile target) {
466 String path = target.getMissing();
467 String xformed = transformPath(path, target, "missing");
468 return xformed != path ? (builder != null ? builder : creator.get()).missing(xformed) : builder;
469 }
470
471 @Override
472 protected ActivationFile.Builder transformActivationFile_Exists(
473 Supplier<? extends ActivationFile.Builder> creator,
474 ActivationFile.Builder builder,
475 ActivationFile target) {
476 final String path = target.getExists();
477 final String xformed = transformPath(path, target, "exists");
478 return xformed != path ? (builder != null ? builder : creator.get()).exists(xformed) : builder;
479 }
480
481 private String transformPath(String path, ActivationFile target, String locationKey) {
482 if (isNotEmpty(path)) {
483 try {
484 return profileActivationFilePathInterpolator.interpolate(path, context);
485 } catch (InterpolationException e) {
486 addInterpolationProblem(problems, target, path, e, locationKey);
487 }
488 }
489 return path;
490 }
491 }
492 return profiles.stream().map(new ProfileInterpolator()).toList();
493 }
494
495 private static void addInterpolationProblem(
496 DefaultModelProblemCollector problems,
497 InputLocationTracker target,
498 String path,
499 InterpolationException e,
500 String locationKey) {
501 problems.add(
502 Severity.ERROR,
503 ModelProblem.Version.BASE,
504 "Failed to interpolate file location " + path + ": " + e.getMessage(),
505 target.getLocation(locationKey),
506 e);
507 }
508
509 private static boolean isNotEmpty(String string) {
510 return string != null && !string.isEmpty();
511 }
512
513 public ModelBuilderResult build(final ModelBuilderRequest request, final ModelBuilderResult result)
514 throws ModelBuilderException {
515 return build(request, result, new LinkedHashSet<>());
516 }
517
518 public Model buildRawModel(ModelBuilderRequest request) throws ModelBuilderException {
519 request = fillRequestDefaults(request);
520 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuilderResult());
521 Model model = readRawModel(request, problems);
522 if (hasModelErrors(problems)) {
523 throw problems.newModelBuilderException();
524 }
525 return model;
526 }
527
528 private ModelBuilderResult build(
529 ModelBuilderRequest request, final ModelBuilderResult phaseOneResult, Collection<String> importIds)
530 throws ModelBuilderException {
531 DefaultModelBuilderResult result = asDefaultModelBuilderResult(phaseOneResult);
532
533 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
534
535
536 Model resultModel = readEffectiveModel(request, result, problems);
537 problems.setSource(resultModel);
538 problems.setRootModel(resultModel);
539
540
541 resultModel = modelPathTranslator.alignToBaseDirectory(resultModel, resultModel.getProjectDirectory(), request);
542
543
544 resultModel = pluginManagementInjector.injectManagement(resultModel, request, problems);
545
546 resultModel = fireEvent(resultModel, request, problems, ModelBuildingListener::buildExtensionsAssembled);
547
548 if (request.isProcessPlugins()) {
549 if (lifecycleBindingsInjector == null) {
550 throw new IllegalStateException("lifecycle bindings injector is missing");
551 }
552
553
554 resultModel = lifecycleBindingsInjector.injectLifecycleBindings(resultModel, request, problems);
555 }
556
557
558 resultModel = importDependencyManagement(resultModel, request, problems, importIds);
559
560
561 resultModel = dependencyManagementInjector.injectManagement(resultModel, request, problems);
562
563 resultModel = modelNormalizer.injectDefaultValues(resultModel, request, problems);
564
565 if (request.isProcessPlugins()) {
566
567 resultModel = pluginConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
568 }
569
570 result.setEffectiveModel(resultModel);
571
572
573 modelValidator.validateEffectiveModel(resultModel, request, problems);
574
575 if (hasModelErrors(problems)) {
576 throw problems.newModelBuilderException();
577 }
578
579 return result;
580 }
581
582 private DefaultModelBuilderResult asDefaultModelBuilderResult(ModelBuilderResult phaseOneResult) {
583 if (phaseOneResult instanceof DefaultModelBuilderResult) {
584 return (DefaultModelBuilderResult) phaseOneResult;
585 } else {
586 return new DefaultModelBuilderResult(phaseOneResult);
587 }
588 }
589
590 public Result<? extends Model> buildRawModel(Path pomFile, int validationLevel, boolean locationTracking) {
591 return buildRawModel(pomFile, validationLevel, locationTracking, null);
592 }
593
594 public Result<? extends Model> buildRawModel(
595 Path pomFile, int validationLevel, boolean locationTracking, ModelTransformerContext context) {
596 final ModelBuilderRequest request = ModelBuilderRequest.builder()
597 .validationLevel(validationLevel)
598 .locationTracking(locationTracking)
599 .source(ModelSource.fromPath(pomFile))
600 .build();
601 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuilderResult());
602 try {
603 Model model = readFileModel(request, problems);
604
605 try {
606 if (transformer != null && context != null) {
607 transformer.transform(context, model, pomFile);
608 }
609 } catch (ModelBuilderException e) {
610 problems.add(Severity.FATAL, ModelProblem.Version.V40, null, e);
611 }
612
613 return Result.newResult(model, problems.getProblems());
614 } catch (ModelBuilderException e) {
615 return Result.error(problems.getProblems());
616 }
617 }
618
619 Model readFileModel(ModelBuilderRequest request, DefaultModelProblemCollector problems)
620 throws ModelBuilderException {
621 ModelSource modelSource = request.getSource();
622 Model model =
623 cache(getModelCache(request), modelSource, FILE, () -> doReadFileModel(modelSource, request, problems));
624
625 if (modelSource.getPath() != null) {
626 if (getTransformerContextBuilder(request) instanceof DefaultModelTransformerContextBuilder contextBuilder) {
627 contextBuilder.putSource(getGroupId(model), model.getArtifactId(), modelSource);
628 }
629 }
630
631 return model;
632 }
633
634 @SuppressWarnings("checkstyle:methodlength")
635 private Model doReadFileModel(
636 ModelSource modelSource, ModelBuilderRequest request, DefaultModelProblemCollector problems)
637 throws ModelBuilderException {
638 Model model;
639 problems.setSource(modelSource.getLocation());
640 try {
641 boolean strict = request.getValidationLevel() >= ModelBuilderRequest.VALIDATION_LEVEL_MAVEN_2_0;
642
643 try (InputStream is = modelSource.openStream()) {
644 model = modelProcessor.read(XmlReaderRequest.builder()
645 .strict(strict)
646 .location(modelSource.getLocation())
647 .path(modelSource.getPath())
648 .inputStream(is)
649 .build());
650 } catch (XmlReaderException e) {
651 if (!strict) {
652 throw e;
653 }
654 try (InputStream is = modelSource.openStream()) {
655 model = modelProcessor.read(XmlReaderRequest.builder()
656 .strict(false)
657 .location(modelSource.getLocation())
658 .path(modelSource.getPath())
659 .inputStream(is)
660 .build());
661 } catch (XmlReaderException ne) {
662
663 throw e;
664 }
665
666 Severity severity = request.isProjectBuild() ? Severity.ERROR : Severity.WARNING;
667 problems.add(
668 severity,
669 ModelProblem.Version.V20,
670 "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage(),
671 e);
672 }
673
674 InputLocation loc = model.getLocation("");
675 InputSource v4src = loc != null ? loc.getSource() : null;
676 if (v4src != null) {
677 try {
678 Field field = InputSource.class.getDeclaredField("modelId");
679 field.setAccessible(true);
680 field.set(v4src, ModelProblemUtils.toId(model));
681 } catch (Throwable t) {
682
683 throw new IllegalStateException("Unable to set modelId on InputSource", t);
684 }
685 }
686 } catch (XmlReaderException e) {
687 problems.add(
688 Severity.FATAL,
689 ModelProblem.Version.BASE,
690 "Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage(),
691 e);
692 throw problems.newModelBuilderException();
693 } catch (IOException e) {
694 String msg = e.getMessage();
695 if (msg == null || msg.isEmpty()) {
696
697 if (e.getClass().getName().endsWith("MalformedInputException")) {
698 msg = "Some input bytes do not match the file encoding.";
699 } else {
700 msg = e.getClass().getSimpleName();
701 }
702 }
703 problems.add(
704 Severity.FATAL,
705 ModelProblem.Version.BASE,
706 "Non-readable POM " + modelSource.getLocation() + ": " + msg,
707 e);
708 throw problems.newModelBuilderException();
709 }
710
711 if (modelSource.getPath() != null) {
712 model = model.withPomFile(modelSource.getPath());
713 }
714
715 problems.setSource(model);
716 modelValidator.validateFileModel(model, request, problems);
717 if (hasFatalErrors(problems)) {
718 throw problems.newModelBuilderException();
719 }
720
721 return model;
722 }
723
724 Model readRawModel(ModelBuilderRequest request, DefaultModelProblemCollector problems)
725 throws ModelBuilderException {
726 ModelSource modelSource = request.getSource();
727
728 ModelData modelData =
729 cache(getModelCache(request), modelSource, RAW, () -> doReadRawModel(modelSource, request, problems));
730
731 return modelData.model();
732 }
733
734 private ModelData doReadRawModel(
735 ModelSource modelSource, ModelBuilderRequest request, DefaultModelProblemCollector problems)
736 throws ModelBuilderException {
737 Model rawModel = readFileModel(request, problems);
738 if (Features.buildConsumer(request.getUserProperties()) && modelSource.getPath() != null) {
739 Path pomFile = modelSource.getPath();
740
741 try {
742 ModelTransformerContextBuilder transformerContextBuilder = getTransformerContextBuilder(request);
743 if (transformerContextBuilder != null) {
744 ModelTransformerContext context = transformerContextBuilder.initialize(request, problems);
745 rawModel = this.transformer.transform(context, rawModel, pomFile);
746 }
747 } catch (ModelTransformerException e) {
748 problems.add(Severity.FATAL, ModelProblem.Version.V40, null, e);
749 }
750 }
751
752 modelValidator.validateRawModel(rawModel, request, problems);
753
754 if (hasFatalErrors(problems)) {
755 throw problems.newModelBuilderException();
756 }
757
758 return new ModelData(modelSource, rawModel);
759 }
760
761 static String getGroupId(Model model) {
762 String groupId = model.getGroupId();
763 if (groupId == null && model.getParent() != null) {
764 groupId = model.getParent().getGroupId();
765 }
766 return groupId;
767 }
768
769 private String getVersion(Model model) {
770 String version = model.getVersion();
771 if (version == null && model.getParent() != null) {
772 version = model.getParent().getVersion();
773 }
774 return version;
775 }
776
777 private DefaultProfileActivationContext getProfileActivationContext(ModelBuilderRequest request, Model model) {
778 DefaultProfileActivationContext context = new DefaultProfileActivationContext();
779
780 context.setActiveProfileIds(request.getActiveProfileIds());
781 context.setInactiveProfileIds(request.getInactiveProfileIds());
782 context.setSystemProperties(request.getSystemProperties());
783
784 Map<String, String> userProperties = new HashMap<>(request.getUserProperties());
785 if (!userProperties.containsKey(ProfileActivationContext.PROPERTY_NAME_PACKAGING)) {
786 userProperties.put(ProfileActivationContext.PROPERTY_NAME_PACKAGING, model.getPackaging());
787 }
788 context.setUserProperties(userProperties);
789 context.setProjectDirectory(model.getProjectDirectory());
790
791 return context;
792 }
793
794 private void checkPluginVersions(List<Model> lineage, ModelBuilderRequest request, ModelProblemCollector problems) {
795 if (request.getValidationLevel() < ModelBuilderRequest.VALIDATION_LEVEL_MAVEN_2_0) {
796 return;
797 }
798
799 Map<String, Plugin> plugins = new HashMap<>();
800 Map<String, String> versions = new HashMap<>();
801 Map<String, String> managedVersions = new HashMap<>();
802
803 for (int i = lineage.size() - 1; i >= 0; i--) {
804 Model model = lineage.get(i);
805 Build build = model.getBuild();
806 if (build != null) {
807 for (Plugin plugin : build.getPlugins()) {
808 String key = plugin.getKey();
809 if (versions.get(key) == null) {
810 versions.put(key, plugin.getVersion());
811 plugins.put(key, plugin);
812 }
813 }
814 PluginManagement mgmt = build.getPluginManagement();
815 if (mgmt != null) {
816 for (Plugin plugin : mgmt.getPlugins()) {
817 String key = plugin.getKey();
818 managedVersions.computeIfAbsent(key, k -> plugin.getVersion());
819 }
820 }
821 }
822 }
823
824 for (String key : versions.keySet()) {
825 if (versions.get(key) == null && managedVersions.get(key) == null) {
826 InputLocation location = plugins.get(key).getLocation("");
827 problems.add(
828 Severity.WARNING,
829 ModelProblem.Version.V20,
830 "'build.plugins.plugin.version' for " + key + " is missing.",
831 location);
832 }
833 }
834 }
835
836 private Model assembleInheritance(
837 List<Model> lineage, ModelBuilderRequest request, ModelProblemCollector problems) {
838 Model parent = lineage.get(lineage.size() - 1);
839 for (int i = lineage.size() - 2; i >= 0; i--) {
840 Model child = lineage.get(i);
841 parent = inheritanceAssembler.assembleModelInheritance(child, parent, request, problems);
842 }
843 return parent;
844 }
845
846 private Map<String, Activation> getProfileActivations(Model model) {
847 return model.getProfiles().stream()
848 .filter(p -> p.getActivation() != null)
849 .collect(Collectors.toMap(Profile::getId, Profile::getActivation));
850 }
851
852 private Model injectProfileActivations(Model model, Map<String, Activation> activations) {
853 List<Profile> profiles = new ArrayList<>();
854 boolean modified = false;
855 for (Profile profile : model.getProfiles()) {
856 Activation activation = profile.getActivation();
857 if (activation != null) {
858
859 profile = profile.withActivation(activations.get(profile.getId()));
860 modified = true;
861 }
862 profiles.add(profile);
863 }
864 return modified ? model.withProfiles(profiles) : model;
865 }
866
867 private Model interpolateModel(Model model, ModelBuilderRequest request, ModelProblemCollector problems) {
868 Model interpolatedModel =
869 modelInterpolator.interpolateModel(model, model.getProjectDirectory(), request, problems);
870 if (interpolatedModel.getParent() != null) {
871 StringSearchInterpolator ssi = new StringSearchInterpolator();
872 ssi.addValueSource(new MapBasedValueSource(request.getSession().getUserProperties()));
873 ssi.addValueSource(new MapBasedValueSource(model.getProperties()));
874 ssi.addValueSource(new MapBasedValueSource(request.getSession().getSystemProperties()));
875 try {
876 String interpolated =
877 ssi.interpolate(interpolatedModel.getParent().getVersion());
878 interpolatedModel = interpolatedModel.withParent(
879 interpolatedModel.getParent().withVersion(interpolated));
880 } catch (Exception e) {
881 problems.add(
882 Severity.ERROR,
883 ModelProblem.Version.BASE,
884 "Failed to interpolate field: "
885 + interpolatedModel.getParent().getVersion()
886 + " on class: ",
887 e);
888 }
889 }
890 interpolatedModel = interpolatedModel.withPomFile(model.getPomFile());
891 return interpolatedModel;
892 }
893
894 private ModelData readParent(
895 Model childModel,
896 ModelSource childSource,
897 ModelBuilderRequest request,
898 DefaultModelProblemCollector problems)
899 throws ModelBuilderException {
900 ModelData parentData = null;
901
902 Parent parent = childModel.getParent();
903 if (parent != null) {
904 parentData = readParentLocally(childModel, childSource, request, problems);
905 if (parentData == null) {
906 parentData = readParentExternally(childModel, request, problems);
907 }
908
909 Model parentModel = parentData.model();
910 if (!"pom".equals(parentModel.getPackaging())) {
911 problems.add(
912 Severity.ERROR,
913 ModelProblem.Version.BASE,
914 "Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint(parentModel)
915 + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"",
916 parentModel.getLocation("packaging"));
917 }
918 }
919
920 return parentData;
921 }
922
923 private ModelData readParentLocally(
924 Model childModel,
925 ModelSource childSource,
926 ModelBuilderRequest request,
927 DefaultModelProblemCollector problems)
928 throws ModelBuilderException {
929 final Parent parent = childModel.getParent();
930 final ModelSource candidateSource;
931 final Model candidateModel;
932 final WorkspaceModelResolver resolver = getWorkspaceModelResolver(request);
933 if (resolver == null) {
934 candidateSource = getParentPomFile(childModel, childSource);
935
936 if (candidateSource == null) {
937 return null;
938 }
939
940 ModelBuilderRequest candidateBuildRequest = ModelBuilderRequest.build(request, candidateSource);
941
942 candidateModel = readRawModel(candidateBuildRequest, problems);
943 } else {
944 try {
945 candidateModel =
946 resolver.resolveRawModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
947 } catch (ModelBuilderException e) {
948 problems.add(Severity.FATAL, ModelProblem.Version.BASE, e.getMessage(), parent.getLocation(""), e);
949 throw problems.newModelBuilderException();
950 }
951 if (candidateModel == null) {
952 return null;
953 }
954 candidateSource = ModelSource.fromPath(candidateModel.getPomFile());
955 }
956
957
958
959
960
961
962
963 String groupId = getGroupId(candidateModel);
964 String artifactId = candidateModel.getArtifactId();
965
966 if (groupId == null
967 || !groupId.equals(parent.getGroupId())
968 || artifactId == null
969 || !artifactId.equals(parent.getArtifactId())) {
970 StringBuilder buffer = new StringBuilder(256);
971 buffer.append("'parent.relativePath'");
972 if (childModel != problems.getRootModel()) {
973 buffer.append(" of POM ").append(ModelProblemUtils.toSourceHint(childModel));
974 }
975 buffer.append(" points at ").append(groupId).append(':').append(artifactId);
976 buffer.append(" instead of ").append(parent.getGroupId()).append(':');
977 buffer.append(parent.getArtifactId()).append(", please verify your project structure");
978
979 problems.setSource(childModel);
980 problems.add(Severity.WARNING, ModelProblem.Version.BASE, buffer.toString(), parent.getLocation(""));
981 return null;
982 }
983
984 String version = getVersion(candidateModel);
985 if (version != null && parent.getVersion() != null && !version.equals(parent.getVersion())) {
986 try {
987 VersionRange parentRange = versionParser.parseVersionRange(parent.getVersion());
988 if (!parentRange.contains(versionParser.parseVersion(version))) {
989
990 return null;
991 }
992
993
994 String rawChildModelVersion = childModel.getVersion();
995
996 if (rawChildModelVersion == null) {
997
998 problems.add(
999 Severity.FATAL,
1000 ModelProblem.Version.V31,
1001 "Version must be a constant",
1002 childModel.getLocation(""));
1003
1004 } else {
1005 if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1006
1007 problems.add(
1008 Severity.FATAL,
1009 ModelProblem.Version.V31,
1010 "Version must be a constant",
1011 childModel.getLocation("version"));
1012 }
1013 }
1014
1015
1016 } catch (VersionParserException e) {
1017
1018 return null;
1019 }
1020 }
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 return new ModelData(candidateSource, candidateModel);
1032 }
1033
1034 private boolean rawChildVersionReferencesParent(String rawChildModelVersion) {
1035 return rawChildModelVersion.equals("${pom.version}")
1036 || rawChildModelVersion.equals("${project.version}")
1037 || rawChildModelVersion.equals("${pom.parent.version}")
1038 || rawChildModelVersion.equals("${project.parent.version}");
1039 }
1040
1041 private ModelSource getParentPomFile(Model childModel, ModelSource source) {
1042 String parentPath = childModel.getParent().getRelativePath();
1043 if (parentPath == null || parentPath.isEmpty()) {
1044 return null;
1045 } else {
1046 return source.resolve(modelProcessor::locateExistingPom, parentPath);
1047 }
1048 }
1049
1050 private ModelData readParentExternally(
1051 Model childModel, ModelBuilderRequest request, DefaultModelProblemCollector problems)
1052 throws ModelBuilderException {
1053 problems.setSource(childModel);
1054
1055 Parent parent = childModel.getParent();
1056
1057 String groupId = parent.getGroupId();
1058 String artifactId = parent.getArtifactId();
1059 String version = parent.getVersion();
1060
1061 ModelResolver modelResolver = getModelResolver(request);
1062 Objects.requireNonNull(
1063 modelResolver,
1064 String.format(
1065 "request.modelResolver cannot be null (parent POM %s and POM %s)",
1066 ModelProblemUtils.toId(groupId, artifactId, version),
1067 ModelProblemUtils.toSourceHint(childModel)));
1068
1069 ModelSource modelSource;
1070 try {
1071 AtomicReference<Parent> modified = new AtomicReference<>();
1072 Session session = request.getSession()
1073 .withRemoteRepositories(request.getModelRepositoryHolder().getRepositories());
1074 modelSource = modelResolver.resolveModel(session, parent, modified);
1075 if (modified.get() != null) {
1076 parent = modified.get();
1077 }
1078 } catch (ModelResolverException e) {
1079
1080 StringBuilder buffer = new StringBuilder(256);
1081 buffer.append("Non-resolvable parent POM");
1082 if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1083 buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1084 }
1085 if (childModel != problems.getRootModel()) {
1086 buffer.append(" for ").append(ModelProblemUtils.toId(childModel));
1087 }
1088 buffer.append(": ").append(e.getMessage());
1089 if (childModel.getProjectDirectory() != null) {
1090 if (parent.getRelativePath() == null || parent.getRelativePath().isEmpty()) {
1091 buffer.append(" and 'parent.relativePath' points at no local POM");
1092 } else {
1093 buffer.append(" and 'parent.relativePath' points at wrong local POM");
1094 }
1095 }
1096
1097 problems.add(Severity.FATAL, ModelProblem.Version.BASE, buffer.toString(), parent.getLocation(""), e);
1098 throw problems.newModelBuilderException();
1099 }
1100
1101 int validationLevel = Math.min(request.getValidationLevel(), ModelBuilderRequest.VALIDATION_LEVEL_MAVEN_2_0);
1102 ModelBuilderRequest lenientRequest = ModelBuilderRequest.builder(request)
1103 .validationLevel(validationLevel)
1104 .projectBuild(false)
1105 .source(modelSource)
1106 .build();
1107
1108 Model parentModel = readRawModel(lenientRequest, problems);
1109
1110 if (!parent.getVersion().equals(version)) {
1111 String rawChildModelVersion = childModel.getVersion();
1112
1113 if (rawChildModelVersion == null) {
1114
1115 problems.add(
1116 Severity.FATAL,
1117 ModelProblem.Version.V31,
1118 "Version must be a constant",
1119 childModel.getLocation(""));
1120
1121 } else {
1122 if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1123
1124 problems.add(
1125 Severity.FATAL,
1126 ModelProblem.Version.V31,
1127 "Version must be a constant",
1128 childModel.getLocation("version"));
1129 }
1130 }
1131
1132
1133 }
1134
1135 return new ModelData(modelSource, parentModel);
1136 }
1137
1138 private Model getSuperModel(String modelVersion) {
1139 return superPomProvider.getSuperPom(modelVersion);
1140 }
1141
1142 private Model importDependencyManagement(
1143 Model model,
1144 ModelBuilderRequest request,
1145 DefaultModelProblemCollector problems,
1146 Collection<String> importIds) {
1147 DependencyManagement depMgmt = model.getDependencyManagement();
1148
1149 if (depMgmt == null) {
1150 return model;
1151 }
1152
1153 String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
1154
1155 importIds.add(importing);
1156
1157 List<DependencyManagement> importMgmts = null;
1158
1159 List<Dependency> deps = new ArrayList<>(depMgmt.getDependencies());
1160 for (Iterator<Dependency> it = deps.iterator(); it.hasNext(); ) {
1161 Dependency dependency = it.next();
1162
1163 if (!("pom".equals(dependency.getType()) && "import".equals(dependency.getScope()))
1164 || "bom".equals(dependency.getType())) {
1165 continue;
1166 }
1167
1168 it.remove();
1169
1170 DependencyManagement importMgmt = loadDependencyManagement(model, request, problems, dependency, importIds);
1171
1172 if (importMgmt != null) {
1173 if (importMgmts == null) {
1174 importMgmts = new ArrayList<>();
1175 }
1176
1177 importMgmts.add(importMgmt);
1178 }
1179 }
1180
1181 importIds.remove(importing);
1182
1183 model = model.withDependencyManagement(model.getDependencyManagement().withDependencies(deps));
1184
1185 return dependencyManagementImporter.importManagement(model, importMgmts, request, problems);
1186 }
1187
1188 private DependencyManagement loadDependencyManagement(
1189 Model model,
1190 ModelBuilderRequest request,
1191 DefaultModelProblemCollector problems,
1192 Dependency dependency,
1193 Collection<String> importIds) {
1194 String groupId = dependency.getGroupId();
1195 String artifactId = dependency.getArtifactId();
1196 String version = dependency.getVersion();
1197
1198 if (groupId == null || groupId.isEmpty()) {
1199 problems.add(
1200 Severity.ERROR,
1201 ModelProblem.Version.BASE,
1202 "'dependencyManagement.dependencies.dependency.groupId' for " + dependency.getManagementKey()
1203 + " is missing.",
1204 dependency.getLocation(""));
1205 return null;
1206 }
1207 if (artifactId == null || artifactId.isEmpty()) {
1208 problems.add(
1209 Severity.ERROR,
1210 ModelProblem.Version.BASE,
1211 "'dependencyManagement.dependencies.dependency.artifactId' for " + dependency.getManagementKey()
1212 + " is missing.",
1213 dependency.getLocation(""));
1214 return null;
1215 }
1216 if (version == null || version.isEmpty()) {
1217 problems.add(
1218 Severity.ERROR,
1219 ModelProblem.Version.BASE,
1220 "'dependencyManagement.dependencies.dependency.version' for " + dependency.getManagementKey()
1221 + " is missing.",
1222 dependency.getLocation(""));
1223 return null;
1224 }
1225
1226 String imported = groupId + ':' + artifactId + ':' + version;
1227
1228 if (importIds.contains(imported)) {
1229 StringBuilder message =
1230 new StringBuilder("The dependencies of type=pom and with scope=import form a cycle: ");
1231 for (String modelId : importIds) {
1232 message.append(modelId).append(" -> ");
1233 }
1234 message.append(imported);
1235 problems.add(Severity.ERROR, ModelProblem.Version.BASE, message.toString());
1236
1237 return null;
1238 }
1239
1240 Model importModel = cache(
1241 getModelCache(request),
1242 groupId,
1243 artifactId,
1244 version,
1245 IMPORT,
1246 () -> doLoadDependencyManagement(
1247 model, request, problems, dependency, groupId, artifactId, version, importIds));
1248 DependencyManagement importMgmt = importModel != null ? importModel.getDependencyManagement() : null;
1249 if (importMgmt == null) {
1250 importMgmt = DependencyManagement.newInstance();
1251 }
1252
1253
1254 List<Exclusion> exclusions = dependency.getExclusions();
1255 if (importMgmt != null && !exclusions.isEmpty()) {
1256
1257 List<Dependency> dependencies = importMgmt.getDependencies().stream()
1258 .filter(candidate -> exclusions.stream().noneMatch(exclusion -> match(exclusion, candidate)))
1259 .map(candidate -> candidate.withExclusions(exclusions))
1260 .collect(Collectors.toList());
1261 importMgmt = importMgmt.withDependencies(dependencies);
1262 }
1263
1264 return importMgmt;
1265 }
1266
1267 private boolean match(Exclusion exclusion, Dependency candidate) {
1268 return match(exclusion.getGroupId(), candidate.getGroupId())
1269 && match(exclusion.getArtifactId(), candidate.getArtifactId());
1270 }
1271
1272 private boolean match(String match, String text) {
1273 return match.equals("*") || match.equals(text);
1274 }
1275
1276 @SuppressWarnings("checkstyle:parameternumber")
1277 private Model doLoadDependencyManagement(
1278 Model model,
1279 ModelBuilderRequest request,
1280 DefaultModelProblemCollector problems,
1281 Dependency dependency,
1282 String groupId,
1283 String artifactId,
1284 String version,
1285 Collection<String> importIds) {
1286 final WorkspaceModelResolver workspaceResolver = getWorkspaceModelResolver(request);
1287 final ModelResolver modelResolver = getModelResolver(request);
1288 if (workspaceResolver == null && modelResolver == null) {
1289 throw new NullPointerException(String.format(
1290 "request.workspaceModelResolver and request.modelResolver cannot be null (parent POM %s and POM %s)",
1291 ModelProblemUtils.toId(groupId, artifactId, version), ModelProblemUtils.toSourceHint(model)));
1292 }
1293
1294 Model importModel = null;
1295 if (workspaceResolver != null) {
1296 try {
1297 importModel = workspaceResolver.resolveEffectiveModel(groupId, artifactId, version);
1298 } catch (ModelBuilderException e) {
1299 problems.add(Severity.FATAL, ModelProblem.Version.BASE, null, e);
1300 return null;
1301 }
1302 }
1303
1304
1305 if (importModel == null) {
1306 final ModelSource importSource;
1307 try {
1308 Session session = request.getSession()
1309 .withRemoteRepositories(
1310 request.getModelRepositoryHolder().getRepositories());
1311 importSource = modelResolver.resolveModel(session, dependency, new AtomicReference<>());
1312 } catch (ModelBuilderException e) {
1313 StringBuilder buffer = new StringBuilder(256);
1314 buffer.append("Non-resolvable import POM");
1315 if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1316 buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1317 }
1318 buffer.append(": ").append(e.getMessage());
1319
1320 problems.add(
1321 Severity.ERROR, ModelProblem.Version.BASE, buffer.toString(), dependency.getLocation(""), e);
1322 return null;
1323 }
1324
1325 Path rootDirectory;
1326 try {
1327 rootDirectory = request.getSession().getRootDirectory();
1328 } catch (IllegalStateException e) {
1329 rootDirectory = null;
1330 }
1331 if (importSource.getPath() != null && rootDirectory != null) {
1332 Path sourcePath = importSource.getPath();
1333 if (sourcePath.startsWith(rootDirectory)) {
1334 problems.add(
1335 Severity.WARNING,
1336 ModelProblem.Version.BASE,
1337 "BOM imports from within reactor should be avoided",
1338 dependency.getLocation(""));
1339 }
1340 }
1341
1342 final ModelBuilderResult importResult;
1343 try {
1344 ModelBuilderRequest importRequest = ModelBuilderRequest.builder()
1345 .session(request.getSession()
1346 .withRemoteRepositories(
1347 request.getModelRepositoryHolder().getRepositories()))
1348 .validationLevel(ModelBuilderRequest.VALIDATION_LEVEL_MINIMAL)
1349 .systemProperties(request.getSystemProperties())
1350 .userProperties(request.getUserProperties())
1351 .source(importSource)
1352 .modelResolver(modelResolver)
1353 .modelCache(request.getModelCache())
1354 .modelRepositoryHolder(
1355 request.getModelRepositoryHolder().copy())
1356 .twoPhaseBuilding(false)
1357 .build();
1358 importResult = build(importRequest, importIds);
1359 } catch (ModelBuilderException e) {
1360 e.getResult().getProblems().forEach(problems::add);
1361 return null;
1362 }
1363
1364 importResult.getProblems().forEach(problems::add);
1365
1366 importModel = importResult.getEffectiveModel();
1367 }
1368
1369 return importModel;
1370 }
1371
1372 private static <T> T cache(
1373 ModelCache cache, String groupId, String artifactId, String version, String tag, Callable<T> supplier) {
1374 Supplier<T> s = asSupplier(supplier);
1375 if (cache == null) {
1376 return s.get();
1377 } else {
1378 return cache.computeIfAbsent(groupId, artifactId, version, tag, s);
1379 }
1380 }
1381
1382 private static <T> T cache(ModelCache cache, Source source, String tag, Callable<T> supplier) {
1383 Supplier<T> s = asSupplier(supplier);
1384 if (cache == null) {
1385 return s.get();
1386 } else {
1387 return cache.computeIfAbsent(source, tag, s);
1388 }
1389 }
1390
1391 private static <T> Supplier<T> asSupplier(Callable<T> supplier) {
1392 return () -> {
1393 try {
1394 return supplier.call();
1395 } catch (Exception e) {
1396 uncheckedThrow(e);
1397 return null;
1398 }
1399 };
1400 }
1401
1402 static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
1403 throw (T) t;
1404 }
1405
1406 private Model fireEvent(
1407 Model model,
1408 ModelBuilderRequest request,
1409 ModelProblemCollector problems,
1410 BiConsumer<ModelBuildingListener, ModelBuildingEvent> catapult) {
1411 ModelBuildingListener listener = getModelBuildingListener(request);
1412
1413 if (listener != null) {
1414 AtomicReference<Model> m = new AtomicReference<>(model);
1415
1416 ModelBuildingEvent event = new DefaultModelBuildingEvent(model, m::set, request, problems);
1417
1418 catapult.accept(listener, event);
1419
1420 return m.get();
1421 }
1422
1423 return model;
1424 }
1425
1426 private boolean containsCoordinates(String message, String groupId, String artifactId, String version) {
1427 return message != null
1428 && (groupId == null || message.contains(groupId))
1429 && (artifactId == null || message.contains(artifactId))
1430 && (version == null || message.contains(version));
1431 }
1432
1433 protected boolean hasModelErrors(ModelProblemCollector problems) {
1434 return problems.hasErrors();
1435 }
1436
1437 protected boolean hasFatalErrors(ModelProblemCollector problems) {
1438 return problems.hasFatalErrors();
1439 }
1440
1441 ModelProcessor getModelProcessor() {
1442 return modelProcessor;
1443 }
1444
1445 private static ModelCache getModelCache(ModelBuilderRequest request) {
1446 return request.getModelCache();
1447 }
1448
1449 private static ModelBuildingListener getModelBuildingListener(ModelBuilderRequest request) {
1450 return (ModelBuildingListener) request.getListener();
1451 }
1452
1453 private static WorkspaceModelResolver getWorkspaceModelResolver(ModelBuilderRequest request) {
1454 return null;
1455 }
1456
1457 private static ModelResolver getModelResolver(ModelBuilderRequest request) {
1458 return request.getModelResolver();
1459 }
1460
1461 private static ModelTransformerContextBuilder getTransformerContextBuilder(ModelBuilderRequest request) {
1462 return request.getTransformerContextBuilder();
1463 }
1464 }