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.util.ArrayList;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.LinkedHashSet;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Objects;
36  import java.util.Optional;
37  import java.util.Properties;
38  import java.util.function.Consumer;
39  import java.util.stream.IntStream;
40  
41  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
42  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
43  import org.apache.maven.artifact.versioning.VersionRange;
44  import org.apache.maven.model.Activation;
45  import org.apache.maven.model.Build;
46  import org.apache.maven.model.Dependency;
47  import org.apache.maven.model.DependencyManagement;
48  import org.apache.maven.model.InputLocation;
49  import org.apache.maven.model.InputLocationTracker;
50  import org.apache.maven.model.InputSource;
51  import org.apache.maven.model.Model;
52  import org.apache.maven.model.Parent;
53  import org.apache.maven.model.Plugin;
54  import org.apache.maven.model.PluginManagement;
55  import org.apache.maven.model.Profile;
56  import org.apache.maven.model.Repository;
57  import org.apache.maven.model.building.ModelProblem.Severity;
58  import org.apache.maven.model.building.ModelProblem.Version;
59  import org.apache.maven.model.composition.DependencyManagementImporter;
60  import org.apache.maven.model.inheritance.InheritanceAssembler;
61  import org.apache.maven.model.interpolation.ModelInterpolator;
62  import org.apache.maven.model.io.ModelParseException;
63  import org.apache.maven.model.management.DependencyManagementInjector;
64  import org.apache.maven.model.management.PluginManagementInjector;
65  import org.apache.maven.model.normalization.ModelNormalizer;
66  import org.apache.maven.model.path.ModelPathTranslator;
67  import org.apache.maven.model.path.ModelUrlNormalizer;
68  import org.apache.maven.model.path.ProfileActivationFilePathInterpolator;
69  import org.apache.maven.model.plugin.LifecycleBindingsInjector;
70  import org.apache.maven.model.plugin.PluginConfigurationExpander;
71  import org.apache.maven.model.plugin.ReportConfigurationExpander;
72  import org.apache.maven.model.plugin.ReportingConverter;
73  import org.apache.maven.model.profile.DefaultProfileActivationContext;
74  import org.apache.maven.model.profile.ProfileActivationContext;
75  import org.apache.maven.model.profile.ProfileInjector;
76  import org.apache.maven.model.profile.ProfileSelector;
77  import org.apache.maven.model.resolution.InvalidRepositoryException;
78  import org.apache.maven.model.resolution.ModelResolver;
79  import org.apache.maven.model.resolution.UnresolvableModelException;
80  import org.apache.maven.model.resolution.WorkspaceModelResolver;
81  import org.apache.maven.model.superpom.SuperPomProvider;
82  import org.apache.maven.model.validation.ModelValidator;
83  import org.codehaus.plexus.interpolation.InterpolationException;
84  import org.codehaus.plexus.interpolation.MapBasedValueSource;
85  import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
86  import org.codehaus.plexus.interpolation.StringSearchInterpolator;
87  import org.codehaus.plexus.util.StringUtils;
88  import org.eclipse.sisu.Nullable;
89  
90  import static org.apache.maven.model.building.Result.error;
91  import static org.apache.maven.model.building.Result.newResult;
92  
93  /**
94   * @deprecated use {@code org.apache.maven.api.services.ModelBuilder} instead
95   */
96  @SuppressWarnings("UnusedReturnValue")
97  @Named
98  @Singleton
99  @Deprecated(since = "4.0.0")
100 public class DefaultModelBuilder implements ModelBuilder {
101     @Inject
102     private ModelProcessor modelProcessor;
103 
104     @Inject
105     private ModelValidator modelValidator;
106 
107     @Inject
108     private ModelNormalizer modelNormalizer;
109 
110     @Inject
111     private ModelInterpolator modelInterpolator;
112 
113     @Inject
114     private ModelPathTranslator modelPathTranslator;
115 
116     @Inject
117     private ModelUrlNormalizer modelUrlNormalizer;
118 
119     @Inject
120     private SuperPomProvider superPomProvider;
121 
122     @Inject
123     private InheritanceAssembler inheritanceAssembler;
124 
125     @Inject
126     private ProfileSelector profileSelector;
127 
128     @Inject
129     private ProfileInjector profileInjector;
130 
131     @Inject
132     private PluginManagementInjector pluginManagementInjector;
133 
134     @Inject
135     private DependencyManagementInjector dependencyManagementInjector;
136 
137     @Inject
138     private DependencyManagementImporter dependencyManagementImporter;
139 
140     @Inject
141     @Nullable
142     private LifecycleBindingsInjector lifecycleBindingsInjector;
143 
144     @Inject
145     private PluginConfigurationExpander pluginConfigurationExpander;
146 
147     @Inject
148     private ReportConfigurationExpander reportConfigurationExpander;
149 
150     @Inject
151     private ReportingConverter reportingConverter;
152 
153     @Inject
154     private ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
155 
156     public DefaultModelBuilder setModelProcessor(ModelProcessor modelProcessor) {
157         this.modelProcessor = modelProcessor;
158         return this;
159     }
160 
161     public DefaultModelBuilder setModelValidator(ModelValidator modelValidator) {
162         this.modelValidator = modelValidator;
163         return this;
164     }
165 
166     public DefaultModelBuilder setModelNormalizer(ModelNormalizer modelNormalizer) {
167         this.modelNormalizer = modelNormalizer;
168         return this;
169     }
170 
171     public DefaultModelBuilder setModelInterpolator(ModelInterpolator modelInterpolator) {
172         this.modelInterpolator = modelInterpolator;
173         return this;
174     }
175 
176     public DefaultModelBuilder setModelPathTranslator(ModelPathTranslator modelPathTranslator) {
177         this.modelPathTranslator = modelPathTranslator;
178         return this;
179     }
180 
181     public DefaultModelBuilder setModelUrlNormalizer(ModelUrlNormalizer modelUrlNormalizer) {
182         this.modelUrlNormalizer = modelUrlNormalizer;
183         return this;
184     }
185 
186     public DefaultModelBuilder setSuperPomProvider(SuperPomProvider superPomProvider) {
187         this.superPomProvider = superPomProvider;
188         return this;
189     }
190 
191     public DefaultModelBuilder setProfileSelector(ProfileSelector profileSelector) {
192         this.profileSelector = profileSelector;
193         return this;
194     }
195 
196     public DefaultModelBuilder setProfileInjector(ProfileInjector profileInjector) {
197         this.profileInjector = profileInjector;
198         return this;
199     }
200 
201     public DefaultModelBuilder setInheritanceAssembler(InheritanceAssembler inheritanceAssembler) {
202         this.inheritanceAssembler = inheritanceAssembler;
203         return this;
204     }
205 
206     public DefaultModelBuilder setDependencyManagementImporter(DependencyManagementImporter depMgmtImporter) {
207         this.dependencyManagementImporter = depMgmtImporter;
208         return this;
209     }
210 
211     public DefaultModelBuilder setDependencyManagementInjector(DependencyManagementInjector depMgmtInjector) {
212         this.dependencyManagementInjector = depMgmtInjector;
213         return this;
214     }
215 
216     public DefaultModelBuilder setLifecycleBindingsInjector(LifecycleBindingsInjector lifecycleBindingsInjector) {
217         this.lifecycleBindingsInjector = lifecycleBindingsInjector;
218         return this;
219     }
220 
221     public DefaultModelBuilder setPluginConfigurationExpander(PluginConfigurationExpander pluginConfigurationExpander) {
222         this.pluginConfigurationExpander = pluginConfigurationExpander;
223         return this;
224     }
225 
226     public DefaultModelBuilder setPluginManagementInjector(PluginManagementInjector pluginManagementInjector) {
227         this.pluginManagementInjector = pluginManagementInjector;
228         return this;
229     }
230 
231     public DefaultModelBuilder setReportConfigurationExpander(ReportConfigurationExpander reportConfigurationExpander) {
232         this.reportConfigurationExpander = reportConfigurationExpander;
233         return this;
234     }
235 
236     public DefaultModelBuilder setReportingConverter(ReportingConverter reportingConverter) {
237         this.reportingConverter = reportingConverter;
238         return this;
239     }
240 
241     public DefaultModelBuilder setProfileActivationFilePathInterpolator(
242             ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) {
243         this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator;
244         return this;
245     }
246 
247     @SuppressWarnings("checkstyle:methodlength")
248     @Override
249     public ModelBuildingResult build(ModelBuildingRequest request) throws ModelBuildingException {
250         return build(request, new LinkedHashSet<>());
251     }
252 
253     @SuppressWarnings("checkstyle:methodlength")
254     protected ModelBuildingResult build(ModelBuildingRequest request, Collection<String> importIds)
255             throws ModelBuildingException {
256         // phase 1
257         DefaultModelBuildingResult result = new DefaultModelBuildingResult();
258 
259         DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
260 
261         // read and validate raw model
262         Model inputModel = request.getRawModel();
263         if (inputModel == null) {
264             inputModel = readModel(request.getModelSource(), request.getPomFile(), request, problems);
265         }
266 
267         // profile activation
268         DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request, inputModel);
269 
270         problems.setSource("(external profiles)");
271         List<Profile> activeExternalProfiles =
272                 profileSelector.getActiveProfiles(request.getProfiles(), profileActivationContext, problems);
273 
274         result.setActiveExternalProfiles(activeExternalProfiles);
275 
276         if (!activeExternalProfiles.isEmpty()) {
277             Properties profileProps = new Properties();
278             for (Profile profile : activeExternalProfiles) {
279                 profileProps.putAll(profile.getProperties());
280             }
281             profileProps.putAll(profileActivationContext.getUserProperties());
282             profileActivationContext.setUserProperties(profileProps);
283         }
284 
285         problems.setRootModel(inputModel);
286 
287         ModelData resultData = new ModelData(request.getModelSource(), inputModel);
288         ModelData superData = new ModelData(null, getSuperModel());
289 
290         Collection<String> parentIds = new LinkedHashSet<>();
291         List<ModelData> lineage = new ArrayList<>();
292 
293         for (ModelData currentData = resultData; currentData != null; ) {
294             lineage.add(currentData);
295 
296             Model rawModel = currentData.getModel();
297             currentData.setRawModel(rawModel);
298 
299             Model tmpModel = rawModel.clone();
300             currentData.setModel(tmpModel);
301 
302             problems.setSource(tmpModel);
303 
304             // model normalization
305             modelNormalizer.mergeDuplicates(tmpModel, request, problems);
306 
307             profileActivationContext.setProjectProperties(tmpModel.getProperties());
308 
309             List<Profile> interpolatedProfiles = getInterpolatedProfiles(rawModel, profileActivationContext, problems);
310             tmpModel.setProfiles(interpolatedProfiles);
311 
312             List<Profile> activePomProfiles =
313                     profileSelector.getActiveProfiles(tmpModel.getProfiles(), profileActivationContext, problems);
314 
315             List<Profile> rawProfiles = new ArrayList<>();
316             for (Profile activePomProfile : activePomProfiles) {
317                 rawProfiles.add(rawModel.getProfiles().get(interpolatedProfiles.indexOf(activePomProfile)));
318             }
319             currentData.setActiveProfiles(rawProfiles);
320 
321             // profile injection
322             for (Profile activeProfile : activePomProfiles) {
323                 profileInjector.injectProfile(tmpModel, activeProfile, request, problems);
324             }
325 
326             if (currentData == resultData) {
327                 for (Profile activeProfile : activeExternalProfiles) {
328                     profileInjector.injectProfile(tmpModel, activeProfile, request, problems);
329                 }
330             }
331 
332             if (currentData == superData) {
333                 break;
334             }
335 
336             configureResolver(request.getModelResolver(), tmpModel, problems);
337 
338             ModelData parentData = readParent(tmpModel, currentData.getSource(), request, problems);
339 
340             if (parentData == null) {
341                 currentData = superData;
342             } else if (currentData == resultData) { // First iteration - add initial id after version resolution.
343                 currentData.setGroupId(
344                         currentData.getRawModel().getGroupId() == null
345                                 ? parentData.getGroupId()
346                                 : currentData.getRawModel().getGroupId());
347 
348                 currentData.setVersion(
349                         currentData.getRawModel().getVersion() == null
350                                 ? parentData.getVersion()
351                                 : currentData.getRawModel().getVersion());
352 
353                 currentData.setArtifactId(currentData.getRawModel().getArtifactId());
354                 parentIds.add(currentData.getId());
355                 // Reset - only needed for 'getId'.
356                 currentData.setGroupId(null);
357                 currentData.setArtifactId(null);
358                 currentData.setVersion(null);
359                 currentData = parentData;
360             } else if (!parentIds.add(parentData.getId())) {
361                 StringBuilder message = new StringBuilder("The parents form a cycle: ");
362                 for (String modelId : parentIds) {
363                     message.append(modelId);
364                     message.append(" -> ");
365                 }
366                 message.append(parentData.getId());
367 
368                 problems.add(new ModelProblemCollectorRequest(ModelProblem.Severity.FATAL, ModelProblem.Version.BASE)
369                         .setMessage(message.toString()));
370 
371                 throw problems.newModelBuildingException();
372             } else {
373                 currentData = parentData;
374             }
375         }
376 
377         problems.setSource(inputModel);
378         checkPluginVersions(lineage, request, problems);
379 
380         // inheritance assembly
381         assembleInheritance(lineage, request, problems);
382 
383         Model resultModel = resultData.getModel();
384 
385         problems.setSource(resultModel);
386         problems.setRootModel(resultModel);
387 
388         // model interpolation
389         resultModel = interpolateModel(resultModel, request, problems);
390         resultData.setModel(resultModel);
391 
392         if (resultModel.getParent() != null) {
393             final ModelData parentData = lineage.get(1);
394             if (parentData.getVersion() == null || parentData.getVersion().contains("${")) {
395                 final Model interpolatedParent = interpolateModel(parentData.getModel(), request, problems);
396                 // parentData.setModel( interpolatedParent );
397                 parentData.setVersion(interpolatedParent.getVersion());
398             }
399         }
400 
401         // url normalization
402         modelUrlNormalizer.normalize(resultModel, request);
403 
404         // Now the fully interpolated model is available: reconfigure the resolver
405         configureResolver(request.getModelResolver(), resultModel, problems, true);
406 
407         resultData.setGroupId(resultModel.getGroupId());
408         resultData.setArtifactId(resultModel.getArtifactId());
409         resultData.setVersion(resultModel.getVersion());
410 
411         result.setEffectiveModel(resultModel);
412 
413         for (ModelData currentData : lineage) {
414             String modelId = (currentData != superData) ? currentData.getId() : "";
415 
416             result.addModelId(modelId);
417             result.setActivePomProfiles(modelId, currentData.getActiveProfiles());
418             result.setRawModel(modelId, currentData.getRawModel());
419         }
420 
421         if (!request.isTwoPhaseBuilding()) {
422             build(request, result, importIds);
423         }
424 
425         return result;
426     }
427 
428     @FunctionalInterface
429     private interface InterpolateString {
430         String apply(String s) throws InterpolationException;
431     }
432 
433     private List<Profile> getInterpolatedProfiles(
434             Model rawModel, DefaultProfileActivationContext context, DefaultModelProblemCollector problems) {
435         List<Profile> interpolatedActivations = getProfiles(rawModel);
436 
437         if (interpolatedActivations.isEmpty()) {
438             return Collections.emptyList();
439         }
440         RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
441 
442         interpolator.addValueSource(new MapBasedValueSource(context.getProjectProperties()));
443         interpolator.addValueSource(new MapBasedValueSource(context.getUserProperties()));
444         interpolator.addValueSource(new MapBasedValueSource(context.getSystemProperties()));
445 
446         class Interpolation {
447             final InputLocationTracker target;
448 
449             final InterpolateString impl;
450 
451             Interpolation(InputLocationTracker target, InterpolateString impl) {
452                 this.target = target;
453                 this.impl = impl;
454             }
455 
456             void performFor(String value, String locationKey, Consumer<String> mutator) {
457                 if (StringUtils.isEmpty(value)) {
458                     return;
459                 }
460                 try {
461                     mutator.accept(impl.apply(value));
462                 } catch (InterpolationException e) {
463                     problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
464                             .setMessage("Failed to interpolate value " + value + ": " + e.getMessage())
465                             .setLocation(target.getLocation(locationKey))
466                             .setException(e));
467                 }
468             }
469         }
470         for (Profile profile : interpolatedActivations) {
471             Activation activation = profile.getActivation();
472             Optional<Activation> a = Optional.ofNullable(activation);
473             a.map(Activation::getFile).ifPresent(fa -> {
474                 Interpolation nt =
475                         new Interpolation(fa, s -> profileActivationFilePathInterpolator.interpolate(s, context));
476                 nt.performFor(fa.getExists(), "exists", fa::setExists);
477                 nt.performFor(fa.getMissing(), "missing", fa::setMissing);
478             });
479             a.map(Activation::getOs).ifPresent(oa -> {
480                 Interpolation nt = new Interpolation(oa, interpolator::interpolate);
481                 nt.performFor(oa.getArch(), "arch", oa::setArch);
482                 nt.performFor(oa.getFamily(), "family", oa::setFamily);
483                 nt.performFor(oa.getName(), "name", oa::setName);
484                 nt.performFor(oa.getVersion(), "version", oa::setVersion);
485             });
486             a.map(Activation::getProperty).ifPresent(pa -> {
487                 Interpolation nt = new Interpolation(pa, interpolator::interpolate);
488                 nt.performFor(pa.getName(), "name", pa::setName);
489                 nt.performFor(pa.getValue(), "value", pa::setValue);
490             });
491             a.map(Activation::getJdk).ifPresent(ja -> new Interpolation(activation, interpolator::interpolate)
492                     .performFor(ja, "jdk", activation::setJdk));
493         }
494         return interpolatedActivations;
495     }
496 
497     @Override
498     public ModelBuildingResult build(ModelBuildingRequest request, ModelBuildingResult result)
499             throws ModelBuildingException {
500         return build(request, result, new LinkedHashSet());
501     }
502 
503     private ModelBuildingResult build(
504             ModelBuildingRequest request, ModelBuildingResult result, Collection<String> imports)
505             throws ModelBuildingException {
506         // phase 2
507         Model resultModel = result.getEffectiveModel();
508 
509         DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result);
510         problems.setSource(resultModel);
511         problems.setRootModel(resultModel);
512 
513         // model path translation
514         modelPathTranslator.alignToBaseDirectory(resultModel, resultModel.getProjectDirectory(), request);
515 
516         // plugin management injection
517         pluginManagementInjector.injectManagement(resultModel, request, problems);
518 
519         fireEvent(resultModel, request, problems, ModelBuildingEventCatapult.BUILD_EXTENSIONS_ASSEMBLED);
520 
521         if (request.isProcessPlugins()) {
522             if (lifecycleBindingsInjector == null) {
523                 throw new IllegalStateException("lifecycle bindings injector is missing");
524             }
525 
526             // lifecycle bindings injection
527             lifecycleBindingsInjector.injectLifecycleBindings(resultModel, request, problems);
528         }
529 
530         // dependency management import
531         importDependencyManagement(resultModel, request, problems, imports);
532 
533         // dependency management injection
534         dependencyManagementInjector.injectManagement(resultModel, request, problems);
535 
536         modelNormalizer.injectDefaultValues(resultModel, request, problems);
537 
538         if (request.isProcessPlugins()) {
539             // reports configuration
540             reportConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
541 
542             // reports conversion to decoupled site plugin
543             reportingConverter.convertReporting(resultModel, request, problems);
544 
545             // plugins configuration
546             pluginConfigurationExpander.expandPluginConfiguration(resultModel, request, problems);
547         }
548 
549         // effective model validation
550         modelValidator.validateEffectiveModel(resultModel, request, problems);
551 
552         if (hasModelErrors(problems)) {
553             throw problems.newModelBuildingException();
554         }
555 
556         return result;
557     }
558 
559     @Override
560     public Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking) {
561         final ModelBuildingRequest request = new DefaultModelBuildingRequest()
562                 .setValidationLevel(validationLevel)
563                 .setLocationTracking(locationTracking);
564         final DefaultModelProblemCollector collector =
565                 new DefaultModelProblemCollector(new DefaultModelBuildingResult());
566         try {
567             return newResult(readModel(null, pomFile, request, collector), collector.getProblems());
568         } catch (ModelBuildingException e) {
569             return error(collector.getProblems());
570         }
571     }
572 
573     private Model readModel(
574             ModelSource modelSource, File pomFile, ModelBuildingRequest request, DefaultModelProblemCollector problems)
575             throws ModelBuildingException {
576         Model model;
577 
578         if (modelSource == null) {
579             if (pomFile != null) {
580                 modelSource = new FileModelSource(pomFile);
581             } else {
582                 throw new NullPointerException("neither pomFile nor modelSource can be null");
583             }
584         }
585 
586         problems.setSource(modelSource.getLocation());
587         try {
588             boolean strict = request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
589             InputSource source = request.isLocationTracking() ? new InputSource() : null;
590 
591             Map<String, Object> options = new HashMap<>();
592             options.put(ModelProcessor.IS_STRICT, strict);
593             options.put(ModelProcessor.INPUT_SOURCE, source);
594             options.put(ModelProcessor.SOURCE, modelSource);
595 
596             try {
597                 model = modelProcessor.read(modelSource.getInputStream(), options);
598             } catch (ModelParseException e) {
599                 if (!strict) {
600                     throw e;
601                 }
602 
603                 options.put(ModelProcessor.IS_STRICT, Boolean.FALSE);
604 
605                 try {
606                     model = modelProcessor.read(modelSource.getInputStream(), options);
607                 } catch (ModelParseException ne) {
608                     // still unreadable even in non-strict mode, rethrow original error
609                     throw e;
610                 }
611 
612                 if (pomFile != null) {
613                     problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.V20)
614                             .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage())
615                             .setException(e));
616                 } else {
617                     problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.V20)
618                             .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage())
619                             .setException(e));
620                 }
621             }
622 
623             if (source != null) {
624                 source.setModelId(ModelProblemUtils.toId(model));
625                 source.setLocation(modelSource.getLocation());
626             }
627         } catch (ModelParseException e) {
628             problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
629                     .setMessage("Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage())
630                     .setException(e));
631             throw problems.newModelBuildingException();
632         } catch (IOException e) {
633             String msg = e.getMessage();
634             if (msg == null || msg.length() <= 0) {
635                 // NOTE: There's java.nio.charset.MalformedInputException and sun.io.MalformedInputException
636                 if (e.getClass().getName().endsWith("MalformedInputException")) {
637                     msg = "Some input bytes do not match the file encoding.";
638                 } else {
639                     msg = e.getClass().getSimpleName();
640                 }
641             }
642             problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
643                     .setMessage("Non-readable POM " + modelSource.getLocation() + ": " + msg)
644                     .setException(e));
645             throw problems.newModelBuildingException();
646         }
647 
648         model.setPomFile(pomFile);
649 
650         problems.setSource(model);
651         modelValidator.validateRawModel(model, request, problems);
652 
653         if (hasFatalErrors(problems)) {
654             throw problems.newModelBuildingException();
655         }
656 
657         return model;
658     }
659 
660     private DefaultProfileActivationContext getProfileActivationContext(ModelBuildingRequest request, Model rawModel) {
661         DefaultProfileActivationContext context = new DefaultProfileActivationContext();
662 
663         context.setActiveProfileIds(request.getActiveProfileIds());
664         context.setInactiveProfileIds(request.getInactiveProfileIds());
665         context.setSystemProperties(request.getSystemProperties());
666         // enrich user properties with project packaging
667         Properties userProperties = request.getUserProperties();
668         userProperties.computeIfAbsent(
669                 (Object) ProfileActivationContext.PROPERTY_NAME_PACKAGING, (p) -> (Object) rawModel.getPackaging());
670         context.setUserProperties(userProperties);
671         context.setProjectDirectory(
672                 (request.getPomFile() != null) ? request.getPomFile().getParentFile() : null);
673 
674         return context;
675     }
676 
677     private void configureResolver(ModelResolver modelResolver, Model model, DefaultModelProblemCollector problems) {
678         configureResolver(modelResolver, model, problems, false);
679     }
680 
681     private void configureResolver(
682             ModelResolver modelResolver,
683             Model model,
684             DefaultModelProblemCollector problems,
685             boolean replaceRepositories) {
686         if (modelResolver == null) {
687             return;
688         }
689 
690         problems.setSource(model);
691 
692         List<Repository> repositories = model.getRepositories();
693 
694         for (Repository repository : repositories) {
695             try {
696                 modelResolver.addRepository(repository, replaceRepositories);
697             } catch (InvalidRepositoryException e) {
698                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
699                         .setMessage("Invalid repository " + repository.getId() + ": " + e.getMessage())
700                         .setLocation(repository.getLocation(""))
701                         .setException(e));
702             }
703         }
704     }
705 
706     private void checkPluginVersions(
707             List<ModelData> lineage, ModelBuildingRequest request, ModelProblemCollector problems) {
708         if (request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
709             return;
710         }
711 
712         Map<String, Plugin> plugins = new HashMap<>();
713         Map<String, String> versions = new HashMap<>();
714         Map<String, String> managedVersions = new HashMap<>();
715 
716         for (int i = lineage.size() - 1; i >= 0; i--) {
717             Model model = lineage.get(i).getModel();
718             Build build = model.getBuild();
719             if (build != null) {
720                 for (Plugin plugin : build.getPlugins()) {
721                     String key = plugin.getKey();
722                     if (versions.get(key) == null) {
723                         versions.put(key, plugin.getVersion());
724                         plugins.put(key, plugin);
725                     }
726                 }
727                 PluginManagement mgmt = build.getPluginManagement();
728                 if (mgmt != null) {
729                     for (Plugin plugin : mgmt.getPlugins()) {
730                         String key = plugin.getKey();
731                         if (managedVersions.get(key) == null) {
732                             managedVersions.put(key, plugin.getVersion());
733                         }
734                     }
735                 }
736             }
737         }
738 
739         for (String key : versions.keySet()) {
740             if (versions.get(key) == null && managedVersions.get(key) == null) {
741                 InputLocation location = plugins.get(key).getLocation("");
742                 problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.V20)
743                         .setMessage("'build.plugins.plugin.version' for " + key + " is missing.")
744                         .setLocation(location));
745             }
746         }
747     }
748 
749     private void assembleInheritance(
750             List<ModelData> lineage, ModelBuildingRequest request, ModelProblemCollector problems) {
751         for (int i = lineage.size() - 2; i >= 0; i--) {
752             Model parent = lineage.get(i + 1).getModel();
753             Model child = lineage.get(i).getModel();
754             inheritanceAssembler.assembleModelInheritance(child, parent, request, problems);
755         }
756     }
757 
758     private List<Profile> getProfiles(Model model) {
759         ArrayList<Profile> profiles = new ArrayList<>();
760         for (Profile profile : model.getProfiles()) {
761             profile = profile.clone();
762             profiles.add(profile);
763         }
764         return profiles;
765     }
766 
767     private Model interpolateModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
768         // save profile activations before interpolation, since they are evaluated with limited scope
769         List<Profile> originalProfiles = getProfiles(model);
770 
771         Model interpolatedModel =
772                 modelInterpolator.interpolateModel(model, model.getProjectDirectory(), request, problems);
773         if (interpolatedModel.getParent() != null) {
774             StringSearchInterpolator ssi = new StringSearchInterpolator();
775             ssi.addValueSource(new MapBasedValueSource(request.getUserProperties()));
776 
777             ssi.addValueSource(new MapBasedValueSource(model.getProperties()));
778 
779             ssi.addValueSource(new MapBasedValueSource(request.getSystemProperties()));
780 
781             try {
782                 String interpolated =
783                         ssi.interpolate(interpolatedModel.getParent().getVersion());
784                 interpolatedModel.getParent().setVersion(interpolated);
785             } catch (Exception e) {
786                 ModelProblemCollectorRequest mpcr = new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
787                         .setMessage("Failed to interpolate field: "
788                                 + interpolatedModel.getParent().getVersion()
789                                 + " on class: ")
790                         .setException(e);
791                 problems.add(mpcr);
792             }
793         }
794         interpolatedModel.setPomFile(model.getPomFile());
795 
796         // restore profiles with any activation to their value before full interpolation
797         List<Profile> interpolatedProfiles = model.getProfiles();
798         IntStream.range(0, interpolatedProfiles.size()).forEach(i -> interpolatedProfiles
799                 .get(i)
800                 .setActivation(originalProfiles.get(i).getActivation()));
801 
802         return interpolatedModel;
803     }
804 
805     private ModelData readParent(
806             Model childModel,
807             ModelSource childSource,
808             ModelBuildingRequest request,
809             DefaultModelProblemCollector problems)
810             throws ModelBuildingException {
811         ModelData parentData;
812 
813         Parent parent = childModel.getParent();
814 
815         if (parent != null) {
816             String groupId = parent.getGroupId();
817             String artifactId = parent.getArtifactId();
818             String version = parent.getVersion();
819 
820             parentData = getCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW);
821 
822             if (parentData == null) {
823                 parentData = readParentLocally(childModel, childSource, request, problems);
824 
825                 if (parentData == null) {
826                     parentData = readParentExternally(childModel, request, problems);
827                 }
828 
829                 putCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW, parentData);
830             } else {
831                 /*
832                  * NOTE: This is a sanity check of the cache hit. If the cached parent POM was locally resolved, the
833                  * child's <relativePath> should point at that parent, too. If it doesn't, we ignore the cache and
834                  * resolve externally, to mimic the behavior if the cache didn't exist in the first place. Otherwise,
835                  * the cache would obscure a bad POM.
836                  */
837 
838                 File pomFile = parentData.getModel().getPomFile();
839                 if (pomFile != null) {
840                     FileModelSource pomSource = new FileModelSource(pomFile);
841                     ModelSource expectedParentSource = getParentPomFile(childModel, childSource);
842 
843                     if (expectedParentSource == null
844                             || (expectedParentSource instanceof ModelSource2
845                                     && !pomSource.equals(expectedParentSource))) {
846                         parentData = readParentExternally(childModel, request, problems);
847                     }
848                 }
849             }
850 
851             Model parentModel = parentData.getModel();
852 
853             if (!"pom".equals(parentModel.getPackaging())) {
854                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
855                         .setMessage("Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint(parentModel)
856                                 + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"")
857                         .setLocation(parentModel.getLocation("packaging")));
858             }
859         } else {
860             parentData = null;
861         }
862 
863         return parentData;
864     }
865 
866     private ModelData readParentLocally(
867             Model childModel,
868             ModelSource childSource,
869             ModelBuildingRequest request,
870             DefaultModelProblemCollector problems)
871             throws ModelBuildingException {
872         final Parent parent = childModel.getParent();
873         final ModelSource candidateSource;
874         final Model candidateModel;
875         final WorkspaceModelResolver resolver = request.getWorkspaceModelResolver();
876         if (resolver == null) {
877             candidateSource = getParentPomFile(childModel, childSource);
878 
879             if (candidateSource == null) {
880                 return null;
881             }
882 
883             File pomFile = null;
884             if (candidateSource instanceof FileModelSource source) {
885                 pomFile = source.getPomFile();
886             }
887 
888             candidateModel = readModel(candidateSource, pomFile, request, problems);
889         } else {
890             try {
891                 candidateModel =
892                         resolver.resolveRawModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
893             } catch (UnresolvableModelException e) {
894                 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE) //
895                         .setMessage(e.getMessage())
896                         .setLocation(parent.getLocation(""))
897                         .setException(e));
898                 throw problems.newModelBuildingException();
899             }
900             if (candidateModel == null) {
901                 return null;
902             }
903             candidateSource = new FileModelSource(candidateModel.getPomFile());
904         }
905 
906         //
907         // TODO jvz Why isn't all this checking the job of the duty of the workspace resolver, we know that we
908         // have a model that is suitable, yet more checks are done here and the one for the version is problematic
909         // before because with parents as ranges it will never work in this scenario.
910         //
911 
912         String groupId = candidateModel.getGroupId();
913         if (groupId == null && candidateModel.getParent() != null) {
914             groupId = candidateModel.getParent().getGroupId();
915         }
916         String artifactId = candidateModel.getArtifactId();
917         String version = candidateModel.getVersion();
918         if (version == null && candidateModel.getParent() != null) {
919             version = candidateModel.getParent().getVersion();
920         }
921 
922         if (groupId == null
923                 || !groupId.equals(parent.getGroupId())
924                 || artifactId == null
925                 || !artifactId.equals(parent.getArtifactId())) {
926             StringBuilder buffer = new StringBuilder(256);
927             buffer.append("'parent.relativePath'");
928             if (childModel != problems.getRootModel()) {
929                 buffer.append(" of POM ").append(ModelProblemUtils.toSourceHint(childModel));
930             }
931             buffer.append(" points at ").append(groupId).append(':').append(artifactId);
932             buffer.append(" instead of ").append(parent.getGroupId()).append(':');
933             buffer.append(parent.getArtifactId()).append(", please verify your project structure");
934 
935             problems.setSource(childModel);
936             problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
937                     .setMessage(buffer.toString())
938                     .setLocation(parent.getLocation("")));
939             return null;
940         }
941         if (version != null && parent.getVersion() != null && !version.equals(parent.getVersion())) {
942             try {
943                 VersionRange parentRange = VersionRange.createFromVersionSpec(parent.getVersion());
944                 if (!parentRange.hasRestrictions()) {
945                     // the parent version is not a range, we have version skew, drop back to resolution from repo
946                     return null;
947                 }
948                 if (!parentRange.containsVersion(new DefaultArtifactVersion(version))) {
949                     // version skew drop back to resolution from the repository
950                     return null;
951                 }
952 
953                 // Validate versions aren't inherited when using parent ranges the same way as when read externally.
954                 String rawChildModelVersion = childModel.getVersion();
955 
956                 if (rawChildModelVersion == null) {
957                     // Message below is checked for in the MNG-2199 core IT.
958                     problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
959                             .setMessage("Version must be a constant")
960                             .setLocation(childModel.getLocation("")));
961 
962                 } else {
963                     if (rawChildVersionReferencesParent(rawChildModelVersion)) {
964                         // Message below is checked for in the MNG-2199 core IT.
965                         problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
966                                 .setMessage("Version must be a constant")
967                                 .setLocation(childModel.getLocation("version")));
968                     }
969                 }
970 
971                 // MNG-2199: What else to check here ?
972             } catch (InvalidVersionSpecificationException e) {
973                 // invalid version range, so drop back to resolution from the repository
974                 return null;
975             }
976         }
977 
978         //
979         // Here we just need to know that a version is fine to use but this validation we can do in our workspace
980         // resolver.
981         //
982 
983         /*
984          * if ( version == null || !version.equals( parent.getVersion() ) ) { return null; }
985          */
986 
987         ModelData parentData = new ModelData(candidateSource, candidateModel, groupId, artifactId, version);
988 
989         return parentData;
990     }
991 
992     private boolean rawChildVersionReferencesParent(String rawChildModelVersion) {
993         return rawChildModelVersion.equals("${pom.version}")
994                 || rawChildModelVersion.equals("${project.version}")
995                 || rawChildModelVersion.equals("${pom.parent.version}")
996                 || rawChildModelVersion.equals("${project.parent.version}");
997     }
998 
999     private ModelSource getParentPomFile(Model childModel, ModelSource source) {
1000         if (!(source instanceof ModelSource2)) {
1001             return null;
1002         }
1003 
1004         String parentPath = childModel.getParent().getRelativePath();
1005         if (parentPath == null) {
1006             parentPath = "../pom.xml";
1007         }
1008 
1009         if (parentPath.length() <= 0) {
1010             return null;
1011         }
1012 
1013         return ((ModelSource2) source).getRelatedSource(parentPath);
1014     }
1015 
1016     private ModelData readParentExternally(
1017             Model childModel, ModelBuildingRequest request, DefaultModelProblemCollector problems)
1018             throws ModelBuildingException {
1019         problems.setSource(childModel);
1020 
1021         Parent parent = childModel.getParent().clone();
1022 
1023         String groupId = parent.getGroupId();
1024         String artifactId = parent.getArtifactId();
1025         String version = parent.getVersion();
1026 
1027         ModelResolver modelResolver = request.getModelResolver();
1028         Objects.requireNonNull(
1029                 modelResolver,
1030                 String.format(
1031                         "request.modelResolver cannot be null (parent POM %s and POM %s)",
1032                         ModelProblemUtils.toId(groupId, artifactId, version),
1033                         ModelProblemUtils.toSourceHint(childModel)));
1034 
1035         ModelSource modelSource;
1036         try {
1037             modelSource = modelResolver.resolveModel(parent);
1038         } catch (UnresolvableModelException e) {
1039             // Message below is checked for in the MNG-2199 core IT.
1040             StringBuilder buffer = new StringBuilder(256);
1041             buffer.append("Non-resolvable parent POM");
1042             if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1043                 buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1044             }
1045             if (childModel != problems.getRootModel()) {
1046                 buffer.append(" for ").append(ModelProblemUtils.toId(childModel));
1047             }
1048             buffer.append(": ").append(e.getMessage());
1049             if (childModel.getProjectDirectory() != null) {
1050                 if (parent.getRelativePath() == null || parent.getRelativePath().length() <= 0) {
1051                     buffer.append(" and 'parent.relativePath' points at no local POM");
1052                 } else {
1053                     buffer.append(" and 'parent.relativePath' points at wrong local POM");
1054                 }
1055             }
1056 
1057             problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1058                     .setMessage(buffer.toString())
1059                     .setLocation(parent.getLocation(""))
1060                     .setException(e));
1061             throw problems.newModelBuildingException();
1062         }
1063 
1064         ModelBuildingRequest lenientRequest = request;
1065         if (request.getValidationLevel() > ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
1066             lenientRequest = new FilterModelBuildingRequest(request) {
1067                 @Override
1068                 public int getValidationLevel() {
1069                     return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
1070                 }
1071             };
1072         }
1073 
1074         Model parentModel = readModel(modelSource, null, lenientRequest, problems);
1075 
1076         if (!parent.getVersion().equals(version)) {
1077             String rawChildModelVersion = childModel.getVersion();
1078 
1079             if (rawChildModelVersion == null) {
1080                 // Message below is checked for in the MNG-2199 core IT.
1081                 problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
1082                         .setMessage("Version must be a constant")
1083                         .setLocation(childModel.getLocation("")));
1084 
1085             } else {
1086                 if (rawChildVersionReferencesParent(rawChildModelVersion)) {
1087                     // Message below is checked for in the MNG-2199 core IT.
1088                     problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31)
1089                             .setMessage("Version must be a constant")
1090                             .setLocation(childModel.getLocation("version")));
1091                 }
1092             }
1093 
1094             // MNG-2199: What else to check here ?
1095         }
1096 
1097         ModelData parentData = new ModelData(
1098                 modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
1099 
1100         return parentData;
1101     }
1102 
1103     private Model getSuperModel() {
1104         return superPomProvider.getSuperModel("4.0.0").clone();
1105     }
1106 
1107     @SuppressWarnings("checkstyle:methodlength")
1108     private void importDependencyManagement(
1109             Model model,
1110             ModelBuildingRequest request,
1111             DefaultModelProblemCollector problems,
1112             Collection<String> importIds) {
1113         DependencyManagement depMgmt = model.getDependencyManagement();
1114 
1115         if (depMgmt == null) {
1116             return;
1117         }
1118 
1119         String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
1120 
1121         importIds.add(importing);
1122 
1123         final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
1124         final ModelResolver modelResolver = request.getModelResolver();
1125 
1126         ModelBuildingRequest importRequest = null;
1127 
1128         List<DependencyManagement> importMgmts = null;
1129 
1130         for (Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); ) {
1131             Dependency dependency = it.next();
1132 
1133             if (!"pom".equals(dependency.getType()) || !"import".equals(dependency.getScope())) {
1134                 continue;
1135             }
1136 
1137             it.remove();
1138 
1139             String groupId = dependency.getGroupId();
1140             String artifactId = dependency.getArtifactId();
1141             String version = dependency.getVersion();
1142 
1143             if (groupId == null || groupId.length() <= 0) {
1144                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1145                         .setMessage("'dependencyManagement.dependencies.dependency.groupId' for "
1146                                 + dependency.getManagementKey() + " is missing.")
1147                         .setLocation(dependency.getLocation("")));
1148                 continue;
1149             }
1150             if (artifactId == null || artifactId.length() <= 0) {
1151                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1152                         .setMessage("'dependencyManagement.dependencies.dependency.artifactId' for "
1153                                 + dependency.getManagementKey() + " is missing.")
1154                         .setLocation(dependency.getLocation("")));
1155                 continue;
1156             }
1157             if (version == null || version.length() <= 0) {
1158                 problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1159                         .setMessage("'dependencyManagement.dependencies.dependency.version' for "
1160                                 + dependency.getManagementKey() + " is missing.")
1161                         .setLocation(dependency.getLocation("")));
1162                 continue;
1163             }
1164 
1165             String imported = groupId + ':' + artifactId + ':' + version;
1166 
1167             if (importIds.contains(imported)) {
1168                 StringBuilder message =
1169                         new StringBuilder("The dependencies of type=pom and with scope=import form a cycle: ");
1170                 for (String modelId : importIds) {
1171                     message.append(modelId);
1172                     message.append(" -> ");
1173                 }
1174                 message.append(imported);
1175                 problems.add(
1176                         new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE).setMessage(message.toString()));
1177 
1178                 continue;
1179             }
1180 
1181             DependencyManagement importMgmt =
1182                     getCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT);
1183 
1184             if (importMgmt == null) {
1185                 if (workspaceResolver == null && modelResolver == null) {
1186                     throw new NullPointerException(String.format(
1187                             "request.workspaceModelResolver and request.modelResolver cannot be null"
1188                                     + " (parent POM %s and POM %s)",
1189                             ModelProblemUtils.toId(groupId, artifactId, version),
1190                             ModelProblemUtils.toSourceHint(model)));
1191                 }
1192 
1193                 Model importModel = null;
1194                 if (workspaceResolver != null) {
1195                     try {
1196                         importModel = workspaceResolver.resolveEffectiveModel(groupId, artifactId, version);
1197                     } catch (UnresolvableModelException e) {
1198                         problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
1199                                 .setMessage(e.getMessage())
1200                                 .setException(e));
1201                         continue;
1202                     }
1203                 }
1204 
1205                 // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
1206                 if (importModel == null) {
1207                     final ModelSource importSource;
1208                     try {
1209                         importSource = modelResolver.resolveModel(groupId, artifactId, version);
1210                     } catch (UnresolvableModelException e) {
1211                         StringBuilder buffer = new StringBuilder(256);
1212                         buffer.append("Non-resolvable import POM");
1213                         if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) {
1214                             buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version));
1215                         }
1216                         buffer.append(": ").append(e.getMessage());
1217 
1218                         problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
1219                                 .setMessage(buffer.toString())
1220                                 .setLocation(dependency.getLocation(""))
1221                                 .setException(e));
1222                         continue;
1223                     }
1224 
1225                     if (importRequest == null) {
1226                         importRequest = new DefaultModelBuildingRequest();
1227                         importRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
1228                         importRequest.setModelCache(request.getModelCache());
1229                         importRequest.setSystemProperties(request.getSystemProperties());
1230                         importRequest.setUserProperties(request.getUserProperties());
1231                         importRequest.setLocationTracking(request.isLocationTracking());
1232                     }
1233 
1234                     importRequest.setModelSource(importSource);
1235                     importRequest.setModelResolver(modelResolver.newCopy());
1236 
1237                     final ModelBuildingResult importResult;
1238                     try {
1239                         importResult = build(importRequest, importIds);
1240                     } catch (ModelBuildingException e) {
1241                         problems.addAll(e.getProblems());
1242                         continue;
1243                     }
1244 
1245                     problems.addAll(importResult.getProblems());
1246 
1247                     importModel = importResult.getEffectiveModel();
1248                 }
1249 
1250                 importMgmt = importModel.getDependencyManagement();
1251 
1252                 if (importMgmt == null) {
1253                     importMgmt = new DependencyManagement();
1254                 }
1255 
1256                 putCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMgmt);
1257             }
1258 
1259             if (importMgmts == null) {
1260                 importMgmts = new ArrayList<>();
1261             }
1262 
1263             importMgmts.add(importMgmt);
1264         }
1265 
1266         importIds.remove(importing);
1267 
1268         dependencyManagementImporter.importManagement(model, importMgmts, request, problems);
1269     }
1270 
1271     private <T> void putCache(
1272             ModelCache modelCache, String groupId, String artifactId, String version, ModelCacheTag<T> tag, T data) {
1273         if (modelCache != null) {
1274             modelCache.put(groupId, artifactId, version, tag.getName(), tag.intoCache(data));
1275         }
1276     }
1277 
1278     private <T> T getCache(
1279             ModelCache modelCache, String groupId, String artifactId, String version, ModelCacheTag<T> tag) {
1280         if (modelCache != null) {
1281             Object data = modelCache.get(groupId, artifactId, version, tag.getName());
1282             if (data != null) {
1283                 return tag.fromCache(tag.getType().cast(data));
1284             }
1285         }
1286         return null;
1287     }
1288 
1289     private void fireEvent(
1290             Model model,
1291             ModelBuildingRequest request,
1292             ModelProblemCollector problems,
1293             ModelBuildingEventCatapult catapult) {
1294         ModelBuildingListener listener = request.getModelBuildingListener();
1295 
1296         if (listener != null) {
1297             ModelBuildingEvent event = new DefaultModelBuildingEvent(model, request, problems);
1298 
1299             catapult.fire(listener, event);
1300         }
1301     }
1302 
1303     private boolean containsCoordinates(String message, String groupId, String artifactId, String version) {
1304         return message != null
1305                 && (groupId == null || message.contains(groupId))
1306                 && (artifactId == null || message.contains(artifactId))
1307                 && (version == null || message.contains(version));
1308     }
1309 
1310     protected boolean hasModelErrors(ModelProblemCollectorExt problems) {
1311         if (problems instanceof DefaultModelProblemCollector collector) {
1312             return collector.hasErrors();
1313         } else {
1314             // the default execution path only knows the DefaultModelProblemCollector,
1315             // only reason it's not in signature is because it's package private
1316             throw new IllegalStateException();
1317         }
1318     }
1319 
1320     protected boolean hasFatalErrors(ModelProblemCollectorExt problems) {
1321         if (problems instanceof DefaultModelProblemCollector collector) {
1322             return collector.hasFatalErrors();
1323         } else {
1324             // the default execution path only knows the DefaultModelProblemCollector,
1325             // only reason it's not in signature is because it's package private
1326             throw new IllegalStateException();
1327         }
1328     }
1329 }