001package org.apache.maven.project;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.Arrays;
026import java.util.Collections;
027import java.util.HashMap;
028import java.util.HashSet;
029import java.util.LinkedHashSet;
030import java.util.List;
031import java.util.Map;
032import java.util.Set;
033
034import org.apache.maven.RepositoryUtils;
035import org.apache.maven.artifact.Artifact;
036import org.apache.maven.artifact.InvalidRepositoryException;
037import org.apache.maven.artifact.repository.ArtifactRepository;
038import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
039import org.apache.maven.bridge.MavenRepositorySystem;
040import org.apache.maven.model.Build;
041import org.apache.maven.model.Dependency;
042import org.apache.maven.model.DependencyManagement;
043import org.apache.maven.model.DeploymentRepository;
044import org.apache.maven.model.Extension;
045import org.apache.maven.model.Model;
046import org.apache.maven.model.Parent;
047import org.apache.maven.model.Plugin;
048import org.apache.maven.model.Profile;
049import org.apache.maven.model.ReportPlugin;
050import org.apache.maven.model.building.DefaultModelBuildingRequest;
051import org.apache.maven.model.building.DefaultModelProblem;
052import org.apache.maven.model.building.FileModelSource;
053import org.apache.maven.model.building.ModelBuilder;
054import org.apache.maven.model.building.ModelBuildingException;
055import org.apache.maven.model.building.ModelBuildingRequest;
056import org.apache.maven.model.building.ModelBuildingResult;
057import org.apache.maven.model.building.ModelProblem;
058import org.apache.maven.model.building.ModelProcessor;
059import org.apache.maven.model.building.ModelSource;
060import org.apache.maven.model.building.StringModelSource;
061import org.apache.maven.model.resolution.ModelResolver;
062import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
063import org.codehaus.plexus.component.annotations.Component;
064import org.codehaus.plexus.component.annotations.Requirement;
065import org.codehaus.plexus.logging.Logger;
066import org.codehaus.plexus.util.Os;
067import org.codehaus.plexus.util.StringUtils;
068import org.eclipse.aether.RepositorySystemSession;
069import org.eclipse.aether.RequestTrace;
070import org.eclipse.aether.impl.RemoteRepositoryManager;
071import org.eclipse.aether.repository.LocalRepositoryManager;
072import org.eclipse.aether.repository.RemoteRepository;
073import org.eclipse.aether.repository.WorkspaceRepository;
074import org.eclipse.aether.resolution.ArtifactRequest;
075import org.eclipse.aether.resolution.ArtifactResult;
076import org.eclipse.aether.resolution.VersionRangeRequest;
077import org.eclipse.aether.resolution.VersionRangeResolutionException;
078import org.eclipse.aether.resolution.VersionRangeResult;
079
080/**
081 */
082@Component( role = ProjectBuilder.class )
083public class DefaultProjectBuilder
084    implements ProjectBuilder
085{
086
087    @Requirement
088    private Logger logger;
089
090    @Requirement
091    private ModelBuilder modelBuilder;
092
093    @Requirement
094    private ModelProcessor modelProcessor;
095
096    @Requirement
097    private ProjectBuildingHelper projectBuildingHelper;
098
099    @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<Artifact>();
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<String>( 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<ProjectBuildingResult>();
392
393        List<InterimResult> interimResults = new ArrayList<InterimResult>();
394
395        ReactorModelPool modelPool = new ReactorModelPool();
396
397        InternalConfig config = new InternalConfig( request, modelPool );
398
399        Map<String, MavenProject> projectIndex = new HashMap<String, MavenProject>( 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<File>();
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<InterimResult>();
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<MavenProject>();
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<Profile>();
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<Artifact>();
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<Artifact>();
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<Artifact>();
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<String, Artifact>();
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}