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