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