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