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