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