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