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