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