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