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