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