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