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