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