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