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