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.project;
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.AbstractMap;
28  import java.util.ArrayList;
29  import java.util.Arrays;
30  import java.util.Collection;
31  import java.util.Collections;
32  import java.util.HashMap;
33  import java.util.HashSet;
34  import java.util.LinkedHashSet;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Set;
38  import java.util.stream.Collectors;
39  
40  import org.apache.maven.RepositoryUtils;
41  import org.apache.maven.artifact.Artifact;
42  import org.apache.maven.artifact.InvalidArtifactRTException;
43  import org.apache.maven.artifact.InvalidRepositoryException;
44  import org.apache.maven.artifact.repository.ArtifactRepository;
45  import org.apache.maven.bridge.MavenRepositorySystem;
46  import org.apache.maven.feature.Features;
47  import org.apache.maven.model.Build;
48  import org.apache.maven.model.Dependency;
49  import org.apache.maven.model.DependencyManagement;
50  import org.apache.maven.model.DeploymentRepository;
51  import org.apache.maven.model.Extension;
52  import org.apache.maven.model.Model;
53  import org.apache.maven.model.Plugin;
54  import org.apache.maven.model.Profile;
55  import org.apache.maven.model.ReportPlugin;
56  import org.apache.maven.model.building.ArtifactModelSource;
57  import org.apache.maven.model.building.DefaultModelBuildingRequest;
58  import org.apache.maven.model.building.DefaultModelProblem;
59  import org.apache.maven.model.building.FileModelSource;
60  import org.apache.maven.model.building.ModelBuilder;
61  import org.apache.maven.model.building.ModelBuildingException;
62  import org.apache.maven.model.building.ModelBuildingRequest;
63  import org.apache.maven.model.building.ModelBuildingResult;
64  import org.apache.maven.model.building.ModelProblem;
65  import org.apache.maven.model.building.ModelProcessor;
66  import org.apache.maven.model.building.ModelSource;
67  import org.apache.maven.model.building.StringModelSource;
68  import org.apache.maven.model.building.TransformerContext;
69  import org.apache.maven.model.building.TransformerContextBuilder;
70  import org.apache.maven.model.resolution.ModelResolver;
71  import org.apache.maven.model.root.RootLocator;
72  import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
73  import org.apache.maven.repository.internal.ModelCacheFactory;
74  import org.codehaus.plexus.util.Os;
75  import org.codehaus.plexus.util.StringUtils;
76  import org.eclipse.aether.RepositorySystem;
77  import org.eclipse.aether.RepositorySystemSession;
78  import org.eclipse.aether.RequestTrace;
79  import org.eclipse.aether.impl.RemoteRepositoryManager;
80  import org.eclipse.aether.repository.LocalRepositoryManager;
81  import org.eclipse.aether.repository.RemoteRepository;
82  import org.eclipse.aether.repository.WorkspaceRepository;
83  import org.eclipse.aether.resolution.ArtifactRequest;
84  import org.eclipse.aether.resolution.ArtifactResult;
85  import org.slf4j.Logger;
86  import org.slf4j.LoggerFactory;
87  
88  /**
89   * DefaultProjectBuilder
90   */
91  @Named
92  @Singleton
93  public class DefaultProjectBuilder implements ProjectBuilder {
94      private final Logger logger = LoggerFactory.getLogger(getClass());
95      private final ModelBuilder modelBuilder;
96      private final ModelProcessor modelProcessor;
97      private final ProjectBuildingHelper projectBuildingHelper;
98      private final MavenRepositorySystem repositorySystem;
99      private final org.eclipse.aether.RepositorySystem repoSystem;
100     private final RemoteRepositoryManager repositoryManager;
101     private final ProjectDependenciesResolver dependencyResolver;
102     private final ModelCacheFactory modelCacheFactory;
103 
104     private final RootLocator rootLocator;
105 
106     @SuppressWarnings("checkstyle:ParameterNumber")
107     @Inject
108     public DefaultProjectBuilder(
109             ModelBuilder modelBuilder,
110             ModelProcessor modelProcessor,
111             ProjectBuildingHelper projectBuildingHelper,
112             MavenRepositorySystem repositorySystem,
113             RepositorySystem repoSystem,
114             RemoteRepositoryManager repositoryManager,
115             ProjectDependenciesResolver dependencyResolver,
116             ModelCacheFactory modelCacheFactory,
117             RootLocator rootLocator) {
118         this.modelBuilder = modelBuilder;
119         this.modelProcessor = modelProcessor;
120         this.projectBuildingHelper = projectBuildingHelper;
121         this.repositorySystem = repositorySystem;
122         this.repoSystem = repoSystem;
123         this.repositoryManager = repositoryManager;
124         this.dependencyResolver = dependencyResolver;
125         this.modelCacheFactory = modelCacheFactory;
126         this.rootLocator = rootLocator;
127     }
128     // ----------------------------------------------------------------------
129     // MavenProjectBuilder Implementation
130     // ----------------------------------------------------------------------
131 
132     @Override
133     public ProjectBuildingResult build(File pomFile, ProjectBuildingRequest request) throws ProjectBuildingException {
134         return build(pomFile, new FileModelSource(pomFile), new InternalConfig(request, null, null));
135     }
136 
137     @Override
138     public ProjectBuildingResult build(ModelSource modelSource, ProjectBuildingRequest request)
139             throws ProjectBuildingException {
140         return build(null, modelSource, new InternalConfig(request, null, null));
141     }
142 
143     private ProjectBuildingResult build(File pomFile, ModelSource modelSource, InternalConfig config)
144             throws ProjectBuildingException {
145         ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
146 
147         try {
148             ProjectBuildingRequest projectBuildingRequest = config.request;
149 
150             MavenProject project = projectBuildingRequest.getProject();
151 
152             List<ModelProblem> modelProblems = null;
153             Throwable error = null;
154 
155             if (project == null) {
156                 ModelBuildingRequest request = getModelBuildingRequest(config);
157 
158                 project = new MavenProject();
159                 project.setFile(pomFile);
160 
161                 DefaultModelBuildingListener listener =
162                         new DefaultModelBuildingListener(project, projectBuildingHelper, projectBuildingRequest);
163                 request.setModelBuildingListener(listener);
164 
165                 request.setPomFile(pomFile);
166                 request.setModelSource(modelSource);
167                 request.setLocationTracking(true);
168 
169                 if (pomFile != null) {
170                     project.setRootDirectory(
171                             rootLocator.findRoot(pomFile.getParentFile().toPath()));
172                 }
173 
174                 ModelBuildingResult result;
175                 try {
176                     result = modelBuilder.build(request);
177                 } catch (ModelBuildingException e) {
178                     result = e.getResult();
179                     if (result == null || result.getEffectiveModel() == null) {
180                         throw new ProjectBuildingException(e.getModelId(), e.getMessage(), pomFile, e);
181                     }
182                     // validation error, continue project building and delay failing to help IDEs
183                     error = e;
184                 }
185 
186                 modelProblems = result.getProblems();
187 
188                 initProject(project, Collections.emptyMap(), true, result, new HashMap<>(), projectBuildingRequest);
189             } else if (projectBuildingRequest.isResolveDependencies()) {
190                 projectBuildingHelper.selectProjectRealm(project);
191             }
192 
193             DependencyResolutionResult resolutionResult = null;
194 
195             if (projectBuildingRequest.isResolveDependencies()) {
196                 resolutionResult = resolveDependencies(project, config.session);
197             }
198 
199             ProjectBuildingResult result = new DefaultProjectBuildingResult(project, modelProblems, resolutionResult);
200 
201             if (error != null) {
202                 ProjectBuildingException e = new ProjectBuildingException(Arrays.asList(result));
203                 e.initCause(error);
204                 throw e;
205             }
206 
207             return result;
208         } finally {
209             Thread.currentThread().setContextClassLoader(oldContextClassLoader);
210         }
211     }
212 
213     private DependencyResolutionResult resolveDependencies(MavenProject project, RepositorySystemSession session) {
214         DependencyResolutionResult resolutionResult;
215 
216         try {
217             DefaultDependencyResolutionRequest resolution = new DefaultDependencyResolutionRequest(project, session);
218             resolutionResult = dependencyResolver.resolve(resolution);
219         } catch (DependencyResolutionException e) {
220             resolutionResult = e.getResult();
221         }
222 
223         Set<Artifact> artifacts = new LinkedHashSet<>();
224         if (resolutionResult.getDependencyGraph() != null) {
225             RepositoryUtils.toArtifacts(
226                     artifacts,
227                     resolutionResult.getDependencyGraph().getChildren(),
228                     Collections.singletonList(project.getArtifact().getId()),
229                     null);
230 
231             // Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
232             LocalRepositoryManager lrm = session.getLocalRepositoryManager();
233             for (Artifact artifact : artifacts) {
234                 if (!artifact.isResolved()) {
235                     String path = lrm.getPathForLocalArtifact(RepositoryUtils.toArtifact(artifact));
236                     artifact.setFile(new File(lrm.getRepository().getBasedir(), path));
237                 }
238             }
239         }
240         project.setResolvedArtifacts(artifacts);
241         project.setArtifacts(artifacts);
242 
243         return resolutionResult;
244     }
245 
246     private List<String> getProfileIds(List<org.apache.maven.model.Profile> profiles) {
247         return profiles.stream().map(org.apache.maven.model.Profile::getId).collect(Collectors.toList());
248     }
249 
250     private ModelBuildingRequest getModelBuildingRequest(InternalConfig config) {
251         ProjectBuildingRequest configuration = config.request;
252 
253         ModelBuildingRequest request = new DefaultModelBuildingRequest();
254 
255         RequestTrace trace = RequestTrace.newChild(null, configuration).newChild(request);
256 
257         ModelResolver resolver = new ProjectModelResolver(
258                 config.session,
259                 trace,
260                 repoSystem,
261                 repositoryManager,
262                 config.repositories,
263                 configuration.getRepositoryMerging(),
264                 config.modelPool);
265 
266         request.setValidationLevel(configuration.getValidationLevel());
267         request.setProcessPlugins(configuration.isProcessPlugins());
268         request.setProfiles(configuration.getProfiles());
269         request.setActiveProfileIds(configuration.getActiveProfileIds());
270         request.setInactiveProfileIds(configuration.getInactiveProfileIds());
271         request.setSystemProperties(configuration.getSystemProperties());
272         request.setUserProperties(configuration.getUserProperties());
273         request.setBuildStartTime(configuration.getBuildStartTime());
274         request.setModelResolver(resolver);
275         // this is a hint that we want to build 1 file, so don't cache. See MNG-7063
276         if (config.modelPool != null) {
277             request.setModelCache(modelCacheFactory.createCache(config.session));
278         }
279         request.setTransformerContextBuilder(config.transformerContextBuilder);
280 
281         return request;
282     }
283 
284     @Override
285     public ProjectBuildingResult build(Artifact artifact, ProjectBuildingRequest request)
286             throws ProjectBuildingException {
287         return build(artifact, false, request);
288     }
289 
290     @Override
291     public ProjectBuildingResult build(Artifact artifact, boolean allowStubModel, ProjectBuildingRequest request)
292             throws ProjectBuildingException {
293         org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact(artifact);
294         pomArtifact = ArtifactDescriptorUtils.toPomArtifact(pomArtifact);
295 
296         InternalConfig config = new InternalConfig(request, null, null);
297 
298         boolean localProject;
299 
300         try {
301             ArtifactRequest pomRequest = new ArtifactRequest();
302             pomRequest.setArtifact(pomArtifact);
303             pomRequest.setRepositories(config.repositories);
304             ArtifactResult pomResult = repoSystem.resolveArtifact(config.session, pomRequest);
305 
306             pomArtifact = pomResult.getArtifact();
307             localProject = pomResult.getRepository() instanceof WorkspaceRepository;
308         } catch (org.eclipse.aether.resolution.ArtifactResolutionException e) {
309             if (e.getResults().get(0).isMissing() && allowStubModel) {
310                 return build(null, createStubModelSource(artifact), config);
311             }
312             throw new ProjectBuildingException(
313                     artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e);
314         }
315 
316         File pomFile = pomArtifact.getFile();
317 
318         if ("pom".equals(artifact.getType())) {
319             artifact.selectVersion(pomArtifact.getVersion());
320             artifact.setFile(pomFile);
321             artifact.setResolved(true);
322         }
323 
324         if (localProject) {
325             return build(pomFile, new FileModelSource(pomFile), config);
326         } else {
327             return build(
328                     null,
329                     new ArtifactModelSource(
330                             pomFile, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()),
331                     config);
332         }
333     }
334 
335     private ModelSource createStubModelSource(Artifact artifact) {
336         StringBuilder buffer = new StringBuilder(1024);
337 
338         buffer.append("<?xml version='1.0'?>");
339         buffer.append("<project>");
340         buffer.append("<modelVersion>4.0.0</modelVersion>");
341         buffer.append("<groupId>").append(artifact.getGroupId()).append("</groupId>");
342         buffer.append("<artifactId>").append(artifact.getArtifactId()).append("</artifactId>");
343         buffer.append("<version>").append(artifact.getBaseVersion()).append("</version>");
344         buffer.append("<packaging>").append(artifact.getType()).append("</packaging>");
345         buffer.append("</project>");
346 
347         return new StringModelSource(buffer, artifact.getId());
348     }
349 
350     @Override
351     public List<ProjectBuildingResult> build(List<File> pomFiles, boolean recursive, ProjectBuildingRequest request)
352             throws ProjectBuildingException {
353         List<ProjectBuildingResult> results = new ArrayList<>();
354 
355         List<InterimResult> interimResults = new ArrayList<>();
356 
357         ReactorModelPool.Builder poolBuilder = new ReactorModelPool.Builder();
358         final ReactorModelPool modelPool = poolBuilder.build();
359 
360         InternalConfig config = new InternalConfig(request, modelPool, modelBuilder.newTransformerContextBuilder());
361 
362         Map<File, MavenProject> projectIndex = new HashMap<>(256);
363 
364         // phase 1: get file Models from the reactor.
365         boolean noErrors = build(
366                 results,
367                 interimResults,
368                 projectIndex,
369                 pomFiles,
370                 new LinkedHashSet<>(),
371                 true,
372                 recursive,
373                 config,
374                 poolBuilder);
375 
376         ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
377 
378         try {
379             // Phase 2: get effective models from the reactor
380             noErrors = build(
381                             results,
382                             new ArrayList<>(),
383                             projectIndex,
384                             interimResults,
385                             request,
386                             new HashMap<>(),
387                             config.session)
388                     && noErrors;
389         } finally {
390             Thread.currentThread().setContextClassLoader(oldContextClassLoader);
391         }
392 
393         if (Features.buildConsumer(request.getUserProperties()).isActive()) {
394             request.getRepositorySession()
395                     .getData()
396                     .set(TransformerContext.KEY, config.transformerContextBuilder.build());
397         }
398 
399         if (!noErrors) {
400             throw new ProjectBuildingException(results);
401         }
402 
403         return results;
404     }
405 
406     @SuppressWarnings("checkstyle:parameternumber")
407     private boolean build(
408             List<ProjectBuildingResult> results,
409             List<InterimResult> interimResults,
410             Map<File, MavenProject> projectIndex,
411             List<File> pomFiles,
412             Set<File> aggregatorFiles,
413             boolean root,
414             boolean recursive,
415             InternalConfig config,
416             ReactorModelPool.Builder poolBuilder) {
417         boolean noErrors = true;
418 
419         for (File pomFile : pomFiles) {
420             aggregatorFiles.add(pomFile);
421 
422             if (!build(
423                     results,
424                     interimResults,
425                     projectIndex,
426                     pomFile,
427                     aggregatorFiles,
428                     root,
429                     recursive,
430                     config,
431                     poolBuilder)) {
432                 noErrors = false;
433             }
434 
435             aggregatorFiles.remove(pomFile);
436         }
437 
438         return noErrors;
439     }
440 
441     @SuppressWarnings("checkstyle:parameternumber")
442     private boolean build(
443             List<ProjectBuildingResult> results,
444             List<InterimResult> interimResults,
445             Map<File, MavenProject> projectIndex,
446             File pomFile,
447             Set<File> aggregatorFiles,
448             boolean isRoot,
449             boolean recursive,
450             InternalConfig config,
451             ReactorModelPool.Builder poolBuilder) {
452         boolean noErrors = true;
453 
454         MavenProject project = new MavenProject();
455         project.setFile(pomFile);
456 
457         project.setRootDirectory(rootLocator.findRoot(pomFile.getParentFile().toPath()));
458 
459         ModelBuildingRequest request = getModelBuildingRequest(config)
460                 .setPomFile(pomFile)
461                 .setTwoPhaseBuilding(true)
462                 .setLocationTracking(true);
463 
464         DefaultModelBuildingListener listener =
465                 new DefaultModelBuildingListener(project, projectBuildingHelper, config.request);
466         request.setModelBuildingListener(listener);
467 
468         ModelBuildingResult result;
469         try {
470             result = modelBuilder.build(request);
471         } catch (ModelBuildingException e) {
472             result = e.getResult();
473             if (result == null || result.getFileModel() == null) {
474                 results.add(new DefaultProjectBuildingResult(e.getModelId(), pomFile, e.getProblems()));
475 
476                 return false;
477             }
478             // validation error, continue project building and delay failing to help IDEs
479             // result.getProblems().addAll(e.getProblems()) ?
480             noErrors = false;
481         }
482 
483         Model model = request.getFileModel();
484 
485         poolBuilder.put(model.getPomFile().toPath(), model);
486 
487         InterimResult interimResult = new InterimResult(pomFile, request, result, listener, isRoot);
488         interimResults.add(interimResult);
489 
490         if (recursive) {
491             File basedir = pomFile.getParentFile();
492             List<File> moduleFiles = new ArrayList<>();
493             for (String module : model.getModules()) {
494                 if (module == null || module.isEmpty()) {
495                     continue;
496                 }
497 
498                 module = module.replace('\\', File.separatorChar).replace('/', File.separatorChar);
499 
500                 File moduleFile = new File(basedir, module);
501 
502                 if (moduleFile.isDirectory()) {
503                     moduleFile = modelProcessor.locatePom(moduleFile);
504                 }
505 
506                 if (!moduleFile.isFile()) {
507                     ModelProblem problem = new DefaultModelProblem(
508                             "Child module " + moduleFile + " of " + pomFile + " does not exist",
509                             ModelProblem.Severity.ERROR,
510                             ModelProblem.Version.BASE,
511                             model,
512                             -1,
513                             -1,
514                             null);
515                     result.getProblems().add(problem);
516 
517                     noErrors = false;
518 
519                     continue;
520                 }
521 
522                 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
523                     // we don't canonicalize on unix to avoid interfering with symlinks
524                     try {
525                         moduleFile = moduleFile.getCanonicalFile();
526                     } catch (IOException e) {
527                         moduleFile = moduleFile.getAbsoluteFile();
528                     }
529                 } else {
530                     moduleFile = new File(moduleFile.toURI().normalize());
531                 }
532 
533                 if (aggregatorFiles.contains(moduleFile)) {
534                     StringBuilder buffer = new StringBuilder(256);
535                     for (File aggregatorFile : aggregatorFiles) {
536                         buffer.append(aggregatorFile).append(" -> ");
537                     }
538                     buffer.append(moduleFile);
539 
540                     ModelProblem problem = new DefaultModelProblem(
541                             "Child module " + moduleFile + " of " + pomFile + " forms aggregation cycle " + buffer,
542                             ModelProblem.Severity.ERROR,
543                             ModelProblem.Version.BASE,
544                             model,
545                             -1,
546                             -1,
547                             null);
548                     result.getProblems().add(problem);
549 
550                     noErrors = false;
551 
552                     continue;
553                 }
554 
555                 moduleFiles.add(moduleFile);
556             }
557 
558             interimResult.modules = new ArrayList<>();
559 
560             if (!build(
561                     results,
562                     interimResult.modules,
563                     projectIndex,
564                     moduleFiles,
565                     aggregatorFiles,
566                     false,
567                     recursive,
568                     config,
569                     poolBuilder)) {
570                 noErrors = false;
571             }
572         }
573 
574         projectIndex.put(pomFile, project);
575 
576         return noErrors;
577     }
578 
579     static class InterimResult {
580 
581         File pomFile;
582 
583         ModelBuildingRequest request;
584 
585         ModelBuildingResult result;
586 
587         DefaultModelBuildingListener listener;
588 
589         boolean root;
590 
591         List<InterimResult> modules = Collections.emptyList();
592 
593         InterimResult(
594                 File pomFile,
595                 ModelBuildingRequest request,
596                 ModelBuildingResult result,
597                 DefaultModelBuildingListener listener,
598                 boolean root) {
599             this.pomFile = pomFile;
600             this.request = request;
601             this.result = result;
602             this.listener = listener;
603             this.root = root;
604         }
605     }
606 
607     private boolean build(
608             List<ProjectBuildingResult> results,
609             List<MavenProject> projects,
610             Map<File, MavenProject> projectIndex,
611             List<InterimResult> interimResults,
612             ProjectBuildingRequest request,
613             Map<File, Boolean> profilesXmls,
614             RepositorySystemSession session) {
615         boolean noErrors = true;
616 
617         for (InterimResult interimResult : interimResults) {
618             MavenProject project = interimResult.listener.getProject();
619             try {
620                 ModelBuildingResult result = modelBuilder.build(interimResult.request, interimResult.result);
621 
622                 // 2nd pass of initialization: resolve and build parent if necessary
623                 try {
624                     initProject(project, projectIndex, true, result, profilesXmls, request);
625                 } catch (InvalidArtifactRTException iarte) {
626                     result.getProblems()
627                             .add(new DefaultModelProblem(
628                                     null,
629                                     ModelProblem.Severity.ERROR,
630                                     null,
631                                     result.getEffectiveModel(),
632                                     -1,
633                                     -1,
634                                     iarte));
635                 }
636 
637                 List<MavenProject> modules = new ArrayList<>();
638                 noErrors = build(results, modules, projectIndex, interimResult.modules, request, profilesXmls, session)
639                         && noErrors;
640 
641                 projects.addAll(modules);
642                 projects.add(project);
643 
644                 project.setExecutionRoot(interimResult.root);
645                 project.setCollectedProjects(modules);
646                 DependencyResolutionResult resolutionResult = null;
647                 if (request.isResolveDependencies()) {
648                     resolutionResult = resolveDependencies(project, session);
649                 }
650 
651                 results.add(new DefaultProjectBuildingResult(project, result.getProblems(), resolutionResult));
652             } catch (ModelBuildingException e) {
653                 DefaultProjectBuildingResult result = null;
654                 if (project == null || interimResult.result.getEffectiveModel() == null) {
655                     result = new DefaultProjectBuildingResult(e.getModelId(), interimResult.pomFile, e.getProblems());
656                 } else {
657                     project.setModel(interimResult.result.getEffectiveModel());
658 
659                     result = new DefaultProjectBuildingResult(project, e.getProblems(), null);
660                 }
661                 results.add(result);
662 
663                 noErrors = false;
664             }
665         }
666 
667         return noErrors;
668     }
669 
670     @SuppressWarnings("checkstyle:methodlength")
671     private void initProject(
672             MavenProject project,
673             Map<File, MavenProject> projects,
674             boolean buildParentIfNotExisting,
675             ModelBuildingResult result,
676             Map<File, Boolean> profilesXmls,
677             ProjectBuildingRequest projectBuildingRequest) {
678         project.setModel(result.getEffectiveModel());
679         project.setOriginalModel(result.getFileModel());
680 
681         initParent(project, projects, buildParentIfNotExisting, result, projectBuildingRequest);
682 
683         Artifact projectArtifact = repositorySystem.createArtifact(
684                 project.getGroupId(), project.getArtifactId(), project.getVersion(), null, project.getPackaging());
685         project.setArtifact(projectArtifact);
686 
687         if (project.getFile() != null && buildParentIfNotExisting) // only set those on 2nd phase, ignore on 1st pass
688         {
689             Build build = project.getBuild();
690             project.addScriptSourceRoot(build.getScriptSourceDirectory());
691             project.addCompileSourceRoot(build.getSourceDirectory());
692             project.addTestCompileSourceRoot(build.getTestSourceDirectory());
693         }
694 
695         List<Profile> activeProfiles = new ArrayList<>();
696         activeProfiles.addAll(result.getActivePomProfiles(result.getModelIds().get(0)));
697         activeProfiles.addAll(result.getActiveExternalProfiles());
698         project.setActiveProfiles(activeProfiles);
699 
700         project.setInjectedProfileIds("external", getProfileIds(result.getActiveExternalProfiles()));
701         for (String modelId : result.getModelIds()) {
702             project.setInjectedProfileIds(modelId, getProfileIds(result.getActivePomProfiles(modelId)));
703         }
704 
705         //
706         // All the parts that were taken out of MavenProject for Maven 4.0.0
707         //
708 
709         project.setProjectBuildingRequest(projectBuildingRequest);
710 
711         // pluginArtifacts
712         Set<Artifact> pluginArtifacts = new HashSet<>();
713         for (Plugin plugin : project.getBuildPlugins()) {
714             Artifact artifact = repositorySystem.createPluginArtifact(plugin);
715 
716             if (artifact != null) {
717                 pluginArtifacts.add(artifact);
718             }
719         }
720         project.setPluginArtifacts(pluginArtifacts);
721 
722         // reportArtifacts
723         Set<Artifact> reportArtifacts = new HashSet<>();
724         for (ReportPlugin report : project.getReportPlugins()) {
725             Plugin pp = new Plugin();
726             pp.setGroupId(report.getGroupId());
727             pp.setArtifactId(report.getArtifactId());
728             pp.setVersion(report.getVersion());
729 
730             Artifact artifact = repositorySystem.createPluginArtifact(pp);
731 
732             if (artifact != null) {
733                 reportArtifacts.add(artifact);
734             }
735         }
736         project.setReportArtifacts(reportArtifacts);
737 
738         // extensionArtifacts
739         Set<Artifact> extensionArtifacts = new HashSet<>();
740         List<Extension> extensions = project.getBuildExtensions();
741         if (extensions != null) {
742             for (Extension ext : extensions) {
743                 String version;
744                 if (StringUtils.isEmpty(ext.getVersion())) {
745                     version = "RELEASE";
746                 } else {
747                     version = ext.getVersion();
748                 }
749 
750                 Artifact artifact =
751                         repositorySystem.createArtifact(ext.getGroupId(), ext.getArtifactId(), version, null, "jar");
752 
753                 if (artifact != null) {
754                     extensionArtifacts.add(artifact);
755                 }
756             }
757         }
758         project.setExtensionArtifacts(extensionArtifacts);
759 
760         // managedVersionMap
761         Map<String, Artifact> map = null;
762         if (repositorySystem != null) {
763             final DependencyManagement dependencyManagement = project.getDependencyManagement();
764             if ((dependencyManagement != null)
765                     && ((dependencyManagement.getDependencies()) != null)
766                     && (dependencyManagement.getDependencies().size() > 0)) {
767                 map = new AbstractMap<String, Artifact>() {
768                     HashMap<String, Artifact> delegate;
769 
770                     @Override
771                     public Set<Entry<String, Artifact>> entrySet() {
772                         return Collections.unmodifiableSet(compute().entrySet());
773                     }
774 
775                     @Override
776                     public Set<String> keySet() {
777                         return Collections.unmodifiableSet(compute().keySet());
778                     }
779 
780                     @Override
781                     public Collection<Artifact> values() {
782                         return Collections.unmodifiableCollection(compute().values());
783                     }
784 
785                     @Override
786                     public boolean containsValue(Object value) {
787                         return compute().containsValue(value);
788                     }
789 
790                     @Override
791                     public boolean containsKey(Object key) {
792                         return compute().containsKey(key);
793                     }
794 
795                     @Override
796                     public Artifact get(Object key) {
797                         return compute().get(key);
798                     }
799 
800                     HashMap<String, Artifact> compute() {
801                         if (delegate == null) {
802                             delegate = new HashMap<>();
803                             for (Dependency d : dependencyManagement.getDependencies()) {
804                                 Artifact artifact = repositorySystem.createDependencyArtifact(d);
805 
806                                 if (artifact != null) {
807                                     delegate.put(d.getManagementKey(), artifact);
808                                 }
809                             }
810                         }
811 
812                         return delegate;
813                     }
814                 };
815             } else {
816                 map = Collections.emptyMap();
817             }
818         }
819         project.setManagedVersionMap(map);
820 
821         // release artifact repository
822         if (project.getDistributionManagement() != null
823                 && project.getDistributionManagement().getRepository() != null) {
824             try {
825                 DeploymentRepository r = project.getDistributionManagement().getRepository();
826                 if (!StringUtils.isEmpty(r.getId()) && !StringUtils.isEmpty(r.getUrl())) {
827                     ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(r);
828                     repositorySystem.injectProxy(projectBuildingRequest.getRepositorySession(), Arrays.asList(repo));
829                     repositorySystem.injectAuthentication(
830                             projectBuildingRequest.getRepositorySession(), Arrays.asList(repo));
831                     project.setReleaseArtifactRepository(repo);
832                 }
833             } catch (InvalidRepositoryException e) {
834                 throw new IllegalStateException(
835                         "Failed to create release distribution repository for " + project.getId(), e);
836             }
837         }
838 
839         // snapshot artifact repository
840         if (project.getDistributionManagement() != null
841                 && project.getDistributionManagement().getSnapshotRepository() != null) {
842             try {
843                 DeploymentRepository r = project.getDistributionManagement().getSnapshotRepository();
844                 if (!StringUtils.isEmpty(r.getId()) && !StringUtils.isEmpty(r.getUrl())) {
845                     ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(r);
846                     repositorySystem.injectProxy(projectBuildingRequest.getRepositorySession(), Arrays.asList(repo));
847                     repositorySystem.injectAuthentication(
848                             projectBuildingRequest.getRepositorySession(), Arrays.asList(repo));
849                     project.setSnapshotArtifactRepository(repo);
850                 }
851             } catch (InvalidRepositoryException e) {
852                 throw new IllegalStateException(
853                         "Failed to create snapshot distribution repository for " + project.getId(), e);
854             }
855         }
856     }
857 
858     private void initParent(
859             MavenProject project,
860             Map<File, MavenProject> projects,
861             boolean buildParentIfNotExisting,
862             ModelBuildingResult result,
863             ProjectBuildingRequest projectBuildingRequest) {
864         Model parentModel =
865                 result.getModelIds().size() > 1 && !result.getModelIds().get(1).isEmpty()
866                         ? result.getRawModel(result.getModelIds().get(1))
867                         : null;
868 
869         if (parentModel != null) {
870             final String parentGroupId = inheritedGroupId(result, 1);
871             final String parentVersion = inheritedVersion(result, 1);
872 
873             project.setParentArtifact(
874                     repositorySystem.createProjectArtifact(parentGroupId, parentModel.getArtifactId(), parentVersion));
875 
876             // org.apache.maven.its.mng4834:parent:0.1
877             String parentModelId = result.getModelIds().get(1);
878             File parentPomFile = result.getRawModel(parentModelId).getPomFile();
879             MavenProject parent = projects.get(parentPomFile);
880             if (parent == null && buildParentIfNotExisting) {
881                 //
882                 // At this point the DefaultModelBuildingListener has fired and it populates the
883                 // remote repositories with those found in the pom.xml, along with the existing externally
884                 // defined repositories.
885                 //
886                 projectBuildingRequest.setRemoteRepositories(project.getRemoteArtifactRepositories());
887                 if (parentPomFile != null) {
888                     project.setParentFile(parentPomFile);
889                     try {
890                         parent = build(parentPomFile, projectBuildingRequest).getProject();
891                     } catch (ProjectBuildingException e) {
892                         // MNG-4488 where let invalid parents slide on by
893                         if (logger.isDebugEnabled()) {
894                             // Message below is checked for in the MNG-2199 core IT.
895                             logger.warn("Failed to build parent project for " + project.getId(), e);
896                         } else {
897                             // Message below is checked for in the MNG-2199 core IT.
898                             logger.warn("Failed to build parent project for " + project.getId());
899                         }
900                     }
901                 } else {
902                     Artifact parentArtifact = project.getParentArtifact();
903                     try {
904                         parent = build(parentArtifact, projectBuildingRequest).getProject();
905                     } catch (ProjectBuildingException e) {
906                         // MNG-4488 where let invalid parents slide on by
907                         if (logger.isDebugEnabled()) {
908                             // Message below is checked for in the MNG-2199 core IT.
909                             logger.warn("Failed to build parent project for " + project.getId(), e);
910                         } else {
911                             // Message below is checked for in the MNG-2199 core IT.
912                             logger.warn("Failed to build parent project for " + project.getId());
913                         }
914                     }
915                 }
916             }
917             project.setParent(parent);
918             if (project.getParentFile() == null && parent != null) {
919                 project.setParentFile(parent.getFile());
920             }
921         }
922     }
923 
924     private static String inheritedGroupId(final ModelBuildingResult result, final int modelIndex) {
925         String groupId = null;
926         final String modelId = result.getModelIds().get(modelIndex);
927 
928         if (!modelId.isEmpty()) {
929             final Model model = result.getRawModel(modelId);
930             groupId = model.getGroupId() != null ? model.getGroupId() : inheritedGroupId(result, modelIndex + 1);
931         }
932 
933         return groupId;
934     }
935 
936     private static String inheritedVersion(final ModelBuildingResult result, final int modelIndex) {
937         String version = null;
938         final String modelId = result.getModelIds().get(modelIndex);
939 
940         if (!modelId.isEmpty()) {
941             version = result.getRawModel(modelId).getVersion();
942             if (version == null) {
943                 version = inheritedVersion(result, modelIndex + 1);
944             }
945         }
946 
947         return version;
948     }
949 
950     /**
951      * InternalConfig
952      */
953     class InternalConfig {
954 
955         private final ProjectBuildingRequest request;
956 
957         private final RepositorySystemSession session;
958 
959         private final List<RemoteRepository> repositories;
960 
961         private final ReactorModelPool modelPool;
962 
963         private final TransformerContextBuilder transformerContextBuilder;
964 
965         InternalConfig(
966                 ProjectBuildingRequest request,
967                 ReactorModelPool modelPool,
968                 TransformerContextBuilder transformerContextBuilder) {
969             this.request = request;
970             this.modelPool = modelPool;
971             this.transformerContextBuilder = transformerContextBuilder;
972 
973             session = RepositoryUtils.overlay(request.getLocalRepository(), request.getRepositorySession(), repoSystem);
974             repositories = RepositoryUtils.toRepos(request.getRemoteRepositories());
975         }
976     }
977 }