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