All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.DefaultMaven Maven / Gradle / Ivy

There is a newer version: 4.0.0-rc-2
Show newest version
package org.apache.maven;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.execution.DefaultMavenExecutionResult;
import org.apache.maven.execution.DuplicateProjectException;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.lifecycle.TaskValidationResult;
import org.apache.maven.monitor.event.DeprecationEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.MavenEvents;
import org.apache.maven.project.MavenProject;

import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.reactor.MavenExecutionException;
import org.apache.maven.reactor.MissingModuleException;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.Os;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.dag.CycleDetectedException;

/**
 * @author Jason van Zyl
 * @version $Id: DefaultMaven.java 721627 2008-11-29 04:54:23Z jvanzyl $
 * @todo EventDispatcher should be a component as it is internal to maven.
 */
@Component(role = Maven.class)
public class DefaultMaven
    implements Maven, LogEnabled
{
    @Requirement
    protected MavenProjectBuilder projectBuilder;
    
    @Requirement
    protected LifecycleExecutor lifecycleExecutor;

    @Requirement
    protected PlexusContainer container;

    @Requirement
    protected RuntimeInformation runtimeInformation;

    private Logger logger;

    // ----------------------------------------------------------------------
    // Project execution
    // ----------------------------------------------------------------------

    // project build
    // artifact resolution
    // lifecycle execution

    public ReactorManager createReactorManager( MavenExecutionRequest request, MavenExecutionResult result )
    {
        List projects;
        try
        {            
            projects = getProjects( request );

            if ( projects.isEmpty() )
            {
                projects.add( projectBuilder.buildStandaloneSuperProject( request.getProjectBuildingConfiguration() ) );

                request.setProjectPresent( false );
            }
        }
        catch ( ProjectBuildingException e )
        {
            result.addException( e );
            return null;
        }
        catch ( MavenExecutionException e )
        {
            result.addException( e );
            return null;
        }

        ReactorManager reactorManager;

        try
        {
            reactorManager = new ReactorManager( projects, request.getReactorFailureBehavior() );

            result.setReactorManager( reactorManager );
        }
        catch ( CycleDetectedException e )
        {
            String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();

            ProjectCycleException error = new ProjectCycleException( projects, message, e );

            result.addException( error );

            return null;
        }
        catch ( DuplicateProjectException e )
        {
            result.addException( e );

            return null;
        }

        return reactorManager;
    }

    public MavenExecutionResult execute( MavenExecutionRequest request )
    {
        request.setStartTime( new Date() );

        MavenExecutionResult result = new DefaultMavenExecutionResult();

        ReactorManager reactorManager = createReactorManager( request, result );

        if ( result.hasExceptions() )
        {
            return result;
        }

        EventDispatcher dispatcher = new DeprecationEventDispatcher( MavenEvents.DEPRECATIONS, request.getEventMonitors() );

        String event = MavenEvents.MAVEN_EXECUTION;

        dispatcher.dispatchStart( event, request.getBaseDirectory() );

        MavenSession session = createSession( request, reactorManager, dispatcher );

        if ( request.getGoals() != null )
        {
            for ( Iterator i = request.getGoals().iterator(); i.hasNext(); )
            {
                String goal = (String) i.next();

                if ( goal == null )
                {
                    i.remove();
                    continue;
                }

                TaskValidationResult tvr = lifecycleExecutor.isTaskValid( goal, session, reactorManager.getTopLevelProject() );

                if ( !tvr.isTaskValid() )
                {
                    Exception e = tvr.generateInvalidTaskException();
                    result.addException( e );
                    dispatcher.dispatchError( event, request.getBaseDirectory(), e );

                    return result;
                }
            }
        }

        getLogger().info( "Scanning for projects..." );

        if ( reactorManager.hasMultipleProjects() )
        {
            getLogger().info( "Reactor build order: " );

            for ( Iterator i = reactorManager.getSortedProjects().iterator(); i.hasNext(); )
            {
                MavenProject project = (MavenProject) i.next();

                getLogger().info( "  " + project.getName() );
            }
        }

        try
        {
            lifecycleExecutor.execute( session, reactorManager, dispatcher );
        }
        catch ( LifecycleExecutionException e )
        {
            result.addException( e );
            dispatcher.dispatchError( event, request.getBaseDirectory(), e );

            return result;
        }
        catch ( BuildFailureException e )
        {
            result.addException( e );
            dispatcher.dispatchError( event, request.getBaseDirectory(), e );

            return result;
        }

        result.setTopologicallySortedProjects( reactorManager.getSortedProjects() );

        result.setProject( reactorManager.getTopLevelProject() );

        result.setBuildPlans( session.getBuildPlans() );

        dispatcher.dispatchEnd( event, request.getBaseDirectory() );

        return result;
    }

    protected List getProjects( MavenExecutionRequest request )
        throws MavenExecutionException
    {
        List projects;

        List files;
        try
        {
            files = getProjectFiles( request );
        }
        catch ( IOException e )
        {
            throw new MavenExecutionException(
                "Error selecting project files for the reactor: " + e.getMessage(),
                e );
        }

        projects = collectProjects( files, request, !request.useReactor() );

        return projects;
    }

    private List collectProjects( List files,
                                  MavenExecutionRequest request,
                                  boolean isRoot )
        throws MavenExecutionException
    {
        List projects = new ArrayList( files.size() );

        if ( !files.isEmpty() )
        {
            for ( Iterator iterator = files.iterator(); iterator.hasNext(); )
            {
                File file = (File) iterator.next();

                boolean usingReleasePom = false;

                if ( RELEASE_POMv4.equals( file.getName() ) )
                {
                    getLogger().info( "NOTE: Using release-pom: " + file + " in reactor build." );

                    usingReleasePom = true;
                }

                MavenProject project;
                try
                {
                    project = projectBuilder.build( file, request.getProjectBuildingConfiguration() );
                }
                catch ( ProjectBuildingException e )
                {
                    throw new MavenExecutionException( "Failed to build MavenProject instance for: " + file, file, e );
                }

                if ( isRoot )
                {
                    project.setExecutionRoot( true );
                }

                if ( ( project.getPrerequisites() != null ) && ( project.getPrerequisites().getMaven() != null ) )
                {
                    DefaultArtifactVersion version = new DefaultArtifactVersion( project.getPrerequisites().getMaven() );

                    if ( runtimeInformation.getApplicationInformation().getVersion().compareTo( version ) < 0 )
                    {
                        throw new MavenExecutionException(
                            "Unable to build project '" + file +
                                "; it requires Maven version " + version.toString(), file );
                    }
                }

                if ( ( project.getModules() != null ) && !project.getModules().isEmpty() && request.isRecursive() )
                {
                    // TODO: Really should fail if it was not? What if it is aggregating - eg "ear"?
                    project.setPackaging( "pom" );

                    File basedir = file.getParentFile();

                    // Initial ordering is as declared in the modules section
                    List moduleFiles = new ArrayList( project.getModules().size() );

                    for ( Iterator i = project.getModules().iterator(); i.hasNext(); )
                    {
                        String name = (String) i.next();

                        if ( StringUtils.isEmpty( StringUtils.trim( name ) ) )
                        {
                            getLogger().warn( "Empty module detected. Please check you don't have any empty module definitions in your POM." );

                            continue;
                        }

                        File moduleFile = new File( basedir, name );
                        if ( !moduleFile.exists() )
                        {
                            throw new MissingModuleException( name, moduleFile, file );
                        }
                        else if ( moduleFile.isDirectory() )
                        {
                            if ( usingReleasePom )
                            {
                                moduleFile = new File( basedir, name + "/" + Maven.RELEASE_POMv4 );
                            }
                            else
                            {
                                moduleFile = new File( basedir, name + "/" + Maven.POMv4 );
                            }
                        }

                        if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
                        {
                            // we don't canonicalize on unix to avoid interfering with symlinks

                            try
                            {
                                moduleFile = moduleFile.getCanonicalFile();
                            }
                            catch ( IOException e )
                            {
                                throw new MavenExecutionException( "Unable to canonicalize file name " + moduleFile, e );
                            }
                        }
                        else
                        {
                            moduleFile = new File( moduleFile.toURI().normalize() );
                        }

                        moduleFiles.add( moduleFile );
                    }

                    List collectedProjects = collectProjects( moduleFiles, request, false );

                    projects.addAll( collectedProjects );
                    project.setCollectedProjects( collectedProjects );
                }
                projects.add( project );
            }
        }

        return projects;
    }

    // ----------------------------------------------------------------------
    // Methods used by all execution request handlers
    // ----------------------------------------------------------------------

    //!! We should probably have the execution request handler create the
    // session as
    // the session type would be specific to the request i.e. having a project
    // or not.

    protected MavenSession createSession( MavenExecutionRequest request,
                                          ReactorManager reactorManager,
                                          EventDispatcher dispatcher )
    {
        MavenSession session = new MavenSession( container, request, dispatcher, reactorManager );

        return session;
    }

    private List getProjectFiles( MavenExecutionRequest request )
        throws IOException
    {
        List files = Collections.EMPTY_LIST;

        File userDir = new File( request.getBaseDirectory() );

        if ( request.useReactor() )
        {
            String includes = System.getProperty( "maven.reactor.includes", "**/" + POMv4 + ",**/" + RELEASE_POMv4 );

            String excludes = System.getProperty( "maven.reactor.excludes", POMv4 + "," + RELEASE_POMv4 );

            files = FileUtils.getFiles( userDir, includes, excludes );

            filterOneProjectFilePerDirectory( files );

            // make sure there is consistent ordering on all platforms, rather than using the filesystem ordering
            Collections.sort( files );
        }
        else if ( request.getPom() != null )
        {
            File projectFile = request.getPom().getAbsoluteFile();

            if ( projectFile.exists() )
            {
                files = Collections.singletonList( projectFile );
            }
        }
        else
        {
            File projectFile = new File( userDir, RELEASE_POMv4 );

            if ( !projectFile.exists() )
            {
                projectFile = new File( userDir, POMv4 );
            }

            if ( projectFile.exists() )
            {
                files = Collections.singletonList( projectFile );
            }
        }

        return files;
    }

    private void filterOneProjectFilePerDirectory( List files )
    {
        List releaseDirs = new ArrayList();

        for ( Iterator it = files.iterator(); it.hasNext(); )
        {
            File projectFile = (File) it.next();

            if ( RELEASE_POMv4.equals( projectFile.getName() ) )
            {
                releaseDirs.add( projectFile.getParentFile() );
            }
        }

        for ( Iterator it = files.iterator(); it.hasNext(); )
        {
            File projectFile = (File) it.next();

            // remove pom.xml files where there is a sibling release-pom.xml file...
            if ( !RELEASE_POMv4.equals( projectFile.getName() ) && releaseDirs.contains( projectFile.getParentFile() ) )
            {
                it.remove();
            }
        }
    }

    protected Logger getLogger()
    {
        return logger;
    }

    public void enableLogging( Logger logger )
    {
        this.logger = logger;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy