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.building.Source;
52  import org.apache.maven.model.Activation;
53  import org.apache.maven.model.Build;
54  import org.apache.maven.model.Dependency;
55  import org.apache.maven.model.DependencyManagement;
56  import org.apache.maven.model.InputLocation;
57  import org.apache.maven.model.Model;
58  import org.apache.maven.model.Parent;
59  import org.apache.maven.model.Plugin;
60  import org.apache.maven.model.PluginManagement;
61  import org.apache.maven.model.Profile;
62  import org.apache.maven.model.building.ModelProblem.Severity;
63  import org.apache.maven.model.building.ModelProblem.Version;
64  import org.apache.maven.model.composition.DependencyManagementImporter;
65  import org.apache.maven.model.inheritance.InheritanceAssembler;
66  import org.apache.maven.model.interpolation.ModelInterpolator;
67  import org.apache.maven.model.interpolation.ModelVersionProcessor;
68  import org.apache.maven.model.io.ModelParseException;
69  import org.apache.maven.model.io.ModelReader;
70  import org.apache.maven.model.management.DependencyManagementInjector;
71  import org.apache.maven.model.management.PluginManagementInjector;
72  import org.apache.maven.model.normalization.ModelNormalizer;
73  import org.apache.maven.model.path.ModelPathTranslator;
74  import org.apache.maven.model.path.ModelUrlNormalizer;
75  import org.apache.maven.model.path.ProfileActivationFilePathInterpolator;
76  import org.apache.maven.model.plugin.LifecycleBindingsInjector;
77  import org.apache.maven.model.plugin.PluginConfigurationExpander;
78  import org.apache.maven.model.plugin.ReportConfigurationExpander;
79  import org.apache.maven.model.plugin.ReportingConverter;
80  import org.apache.maven.model.profile.DefaultProfileActivationContext;
81  import org.apache.maven.model.profile.ProfileActivationContext;
82  import org.apache.maven.model.profile.ProfileInjector;
83  import org.apache.maven.model.profile.ProfileSelector;
84  import org.apache.maven.model.resolution.InvalidRepositoryException;
85  import org.apache.maven.model.resolution.ModelResolver;
86  import org.apache.maven.model.resolution.UnresolvableModelException;
87  import org.apache.maven.model.resolution.WorkspaceModelResolver;
88  import org.apache.maven.model.superpom.SuperPomProvider;
89  import org.apache.maven.model.v4.MavenTransformer;
90  import org.apache.maven.model.validation.DefaultModelValidator;
91  import org.apache.maven.model.validation.ModelValidator;
92  import org.apache.maven.model.version.ModelVersionParser;
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         for (Profile activeProfile : activeExternalProfiles) {
758             profileInjector.injectProfile(inputModel, activeProfile, request, problems);
759         }
760     }
761 
762     @SuppressWarnings("checkstyle:methodlength")
763     private Model readEffectiveModel(
764             final ModelBuildingRequest request,
765             final DefaultModelBuildingResult result,
766             DefaultModelProblemCollector problems)
767             throws ModelBuildingException {
768         Model inputModel = readRawModel(request, problems);
769         if (problems.hasFatalErrors()) {
770             throw problems.newModelBuildingException();
771         }
772 
773         problems.setRootModel(inputModel);
774 
775         ModelData resultData = new ModelData(request.getModelSource(), inputModel);
776         String superModelVersion = inputModel.getModelVersion() != null ? inputModel.getModelVersion() : "4.0.0";
777         if (!DefaultModelValidator.VALID_MODEL_VERSIONS.contains(superModelVersion)) {
778             // Maven 3.x is always using 4.0.0 version to load the supermodel, so
779             // do the same when loading a dependency.  The model validator will also
780             // check that field later.
781             superModelVersion = "4.0.0";
782         }
783         ModelData superData = new ModelData(null, getSuperModel(superModelVersion));
784 
785         // profile activation
786         DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request);
787 
788         List<Profile> activeExternalProfiles = result.getActiveExternalProfiles();
789 
790         if (!activeExternalProfiles.isEmpty()) {
791             Properties profileProps = new Properties();
792             for (Profile profile : activeExternalProfiles) {
793                 profileProps.putAll(profile.getProperties());
794             }
795             profileProps.putAll(profileActivationContext.getUserProperties());
796             profileActivationContext.setUserProperties(profileProps);
797         }
798 
799         Collection<String> parentIds = new LinkedHashSet<>();
800 
801         List<Model> lineage = new ArrayList<>();
802 
803         for (ModelData currentData = resultData; ; ) {
804             String modelId = currentData.getId();
805             result.addModelId(modelId);
806 
807             Model model = currentData.getModel();
808             result.setRawModel(modelId, model);
809             problems.setSource(model);
810             org.apache.maven.api.model.Model modelv4 = model.getDelegate();
811 
812             // model normalization
813             modelv4 = modelNormalizer.mergeDuplicates(modelv4, request, problems);
814 
815             // profile activation
816             profileActivationContext.setProjectProperties(modelv4.getProperties());
817 
818             List<org.apache.maven.api.model.Profile> interpolatedProfiles =
819                     interpolateActivations(modelv4.getProfiles(), profileActivationContext, problems);
820 
821             // profile injection
822             List<org.apache.maven.api.model.Profile> activePomProfiles =
823                     profileSelector.getActiveProfilesV4(interpolatedProfiles, profileActivationContext, problems);
824             result.setActivePomProfiles(
825                     modelId, activePomProfiles.stream().map(Profile::new).collect(Collectors.toList()));
826             modelv4 = profileInjector.injectProfiles(modelv4, activePomProfiles, request, problems);
827             if (currentData == resultData) {
828                 for (Profile activeProfile : activeExternalProfiles) {
829                     modelv4 = profileInjector.injectProfile(modelv4, activeProfile.getDelegate(), request, problems);
830                 }
831             }
832 
833             lineage.add(new Model(modelv4));
834 
835             if (currentData == superData) {
836                 break;
837             }
838 
839             // add repositories specified by the current model so that we can resolve the parent
840             configureResolver(request.getModelResolver(), modelv4, problems, false);
841 
842             // we pass a cloned model, so that resolving the parent version does not affect the returned model
843             ModelData parentData = readParent(new Model(modelv4), currentData.getSource(), request, problems);
844 
845             if (parentData == null) {
846                 currentData = superData;
847             } else if (!parentIds.add(parentData.getId())) {
848                 StringBuilder message = new StringBuilder("The parents form a cycle: ");
849                 for (String parentId : parentIds) {
850                     message.append(parentId).append(" -> ");
851                 }
852                 message.append(parentData.getId());
853 
854                 problems.add(new ModelProblemCollectorRequest(ModelProblem.Severity.FATAL, ModelProblem.Version.BASE)
855                         .setMessage(message.toString()));
856 
857                 throw problems.newModelBuildingException();
858             } else {
859                 currentData = parentData;
860             }
861         }
862 
863         Model tmpModel = lineage.get(0);
864 
865         // inject interpolated activations
866         List<org.apache.maven.api.model.Profile> interpolated =
867                 interpolateActivations(tmpModel.getDelegate().getProfiles(), profileActivationContext, problems);
868         if (interpolated != tmpModel.getDelegate().getProfiles()) {
869             tmpModel.update(tmpModel.getDelegate().withProfiles(interpolated));
870         }
871 
872         // inject external profile into current model
873         tmpModel.update(profileInjector.injectProfiles(
874                 tmpModel.getDelegate(),
875                 activeExternalProfiles.stream().map(Profile::getDelegate).collect(Collectors.toList()),
876                 request,
877                 problems));
878 
879         checkPluginVersions(lineage, request, problems);
880 
881         // inheritance assembly
882         Model resultModel = assembleInheritance(lineage, request, problems);
883 
884         // consider caching inherited model
885 
886         problems.setSource(resultModel);
887         problems.setRootModel(resultModel);
888 
889         // model interpolation
890         resultModel = interpolateModel(resultModel, request, problems);
891 
892         // url normalization
893         modelUrlNormalizer.normalize(resultModel, request);
894 
895         result.setEffectiveModel(resultModel);
896 
897         // Now the fully interpolated model is available: reconfigure the resolver
898         configureResolver(request.getModelResolver(), resultModel.getDelegate(), problems, true);
899 
900         return resultModel;
901     }
902 
903     private List<org.apache.maven.api.model.Profile> interpolateActivations(
904             List<org.apache.maven.api.model.Profile> profiles,
905             DefaultProfileActivationContext context,
906             DefaultModelProblemCollector problems) {
907         if (profiles.stream()
908                 .map(org.apache.maven.api.model.Profile::getActivation)
909                 .noneMatch(Objects::nonNull)) {
910             return profiles;
911         }
912         final Interpolator xform = new RegexBasedInterpolator();
913         xform.setCacheAnswers(true);
914         Stream.of(context.getUserProperties(), context.getSystemProperties())
915                 .map(MapBasedValueSource::new)
916                 .forEach(xform::addValueSource);
917 
918         class ProfileInterpolator extends MavenTransformer
919                 implements UnaryOperator<org.apache.maven.api.model.Profile> {
920             ProfileInterpolator() {
921                 super(s -> {
922                     if (isNotEmpty(s)) {
923                         try {
924                             return xform.interpolate(s);
925                         } catch (InterpolationException e) {
926                             problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
927                                     .setMessage(e.getMessage())
928                                     .setException(e));
929                         }
930                     }
931                     return s;
932                 });
933             }
934 
935             @Override
936             public org.apache.maven.api.model.Profile apply(org.apache.maven.api.model.Profile p) {
937                 return org.apache.maven.api.model.Profile.newBuilder(p)
938                         .activation(transformActivation(p.getActivation()))
939                         .build();
940             }
941 
942             @Override
943             protected ActivationFile.Builder transformActivationFile_Missing(
944                     Supplier<? extends ActivationFile.Builder> creator,
945                     ActivationFile.Builder builder,
946                     ActivationFile target) {
947                 final String path = target.getMissing();
948                 final String xformed = transformPath(path, target, "missing");
949                 return xformed != path ? (builder != null ? builder : creator.get()).missing(xformed) : builder;
950             }
951 
952             @Override
953             protected ActivationFile.Builder transformActivationFile_Exists(
954                     Supplier<? extends ActivationFile.Builder> creator,
955                     ActivationFile.Builder builder,
956                     ActivationFile target) {
957                 final String path = target.getExists();
958                 final String xformed = transformPath(path, target, "exists");
959                 return xformed != path ? (builder != null ? builder : creator.get()).exists(xformed) : builder;
960             }
961 
962             private String transformPath(String path, ActivationFile target, String locationKey) {
963                 if (isNotEmpty(path)) {
964                     try {
965                         return profileActivationFilePathInterpolator.interpolate(path, context);
966                     } catch (InterpolationException e) {
967                         addInterpolationProblem(problems, target, path, e, locationKey);
968                     }
969                 }
970                 return path;
971             }
972         }
973         return profiles.stream().map(new ProfileInterpolator()).toList();
974     }
975 
976     private static void addInterpolationProblem(
977             DefaultModelProblemCollector problems,
978             org.apache.maven.api.model.InputLocationTracker target,
979             String path,
980             InterpolationException e,
981             String locationKey) {
982         problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
983                 .setMessage("Failed to interpolate file location " + path + ": " + e.getMessage())
984                 .setLocation(Optional.ofNullable(target.getLocation(locationKey))
985                         .map(InputLocation::new)
986                         .orElse(null))
987                 .setException(e));
988     }
989 
990     private static boolean isNotEmpty(String string) {
991         return string != null && !string.isEmpty();
992     }
993 
994     @Override
995     public ModelBuildingResult build(final ModelBuildingRequest request, final ModelBuildingResult result)
996             throws ModelBuildingException {
997         return build(request, result, new LinkedHashSet<>());
998     }
999 
1000     public Model buildRawModel(final ModelBuildingRequest request) throws ModelBuildingException {
1001         DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult());
1002         Model model = readRawModel(request, problems);
1003         if (hasModelErrors(problems)) {
1004             throw problems.newModelBuildingException();
1005         }
1006         return model;
1007     }
1008 
1009     private ModelBuildingResult build(
1010             final ModelBuildingRequest request, final ModelBuildingResult phaseOneResult, Collection<String> imports)
1011             throws ModelBuildingException {
1012         DefaultModelBuildingResult result = asDefaultModelBuildingResult(phaseOneResult);
1013 
1014         DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
1015 
1016         // phase 2
1017         Model resultModel = readEffectiveModel(request, result, problems);
1018         problems.setSource(resultModel);
1019         problems.setRootModel(resultModel);
1020 
1021         // model path translation
1022         modelPathTranslator.alignToBaseDirectory(resultModel, resultModel.getProjectDirectoryPath(), request);
1023 
1024         // plugin management injection
1025         pluginManagementInjector.injectManagement(resultModel, request, problems);
1026 
1027         fireEvent(resultModel, request, problems, ModelBuildingEventCatapult.BUILD_EXTENSIONS_ASSEMBLED);
1028 
1029         if (request.isProcessPlugins()) {
1030             if (lifecycleBindingsInjector == null) {
1031                 throw new IllegalStateException("lifecycle bindings injector is missing");
1032             }
1033 
1034             // lifecycle bindings injection
1035             lifecycleBindingsInjector.injectLifecycleBindings(resultModel, request, problems);
1036         }
1037 
1038         // dependency management import
1039         importDependencyManagement(resultModel, request, problems, imports);
1040 
1041         // dependency management injection
1042         dependencyManagementInjector.injectManagement(resultModel, request, problems);
1043 
1044         resultModel.update(modelNormalizer.injectDefaultValues(resultModel.getDelegate(), request, problems));
1045 
1046         if (request.isProcessPlugins()) {
1047             // reports configuration
1048             reportConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
1049 
1050             // plugins configuration
1051             pluginConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
1052         }
1053 
1054         // effective model validation
1055         modelValidator.validateEffectiveModel(resultModel, request, problems);
1056 
1057         if (hasModelErrors(problems)) {
1058             throw problems.newModelBuildingException();
1059         }
1060 
1061         return result;
1062     }
1063 
1064     private DefaultModelBuildingResult asDefaultModelBuildingResult(ModelBuildingResult phaseOneResult) {
1065         if (phaseOneResult instanceof DefaultModelBuildingResult) {
1066             return (DefaultModelBuildingResult) phaseOneResult;
1067         } else {
1068             return new DefaultModelBuildingResult(phaseOneResult);
1069         }
1070     }
1071 
1072     @Deprecated
1073     @Override
1074     public Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking) {
1075         return buildRawModel(pomFile.toPath(), validationLevel, locationTracking, null);
1076     }
1077 
1078     @Override
1079     public Result<? extends Model> buildRawModel(Path pomFile, int validationLevel, boolean locationTracking) {
1080         return buildRawModel(pomFile, validationLevel, locationTracking, null);
1081     }
1082 
1083     @Deprecated
1084     @Override
1085     public Result<? extends Model> buildRawModel(
1086             File pomFile, int validationLevel, boolean locationTracking, TransformerContext context) {
1087         return buildRawModel(pomFile.toPath(), validationLevel, locationTracking, context);
1088     }
1089 
1090     @Override
1091     public Result<? extends Model> buildRawModel(
1092             Path pomFile, int validationLevel, boolean locationTracking, TransformerContext context) {
1093         final ModelBuildingRequest request = new DefaultModelBuildingRequest()
1094                 .setValidationLevel(validationLevel)
1095                 .setLocationTracking(locationTracking)
1096                 .setModelSource(new FileModelSource(pomFile));
1097         DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult());
1098         try {
1099             Model model = readFileModel(request, problems);
1100 
1101             try {
1102                 if (transformer != null && context != null) {
1103                     transformer.transform(pomFile, context, model);
1104                 }
1105             } catch (TransformerException e) {
1106                 problems.add(
1107                         new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V40).setException(e));
1108             }
1109 
1110             return newResult(model, problems.getProblems());
1111         } catch (ModelBuildingException e) {
1112             return error(problems.getProblems());
1113         }
1114     }
1115 
1116     Model readFileModel(ModelBuildingRequest request, DefaultModelProblemCollector problems)
1117             throws ModelBuildingException {
1118         ModelSource modelSource = request.getModelSource();
1119         org.apache.maven.api.model.Model model = cache(
1120                 request.getModelCache(),
1121                 modelSource,
1122                 ModelCacheTag.FILE,
1123                 () -> doReadFileModel(modelSource, request, problems));
1124 
1125         if (modelSource instanceof FileModelSource) {
1126             if (request.getTransformerContextBuilder() instanceof DefaultTransformerContextBuilder) {
1127                 DefaultTransformerContextBuilder contextBuilder =
1128                         (DefaultTransformerContextBuilder) request.getTransformerContextBuilder();
1129                 contextBuilder.putSource(getGroupId(model), model.getArtifactId(), (FileModelSource) modelSource);
1130             }
1131         }
1132 
1133         return new Model(model);
1134     }
1135 
1136     @SuppressWarnings("checkstyle:methodlength")
1137     private org.apache.maven.api.model.Model doReadFileModel(
1138             ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1139             throws ModelBuildingException {
1140         org.apache.maven.api.model.Model model;
1141         problems.setSource(modelSource.getLocation());
1142         try {
1143             boolean strict = request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
1144 
1145             Map<String, Object> options = new HashMap<>(3);
1146             options.put(ModelProcessor.IS_STRICT, strict);
1147             options.put(ModelProcessor.SOURCE, modelSource);
1148             options.put(ModelReader.ROOT_DIRECTORY, request.getRootDirectory());
1149 
1150             InputSource source;
1151             if (request.isLocationTracking()) {
1152                 source = new InputSource(null, modelSource.getLocation());
1153                 options.put(ModelProcessor.INPUT_SOURCE, new org.apache.maven.model.InputSource(source));
1154             } else {
1155                 source = null;
1156             }
1157 
1158             try {
1159                 model = modelProcessor
1160                         .read(modelSource.getInputStream(), options)
1161                         .getDelegate();
1162             } catch (ModelParseException e) {
1163                 if (!strict) {
1164                     throw e;
1165                 }
1166 
1167                 options.put(ModelProcessor.IS_STRICT, Boolean.FALSE);
1168 
1169                 try {
1170                     model = modelProcessor
1171                             .read(modelSource.getInputStream(), options)
1172                             .getDelegate();
1173                 } catch (ModelParseException ne) {
1174                     // still unreadable even in non-strict mode, rethrow original error
1175                     throw e;
1176                 }
1177 
1178                 Severity severity = (modelSource instanceof FileModelSource) ? Severity.ERROR : Severity.WARNING;
1179                 problems.add(new ModelProblemCollectorRequest(severity, ModelProblem.Version.V20)
1180                         .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage())
1181                         .setException(e));
1182             }
1183 
1184             if (source != null) {
1185                 try {
1186                     org.apache.maven.api.model.InputLocation loc = model.getLocation("");
1187                     org.apache.maven.api.model.InputSource v4src = loc != null ? loc.getSource() : null;
1188                     if (v4src != null) {
1189                         Field field = InputSource.class.getDeclaredField("modelId");
1190                         field.setAccessible(true);
1191                         field.set(v4src, ModelProblemUtils.toId(model));
1192                     }
1193                 } catch (Throwable t) {
1194                     // TODO: use a lazy source ?
1195                     throw new IllegalStateException("Unable to set modelId on InputSource", t);
1196                 }
1197             }
1198         } catch (ModelParseException e) {
1199             problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE)
1200                     .setMessage("Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage())
1201                     .setException(e));
1202             throw problems.newModelBuildingException();
1203         } catch (IOException e) {
1204             String msg = e.getMessage();
1205             if (msg == null || msg.isEmpty()) {
1206                 // NOTE: There's java.nio.charset.MalformedInputException and sun.io.MalformedInputException
1207                 if (e.getClass().getName().endsWith("MalformedInputException")) {
1208                     msg = "Some input bytes do not match the file encoding.";
1209                 } else {
1210                     msg = e.getClass().getSimpleName();
1211                 }
1212             }
1213             problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE)
1214                     .setMessage("Non-readable POM " + modelSource.getLocation() + ": " + msg)
1215                     .setException(e));
1216             throw problems.newModelBuildingException();
1217         }
1218 
1219         if (modelSource instanceof FileModelSource) {
1220             model = model.withPomFile(((FileModelSource) modelSource).getPath());
1221         }
1222 
1223         Model retModel = new Model(model);
1224 
1225         problems.setSource(retModel);
1226 
1227         modelValidator.validateFileModel(retModel, request, problems);
1228 
1229         if (hasFatalErrors(problems)) {
1230             throw problems.newModelBuildingException();
1231         }
1232 
1233         return model;
1234     }
1235 
1236     Model readRawModel(ModelBuildingRequest request, DefaultModelProblemCollector problems)
1237             throws ModelBuildingException {
1238         ModelSource modelSource = request.getModelSource();
1239 
1240         ModelData modelData = cache(
1241                 request.getModelCache(),
1242                 modelSource,
1243                 ModelCacheTag.RAW,
1244                 () -> doReadRawModel(modelSource, request, problems));
1245 
1246         return modelData.getModel();
1247     }
1248 
1249     private ModelData doReadRawModel(
1250             ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1251             throws ModelBuildingException {
1252         Model rawModel;
1253         if (Features.buildConsumer(request.getUserProperties()) && modelSource instanceof FileModelSource) {
1254             rawModel = readFileModel(request, problems);
1255             File pomFile = ((FileModelSource) modelSource).getFile();
1256 
1257             try {
1258                 if (request.getTransformerContextBuilder() != null) {
1259                     TransformerContext context =
1260                             request.getTransformerContextBuilder().initialize(request, problems);
1261                     transformer.transform(pomFile.toPath(), context, rawModel);
1262                 }
1263             } catch (TransformerException e) {
1264                 problems.add(
1265                         new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V40).setException(e));
1266             }
1267         } else if (request.getFileModel() == null) {
1268             rawModel = readFileModel(request, problems);
1269         } else {
1270             rawModel = request.getFileModel().clone();
1271         }
1272 
1273         modelValidator.validateRawModel(rawModel, request, problems);
1274 
1275         if (hasFatalErrors(problems)) {
1276             throw problems.newModelBuildingException();
1277         }
1278 
1279         String groupId = getGroupId(rawModel);
1280         String artifactId = rawModel.getArtifactId();
1281         String version = getVersion(rawModel);
1282 
1283         return new ModelData(modelSource, rawModel, groupId, artifactId, version);
1284     }
1285 
1286     String getGroupId(Model model) {
1287         return getGroupId(model.getDelegate());
1288     }
1289 
1290     private String getGroupId(org.apache.maven.api.model.Model model) {
1291         String groupId = model.getGroupId();
1292         if (groupId == null && model.getParent() != null) {
1293             groupId = model.getParent().getGroupId();
1294         }
1295         return groupId;
1296     }
1297 
1298     private String getVersion(Model model) {
1299         String version = model.getVersion();
1300         if (version == null && model.getParent() != null) {
1301             version = model.getParent().getVersion();
1302         }
1303         return version;
1304     }
1305 
1306     private DefaultProfileActivationContext getProfileActivationContext(ModelBuildingRequest request) {
1307         DefaultProfileActivationContext context = new DefaultProfileActivationContext();
1308 
1309         context.setActiveProfileIds(request.getActiveProfileIds());
1310         context.setInactiveProfileIds(request.getInactiveProfileIds());
1311         context.setSystemProperties(request.getSystemProperties());
1312         // enrich user properties with project packaging
1313         Properties userProperties = request.getUserProperties();
1314         if (!userProperties.containsKey(ProfileActivationContext.PROPERTY_NAME_PACKAGING)) {
1315             userProperties.put(
1316                     ProfileActivationContext.PROPERTY_NAME_PACKAGING,
1317                     request.getFileModel().getPackaging());
1318         }
1319         context.setUserProperties(userProperties);
1320         context.setProjectDirectory(
1321                 (request.getPomFile() != null) ? request.getPomFile().getParentFile() : null);
1322 
1323         return context;
1324     }
1325 
1326     private void configureResolver(
1327             ModelResolver modelResolver,
1328             org.apache.maven.api.model.Model model,
1329             DefaultModelProblemCollector problems,
1330             boolean replaceRepositories) {
1331         if (modelResolver != null) {
1332             for (org.apache.maven.api.model.Repository repository : model.getRepositories()) {
1333                 try {
1334                     modelResolver.addRepository(repository, replaceRepositories);
1335                 } catch (InvalidRepositoryException e) {
1336                     problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1337                             .setMessage("Invalid repository " + repository.getId() + ": " + e.getMessage())
1338                             .setLocation(new InputLocation(repository.getLocation("")))
1339                             .setException(e));
1340                 }
1341             }
1342         }
1343     }
1344 
1345     private void checkPluginVersions(
1346             List<Model> lineage, ModelBuildingRequest request, ModelProblemCollector problems) {
1347         if (request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
1348             return;
1349         }
1350 
1351         Map<String, Plugin> plugins = new HashMap<>();
1352         Map<String, String> versions = new HashMap<>();
1353         Map<String, String> managedVersions = new HashMap<>();
1354 
1355         for (int i = lineage.size() - 1; i >= 0; i--) {
1356             Model model = lineage.get(i);
1357             Build build = model.getBuild();
1358             if (build != null) {
1359                 for (Plugin plugin : build.getPlugins()) {
1360                     String key = plugin.getKey();
1361                     if (versions.get(key) == null) {
1362                         versions.put(key, plugin.getVersion());
1363                         plugins.put(key, plugin);
1364                     }
1365                 }
1366                 PluginManagement mgmt = build.getPluginManagement();
1367                 if (mgmt != null) {
1368                     for (Plugin plugin : mgmt.getPlugins()) {
1369                         String key = plugin.getKey();
1370                         managedVersions.computeIfAbsent(key, k -> plugin.getVersion());
1371                     }
1372                 }
1373             }
1374         }
1375 
1376         for (String key : versions.keySet()) {
1377             if (versions.get(key) == null && managedVersions.get(key) == null) {
1378                 InputLocation location = plugins.get(key).getLocation("");
1379                 problems.add(new ModelProblemCollectorRequest(Severity.WARNING, ModelProblem.Version.V20)
1380                         .setMessage("'build.plugins.plugin.version' for " + key + " is missing.")
1381                         .setLocation(location));
1382             }
1383         }
1384     }
1385 
1386     private Model assembleInheritance(
1387             List<Model> lineage, ModelBuildingRequest request, ModelProblemCollector problems) {
1388         org.apache.maven.api.model.Model parent =
1389                 lineage.get(lineage.size() - 1).getDelegate();
1390         for (int i = lineage.size() - 2; i >= 0; i--) {
1391             Model child = lineage.get(i);
1392             parent = inheritanceAssembler.assembleModelInheritance(child.getDelegate(), parent, request, problems);
1393         }
1394         return new Model(parent);
1395     }
1396 
1397     private Map<String, Activation> getProfileActivations(Model model, boolean clone) {
1398         Map<String, Activation> activations = new HashMap<>();
1399         for (Profile profile : model.getProfiles()) {
1400             Activation activation = profile.getActivation();
1401 
1402             if (activation == null) {
1403                 continue;
1404             }
1405 
1406             if (clone) {
1407                 activation = activation.clone();
1408             }
1409 
1410             activations.put(profile.getId(), activation);
1411         }
1412 
1413         return activations;
1414     }
1415 
1416     private void injectProfileActivations(Model model, Map<String, Activation> activations) {
1417         for (Profile profile : model.getProfiles()) {
1418             Activation activation = profile.getActivation();
1419 
1420             if (activation == null) {
1421                 continue;
1422             }
1423 
1424             // restore activation
1425             profile.setActivation(activations.get(profile.getId()));
1426         }
1427     }
1428 
1429     private Model interpolateModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
1430         // save profile activations before interpolation, since they are evaluated with limited scope
1431         Map<String, Activation> originalActivations = getProfileActivations(model, true);
1432 
1433         Model interpolatedModel = new Model(modelInterpolator.interpolateModel(
1434                 model.getDelegate(), model.getProjectDirectoryPath(), request, problems));
1435         if (interpolatedModel.getParent() != null) {
1436             StringSearchInterpolator ssi = new StringSearchInterpolator();
1437             ssi.addValueSource(new MapBasedValueSource(request.getUserProperties()));
1438 
1439             ssi.addValueSource(new MapBasedValueSource(model.getProperties()));
1440 
1441             ssi.addValueSource(new MapBasedValueSource(request.getSystemProperties()));
1442 
1443             try {
1444                 String interpolated =
1445                         ssi.interpolate(interpolatedModel.getParent().getVersion());
1446                 interpolatedModel.getParent().setVersion(interpolated);
1447             } catch (Exception e) {
1448                 ModelProblemCollectorRequest mpcr = new ModelProblemCollectorRequest(
1449                                 Severity.ERROR, ModelProblem.Version.BASE)
1450                         .setMessage("Failed to interpolate field: "
1451                                 + interpolatedModel.getParent().getVersion()
1452                                 + " on class: ")
1453                         .setException(e);
1454                 problems.add(mpcr);
1455             }
1456         }
1457         interpolatedModel.setPomPath(model.getPomPath());
1458 
1459         // restore profiles with file activation to their value before full interpolation
1460         injectProfileActivations(model, originalActivations);
1461 
1462         return interpolatedModel;
1463     }
1464 
1465     private ModelData readParent(
1466             Model childModel, Source childSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1467             throws ModelBuildingException {
1468         ModelData parentData = null;
1469 
1470         Parent parent = childModel.getParent();
1471         if (parent != null) {
1472             parentData = readParentLocally(childModel, childSource, request, problems);
1473             if (parentData == null) {
1474                 parentData = readParentExternally(childModel, request, problems);
1475             }
1476 
1477             Model parentModel = parentData.getModel();
1478             if (!"pom".equals(parentModel.getPackaging())) {
1479                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1480                         .setMessage("Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint(parentModel)
1481                                 + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"")
1482                         .setLocation(parentModel.getLocation("packaging")));
1483             }
1484         }
1485 
1486         return parentData;
1487     }
1488 
1489     private ModelData readParentLocally(
1490             Model childModel, Source childSource, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1491             throws ModelBuildingException {
1492         final Parent parent = childModel.getParent();
1493         final ModelSource2 candidateSource;
1494         final Model candidateModel;
1495         final WorkspaceModelResolver resolver = request.getWorkspaceModelResolver();
1496         if (resolver == null) {
1497             candidateSource = getParentPomFile(childModel, childSource);
1498 
1499             if (candidateSource == null) {
1500                 return null;
1501             }
1502 
1503             ModelBuildingRequest candidateBuildRequest =
1504                     new DefaultModelBuildingRequest(request).setModelSource(candidateSource);
1505 
1506             candidateModel = readRawModel(candidateBuildRequest, problems);
1507         } else {
1508             try {
1509                 candidateModel =
1510                         resolver.resolveRawModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
1511             } catch (UnresolvableModelException e) {
1512                 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE) //
1513                         .setMessage(e.getMessage())
1514                         .setLocation(parent.getLocation(""))
1515                         .setException(e));
1516                 throw problems.newModelBuildingException();
1517             }
1518             if (candidateModel == null) {
1519                 return null;
1520             }
1521             candidateSource = new FileModelSource(candidateModel.getPomPath());
1522         }
1523 
1524         //
1525         // TODO jvz Why isn't all this checking the job of the duty of the workspace resolver, we know that we
1526         // have a model that is suitable, yet more checks are done here and the one for the version is problematic
1527         // before because with parents as ranges it will never work in this scenario.
1528         //
1529 
1530         String groupId = getGroupId(candidateModel);
1531         String artifactId = candidateModel.getArtifactId();
1532 
1533         if (groupId == null
1534                 || !groupId.equals(parent.getGroupId())
1535                 || artifactId == null
1536                 || !artifactId.equals(parent.getArtifactId())) {
1537             StringBuilder buffer = new StringBuilder(256);
1538             buffer.append("'parent.relativePath'");
1539             if (childModel != problems.getRootModel()) {
1540                 buffer.append(" of POM ").append(ModelProblemUtils.toSourceHint(childModel));
1541             }
1542             buffer.append(" points at ").append(groupId).append(':').append(artifactId);
1543             buffer.append(" instead of ").append(parent.getGroupId()).append(':');
1544             buffer.append(parent.getArtifactId()).append(", please verify your project structure");
1545 
1546             problems.setSource(childModel);
1547             problems.add(new ModelProblemCollectorRequest(Severity.WARNING, ModelProblem.Version.BASE)
1548                     .setMessage(buffer.toString())
1549                     .setLocation(parent.getLocation("")));
1550             return null;
1551         }
1552 
1553         String version = getVersion(candidateModel);
1554         if (version != null && parent.getVersion() != null && !version.equals(parent.getVersion())) {
1555             try {
1556                 VersionRange parentRange = versionParser.parseVersionRange(parent.getVersion());
1557                 if (!parentRange.contains(versionParser.parseVersion(version))) {
1558                     // version skew drop back to resolution from the repository
1559                     return null;
1560                 }
1561 
1562                 // Validate versions aren't inherited when using parent ranges the same way as when read externally.
1563                 String rawChildModelVersion = childModel.getVersion();
1564 
1565                 if (rawChildModelVersion == null) {
1566                     // Message below is checked for in the MNG-2199 core IT.
1567                     problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31)
1568                             .setMessage("Version must be a constant")
1569                             .setLocation(childModel.getLocation("")));
1570 
1571                 } else {
1572                     if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1573                         // Message below is checked for in the MNG-2199 core IT.
1574                         problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31)
1575                                 .setMessage("Version must be a constant")
1576                                 .setLocation(childModel.getLocation("version")));
1577                     }
1578                 }
1579 
1580                 // MNG-2199: What else to check here ?
1581             } catch (VersionParserException e) {
1582                 // invalid version range, so drop back to resolution from the repository
1583                 return null;
1584             }
1585         }
1586 
1587         //
1588         // Here we just need to know that a version is fine to use but this validation we can do in our workspace
1589         // resolver.
1590         //
1591 
1592         /*
1593          * if ( version == null || !version.equals( parent.getVersion() ) ) { return null; }
1594          */
1595 
1596         return new ModelData(candidateSource, candidateModel, groupId, artifactId, version);
1597     }
1598 
1599     private boolean rawChildVersionReferencesParent(String rawChildModelVersion) {
1600         return rawChildModelVersion.equals("${pom.version}")
1601                 || rawChildModelVersion.equals("${project.version}")
1602                 || rawChildModelVersion.equals("${pom.parent.version}")
1603                 || rawChildModelVersion.equals("${project.parent.version}");
1604     }
1605 
1606     private ModelSource2 getParentPomFile(Model childModel, Source source) {
1607         if (!(source instanceof ModelSource2)) {
1608             return null;
1609         }
1610 
1611         String parentPath = childModel.getParent().getRelativePath();
1612 
1613         if (parentPath == null || parentPath.isEmpty()) {
1614             return null;
1615         }
1616 
1617         if (source instanceof ModelSource3) {
1618             return ((ModelSource3) source).getRelatedSource(modelProcessor, parentPath);
1619         } else {
1620             return ((ModelSource2) source).getRelatedSource(parentPath);
1621         }
1622     }
1623 
1624     private ModelData readParentExternally(
1625             Model childModel, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1626             throws ModelBuildingException {
1627         problems.setSource(childModel);
1628 
1629         Parent parent = childModel.getParent();
1630 
1631         String groupId = parent.getGroupId();
1632         String artifactId = parent.getArtifactId();
1633         String version = parent.getVersion();
1634 
1635         ModelResolver modelResolver = request.getModelResolver();
1636         Objects.requireNonNull(
1637                 modelResolver,
1638                 String.format(
1639                         "request.modelResolver cannot be null (parent POM %s and POM %s)",
1640                         ModelProblemUtils.toId(groupId, artifactId, version),
1641                         ModelProblemUtils.toSourceHint(childModel)));
1642 
1643         ModelSource modelSource;
1644         try {
1645             modelSource = modelResolver.resolveModel(parent);
1646         } catch (UnresolvableModelException e) {
1647             // Message below is checked for in the MNG-2199 core IT.
1648             StringBuilder buffer = new StringBuilder(256);
1649             buffer.append("Non-resolvable parent POM");
1650             if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1651                 buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1652             }
1653             if (childModel != problems.getRootModel()) {
1654                 buffer.append(" for ").append(ModelProblemUtils.toId(childModel));
1655             }
1656             buffer.append(": ").append(e.getMessage());
1657             if (childModel.getProjectDirectoryPath() != null) {
1658                 if (parent.getRelativePath() == null || parent.getRelativePath().isEmpty()) {
1659                     buffer.append(" and 'parent.relativePath' points at no local POM");
1660                 } else {
1661                     buffer.append(" and 'parent.relativePath' points at wrong local POM");
1662                 }
1663             }
1664 
1665             problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE)
1666                     .setMessage(buffer.toString())
1667                     .setLocation(parent.getLocation(""))
1668                     .setException(e));
1669             throw problems.newModelBuildingException();
1670         }
1671 
1672         int validationLevel = Math.min(request.getValidationLevel(), ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0);
1673         ModelBuildingRequest lenientRequest = new DefaultModelBuildingRequest(request)
1674                 .setValidationLevel(validationLevel)
1675                 .setFileModel(null)
1676                 .setModelSource(modelSource);
1677 
1678         Model parentModel = readRawModel(lenientRequest, problems);
1679 
1680         if (!parent.getVersion().equals(version)) {
1681             String rawChildModelVersion = childModel.getVersion();
1682 
1683             if (rawChildModelVersion == null) {
1684                 // Message below is checked for in the MNG-2199 core IT.
1685                 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31)
1686                         .setMessage("Version must be a constant")
1687                         .setLocation(childModel.getLocation("")));
1688 
1689             } else {
1690                 if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1691                     // Message below is checked for in the MNG-2199 core IT.
1692                     problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31)
1693                             .setMessage("Version must be a constant")
1694                             .setLocation(childModel.getLocation("version")));
1695                 }
1696             }
1697 
1698             // MNG-2199: What else to check here ?
1699         }
1700 
1701         return new ModelData(
1702                 modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
1703     }
1704 
1705     private Model getSuperModel(String modelVersion) {
1706         return superPomProvider.getSuperModel(modelVersion);
1707     }
1708 
1709     private void importDependencyManagement(
1710             Model model,
1711             ModelBuildingRequest request,
1712             DefaultModelProblemCollector problems,
1713             Collection<String> importIds) {
1714         DependencyManagement depMgmt = model.getDependencyManagement();
1715 
1716         if (depMgmt == null) {
1717             return;
1718         }
1719 
1720         String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
1721 
1722         importIds.add(importing);
1723 
1724         List<org.apache.maven.api.model.DependencyManagement> importMgmts = null;
1725 
1726         for (Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); ) {
1727             Dependency dependency = it.next();
1728 
1729             if (!("pom".equals(dependency.getType()) && "import".equals(dependency.getScope()))
1730                     || "bom".equals(dependency.getType())) {
1731                 continue;
1732             }
1733 
1734             it.remove();
1735 
1736             DependencyManagement importMgmt = loadDependencyManagement(model, request, problems, dependency, importIds);
1737 
1738             if (importMgmt != null) {
1739                 if (importMgmts == null) {
1740                     importMgmts = new ArrayList<>();
1741                 }
1742 
1743                 importMgmts.add(importMgmt.getDelegate());
1744             }
1745         }
1746 
1747         importIds.remove(importing);
1748 
1749         model.update(
1750                 dependencyManagementImporter.importManagement(model.getDelegate(), importMgmts, request, problems));
1751     }
1752 
1753     private DependencyManagement loadDependencyManagement(
1754             Model model,
1755             ModelBuildingRequest request,
1756             DefaultModelProblemCollector problems,
1757             Dependency dependency,
1758             Collection<String> importIds) {
1759         String groupId = dependency.getGroupId();
1760         String artifactId = dependency.getArtifactId();
1761         String version = dependency.getVersion();
1762 
1763         if (groupId == null || groupId.isEmpty()) {
1764             problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1765                     .setMessage("'dependencyManagement.dependencies.dependency.groupId' for "
1766                             + dependency.getManagementKey() + " is missing.")
1767                     .setLocation(dependency.getLocation("")));
1768             return null;
1769         }
1770         if (artifactId == null || artifactId.isEmpty()) {
1771             problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1772                     .setMessage("'dependencyManagement.dependencies.dependency.artifactId' for "
1773                             + dependency.getManagementKey() + " is missing.")
1774                     .setLocation(dependency.getLocation("")));
1775             return null;
1776         }
1777         if (version == null || version.isEmpty()) {
1778             problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1779                     .setMessage("'dependencyManagement.dependencies.dependency.version' for "
1780                             + dependency.getManagementKey() + " is missing.")
1781                     .setLocation(dependency.getLocation("")));
1782             return null;
1783         }
1784 
1785         String imported = groupId + ':' + artifactId + ':' + version;
1786 
1787         if (importIds.contains(imported)) {
1788             StringBuilder message =
1789                     new StringBuilder("The dependencies of type=pom and with scope=import form a cycle: ");
1790             for (String modelId : importIds) {
1791                 message.append(modelId).append(" -> ");
1792             }
1793             message.append(imported);
1794             problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1795                     .setMessage(message.toString()));
1796 
1797             return null;
1798         }
1799 
1800         org.apache.maven.api.model.DependencyManagement importMgmt = cache(
1801                 request.getModelCache(),
1802                 groupId,
1803                 artifactId,
1804                 version,
1805                 ModelCacheTag.IMPORT,
1806                 () -> doLoadDependencyManagement(
1807                         model, request, problems, dependency, groupId, artifactId, version, importIds));
1808 
1809         // [MNG-5600] Dependency management import should support exclusions.
1810         List<Exclusion> exclusions = dependency.getDelegate().getExclusions();
1811         if (importMgmt != null && !exclusions.isEmpty()) {
1812             // Dependency excluded from import.
1813             List<org.apache.maven.api.model.Dependency> dependencies = importMgmt.getDependencies().stream()
1814                     .filter(candidate -> exclusions.stream().noneMatch(exclusion -> match(exclusion, candidate)))
1815                     .map(candidate -> addExclusions(candidate, exclusions))
1816                     .collect(Collectors.toList());
1817             importMgmt = importMgmt.withDependencies(dependencies);
1818         }
1819 
1820         return importMgmt != null ? new DependencyManagement(importMgmt) : null;
1821     }
1822 
1823     private static org.apache.maven.api.model.Dependency addExclusions(
1824             org.apache.maven.api.model.Dependency candidate, List<Exclusion> exclusions) {
1825         return candidate.withExclusions(Stream.concat(candidate.getExclusions().stream(), exclusions.stream())
1826                 .toList());
1827     }
1828 
1829     private boolean match(Exclusion exclusion, org.apache.maven.api.model.Dependency candidate) {
1830         return match(exclusion.getGroupId(), candidate.getGroupId())
1831                 && match(exclusion.getArtifactId(), candidate.getArtifactId());
1832     }
1833 
1834     private boolean match(String match, String text) {
1835         return match.equals("*") || match.equals(text);
1836     }
1837 
1838     @SuppressWarnings("checkstyle:parameternumber")
1839     private org.apache.maven.api.model.DependencyManagement doLoadDependencyManagement(
1840             Model model,
1841             ModelBuildingRequest request,
1842             DefaultModelProblemCollector problems,
1843             Dependency dependency,
1844             String groupId,
1845             String artifactId,
1846             String version,
1847             Collection<String> importIds) {
1848         DependencyManagement importMgmt;
1849         final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
1850         final ModelResolver modelResolver = request.getModelResolver();
1851         if (workspaceResolver == null && modelResolver == null) {
1852             throw new NullPointerException(String.format(
1853                     "request.workspaceModelResolver and request.modelResolver cannot be null (parent POM %s and POM %s)",
1854                     ModelProblemUtils.toId(groupId, artifactId, version), ModelProblemUtils.toSourceHint(model)));
1855         }
1856 
1857         Model importModel = null;
1858         if (workspaceResolver != null) {
1859             try {
1860                 importModel = workspaceResolver.resolveEffectiveModel(groupId, artifactId, version);
1861             } catch (UnresolvableModelException e) {
1862                 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE)
1863                         .setMessage(e.getMessage())
1864                         .setException(e));
1865                 return null;
1866             }
1867         }
1868 
1869         // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
1870         if (importModel == null) {
1871             final ModelSource importSource;
1872             try {
1873                 importSource = modelResolver.resolveModel(dependency);
1874             } catch (UnresolvableModelException e) {
1875                 StringBuilder buffer = new StringBuilder(256);
1876                 buffer.append("Non-resolvable import POM");
1877                 if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1878                     buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1879                 }
1880                 buffer.append(": ").append(e.getMessage());
1881 
1882                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE)
1883                         .setMessage(buffer.toString())
1884                         .setLocation(dependency.getLocation(""))
1885                         .setException(e));
1886                 return null;
1887             }
1888 
1889             if (importSource instanceof FileModelSource && request.getRootDirectory() != null) {
1890                 Path sourcePath = ((FileModelSource) importSource).getPath();
1891                 if (sourcePath.startsWith(request.getRootDirectory())) {
1892                     problems.add(new ModelProblemCollectorRequest(Severity.WARNING, ModelProblem.Version.BASE)
1893                             .setMessage("BOM imports from within reactor should be avoided")
1894                             .setLocation(dependency.getLocation("")));
1895                 }
1896             }
1897 
1898             final ModelBuildingResult importResult;
1899             try {
1900                 ModelBuildingRequest importRequest = new DefaultModelBuildingRequest();
1901                 importRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
1902                 importRequest.setModelCache(request.getModelCache());
1903                 importRequest.setSystemProperties(request.getSystemProperties());
1904                 importRequest.setUserProperties(request.getUserProperties());
1905                 importRequest.setLocationTracking(request.isLocationTracking());
1906 
1907                 importRequest.setModelSource(importSource);
1908                 importRequest.setModelResolver(modelResolver.newCopy());
1909 
1910                 importResult = build(importRequest, importIds);
1911             } catch (ModelBuildingException e) {
1912                 problems.addAll(e.getProblems());
1913                 return null;
1914             }
1915 
1916             problems.addAll(importResult.getProblems());
1917 
1918             importModel = importResult.getEffectiveModel();
1919         }
1920 
1921         importMgmt = importModel.getDependencyManagement();
1922 
1923         if (importMgmt == null) {
1924             importMgmt = new DependencyManagement();
1925         }
1926         return importMgmt.getDelegate();
1927     }
1928 
1929     private static <T> T cache(
1930             ModelCache cache,
1931             String groupId,
1932             String artifactId,
1933             String version,
1934             ModelCacheTag<T> tag,
1935             Callable<T> supplier) {
1936         Supplier<T> s = asSupplier(supplier);
1937         if (cache == null) {
1938             return s.get();
1939         } else {
1940             return cache.computeIfAbsent(groupId, artifactId, version, tag.getName(), s);
1941         }
1942     }
1943 
1944     private static <T> T cache(ModelCache cache, Source source, ModelCacheTag<T> tag, Callable<T> supplier) {
1945         Supplier<T> s = asSupplier(supplier);
1946         if (cache == null) {
1947             return s.get();
1948         } else {
1949             return cache.computeIfAbsent(source, tag.getName(), s);
1950         }
1951     }
1952 
1953     private static <T> Supplier<T> asSupplier(Callable<T> supplier) {
1954         return () -> {
1955             try {
1956                 return supplier.call();
1957             } catch (Exception e) {
1958                 uncheckedThrow(e);
1959                 return null;
1960             }
1961         };
1962     }
1963 
1964     static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
1965         throw (T) t; // rely on vacuous cast
1966     }
1967 
1968     private void fireEvent(
1969             Model model,
1970             ModelBuildingRequest request,
1971             ModelProblemCollector problems,
1972             ModelBuildingEventCatapult catapult) {
1973         ModelBuildingListener listener = request.getModelBuildingListener();
1974 
1975         if (listener != null) {
1976             ModelBuildingEvent event = new DefaultModelBuildingEvent(model, request, problems);
1977 
1978             catapult.fire(listener, event);
1979         }
1980     }
1981 
1982     private boolean containsCoordinates(String message, String groupId, String artifactId, String version) {
1983         return message != null
1984                 && (groupId == null || message.contains(groupId))
1985                 && (artifactId == null || message.contains(artifactId))
1986                 && (version == null || message.contains(version));
1987     }
1988 
1989     protected boolean hasModelErrors(ModelProblemCollectorExt problems) {
1990         if (problems instanceof DefaultModelProblemCollector) {
1991             return ((DefaultModelProblemCollector) problems).hasErrors();
1992         } else {
1993             // the default execution path only knows the DefaultModelProblemCollector,
1994             // only reason it's not in signature is because it's package private
1995             throw new IllegalStateException();
1996         }
1997     }
1998 
1999     protected boolean hasFatalErrors(ModelProblemCollectorExt problems) {
2000         if (problems instanceof DefaultModelProblemCollector) {
2001             return ((DefaultModelProblemCollector) problems).hasFatalErrors();
2002         } else {
2003             // the default execution path only knows the DefaultModelProblemCollector,
2004             // only reason it's not in signature is because it's package private
2005             throw new IllegalStateException();
2006         }
2007     }
2008 
2009     ModelProcessor getModelProcessor() {
2010         return modelProcessor;
2011     }
2012 }