1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.building;
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.io.IOException;
27 import java.lang.reflect.Field;
28 import java.util.*;
29 import java.util.concurrent.Callable;
30 import java.util.concurrent.ForkJoinTask;
31 import java.util.function.Function;
32 import java.util.function.Supplier;
33 import java.util.stream.Collectors;
34
35 import org.apache.maven.api.feature.Features;
36 import org.apache.maven.api.model.Exclusion;
37 import org.apache.maven.api.model.InputSource;
38 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
39 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
40 import org.apache.maven.artifact.versioning.VersionRange;
41 import org.apache.maven.building.Source;
42 import org.apache.maven.model.Activation;
43 import org.apache.maven.model.Build;
44 import org.apache.maven.model.Dependency;
45 import org.apache.maven.model.DependencyManagement;
46 import org.apache.maven.model.InputLocation;
47 import org.apache.maven.model.Model;
48 import org.apache.maven.model.Parent;
49 import org.apache.maven.model.Plugin;
50 import org.apache.maven.model.PluginManagement;
51 import org.apache.maven.model.Profile;
52 import org.apache.maven.model.building.ModelProblem.Severity;
53 import org.apache.maven.model.building.ModelProblem.Version;
54 import org.apache.maven.model.composition.DependencyManagementImporter;
55 import org.apache.maven.model.inheritance.InheritanceAssembler;
56 import org.apache.maven.model.interpolation.ModelInterpolator;
57 import org.apache.maven.model.interpolation.ModelVersionProcessor;
58 import org.apache.maven.model.io.ModelParseException;
59 import org.apache.maven.model.io.ModelReader;
60 import org.apache.maven.model.management.DependencyManagementInjector;
61 import org.apache.maven.model.management.PluginManagementInjector;
62 import org.apache.maven.model.normalization.ModelNormalizer;
63 import org.apache.maven.model.path.ModelPathTranslator;
64 import org.apache.maven.model.path.ModelUrlNormalizer;
65 import org.apache.maven.model.path.ProfileActivationFilePathInterpolator;
66 import org.apache.maven.model.plugin.LifecycleBindingsInjector;
67 import org.apache.maven.model.plugin.PluginConfigurationExpander;
68 import org.apache.maven.model.plugin.ReportConfigurationExpander;
69 import org.apache.maven.model.plugin.ReportingConverter;
70 import org.apache.maven.model.profile.DefaultProfileActivationContext;
71 import org.apache.maven.model.profile.ProfileActivationContext;
72 import org.apache.maven.model.profile.ProfileInjector;
73 import org.apache.maven.model.profile.ProfileSelector;
74 import org.apache.maven.model.resolution.InvalidRepositoryException;
75 import org.apache.maven.model.resolution.ModelResolver;
76 import org.apache.maven.model.resolution.UnresolvableModelException;
77 import org.apache.maven.model.resolution.WorkspaceModelResolver;
78 import org.apache.maven.model.superpom.SuperPomProvider;
79 import org.apache.maven.model.validation.DefaultModelValidator;
80 import org.apache.maven.model.validation.ModelValidator;
81 import org.codehaus.plexus.interpolation.InterpolationException;
82 import org.codehaus.plexus.interpolation.MapBasedValueSource;
83 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
84 import org.eclipse.sisu.Nullable;
85
86 import static org.apache.maven.model.building.Result.error;
87 import static org.apache.maven.model.building.Result.newResult;
88
89
90
91 @Named
92 @Singleton
93 public class DefaultModelBuilder implements ModelBuilder {
94
95 private final ModelProcessor modelProcessor;
96 private final ModelValidator modelValidator;
97 private final ModelNormalizer modelNormalizer;
98 private final ModelInterpolator modelInterpolator;
99 private final ModelPathTranslator modelPathTranslator;
100 private final ModelUrlNormalizer modelUrlNormalizer;
101 private final SuperPomProvider superPomProvider;
102 private final InheritanceAssembler inheritanceAssembler;
103 private final ProfileSelector profileSelector;
104 private final ProfileInjector profileInjector;
105 private final PluginManagementInjector pluginManagementInjector;
106 private final DependencyManagementInjector dependencyManagementInjector;
107 private final DependencyManagementImporter dependencyManagementImporter;
108 private final LifecycleBindingsInjector lifecycleBindingsInjector;
109 private final PluginConfigurationExpander pluginConfigurationExpander;
110 private final ReportConfigurationExpander reportConfigurationExpander;
111 private final ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
112 private final ModelVersionProcessor versionProcessor;
113 private final ModelSourceTransformer transformer;
114
115 @SuppressWarnings("checkstyle:ParameterNumber")
116 @Inject
117 public DefaultModelBuilder(
118 ModelProcessor modelProcessor,
119 ModelValidator modelValidator,
120 ModelNormalizer modelNormalizer,
121 ModelInterpolator modelInterpolator,
122 ModelPathTranslator modelPathTranslator,
123 ModelUrlNormalizer modelUrlNormalizer,
124 SuperPomProvider superPomProvider,
125 InheritanceAssembler inheritanceAssembler,
126 ProfileSelector profileSelector,
127 ProfileInjector profileInjector,
128 PluginManagementInjector pluginManagementInjector,
129 DependencyManagementInjector dependencyManagementInjector,
130 DependencyManagementImporter dependencyManagementImporter,
131 @Nullable LifecycleBindingsInjector lifecycleBindingsInjector,
132 PluginConfigurationExpander pluginConfigurationExpander,
133 ReportConfigurationExpander reportConfigurationExpander,
134 ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator,
135 ModelVersionProcessor versionProcessor,
136 ModelSourceTransformer transformer) {
137 this.modelProcessor = modelProcessor;
138 this.modelValidator = modelValidator;
139 this.modelNormalizer = modelNormalizer;
140 this.modelInterpolator = modelInterpolator;
141 this.modelPathTranslator = modelPathTranslator;
142 this.modelUrlNormalizer = modelUrlNormalizer;
143 this.superPomProvider = superPomProvider;
144 this.inheritanceAssembler = inheritanceAssembler;
145 this.profileSelector = profileSelector;
146 this.profileInjector = profileInjector;
147 this.pluginManagementInjector = pluginManagementInjector;
148 this.dependencyManagementInjector = dependencyManagementInjector;
149 this.dependencyManagementImporter = dependencyManagementImporter;
150 this.lifecycleBindingsInjector = lifecycleBindingsInjector;
151 this.pluginConfigurationExpander = pluginConfigurationExpander;
152 this.reportConfigurationExpander = reportConfigurationExpander;
153 this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator;
154 this.versionProcessor = versionProcessor;
155 this.transformer = transformer;
156 }
157
158
159
160
161
162 @Deprecated
163 public DefaultModelBuilder setModelProcessor(ModelProcessor modelProcessor) {
164 return new DefaultModelBuilder(
165 modelProcessor,
166 modelValidator,
167 modelNormalizer,
168 modelInterpolator,
169 modelPathTranslator,
170 modelUrlNormalizer,
171 superPomProvider,
172 inheritanceAssembler,
173 profileSelector,
174 profileInjector,
175 pluginManagementInjector,
176 dependencyManagementInjector,
177 dependencyManagementImporter,
178 lifecycleBindingsInjector,
179 pluginConfigurationExpander,
180 reportConfigurationExpander,
181 profileActivationFilePathInterpolator,
182 versionProcessor,
183 transformer);
184 }
185
186
187
188
189
190 @Deprecated
191 public DefaultModelBuilder setModelValidator(ModelValidator modelValidator) {
192 return new DefaultModelBuilder(
193 modelProcessor,
194 modelValidator,
195 modelNormalizer,
196 modelInterpolator,
197 modelPathTranslator,
198 modelUrlNormalizer,
199 superPomProvider,
200 inheritanceAssembler,
201 profileSelector,
202 profileInjector,
203 pluginManagementInjector,
204 dependencyManagementInjector,
205 dependencyManagementImporter,
206 lifecycleBindingsInjector,
207 pluginConfigurationExpander,
208 reportConfigurationExpander,
209 profileActivationFilePathInterpolator,
210 versionProcessor,
211 transformer);
212 }
213
214
215
216
217
218 @Deprecated
219 public DefaultModelBuilder setModelNormalizer(ModelNormalizer modelNormalizer) {
220 return new DefaultModelBuilder(
221 modelProcessor,
222 modelValidator,
223 modelNormalizer,
224 modelInterpolator,
225 modelPathTranslator,
226 modelUrlNormalizer,
227 superPomProvider,
228 inheritanceAssembler,
229 profileSelector,
230 profileInjector,
231 pluginManagementInjector,
232 dependencyManagementInjector,
233 dependencyManagementImporter,
234 lifecycleBindingsInjector,
235 pluginConfigurationExpander,
236 reportConfigurationExpander,
237 profileActivationFilePathInterpolator,
238 versionProcessor,
239 transformer);
240 }
241
242
243
244
245
246 @Deprecated
247 public DefaultModelBuilder setModelInterpolator(ModelInterpolator modelInterpolator) {
248 return new DefaultModelBuilder(
249 modelProcessor,
250 modelValidator,
251 modelNormalizer,
252 modelInterpolator,
253 modelPathTranslator,
254 modelUrlNormalizer,
255 superPomProvider,
256 inheritanceAssembler,
257 profileSelector,
258 profileInjector,
259 pluginManagementInjector,
260 dependencyManagementInjector,
261 dependencyManagementImporter,
262 lifecycleBindingsInjector,
263 pluginConfigurationExpander,
264 reportConfigurationExpander,
265 profileActivationFilePathInterpolator,
266 versionProcessor,
267 transformer);
268 }
269
270
271
272
273
274 @Deprecated
275 public DefaultModelBuilder setModelPathTranslator(ModelPathTranslator modelPathTranslator) {
276 return new DefaultModelBuilder(
277 modelProcessor,
278 modelValidator,
279 modelNormalizer,
280 modelInterpolator,
281 modelPathTranslator,
282 modelUrlNormalizer,
283 superPomProvider,
284 inheritanceAssembler,
285 profileSelector,
286 profileInjector,
287 pluginManagementInjector,
288 dependencyManagementInjector,
289 dependencyManagementImporter,
290 lifecycleBindingsInjector,
291 pluginConfigurationExpander,
292 reportConfigurationExpander,
293 profileActivationFilePathInterpolator,
294 versionProcessor,
295 transformer);
296 }
297
298
299
300
301
302 @Deprecated
303 public DefaultModelBuilder setModelUrlNormalizer(ModelUrlNormalizer modelUrlNormalizer) {
304 return new DefaultModelBuilder(
305 modelProcessor,
306 modelValidator,
307 modelNormalizer,
308 modelInterpolator,
309 modelPathTranslator,
310 modelUrlNormalizer,
311 superPomProvider,
312 inheritanceAssembler,
313 profileSelector,
314 profileInjector,
315 pluginManagementInjector,
316 dependencyManagementInjector,
317 dependencyManagementImporter,
318 lifecycleBindingsInjector,
319 pluginConfigurationExpander,
320 reportConfigurationExpander,
321 profileActivationFilePathInterpolator,
322 versionProcessor,
323 transformer);
324 }
325
326
327
328
329
330 @Deprecated
331 public DefaultModelBuilder setSuperPomProvider(SuperPomProvider superPomProvider) {
332 return new DefaultModelBuilder(
333 modelProcessor,
334 modelValidator,
335 modelNormalizer,
336 modelInterpolator,
337 modelPathTranslator,
338 modelUrlNormalizer,
339 superPomProvider,
340 inheritanceAssembler,
341 profileSelector,
342 profileInjector,
343 pluginManagementInjector,
344 dependencyManagementInjector,
345 dependencyManagementImporter,
346 lifecycleBindingsInjector,
347 pluginConfigurationExpander,
348 reportConfigurationExpander,
349 profileActivationFilePathInterpolator,
350 versionProcessor,
351 transformer);
352 }
353
354
355
356
357
358 @Deprecated
359 public DefaultModelBuilder setInheritanceAssembler(InheritanceAssembler inheritanceAssembler) {
360 return new DefaultModelBuilder(
361 modelProcessor,
362 modelValidator,
363 modelNormalizer,
364 modelInterpolator,
365 modelPathTranslator,
366 modelUrlNormalizer,
367 superPomProvider,
368 inheritanceAssembler,
369 profileSelector,
370 profileInjector,
371 pluginManagementInjector,
372 dependencyManagementInjector,
373 dependencyManagementImporter,
374 lifecycleBindingsInjector,
375 pluginConfigurationExpander,
376 reportConfigurationExpander,
377 profileActivationFilePathInterpolator,
378 versionProcessor,
379 transformer);
380 }
381
382
383
384
385
386 @Deprecated
387 public DefaultModelBuilder setProfileSelector(ProfileSelector profileSelector) {
388 return new DefaultModelBuilder(
389 modelProcessor,
390 modelValidator,
391 modelNormalizer,
392 modelInterpolator,
393 modelPathTranslator,
394 modelUrlNormalizer,
395 superPomProvider,
396 inheritanceAssembler,
397 profileSelector,
398 profileInjector,
399 pluginManagementInjector,
400 dependencyManagementInjector,
401 dependencyManagementImporter,
402 lifecycleBindingsInjector,
403 pluginConfigurationExpander,
404 reportConfigurationExpander,
405 profileActivationFilePathInterpolator,
406 versionProcessor,
407 transformer);
408 }
409
410
411
412
413
414 @Deprecated
415 public DefaultModelBuilder setProfileInjector(ProfileInjector profileInjector) {
416 return new DefaultModelBuilder(
417 modelProcessor,
418 modelValidator,
419 modelNormalizer,
420 modelInterpolator,
421 modelPathTranslator,
422 modelUrlNormalizer,
423 superPomProvider,
424 inheritanceAssembler,
425 profileSelector,
426 profileInjector,
427 pluginManagementInjector,
428 dependencyManagementInjector,
429 dependencyManagementImporter,
430 lifecycleBindingsInjector,
431 pluginConfigurationExpander,
432 reportConfigurationExpander,
433 profileActivationFilePathInterpolator,
434 versionProcessor,
435 transformer);
436 }
437
438
439
440
441
442 @Deprecated
443 public DefaultModelBuilder setPluginManagementInjector(PluginManagementInjector pluginManagementInjector) {
444 return new DefaultModelBuilder(
445 modelProcessor,
446 modelValidator,
447 modelNormalizer,
448 modelInterpolator,
449 modelPathTranslator,
450 modelUrlNormalizer,
451 superPomProvider,
452 inheritanceAssembler,
453 profileSelector,
454 profileInjector,
455 pluginManagementInjector,
456 dependencyManagementInjector,
457 dependencyManagementImporter,
458 lifecycleBindingsInjector,
459 pluginConfigurationExpander,
460 reportConfigurationExpander,
461 profileActivationFilePathInterpolator,
462 versionProcessor,
463 transformer);
464 }
465
466
467
468
469
470 @Deprecated
471 public DefaultModelBuilder setDependencyManagementInjector(
472 DependencyManagementInjector dependencyManagementInjector) {
473 return new DefaultModelBuilder(
474 modelProcessor,
475 modelValidator,
476 modelNormalizer,
477 modelInterpolator,
478 modelPathTranslator,
479 modelUrlNormalizer,
480 superPomProvider,
481 inheritanceAssembler,
482 profileSelector,
483 profileInjector,
484 pluginManagementInjector,
485 dependencyManagementInjector,
486 dependencyManagementImporter,
487 lifecycleBindingsInjector,
488 pluginConfigurationExpander,
489 reportConfigurationExpander,
490 profileActivationFilePathInterpolator,
491 versionProcessor,
492 transformer);
493 }
494
495
496
497
498
499 @Deprecated
500 public DefaultModelBuilder setDependencyManagementImporter(
501 DependencyManagementImporter dependencyManagementImporter) {
502 return new DefaultModelBuilder(
503 modelProcessor,
504 modelValidator,
505 modelNormalizer,
506 modelInterpolator,
507 modelPathTranslator,
508 modelUrlNormalizer,
509 superPomProvider,
510 inheritanceAssembler,
511 profileSelector,
512 profileInjector,
513 pluginManagementInjector,
514 dependencyManagementInjector,
515 dependencyManagementImporter,
516 lifecycleBindingsInjector,
517 pluginConfigurationExpander,
518 reportConfigurationExpander,
519 profileActivationFilePathInterpolator,
520 versionProcessor,
521 transformer);
522 }
523
524
525
526
527
528 @Deprecated
529 public DefaultModelBuilder setLifecycleBindingsInjector(LifecycleBindingsInjector lifecycleBindingsInjector) {
530 return new DefaultModelBuilder(
531 modelProcessor,
532 modelValidator,
533 modelNormalizer,
534 modelInterpolator,
535 modelPathTranslator,
536 modelUrlNormalizer,
537 superPomProvider,
538 inheritanceAssembler,
539 profileSelector,
540 profileInjector,
541 pluginManagementInjector,
542 dependencyManagementInjector,
543 dependencyManagementImporter,
544 lifecycleBindingsInjector,
545 pluginConfigurationExpander,
546 reportConfigurationExpander,
547 profileActivationFilePathInterpolator,
548 versionProcessor,
549 transformer);
550 }
551
552
553
554
555
556 @Deprecated
557 public DefaultModelBuilder setPluginConfigurationExpander(PluginConfigurationExpander pluginConfigurationExpander) {
558 return new DefaultModelBuilder(
559 modelProcessor,
560 modelValidator,
561 modelNormalizer,
562 modelInterpolator,
563 modelPathTranslator,
564 modelUrlNormalizer,
565 superPomProvider,
566 inheritanceAssembler,
567 profileSelector,
568 profileInjector,
569 pluginManagementInjector,
570 dependencyManagementInjector,
571 dependencyManagementImporter,
572 lifecycleBindingsInjector,
573 pluginConfigurationExpander,
574 reportConfigurationExpander,
575 profileActivationFilePathInterpolator,
576 versionProcessor,
577 transformer);
578 }
579
580
581
582
583
584 @Deprecated
585 public DefaultModelBuilder setReportConfigurationExpander(ReportConfigurationExpander reportConfigurationExpander) {
586 return new DefaultModelBuilder(
587 modelProcessor,
588 modelValidator,
589 modelNormalizer,
590 modelInterpolator,
591 modelPathTranslator,
592 modelUrlNormalizer,
593 superPomProvider,
594 inheritanceAssembler,
595 profileSelector,
596 profileInjector,
597 pluginManagementInjector,
598 dependencyManagementInjector,
599 dependencyManagementImporter,
600 lifecycleBindingsInjector,
601 pluginConfigurationExpander,
602 reportConfigurationExpander,
603 profileActivationFilePathInterpolator,
604 versionProcessor,
605 transformer);
606 }
607
608
609
610
611
612 @Deprecated
613 public DefaultModelBuilder setProfileActivationFilePathInterpolator(
614 ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) {
615 return new DefaultModelBuilder(
616 modelProcessor,
617 modelValidator,
618 modelNormalizer,
619 modelInterpolator,
620 modelPathTranslator,
621 modelUrlNormalizer,
622 superPomProvider,
623 inheritanceAssembler,
624 profileSelector,
625 profileInjector,
626 pluginManagementInjector,
627 dependencyManagementInjector,
628 dependencyManagementImporter,
629 lifecycleBindingsInjector,
630 pluginConfigurationExpander,
631 reportConfigurationExpander,
632 profileActivationFilePathInterpolator,
633 versionProcessor,
634 transformer);
635 }
636
637
638
639
640
641 @Deprecated
642 public DefaultModelBuilder setReportingConverter(ReportingConverter reportingConverter) {
643 return this;
644 }
645
646 @Override
647 public DefaultTransformerContextBuilder newTransformerContextBuilder() {
648 return new DefaultTransformerContextBuilder(this);
649 }
650
651 @Override
652 public ModelBuildingResult build(ModelBuildingRequest request) throws ModelBuildingException {
653 return build(request, new LinkedHashSet<>());
654 }
655
656 protected ModelBuildingResult build(ModelBuildingRequest request, Collection<String> importIds)
657 throws ModelBuildingException {
658
659 DefaultModelBuildingResult result = new DefaultModelBuildingResult();
660
661 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
662
663
664 Model fileModel = readFileModel(request, problems);
665
666 request.setFileModel(fileModel);
667 result.setFileModel(fileModel.clone());
668
669 activateFileModel(request, result, problems);
670
671 if (!request.isTwoPhaseBuilding()) {
672 return build(request, result, importIds);
673 } else if (hasModelErrors(problems)) {
674 throw problems.newModelBuildingException();
675 }
676
677 return result;
678 }
679
680 private void activateFileModel(
681 final ModelBuildingRequest request,
682 final DefaultModelBuildingResult result,
683 DefaultModelProblemCollector problems)
684 throws ModelBuildingException {
685 Model inputModel = request.getFileModel();
686 problems.setRootModel(inputModel);
687
688
689 DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request);
690
691 problems.setSource("(external profiles)");
692 List<Profile> activeExternalProfiles =
693 profileSelector.getActiveProfiles(request.getProfiles(), profileActivationContext, problems);
694
695 result.setActiveExternalProfiles(activeExternalProfiles);
696
697 if (!activeExternalProfiles.isEmpty()) {
698 Properties profileProps = new Properties();
699 for (Profile profile : activeExternalProfiles) {
700 profileProps.putAll(profile.getProperties());
701 }
702 profileProps.putAll(profileActivationContext.getUserProperties());
703 profileActivationContext.setUserProperties(profileProps);
704 }
705
706 profileActivationContext.setProjectProperties(inputModel.getDelegate().getProperties());
707 problems.setSource(inputModel);
708 List<Profile> activePomProfiles =
709 profileSelector.getActiveProfiles(inputModel.getProfiles(), profileActivationContext, problems);
710
711
712 problems.setSource(inputModel);
713 inputModel.update(modelNormalizer.mergeDuplicates(inputModel.getDelegate(), request, problems));
714
715 Map<String, Activation> interpolatedActivations = getProfileActivations(inputModel, false);
716 injectProfileActivations(inputModel, interpolatedActivations);
717
718
719 for (Profile activeProfile : activePomProfiles) {
720 profileInjector.injectProfile(inputModel, activeProfile, request, problems);
721 }
722
723 for (Profile activeProfile : activeExternalProfiles) {
724 profileInjector.injectProfile(inputModel, activeProfile, request, problems);
725 }
726 }
727
728 @SuppressWarnings("checkstyle:methodlength")
729 private Model readEffectiveModel(
730 final ModelBuildingRequest request,
731 final DefaultModelBuildingResult result,
732 DefaultModelProblemCollector problems)
733 throws ModelBuildingException {
734 Model inputModel = readRawModel(request, problems);
735 if (problems.hasFatalErrors()) {
736 throw problems.newModelBuildingException();
737 }
738
739 problems.setRootModel(inputModel);
740
741 ModelData resultData = new ModelData(request.getModelSource(), inputModel);
742 String superModelVersion = inputModel.getModelVersion() != null ? inputModel.getModelVersion() : "4.0.0";
743 if (!DefaultModelValidator.VALID_MODEL_VERSIONS.contains(superModelVersion)) {
744
745
746
747 superModelVersion = "4.0.0";
748 }
749 ModelData superData = new ModelData(null, getSuperModel(superModelVersion));
750
751
752 DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request);
753
754 List<Profile> activeExternalProfiles = result.getActiveExternalProfiles();
755
756 if (!activeExternalProfiles.isEmpty()) {
757 Properties profileProps = new Properties();
758 for (Profile profile : activeExternalProfiles) {
759 profileProps.putAll(profile.getProperties());
760 }
761 profileProps.putAll(profileActivationContext.getUserProperties());
762 profileActivationContext.setUserProperties(profileProps);
763 }
764
765 Collection<String> parentIds = new LinkedHashSet<>();
766
767 List<Model> lineage = new ArrayList<>();
768
769 for (ModelData currentData = resultData; ; ) {
770 String modelId = currentData.getId();
771 result.addModelId(modelId);
772
773 Model model = currentData.getModel();
774 result.setRawModel(modelId, model);
775 problems.setSource(model);
776 org.apache.maven.api.model.Model modelv4 = model.getDelegate();
777
778
779 modelv4 = modelNormalizer.mergeDuplicates(modelv4, request, problems);
780
781
782 profileActivationContext.setProjectProperties(modelv4.getProperties());
783
784 List<org.apache.maven.api.model.Profile> interpolatedProfiles =
785 interpolateActivations(modelv4.getProfiles(), profileActivationContext, problems);
786
787
788 List<org.apache.maven.api.model.Profile> activePomProfiles =
789 profileSelector.getActiveProfilesV4(interpolatedProfiles, profileActivationContext, problems);
790 result.setActivePomProfiles(
791 modelId, activePomProfiles.stream().map(Profile::new).collect(Collectors.toList()));
792 modelv4 = profileInjector.injectProfiles(modelv4, activePomProfiles, request, problems);
793 if (currentData == resultData) {
794 for (Profile activeProfile : activeExternalProfiles) {
795 modelv4 = profileInjector.injectProfile(modelv4, activeProfile.getDelegate(), request, problems);
796 }
797 }
798
799 lineage.add(new Model(modelv4));
800
801 if (currentData == superData) {
802 break;
803 }
804
805
806 configureResolver(request.getModelResolver(), modelv4, problems, false);
807
808
809 ModelData parentData = readParent(new Model(modelv4), currentData.getSource(), request, problems);
810
811 if (parentData == null) {
812 currentData = superData;
813 } else if (!parentIds.add(parentData.getId())) {
814 StringBuilder message = new StringBuilder("The parents form a cycle: ");
815 for (String parentId : parentIds) {
816 message.append(parentId).append(" -> ");
817 }
818 message.append(parentData.getId());
819
820 problems.add(new ModelProblemCollectorRequest(ModelProblem.Severity.FATAL, ModelProblem.Version.BASE)
821 .setMessage(message.toString()));
822
823 throw problems.newModelBuildingException();
824 } else {
825 currentData = parentData;
826 }
827 }
828
829 Model tmpModel = lineage.get(0);
830
831
832 List<org.apache.maven.api.model.Profile> interpolated =
833 interpolateActivations(tmpModel.getDelegate().getProfiles(), profileActivationContext, problems);
834 if (interpolated != tmpModel.getDelegate().getProfiles()) {
835 tmpModel.update(tmpModel.getDelegate().withProfiles(interpolated));
836 }
837
838
839 tmpModel.update(profileInjector.injectProfiles(
840 tmpModel.getDelegate(),
841 activeExternalProfiles.stream().map(Profile::getDelegate).collect(Collectors.toList()),
842 request,
843 problems));
844
845 checkPluginVersions(lineage, request, problems);
846
847
848 Model resultModel = assembleInheritance(lineage, request, problems);
849
850
851
852 problems.setSource(resultModel);
853 problems.setRootModel(resultModel);
854
855
856 resultModel = interpolateModel(resultModel, request, problems);
857
858
859 modelUrlNormalizer.normalize(resultModel, request);
860
861 result.setEffectiveModel(resultModel);
862
863
864 configureResolver(request.getModelResolver(), resultModel.getDelegate(), problems, true);
865
866 return resultModel;
867 }
868
869 private List<org.apache.maven.api.model.Profile> interpolateActivations(
870 List<org.apache.maven.api.model.Profile> profiles,
871 DefaultProfileActivationContext context,
872 DefaultModelProblemCollector problems) {
873 List<org.apache.maven.api.model.Profile> newProfiles = null;
874 for (int index = 0; index < profiles.size(); index++) {
875 org.apache.maven.api.model.Profile profile = profiles.get(index);
876 org.apache.maven.api.model.Activation activation = profile.getActivation();
877 if (activation != null) {
878 org.apache.maven.api.model.ActivationFile file = activation.getFile();
879 if (file != null) {
880 String oldExists = file.getExists();
881 if (isNotEmpty(oldExists)) {
882 try {
883 String newExists = interpolate(oldExists, context);
884 if (!Objects.equals(oldExists, newExists)) {
885 if (newProfiles == null) {
886 newProfiles = new ArrayList<>(profiles);
887 }
888 newProfiles.set(
889 index, profile.withActivation(activation.withFile(file.withExists(newExists))));
890 }
891 } catch (InterpolationException e) {
892 addInterpolationProblem(problems, file, oldExists, e, "exists");
893 }
894 } else {
895 String oldMissing = file.getMissing();
896 if (isNotEmpty(oldMissing)) {
897 try {
898 String newMissing = interpolate(oldMissing, context);
899 if (!Objects.equals(oldMissing, newMissing)) {
900 if (newProfiles == null) {
901 newProfiles = new ArrayList<>(profiles);
902 }
903 newProfiles.set(
904 index,
905 profile.withActivation(activation.withFile(file.withMissing(newMissing))));
906 }
907 } catch (InterpolationException e) {
908 addInterpolationProblem(problems, file, oldMissing, e, "missing");
909 }
910 }
911 }
912 }
913 }
914 }
915 return newProfiles != null ? newProfiles : profiles;
916 }
917
918 private static void addInterpolationProblem(
919 DefaultModelProblemCollector problems,
920 org.apache.maven.api.model.ActivationFile file,
921 String path,
922 InterpolationException e,
923 String locationKey) {
924 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
925 .setMessage("Failed to interpolate file location " + path + ": " + e.getMessage())
926 .setLocation(Optional.ofNullable(file.getLocation(locationKey))
927 .map(InputLocation::new)
928 .orElse(null))
929 .setException(e));
930 }
931
932 private String interpolate(String path, ProfileActivationContext context) throws InterpolationException {
933 return isNotEmpty(path) ? profileActivationFilePathInterpolator.interpolate(path, context) : path;
934 }
935
936 private static boolean isNotEmpty(String string) {
937 return string != null && !string.isEmpty();
938 }
939
940 @Override
941 public ModelBuildingResult build(final ModelBuildingRequest request, final ModelBuildingResult result)
942 throws ModelBuildingException {
943 return build(request, result, new LinkedHashSet<>());
944 }
945
946 public Model buildRawModel(final ModelBuildingRequest request) throws ModelBuildingException {
947 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult());
948 Model model = readRawModel(request, problems);
949 if (hasModelErrors(problems)) {
950 throw problems.newModelBuildingException();
951 }
952 return model;
953 }
954
955 private ModelBuildingResult build(
956 final ModelBuildingRequest request, final ModelBuildingResult phaseOneResult, Collection<String> imports)
957 throws ModelBuildingException {
958 DefaultModelBuildingResult result = asDefaultModelBuildingResult(phaseOneResult);
959
960 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
961
962
963 Model resultModel = readEffectiveModel(request, result, problems);
964 problems.setSource(resultModel);
965 problems.setRootModel(resultModel);
966
967
968 modelPathTranslator.alignToBaseDirectory(resultModel, resultModel.getProjectDirectory(), request);
969
970
971 pluginManagementInjector.injectManagement(resultModel, request, problems);
972
973 fireEvent(resultModel, request, problems, ModelBuildingEventCatapult.BUILD_EXTENSIONS_ASSEMBLED);
974
975 if (request.isProcessPlugins()) {
976 if (lifecycleBindingsInjector == null) {
977 throw new IllegalStateException("lifecycle bindings injector is missing");
978 }
979
980
981 lifecycleBindingsInjector.injectLifecycleBindings(resultModel, request, problems);
982 }
983
984
985 importDependencyManagement(resultModel, request, problems, imports);
986
987
988 dependencyManagementInjector.injectManagement(resultModel, request, problems);
989
990 resultModel.update(modelNormalizer.injectDefaultValues(resultModel.getDelegate(), request, problems));
991
992 if (request.isProcessPlugins()) {
993
994 reportConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
995
996
997 pluginConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
998 }
999
1000
1001 modelValidator.validateEffectiveModel(resultModel, request, problems);
1002
1003 if (hasModelErrors(problems)) {
1004 throw problems.newModelBuildingException();
1005 }
1006
1007 return result;
1008 }
1009
1010 private DefaultModelBuildingResult asDefaultModelBuildingResult(ModelBuildingResult phaseOneResult) {
1011 if (phaseOneResult instanceof DefaultModelBuildingResult) {
1012 return (DefaultModelBuildingResult) phaseOneResult;
1013 } else {
1014 return new DefaultModelBuildingResult(phaseOneResult);
1015 }
1016 }
1017
1018 @Override
1019 public Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking) {
1020 return buildRawModel(pomFile, validationLevel, locationTracking, null);
1021 }
1022
1023 @Override
1024 public Result<? extends Model> buildRawModel(
1025 File pomFile, int validationLevel, boolean locationTracking, TransformerContext context) {
1026 final ModelBuildingRequest request = new DefaultModelBuildingRequest()
1027 .setValidationLevel(validationLevel)
1028 .setLocationTracking(locationTracking)
1029 .setModelSource(new FileModelSource(pomFile));
1030 DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult());
1031 try {
1032 Model model = readFileModel(request, problems);
1033
1034 try {
1035 if (transformer != null && context != null) {
1036 transformer.transform(pomFile.toPath(), context, model);
1037 }
1038 } catch (TransformerException e) {
1039 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V40).setException(e));
1040 }
1041
1042 return newResult(model, problems.getProblems());
1043 } catch (ModelBuildingException e) {
1044 return error(problems.getProblems());
1045 }
1046 }
1047
1048 Model readFileModel(ModelBuildingRequest request, DefaultModelProblemCollector problems)
1049 throws ModelBuildingException {
1050 ModelSource modelSource = request.getModelSource();
1051 org.apache.maven.api.model.Model model = cache(
1052 request.getModelCache(),
1053 modelSource,
1054 ModelCacheTag.FILE,
1055 () -> doReadFileModel(modelSource, request, problems));
1056
1057 if (modelSource instanceof FileModelSource) {
1058 if (request.getTransformerContextBuilder() instanceof DefaultTransformerContextBuilder) {
1059 DefaultTransformerContextBuilder contextBuilder =
1060 (DefaultTransformerContextBuilder) request.getTransformerContextBuilder();
1061 contextBuilder.putSource(getGroupId(model), model.getArtifactId(), (FileModelSource) modelSource);
1062 }
1063 }
1064
1065 return new Model(model);
1066 }
1067
1068 @SuppressWarnings("checkstyle:methodlength")
1069 private org.apache.maven.api.model.Model doReadFileModel(
1070 ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1071 throws ModelBuildingException {
1072 org.apache.maven.api.model.Model model;
1073 problems.setSource(modelSource.getLocation());
1074 try {
1075 boolean strict = request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
1076
1077 Map<String, Object> options = new HashMap<>(3);
1078 options.put(ModelProcessor.IS_STRICT, strict);
1079 options.put(ModelProcessor.SOURCE, modelSource);
1080 options.put(ModelReader.ROOT_DIRECTORY, request.getRootDirectory());
1081
1082 InputSource source;
1083 if (request.isLocationTracking()) {
1084 source = new InputSource(null, modelSource.getLocation());
1085 options.put(ModelProcessor.INPUT_SOURCE, new org.apache.maven.model.InputSource(source));
1086 } else {
1087 source = null;
1088 }
1089
1090 try {
1091 model = modelProcessor
1092 .read(modelSource.getInputStream(), options)
1093 .getDelegate();
1094 } catch (ModelParseException e) {
1095 if (!strict) {
1096 throw e;
1097 }
1098
1099 options.put(ModelProcessor.IS_STRICT, Boolean.FALSE);
1100
1101 try {
1102 model = modelProcessor
1103 .read(modelSource.getInputStream(), options)
1104 .getDelegate();
1105 } catch (ModelParseException ne) {
1106
1107 throw e;
1108 }
1109
1110 Severity severity = (modelSource instanceof FileModelSource) ? Severity.ERROR : Severity.WARNING;
1111 problems.add(new ModelProblemCollectorRequest(severity, Version.V20)
1112 .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage())
1113 .setException(e));
1114 }
1115
1116 if (source != null) {
1117 try {
1118 org.apache.maven.api.model.InputLocation loc = model.getLocation("");
1119 org.apache.maven.api.model.InputSource v4src = loc != null ? loc.getSource() : null;
1120 if (v4src != null) {
1121 Field field = InputSource.class.getDeclaredField("modelId");
1122 field.setAccessible(true);
1123 field.set(v4src, ModelProblemUtils.toId(model));
1124 }
1125 } catch (Throwable t) {
1126
1127 throw new IllegalStateException("Unable to set modelId on InputSource", t);
1128 }
1129 }
1130 } catch (ModelParseException e) {
1131 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1132 .setMessage("Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage())
1133 .setException(e));
1134 throw problems.newModelBuildingException();
1135 } catch (IOException e) {
1136 String msg = e.getMessage();
1137 if (msg == null || msg.length() <= 0) {
1138
1139 if (e.getClass().getName().endsWith("MalformedInputException")) {
1140 msg = "Some input bytes do not match the file encoding.";
1141 } else {
1142 msg = e.getClass().getSimpleName();
1143 }
1144 }
1145 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1146 .setMessage("Non-readable POM " + modelSource.getLocation() + ": " + msg)
1147 .setException(e));
1148 throw problems.newModelBuildingException();
1149 }
1150
1151 if (modelSource instanceof FileModelSource) {
1152 model = model.withPomFile(((FileModelSource) modelSource).getFile().toPath());
1153 }
1154
1155 Model retModel = new Model(model);
1156
1157 problems.setSource(retModel);
1158
1159 modelValidator.validateFileModel(retModel, request, problems);
1160
1161 if (hasFatalErrors(problems)) {
1162 throw problems.newModelBuildingException();
1163 }
1164
1165 return model;
1166 }
1167
1168 Model readRawModel(ModelBuildingRequest request, DefaultModelProblemCollector problems)
1169 throws ModelBuildingException {
1170 ModelSource modelSource = request.getModelSource();
1171
1172 ModelData modelData = cache(
1173 request.getModelCache(),
1174 modelSource,
1175 ModelCacheTag.RAW,
1176 () -> doReadRawModel(modelSource, request, problems));
1177
1178 return modelData.getModel();
1179 }
1180
1181 private ModelData doReadRawModel(
1182 ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1183 throws ModelBuildingException {
1184 Model rawModel;
1185 if (Features.buildConsumer(request.getUserProperties()) && modelSource instanceof FileModelSource) {
1186 rawModel = readFileModel(request, problems);
1187 File pomFile = ((FileModelSource) modelSource).getFile();
1188
1189 try {
1190 if (request.getTransformerContextBuilder() != null) {
1191 TransformerContext context =
1192 request.getTransformerContextBuilder().initialize(request, problems);
1193 transformer.transform(pomFile.toPath(), context, rawModel);
1194 }
1195 } catch (TransformerException e) {
1196 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V40).setException(e));
1197 }
1198 } else if (request.getFileModel() == null) {
1199 rawModel = readFileModel(request, problems);
1200 } else {
1201 rawModel = request.getFileModel().clone();
1202 }
1203
1204 modelValidator.validateRawModel(rawModel, request, problems);
1205
1206 if (hasFatalErrors(problems)) {
1207 throw problems.newModelBuildingException();
1208 }
1209
1210 String groupId = getGroupId(rawModel);
1211 String artifactId = rawModel.getArtifactId();
1212 String version = getVersion(rawModel);
1213
1214 return new ModelData(modelSource, rawModel, groupId, artifactId, version);
1215 }
1216
1217 String getGroupId(Model model) {
1218 return getGroupId(model.getDelegate());
1219 }
1220
1221 private String getGroupId(org.apache.maven.api.model.Model model) {
1222 String groupId = model.getGroupId();
1223 if (groupId == null && model.getParent() != null) {
1224 groupId = model.getParent().getGroupId();
1225 }
1226 return groupId;
1227 }
1228
1229 private String getVersion(Model model) {
1230 String version = model.getVersion();
1231 if (version == null && model.getParent() != null) {
1232 version = model.getParent().getVersion();
1233 }
1234 return version;
1235 }
1236
1237 private DefaultProfileActivationContext getProfileActivationContext(ModelBuildingRequest request) {
1238 DefaultProfileActivationContext context = new DefaultProfileActivationContext();
1239
1240 context.setActiveProfileIds(request.getActiveProfileIds());
1241 context.setInactiveProfileIds(request.getInactiveProfileIds());
1242 context.setSystemProperties(request.getSystemProperties());
1243
1244 Properties userProperties = request.getUserProperties();
1245 if (!userProperties.containsKey(ProfileActivationContext.PROPERTY_NAME_PACKAGING)) {
1246 userProperties.put(
1247 ProfileActivationContext.PROPERTY_NAME_PACKAGING,
1248 request.getFileModel().getPackaging());
1249 }
1250 context.setUserProperties(userProperties);
1251 context.setProjectDirectory(
1252 (request.getPomFile() != null) ? request.getPomFile().getParentFile() : null);
1253
1254 return context;
1255 }
1256
1257 private void configureResolver(
1258 ModelResolver modelResolver,
1259 org.apache.maven.api.model.Model model,
1260 DefaultModelProblemCollector problems,
1261 boolean replaceRepositories) {
1262 if (modelResolver != null) {
1263 for (org.apache.maven.api.model.Repository repository : model.getRepositories()) {
1264 try {
1265 modelResolver.addRepository(repository, replaceRepositories);
1266 } catch (InvalidRepositoryException e) {
1267 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1268 .setMessage("Invalid repository " + repository.getId() + ": " + e.getMessage())
1269 .setLocation(new InputLocation(repository.getLocation("")))
1270 .setException(e));
1271 }
1272 }
1273 }
1274 }
1275
1276 private void checkPluginVersions(
1277 List<Model> lineage, ModelBuildingRequest request, ModelProblemCollector problems) {
1278 if (request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
1279 return;
1280 }
1281
1282 Map<String, Plugin> plugins = new HashMap<>();
1283 Map<String, String> versions = new HashMap<>();
1284 Map<String, String> managedVersions = new HashMap<>();
1285
1286 for (int i = lineage.size() - 1; i >= 0; i--) {
1287 Model model = lineage.get(i);
1288 Build build = model.getBuild();
1289 if (build != null) {
1290 for (Plugin plugin : build.getPlugins()) {
1291 String key = plugin.getKey();
1292 if (versions.get(key) == null) {
1293 versions.put(key, plugin.getVersion());
1294 plugins.put(key, plugin);
1295 }
1296 }
1297 PluginManagement mgmt = build.getPluginManagement();
1298 if (mgmt != null) {
1299 for (Plugin plugin : mgmt.getPlugins()) {
1300 String key = plugin.getKey();
1301 managedVersions.computeIfAbsent(key, k -> plugin.getVersion());
1302 }
1303 }
1304 }
1305 }
1306
1307 for (String key : versions.keySet()) {
1308 if (versions.get(key) == null && managedVersions.get(key) == null) {
1309 InputLocation location = plugins.get(key).getLocation("");
1310 problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.V20)
1311 .setMessage("'build.plugins.plugin.version' for " + key + " is missing.")
1312 .setLocation(location));
1313 }
1314 }
1315 }
1316
1317 private Model assembleInheritance(
1318 List<Model> lineage, ModelBuildingRequest request, ModelProblemCollector problems) {
1319 org.apache.maven.api.model.Model parent =
1320 lineage.get(lineage.size() - 1).getDelegate();
1321 for (int i = lineage.size() - 2; i >= 0; i--) {
1322 Model child = lineage.get(i);
1323 parent = inheritanceAssembler.assembleModelInheritance(child.getDelegate(), parent, request, problems);
1324 }
1325 return new Model(parent);
1326 }
1327
1328 private Map<String, Activation> getProfileActivations(Model model, boolean clone) {
1329 Map<String, Activation> activations = new HashMap<>();
1330 for (Profile profile : model.getProfiles()) {
1331 Activation activation = profile.getActivation();
1332
1333 if (activation == null) {
1334 continue;
1335 }
1336
1337 if (clone) {
1338 activation = activation.clone();
1339 }
1340
1341 activations.put(profile.getId(), activation);
1342 }
1343
1344 return activations;
1345 }
1346
1347 private void injectProfileActivations(Model model, Map<String, Activation> activations) {
1348 for (Profile profile : model.getProfiles()) {
1349 Activation activation = profile.getActivation();
1350
1351 if (activation == null) {
1352 continue;
1353 }
1354
1355
1356 profile.setActivation(activations.get(profile.getId()));
1357 }
1358 }
1359
1360 private Model interpolateModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
1361
1362 Map<String, Activation> originalActivations = getProfileActivations(model, true);
1363
1364 Model interpolatedModel = new Model(modelInterpolator.interpolateModel(
1365 model.getDelegate(), model.getProjectDirectory(), request, problems));
1366 if (interpolatedModel.getParent() != null) {
1367 StringSearchInterpolator ssi = new StringSearchInterpolator();
1368 ssi.addValueSource(new MapBasedValueSource(request.getUserProperties()));
1369
1370 ssi.addValueSource(new MapBasedValueSource(model.getProperties()));
1371
1372 ssi.addValueSource(new MapBasedValueSource(request.getSystemProperties()));
1373
1374 try {
1375 String interpolated =
1376 ssi.interpolate(interpolatedModel.getParent().getVersion());
1377 interpolatedModel.getParent().setVersion(interpolated);
1378 } catch (Exception e) {
1379 ModelProblemCollectorRequest mpcr = new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1380 .setMessage("Failed to interpolate field: "
1381 + interpolatedModel.getParent().getVersion()
1382 + " on class: ")
1383 .setException(e);
1384 problems.add(mpcr);
1385 }
1386 }
1387 interpolatedModel.setPomFile(model.getPomFile());
1388
1389
1390 injectProfileActivations(model, originalActivations);
1391
1392 return interpolatedModel;
1393 }
1394
1395 private ModelData readParent(
1396 Model childModel, Source childSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1397 throws ModelBuildingException {
1398 ModelData parentData = null;
1399
1400 Parent parent = childModel.getParent();
1401 if (parent != null) {
1402 parentData = readParentLocally(childModel, childSource, request, problems);
1403 if (parentData == null) {
1404 parentData = readParentExternally(childModel, request, problems);
1405 }
1406
1407 Model parentModel = parentData.getModel();
1408 if (!"pom".equals(parentModel.getPackaging())) {
1409 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1410 .setMessage("Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint(parentModel)
1411 + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"")
1412 .setLocation(parentModel.getLocation("packaging")));
1413 }
1414 }
1415
1416 return parentData;
1417 }
1418
1419 private ModelData readParentLocally(
1420 Model childModel, Source childSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1421 throws ModelBuildingException {
1422 final Parent parent = childModel.getParent();
1423 final ModelSource2 candidateSource;
1424 final Model candidateModel;
1425 final WorkspaceModelResolver resolver = request.getWorkspaceModelResolver();
1426 if (resolver == null) {
1427 candidateSource = getParentPomFile(childModel, childSource);
1428
1429 if (candidateSource == null) {
1430 return null;
1431 }
1432
1433 ModelBuildingRequest candidateBuildRequest =
1434 new DefaultModelBuildingRequest(request).setModelSource(candidateSource);
1435
1436 candidateModel = readRawModel(candidateBuildRequest, problems);
1437 } else {
1438 try {
1439 candidateModel =
1440 resolver.resolveRawModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
1441 } catch (UnresolvableModelException e) {
1442 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1443 .setMessage(e.getMessage())
1444 .setLocation(parent.getLocation(""))
1445 .setException(e));
1446 throw problems.newModelBuildingException();
1447 }
1448 if (candidateModel == null) {
1449 return null;
1450 }
1451 candidateSource = new FileModelSource(candidateModel.getPomFile());
1452 }
1453
1454
1455
1456
1457
1458
1459
1460 String groupId = getGroupId(candidateModel);
1461 String artifactId = candidateModel.getArtifactId();
1462
1463 if (groupId == null
1464 || !groupId.equals(parent.getGroupId())
1465 || artifactId == null
1466 || !artifactId.equals(parent.getArtifactId())) {
1467 StringBuilder buffer = new StringBuilder(256);
1468 buffer.append("'parent.relativePath'");
1469 if (childModel != problems.getRootModel()) {
1470 buffer.append(" of POM ").append(ModelProblemUtils.toSourceHint(childModel));
1471 }
1472 buffer.append(" points at ").append(groupId).append(':').append(artifactId);
1473 buffer.append(" instead of ").append(parent.getGroupId()).append(':');
1474 buffer.append(parent.getArtifactId()).append(", please verify your project structure");
1475
1476 problems.setSource(childModel);
1477 problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
1478 .setMessage(buffer.toString())
1479 .setLocation(parent.getLocation("")));
1480 return null;
1481 }
1482
1483 String version = getVersion(candidateModel);
1484 if (version != null && parent.getVersion() != null && !version.equals(parent.getVersion())) {
1485 try {
1486 VersionRange parentRange = VersionRange.createFromVersionSpec(parent.getVersion());
1487 if (!parentRange.hasRestrictions()) {
1488
1489 return null;
1490 }
1491 if (!parentRange.containsVersion(new DefaultArtifactVersion(version))) {
1492
1493 return null;
1494 }
1495
1496
1497 String rawChildModelVersion = childModel.getVersion();
1498
1499 if (rawChildModelVersion == null) {
1500
1501 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
1502 .setMessage("Version must be a constant")
1503 .setLocation(childModel.getLocation("")));
1504
1505 } else {
1506 if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1507
1508 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
1509 .setMessage("Version must be a constant")
1510 .setLocation(childModel.getLocation("version")));
1511 }
1512 }
1513
1514
1515 } catch (InvalidVersionSpecificationException e) {
1516
1517 return null;
1518 }
1519 }
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530 return new ModelData(candidateSource, candidateModel, groupId, artifactId, version);
1531 }
1532
1533 private boolean rawChildVersionReferencesParent(String rawChildModelVersion) {
1534 return rawChildModelVersion.equals("${pom.version}")
1535 || rawChildModelVersion.equals("${project.version}")
1536 || rawChildModelVersion.equals("${pom.parent.version}")
1537 || rawChildModelVersion.equals("${project.parent.version}");
1538 }
1539
1540 private ModelSource2 getParentPomFile(Model childModel, Source source) {
1541 if (!(source instanceof ModelSource2)) {
1542 return null;
1543 }
1544
1545 String parentPath = childModel.getParent().getRelativePath();
1546
1547 if (parentPath == null || parentPath.length() <= 0) {
1548 return null;
1549 }
1550
1551 if (source instanceof ModelSource3) {
1552 return ((ModelSource3) source).getRelatedSource(modelProcessor, parentPath);
1553 } else {
1554 return ((ModelSource2) source).getRelatedSource(parentPath);
1555 }
1556 }
1557
1558 private ModelData readParentExternally(
1559 Model childModel, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1560 throws ModelBuildingException {
1561 problems.setSource(childModel);
1562
1563 Parent parent = childModel.getParent();
1564
1565 String groupId = parent.getGroupId();
1566 String artifactId = parent.getArtifactId();
1567 String version = parent.getVersion();
1568
1569 ModelResolver modelResolver = request.getModelResolver();
1570 Objects.requireNonNull(
1571 modelResolver,
1572 String.format(
1573 "request.modelResolver cannot be null (parent POM %s and POM %s)",
1574 ModelProblemUtils.toId(groupId, artifactId, version),
1575 ModelProblemUtils.toSourceHint(childModel)));
1576
1577 ModelSource modelSource;
1578 try {
1579 modelSource = modelResolver.resolveModel(parent);
1580 } catch (UnresolvableModelException e) {
1581
1582 StringBuilder buffer = new StringBuilder(256);
1583 buffer.append("Non-resolvable parent POM");
1584 if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1585 buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1586 }
1587 if (childModel != problems.getRootModel()) {
1588 buffer.append(" for ").append(ModelProblemUtils.toId(childModel));
1589 }
1590 buffer.append(": ").append(e.getMessage());
1591 if (childModel.getProjectDirectory() != null) {
1592 if (parent.getRelativePath() == null || parent.getRelativePath().length() <= 0) {
1593 buffer.append(" and 'parent.relativePath' points at no local POM");
1594 } else {
1595 buffer.append(" and 'parent.relativePath' points at wrong local POM");
1596 }
1597 }
1598
1599 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1600 .setMessage(buffer.toString())
1601 .setLocation(parent.getLocation(""))
1602 .setException(e));
1603 throw problems.newModelBuildingException();
1604 }
1605
1606 int validationLevel = Math.min(request.getValidationLevel(), ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0);
1607 ModelBuildingRequest lenientRequest = new DefaultModelBuildingRequest(request)
1608 .setValidationLevel(validationLevel)
1609 .setFileModel(null)
1610 .setModelSource(modelSource);
1611
1612 Model parentModel = readRawModel(lenientRequest, problems);
1613
1614 if (!parent.getVersion().equals(version)) {
1615 String rawChildModelVersion = childModel.getVersion();
1616
1617 if (rawChildModelVersion == null) {
1618
1619 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
1620 .setMessage("Version must be a constant")
1621 .setLocation(childModel.getLocation("")));
1622
1623 } else {
1624 if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1625
1626 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
1627 .setMessage("Version must be a constant")
1628 .setLocation(childModel.getLocation("version")));
1629 }
1630 }
1631
1632
1633 }
1634
1635 return new ModelData(
1636 modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
1637 }
1638
1639 private Model getSuperModel(String modelVersion) {
1640 return superPomProvider.getSuperModel(modelVersion);
1641 }
1642
1643 private void importDependencyManagement(
1644 Model model,
1645 ModelBuildingRequest request,
1646 DefaultModelProblemCollector problems,
1647 Collection<String> importIds) {
1648 DependencyManagement depMgmt = model.getDependencyManagement();
1649
1650 if (depMgmt == null) {
1651 return;
1652 }
1653
1654 String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
1655
1656 importIds.add(importing);
1657
1658 List<org.apache.maven.api.model.DependencyManagement> importMgmts = null;
1659
1660 for (Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); ) {
1661 Dependency dependency = it.next();
1662
1663 if (!("pom".equals(dependency.getType()) && "import".equals(dependency.getScope()))
1664 || "bom".equals(dependency.getType())) {
1665 continue;
1666 }
1667
1668 it.remove();
1669
1670 DependencyManagement importMgmt = loadDependencyManagement(model, request, problems, dependency, importIds);
1671
1672 if (importMgmt != null) {
1673 if (importMgmts == null) {
1674 importMgmts = new ArrayList<>();
1675 }
1676
1677 importMgmts.add(importMgmt.getDelegate());
1678 }
1679 }
1680
1681 importIds.remove(importing);
1682
1683 model.update(
1684 dependencyManagementImporter.importManagement(model.getDelegate(), importMgmts, request, problems));
1685 }
1686
1687 private DependencyManagement loadDependencyManagement(
1688 Model model,
1689 ModelBuildingRequest request,
1690 DefaultModelProblemCollector problems,
1691 Dependency dependency,
1692 Collection<String> importIds) {
1693 String groupId = dependency.getGroupId();
1694 String artifactId = dependency.getArtifactId();
1695 String version = dependency.getVersion();
1696
1697 if (groupId == null || groupId.length() <= 0) {
1698 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1699 .setMessage("'dependencyManagement.dependencies.dependency.groupId' for "
1700 + dependency.getManagementKey() + " is missing.")
1701 .setLocation(dependency.getLocation("")));
1702 return null;
1703 }
1704 if (artifactId == null || artifactId.length() <= 0) {
1705 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1706 .setMessage("'dependencyManagement.dependencies.dependency.artifactId' for "
1707 + dependency.getManagementKey() + " is missing.")
1708 .setLocation(dependency.getLocation("")));
1709 return null;
1710 }
1711 if (version == null || version.length() <= 0) {
1712 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1713 .setMessage("'dependencyManagement.dependencies.dependency.version' for "
1714 + dependency.getManagementKey() + " is missing.")
1715 .setLocation(dependency.getLocation("")));
1716 return null;
1717 }
1718
1719 String imported = groupId + ':' + artifactId + ':' + version;
1720
1721 if (importIds.contains(imported)) {
1722 StringBuilder message =
1723 new StringBuilder("The dependencies of type=pom and with scope=import form a cycle: ");
1724 for (String modelId : importIds) {
1725 message.append(modelId).append(" -> ");
1726 }
1727 message.append(imported);
1728 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE).setMessage(message.toString()));
1729
1730 return null;
1731 }
1732
1733 org.apache.maven.api.model.DependencyManagement importMgmt = cache(
1734 request.getModelCache(),
1735 groupId,
1736 artifactId,
1737 version,
1738 ModelCacheTag.IMPORT,
1739 () -> doLoadDependencyManagement(
1740 model, request, problems, dependency, groupId, artifactId, version, importIds));
1741
1742
1743 List<Exclusion> exclusions = dependency.getDelegate().getExclusions();
1744 if (importMgmt != null && !exclusions.isEmpty()) {
1745
1746 List<org.apache.maven.api.model.Dependency> dependencies = importMgmt.getDependencies().stream()
1747 .filter(candidate -> exclusions.stream().noneMatch(exclusion -> match(exclusion, candidate)))
1748 .map(candidate -> candidate.withExclusions(exclusions))
1749 .collect(Collectors.toList());
1750 importMgmt = importMgmt.withDependencies(dependencies);
1751 }
1752
1753 return importMgmt != null ? new DependencyManagement(importMgmt) : null;
1754 }
1755
1756 private boolean match(Exclusion exclusion, org.apache.maven.api.model.Dependency candidate) {
1757 return match(exclusion.getGroupId(), candidate.getGroupId())
1758 && match(exclusion.getArtifactId(), candidate.getArtifactId());
1759 }
1760
1761 private boolean match(String match, String text) {
1762 return match.equals("*") || match.equals(text);
1763 }
1764
1765 @SuppressWarnings("checkstyle:parameternumber")
1766 private org.apache.maven.api.model.DependencyManagement doLoadDependencyManagement(
1767 Model model,
1768 ModelBuildingRequest request,
1769 DefaultModelProblemCollector problems,
1770 Dependency dependency,
1771 String groupId,
1772 String artifactId,
1773 String version,
1774 Collection<String> importIds) {
1775 DependencyManagement importMgmt;
1776 final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
1777 final ModelResolver modelResolver = request.getModelResolver();
1778 if (workspaceResolver == null && modelResolver == null) {
1779 throw new NullPointerException(String.format(
1780 "request.workspaceModelResolver and request.modelResolver cannot be null (parent POM %s and POM %s)",
1781 ModelProblemUtils.toId(groupId, artifactId, version), ModelProblemUtils.toSourceHint(model)));
1782 }
1783
1784 Model importModel = null;
1785 if (workspaceResolver != null) {
1786 try {
1787 importModel = workspaceResolver.resolveEffectiveModel(groupId, artifactId, version);
1788 } catch (UnresolvableModelException e) {
1789 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1790 .setMessage(e.getMessage())
1791 .setException(e));
1792 return null;
1793 }
1794 }
1795
1796
1797 if (importModel == null) {
1798 final ModelSource importSource;
1799 try {
1800 importSource = modelResolver.resolveModel(dependency);
1801 } catch (UnresolvableModelException e) {
1802 StringBuilder buffer = new StringBuilder(256);
1803 buffer.append("Non-resolvable import POM");
1804 if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1805 buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1806 }
1807 buffer.append(": ").append(e.getMessage());
1808
1809 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1810 .setMessage(buffer.toString())
1811 .setLocation(dependency.getLocation(""))
1812 .setException(e));
1813 return null;
1814 }
1815
1816 final ModelBuildingResult importResult;
1817 try {
1818 ModelBuildingRequest importRequest = new DefaultModelBuildingRequest();
1819 importRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
1820 importRequest.setModelCache(request.getModelCache());
1821 importRequest.setSystemProperties(request.getSystemProperties());
1822 importRequest.setUserProperties(request.getUserProperties());
1823 importRequest.setLocationTracking(request.isLocationTracking());
1824
1825 importRequest.setModelSource(importSource);
1826 importRequest.setModelResolver(modelResolver.newCopy());
1827
1828 importResult = build(importRequest, importIds);
1829 } catch (ModelBuildingException e) {
1830 problems.addAll(e.getProblems());
1831 return null;
1832 }
1833
1834 problems.addAll(importResult.getProblems());
1835
1836 importModel = importResult.getEffectiveModel();
1837 }
1838
1839 importMgmt = importModel.getDependencyManagement();
1840
1841 if (importMgmt == null) {
1842 importMgmt = new DependencyManagement();
1843 }
1844 return importMgmt.getDelegate();
1845 }
1846
1847 private static <T> T cache(
1848 ModelCache cache,
1849 String groupId,
1850 String artifactId,
1851 String version,
1852 ModelCacheTag<T> tag,
1853 Callable<T> supplier) {
1854 return doWithCache(cache, supplier, s -> cache.computeIfAbsent(groupId, artifactId, version, tag, s));
1855 }
1856
1857 private static <T> T cache(ModelCache cache, Source source, ModelCacheTag<T> tag, Callable<T> supplier) {
1858 return doWithCache(cache, supplier, s -> cache.computeIfAbsent(source, tag, s));
1859 }
1860
1861 private static <T> T doWithCache(
1862 ModelCache cache, Callable<T> supplier, Function<Supplier<Supplier<T>>, T> asyncSupplierConsumer) {
1863 if (cache != null) {
1864 return asyncSupplierConsumer.apply(() -> {
1865 ForkJoinTask<T> task = ForkJoinTask.adapt(supplier);
1866 task.fork();
1867 return () -> {
1868 task.quietlyJoin();
1869 if (task.isCompletedAbnormally()) {
1870 Throwable e = task.getException();
1871 while (e instanceof RuntimeException && e.getCause() != null) {
1872 e = e.getCause();
1873 }
1874 uncheckedThrow(e);
1875 }
1876 return task.getRawResult();
1877 };
1878 });
1879 } else {
1880 try {
1881 return supplier.call();
1882 } catch (Exception e) {
1883 uncheckedThrow(e);
1884 return null;
1885 }
1886 }
1887 }
1888
1889 static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
1890 throw (T) t;
1891 }
1892
1893 private void fireEvent(
1894 Model model,
1895 ModelBuildingRequest request,
1896 ModelProblemCollector problems,
1897 ModelBuildingEventCatapult catapult) {
1898 ModelBuildingListener listener = request.getModelBuildingListener();
1899
1900 if (listener != null) {
1901 ModelBuildingEvent event = new DefaultModelBuildingEvent(model, request, problems);
1902
1903 catapult.fire(listener, event);
1904 }
1905 }
1906
1907 private boolean containsCoordinates(String message, String groupId, String artifactId, String version) {
1908 return message != null
1909 && (groupId == null || message.contains(groupId))
1910 && (artifactId == null || message.contains(artifactId))
1911 && (version == null || message.contains(version));
1912 }
1913
1914 protected boolean hasModelErrors(ModelProblemCollectorExt problems) {
1915 if (problems instanceof DefaultModelProblemCollector) {
1916 return ((DefaultModelProblemCollector) problems).hasErrors();
1917 } else {
1918
1919
1920 throw new IllegalStateException();
1921 }
1922 }
1923
1924 protected boolean hasFatalErrors(ModelProblemCollectorExt problems) {
1925 if (problems instanceof DefaultModelProblemCollector) {
1926 return ((DefaultModelProblemCollector) problems).hasFatalErrors();
1927 } else {
1928
1929
1930 throw new IllegalStateException();
1931 }
1932 }
1933
1934 ModelProcessor getModelProcessor() {
1935 return modelProcessor;
1936 }
1937 }