Save This Page
Home » maven-2.0.9-src » org.apache » maven » lifecycle » [javadoc | source]
    1   package org.apache.maven.lifecycle;
    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 org.apache.maven.BuildFailureException;
   23   import org.apache.maven.artifact.handler.ArtifactHandler;
   24   import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
   25   import org.apache.maven.artifact.repository.ArtifactRepository;
   26   import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
   27   import org.apache.maven.artifact.resolver.ArtifactResolutionException;
   28   import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
   29   import org.apache.maven.execution.MavenSession;
   30   import org.apache.maven.execution.ReactorManager;
   31   import org.apache.maven.extension.ExtensionManager;
   32   import org.apache.maven.lifecycle.mapping.LifecycleMapping;
   33   import org.apache.maven.model.Extension;
   34   import org.apache.maven.model.Plugin;
   35   import org.apache.maven.model.PluginExecution;
   36   import org.apache.maven.model.ReportPlugin;
   37   import org.apache.maven.model.ReportSet;
   38   import org.apache.maven.monitor.event.EventDispatcher;
   39   import org.apache.maven.monitor.event.MavenEvents;
   40   import org.apache.maven.plugin.InvalidPluginException;
   41   import org.apache.maven.plugin.MojoExecution;
   42   import org.apache.maven.plugin.MojoExecutionException;
   43   import org.apache.maven.plugin.MojoFailureException;
   44   import org.apache.maven.plugin.PluginConfigurationException;
   45   import org.apache.maven.plugin.PluginManager;
   46   import org.apache.maven.plugin.PluginManagerException;
   47   import org.apache.maven.plugin.PluginNotFoundException;
   48   import org.apache.maven.plugin.descriptor.MojoDescriptor;
   49   import org.apache.maven.plugin.descriptor.PluginDescriptor;
   50   import org.apache.maven.plugin.lifecycle.Execution;
   51   import org.apache.maven.plugin.lifecycle.Phase;
   52   import org.apache.maven.plugin.version.PluginVersionNotFoundException;
   53   import org.apache.maven.plugin.version.PluginVersionResolutionException;
   54   import org.apache.maven.project.MavenProject;
   55   import org.apache.maven.project.artifact.InvalidDependencyVersionException;
   56   import org.apache.maven.reporting.MavenReport;
   57   import org.apache.maven.settings.Settings;
   58   import org.codehaus.plexus.PlexusContainerException;
   59   import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
   60   import org.codehaus.plexus.logging.AbstractLogEnabled;
   61   import org.codehaus.plexus.util.StringUtils;
   62   import org.codehaus.plexus.util.xml.Xpp3Dom;
   63   import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
   64   
   65   import java.io.IOException;
   66   import java.util.ArrayList;
   67   import java.util.Collections;
   68   import java.util.HashMap;
   69   import java.util.Iterator;
   70   import java.util.List;
   71   import java.util.Map;
   72   import java.util.Stack;
   73   import java.util.StringTokenizer;
   74   
   75   /**
   76    * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
   77    * @author <a href="mailto:brett@apache.org">Brett Porter</a>
   78    * @version $Id: DefaultLifecycleExecutor.java 642436 2008-03-28 23:39:20Z jdcasey $
   79    * @todo because of aggregation, we ended up with cli-ish stuff in here (like line() and the project logging, without much of the event handling)
   80    */
   81   public class DefaultLifecycleExecutor
   82       extends AbstractLogEnabled
   83       implements LifecycleExecutor
   84   {
   85       // ----------------------------------------------------------------------
   86       // Components
   87       // ----------------------------------------------------------------------
   88   
   89       private PluginManager pluginManager;
   90   
   91       private ExtensionManager extensionManager;
   92   
   93       private List lifecycles;
   94   
   95       private ArtifactHandlerManager artifactHandlerManager;
   96   
   97       private List defaultReports;
   98   
   99       private Map phaseToLifecycleMap;
  100   
  101       // ----------------------------------------------------------------------
  102       //
  103       // ----------------------------------------------------------------------
  104   
  105       /**
  106        * Execute a task. Each task may be a phase in the lifecycle or the
  107        * execution of a mojo.
  108        *
  109        * @param session
  110        * @param rm
  111        * @param dispatcher
  112        */
  113       public void execute( MavenSession session, ReactorManager rm, EventDispatcher dispatcher )
  114           throws BuildFailureException, LifecycleExecutionException
  115       {
  116           // TODO: This is dangerous, particularly when it's just a collection of loose-leaf projects being built
  117           // within the same reactor (using an inclusion pattern to gather them up)...
  118           MavenProject rootProject = rm.getTopLevelProject();
  119   
  120           List goals = session.getGoals();
  121   
  122           if ( goals.isEmpty() && rootProject != null )
  123           {
  124               String goal = rootProject.getDefaultGoal();
  125   
  126               if ( goal != null )
  127               {
  128                   goals = Collections.singletonList( goal );
  129               }
  130           }
  131   
  132           if ( goals.isEmpty() )
  133           {
  134               throw new BuildFailureException( "\n\nYou must specify at least one goal. Try 'mvn install' to build or 'mvn -?' for options \nSee http://maven.apache.org for more information.\n\n" );
  135           }
  136   
  137           List taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject );
  138   
  139           // TODO: probably don't want to do all this up front
  140           findExtensions( session );
  141   
  142           executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
  143       }
  144   
  145       private void findExtensions( MavenSession session )
  146           throws LifecycleExecutionException
  147       {
  148           for ( Iterator i = session.getSortedProjects().iterator(); i.hasNext(); )
  149           {
  150               MavenProject project = (MavenProject) i.next();
  151   
  152               for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
  153               {
  154                   Extension extension = (Extension) j.next();
  155                   try
  156                   {
  157                       extensionManager.addExtension( extension, project, session.getLocalRepository() );
  158                   }
  159                   catch ( PlexusContainerException e )
  160                   {
  161                       throw new LifecycleExecutionException( "Unable to initialise extensions", e );
  162                   }
  163                   catch ( ArtifactResolutionException e )
  164                   {
  165                       throw new LifecycleExecutionException( e.getMessage(), e );
  166                   }
  167                   catch ( ArtifactNotFoundException e )
  168                   {
  169                       throw new LifecycleExecutionException( e.getMessage(), e );
  170                   }
  171               }
  172   
  173               extensionManager.registerWagons();
  174   
  175               try
  176               {
  177                   Map handlers = findArtifactTypeHandlers( project, session.getSettings(), session.getLocalRepository() );
  178   
  179                   artifactHandlerManager.addHandlers( handlers );
  180               }
  181               catch ( PluginNotFoundException e )
  182               {
  183                   throw new LifecycleExecutionException( e.getMessage(), e );
  184               }
  185           }
  186       }
  187   
  188       private void executeTaskSegments( List taskSegments, ReactorManager rm, MavenSession session,
  189                                         MavenProject rootProject, EventDispatcher dispatcher )
  190           throws LifecycleExecutionException, BuildFailureException
  191       {
  192           for ( Iterator it = taskSegments.iterator(); it.hasNext(); )
  193           {
  194               TaskSegment segment = (TaskSegment) it.next();
  195   
  196               if ( segment.aggregate() )
  197               {
  198                   if ( !rm.isBlackListed( rootProject ) )
  199                   {
  200                       line();
  201   
  202                       getLogger().info( "Building " + rootProject.getName() );
  203   
  204                       getLogger().info( "  " + segment );
  205   
  206                       line();
  207   
  208                       // !! This is ripe for refactoring to an aspect.
  209                       // Event monitoring.
  210                       String event = MavenEvents.PROJECT_EXECUTION;
  211   
  212                       long buildStartTime = System.currentTimeMillis();
  213   
  214                       String target = rootProject.getId() + " ( " + segment + " )";
  215   
  216                       dispatcher.dispatchStart( event, target );
  217   
  218                       try
  219                       {
  220                           session.setCurrentProject( rootProject );
  221   
  222                           // only call once, with the top-level project (assumed to be provided as a parameter)...
  223                           for ( Iterator goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); )
  224                           {
  225                               String task = (String) goalIterator.next();
  226   
  227                               executeGoalAndHandleFailures( task, session, rootProject, dispatcher, event, rm, buildStartTime,
  228                                                             target );
  229                           }
  230   
  231                           rm.registerBuildSuccess( rootProject, System.currentTimeMillis() - buildStartTime );
  232   
  233                       }
  234                       finally
  235                       {
  236                           session.setCurrentProject( null );
  237                       }
  238   
  239                       dispatcher.dispatchEnd( event, target );
  240                   }
  241                   else
  242                   {
  243                       line();
  244   
  245                       getLogger().info( "SKIPPING " + rootProject.getName() );
  246   
  247                       getLogger().info( "  " + segment );
  248   
  249                       getLogger().info(
  250                           "This project has been banned from further executions due to previous failures." );
  251   
  252                       line();
  253                   }
  254               }
  255               else
  256               {
  257                   List sortedProjects = session.getSortedProjects();
  258   
  259                   // iterate over projects, and execute on each...
  260                   for ( Iterator projectIterator = sortedProjects.iterator(); projectIterator.hasNext(); )
  261                   {
  262                       MavenProject currentProject = (MavenProject) projectIterator.next();
  263   
  264                       if ( !rm.isBlackListed( currentProject ) )
  265                       {
  266                           line();
  267   
  268                           getLogger().info( "Building " + currentProject.getName() );
  269   
  270                           getLogger().info( "  " + segment );
  271   
  272                           line();
  273   
  274                           // !! This is ripe for refactoring to an aspect.
  275                           // Event monitoring.
  276                           String event = MavenEvents.PROJECT_EXECUTION;
  277   
  278                           long buildStartTime = System.currentTimeMillis();
  279   
  280                           String target = currentProject.getId() + " ( " + segment + " )";
  281                           dispatcher.dispatchStart( event, target );
  282   
  283                           try
  284                           {
  285                               session.setCurrentProject( currentProject );
  286   
  287                               for ( Iterator goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); )
  288                               {
  289                                   String task = (String) goalIterator.next();
  290   
  291                                   executeGoalAndHandleFailures( task, session, currentProject, dispatcher, event, rm,
  292                                                                 buildStartTime, target );
  293                               }
  294   
  295                           }
  296                           finally
  297                           {
  298                               session.setCurrentProject( null );
  299                           }
  300   
  301                           rm.registerBuildSuccess( currentProject, System.currentTimeMillis() - buildStartTime );
  302   
  303                           dispatcher.dispatchEnd( event, target );
  304                       }
  305                       else
  306                       {
  307                           line();
  308   
  309                           getLogger().info( "SKIPPING " + currentProject.getName() );
  310   
  311                           getLogger().info( "  " + segment );
  312   
  313                           getLogger().info(
  314                               "This project has been banned from further executions due to previous failures." );
  315   
  316                           line();
  317                       }
  318                   }
  319               }
  320           }
  321       }
  322   
  323       private void executeGoalAndHandleFailures( String task, MavenSession session, MavenProject project,
  324                                                  EventDispatcher dispatcher, String event, ReactorManager rm,
  325                                                  long buildStartTime, String target )
  326           throws BuildFailureException, LifecycleExecutionException
  327       {
  328           try
  329           {
  330               executeGoal( task, session, project );
  331           }
  332           catch ( LifecycleExecutionException e )
  333           {
  334               dispatcher.dispatchError( event, target, e );
  335   
  336               if ( handleExecutionFailure( rm, project, e, task, buildStartTime ) )
  337               {
  338                   throw e;
  339               }
  340           }
  341           catch ( BuildFailureException e )
  342           {
  343               dispatcher.dispatchError( event, target, e );
  344   
  345               if ( handleExecutionFailure( rm, project, e, task, buildStartTime ) )
  346               {
  347                   throw e;
  348               }
  349           }
  350       }
  351   
  352       private boolean handleExecutionFailure( ReactorManager rm, MavenProject project, Exception e, String task,
  353                                               long buildStartTime )
  354       {
  355           rm.registerBuildFailure( project, e, task, System.currentTimeMillis() - buildStartTime );
  356   
  357           if ( ReactorManager.FAIL_FAST.equals( rm.getFailureBehavior() ) )
  358           {
  359               return true;
  360           }
  361           else if ( ReactorManager.FAIL_AT_END.equals( rm.getFailureBehavior() ) )
  362           {
  363               rm.blackList( project );
  364           }
  365           // if NEVER, don't blacklist
  366           return false;
  367       }
  368   
  369       private List segmentTaskListByAggregationNeeds( List tasks, MavenSession session, MavenProject project )
  370           throws LifecycleExecutionException, BuildFailureException
  371       {
  372           List segments = new ArrayList();
  373   
  374           if ( project != null )
  375           {
  376   
  377               TaskSegment currentSegment = null;
  378               for ( Iterator it = tasks.iterator(); it.hasNext(); )
  379               {
  380                   String task = (String) it.next();
  381   
  382                   // if it's a phase, then we don't need to check whether it's an aggregator.
  383                   // simply add it to the current task partition.
  384                   if ( getPhaseToLifecycleMap().containsKey( task ) )
  385                   {
  386                       if ( currentSegment != null && currentSegment.aggregate() )
  387                       {
  388                           segments.add( currentSegment );
  389                           currentSegment = null;
  390                       }
  391   
  392                       if ( currentSegment == null )
  393                       {
  394                           currentSegment = new TaskSegment();
  395                       }
  396   
  397                       currentSegment.add( task );
  398                   }
  399                   else
  400                   {
  401                       MojoDescriptor mojo = null;
  402                       try
  403                       {
  404                           // definitely a CLI goal, can use prefix
  405                           mojo = getMojoDescriptor( task, session, project, task, true, false );
  406                       }
  407                       catch ( PluginNotFoundException e )
  408                       {
  409                           // TODO: shouldn't hit this, investigate using the same resolution logic as otheres for plugins in the reactor
  410                           getLogger().info(
  411                               "Cannot find mojo descriptor for: \'" + task + "\' - Treating as non-aggregator." );
  412                           getLogger().debug( "", e );
  413                       }
  414   
  415                       // if the mojo descriptor was found, determine aggregator status according to:
  416                       // 1. whether the mojo declares itself an aggregator
  417                       // 2. whether the mojo DOES NOT require a project to function (implicitly avoid reactor)
  418                       if ( mojo != null && ( mojo.isAggregator() || !mojo.isProjectRequired() ) )
  419                       {
  420                           if ( currentSegment != null && !currentSegment.aggregate() )
  421                           {
  422                               segments.add( currentSegment );
  423                               currentSegment = null;
  424                           }
  425   
  426                           if ( currentSegment == null )
  427                           {
  428                               currentSegment = new TaskSegment( true );
  429                           }
  430   
  431                           currentSegment.add( task );
  432                       }
  433                       else
  434                       {
  435                           if ( currentSegment != null && currentSegment.aggregate() )
  436                           {
  437                               segments.add( currentSegment );
  438                               currentSegment = null;
  439                           }
  440   
  441                           if ( currentSegment == null )
  442                           {
  443                               currentSegment = new TaskSegment();
  444                           }
  445   
  446                           currentSegment.add( task );
  447                       }
  448                   }
  449               }
  450   
  451               segments.add( currentSegment );
  452           }
  453           else
  454           {
  455               TaskSegment segment = new TaskSegment( false );
  456               for ( Iterator i = tasks.iterator(); i.hasNext(); )
  457               {
  458                   segment.add( (String) i.next() );
  459               }
  460               segments.add( segment );
  461           }
  462   
  463           return segments;
  464       }
  465   
  466       private void executeGoal( String task, MavenSession session, MavenProject project )
  467           throws LifecycleExecutionException, BuildFailureException
  468       {
  469           try
  470           {
  471               Stack forkEntryPoints = new Stack();
  472               if ( getPhaseToLifecycleMap().containsKey( task ) )
  473               {
  474                   Lifecycle lifecycle = getLifecycleForPhase( task );
  475   
  476                   // we have a lifecycle phase, so lets bind all the necessary goals
  477                   Map lifecycleMappings = constructLifecycleMappings( session, task, project, lifecycle );
  478                   executeGoalWithLifecycle( task, forkEntryPoints, session, lifecycleMappings, project, lifecycle );
  479               }
  480               else
  481               {
  482                   executeStandaloneGoal( task, forkEntryPoints, session, project );
  483               }
  484           }
  485           catch ( PluginNotFoundException e )
  486           {
  487               throw new BuildFailureException( "A required plugin was not found: " + e.getMessage(), e );
  488           }
  489       }
  490   
  491       private void executeGoalWithLifecycle( String task, Stack forkEntryPoints, MavenSession session,
  492                                              Map lifecycleMappings, MavenProject project, Lifecycle lifecycle )
  493           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
  494       {
  495           List goals = processGoalChain( task, lifecycleMappings, lifecycle );
  496   
  497           if ( !goals.isEmpty() )
  498           {
  499               executeGoals( goals, forkEntryPoints, session, project );
  500           }
  501           else
  502           {
  503               getLogger().info( "No goals needed for project - skipping" );
  504           }
  505       }
  506   
  507       private void executeStandaloneGoal( String task, Stack forkEntryPoints, MavenSession session, MavenProject project )
  508           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
  509       {
  510           // guaranteed to come from the CLI and not be part of a phase
  511           MojoDescriptor mojoDescriptor = getMojoDescriptor( task, session, project, task, true, false );
  512           executeGoals( Collections.singletonList( new MojoExecution( mojoDescriptor ) ), forkEntryPoints, session,
  513                         project );
  514       }
  515   
  516       private void executeGoals( List goals, Stack forkEntryPoints, MavenSession session, MavenProject project )
  517           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
  518       {
  519           for ( Iterator i = goals.iterator(); i.hasNext(); )
  520           {
  521               MojoExecution mojoExecution = (MojoExecution) i.next();
  522   
  523               MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
  524   
  525               if ( mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null )
  526               {
  527                   forkEntryPoints.push( mojoDescriptor );
  528   
  529                   forkLifecycle( mojoDescriptor, forkEntryPoints, session, project );
  530   
  531                   forkEntryPoints.pop();
  532               }
  533   
  534               if ( mojoDescriptor.isRequiresReports() )
  535               {
  536                   List reports = getReports( project, forkEntryPoints, mojoExecution, session );
  537   
  538                   mojoExecution.setReports( reports );
  539   
  540                   for ( Iterator j = mojoExecution.getForkedExecutions().iterator(); j.hasNext(); )
  541                   {
  542                       MojoExecution forkedExecution = (MojoExecution) j.next();
  543                       MojoDescriptor descriptor = forkedExecution.getMojoDescriptor();
  544   
  545                       if ( descriptor.getExecutePhase() != null )
  546                       {
  547                           forkEntryPoints.push( descriptor );
  548   
  549                           forkLifecycle( descriptor, forkEntryPoints, session, project );
  550   
  551                           forkEntryPoints.pop();
  552                       }
  553                   }
  554               }
  555   
  556               try
  557               {
  558                   pluginManager.executeMojo( project, mojoExecution, session );
  559               }
  560               catch ( PluginManagerException e )
  561               {
  562                   throw new LifecycleExecutionException( "Internal error in the plugin manager executing goal '" +
  563                       mojoDescriptor.getId() + "': " + e.getMessage(), e );
  564               }
  565               catch ( ArtifactNotFoundException e )
  566               {
  567                   throw new LifecycleExecutionException( e.getMessage(), e );
  568               }
  569               catch ( InvalidDependencyVersionException e )
  570               {
  571                   throw new LifecycleExecutionException( e.getMessage(), e );
  572               }
  573               catch ( ArtifactResolutionException e )
  574               {
  575                   throw new LifecycleExecutionException( e.getMessage(), e );
  576               }
  577               catch ( MojoFailureException e )
  578               {
  579                   throw new BuildFailureException( e.getMessage(), e );
  580               }
  581               catch ( MojoExecutionException e )
  582               {
  583                   throw new LifecycleExecutionException( e.getMessage(), e );
  584               }
  585               catch ( PluginConfigurationException e )
  586               {
  587                   throw new LifecycleExecutionException( e.getMessage(), e );
  588               }
  589           }
  590       }
  591   
  592       private List getReports( MavenProject project, Stack forkEntryPoints, MojoExecution mojoExecution, MavenSession session )
  593           throws LifecycleExecutionException, PluginNotFoundException
  594       {
  595           List reportPlugins = project.getReportPlugins();
  596   
  597           if ( project.getModel().getReports() != null )
  598           {
  599               getLogger().error(
  600                   "Plugin contains a <reports/> section: this is IGNORED - please use <reporting/> instead." );
  601           }
  602   
  603           if ( project.getReporting() == null || !project.getReporting().isExcludeDefaults() )
  604           {
  605               if ( reportPlugins == null )
  606               {
  607                   reportPlugins = new ArrayList();
  608               }
  609               else
  610               {
  611                   reportPlugins = new ArrayList( reportPlugins );
  612               }
  613   
  614               for ( Iterator i = defaultReports.iterator(); i.hasNext(); )
  615               {
  616                   String report = (String) i.next();
  617   
  618                   StringTokenizer tok = new StringTokenizer( report, ":" );
  619                   if ( tok.countTokens() != 2 )
  620                   {
  621                       getLogger().warn( "Invalid default report ignored: '" + report + "' (must be groupId:artifactId)" );
  622                   }
  623                   else
  624                   {
  625                       String groupId = tok.nextToken();
  626                       String artifactId = tok.nextToken();
  627   
  628                       boolean found = false;
  629                       for ( Iterator j = reportPlugins.iterator(); j.hasNext() && !found; )
  630                       {
  631                           ReportPlugin reportPlugin = (ReportPlugin) j.next();
  632                           if ( reportPlugin.getGroupId().equals( groupId ) &&
  633                               reportPlugin.getArtifactId().equals( artifactId ) )
  634                           {
  635                               found = true;
  636                           }
  637                       }
  638   
  639                       if ( !found )
  640                       {
  641                           ReportPlugin reportPlugin = new ReportPlugin();
  642                           reportPlugin.setGroupId( groupId );
  643                           reportPlugin.setArtifactId( artifactId );
  644                           reportPlugins.add( reportPlugin );
  645                       }
  646                   }
  647               }
  648           }
  649   
  650           List reports = new ArrayList();
  651           if ( reportPlugins != null )
  652           {
  653               for ( Iterator it = reportPlugins.iterator(); it.hasNext(); )
  654               {
  655                   ReportPlugin reportPlugin = (ReportPlugin) it.next();
  656   
  657                   List reportSets = reportPlugin.getReportSets();
  658   
  659                   if ( reportSets == null || reportSets.isEmpty() )
  660                   {
  661                       reports.addAll( getReports( reportPlugin, forkEntryPoints, null, project, session, mojoExecution ) );
  662                   }
  663                   else
  664                   {
  665                       for ( Iterator j = reportSets.iterator(); j.hasNext(); )
  666                       {
  667                           ReportSet reportSet = (ReportSet) j.next();
  668   
  669                           reports.addAll( getReports( reportPlugin, forkEntryPoints, reportSet, project, session, mojoExecution ) );
  670                       }
  671                   }
  672               }
  673           }
  674           return reports;
  675       }
  676   
  677       private List getReports( ReportPlugin reportPlugin,
  678                                Stack forkEntryPoints,
  679                                ReportSet reportSet,
  680                                MavenProject project,
  681                                MavenSession session,
  682                                MojoExecution mojoExecution )
  683           throws LifecycleExecutionException, PluginNotFoundException
  684       {
  685           PluginDescriptor pluginDescriptor = verifyReportPlugin( reportPlugin, project, session );
  686   
  687           List reports = new ArrayList();
  688           for ( Iterator i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
  689           {
  690               MojoDescriptor mojoDescriptor = (MojoDescriptor) i.next();
  691               if ( forkEntryPoints.contains( mojoDescriptor ) )
  692               {
  693                   getLogger().debug( "Omitting report: " + mojoDescriptor.getFullGoalName() + " from reports list. It initiated part of the fork currently executing." );
  694                   continue;
  695               }
  696   
  697               // TODO: check ID is correct for reports
  698               // if the POM configured no reports, give all from plugin
  699               if ( reportSet == null || reportSet.getReports().contains( mojoDescriptor.getGoal() ) )
  700               {
  701                   String id = null;
  702                   if ( reportSet != null )
  703                   {
  704                       id = reportSet.getId();
  705                   }
  706   
  707                   MojoExecution reportExecution = new MojoExecution( mojoDescriptor, id );
  708   
  709                   try
  710                   {
  711                       MavenReport reportMojo = pluginManager.getReport( project, reportExecution, session );
  712   
  713                       // Comes back null if it was a plugin, not a report - these are mojos in the reporting plugins that are not reports
  714                       if ( reportMojo != null )
  715                       {
  716                           reports.add( reportMojo );
  717                           mojoExecution.addMojoExecution( reportExecution );
  718                       }
  719                   }
  720                   catch ( PluginManagerException e )
  721                   {
  722                       throw new LifecycleExecutionException(
  723                           "Error getting reports from the plugin '" + reportPlugin.getKey() + "': " + e.getMessage(), e );
  724                   }
  725                   catch ( PluginConfigurationException e )
  726                   {
  727                       throw new LifecycleExecutionException(
  728                           "Error getting reports from the plugin '" + reportPlugin.getKey() + "'", e );
  729                   }
  730                   catch ( ArtifactNotFoundException e )
  731                   {
  732                       throw new LifecycleExecutionException( e.getMessage(), e );
  733                   }
  734                   catch ( ArtifactResolutionException e )
  735                   {
  736                       throw new LifecycleExecutionException( e.getMessage(), e );
  737                   }
  738               }
  739           }
  740           return reports;
  741       }
  742   
  743       private void forkLifecycle( MojoDescriptor mojoDescriptor, Stack ancestorLifecycleForkers, MavenSession session,
  744                                   MavenProject project )
  745           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
  746       {
  747           PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
  748           getLogger().info( "Preparing " + pluginDescriptor.getGoalPrefix() + ":" + mojoDescriptor.getGoal() );
  749   
  750           if ( mojoDescriptor.isAggregator() )
  751           {
  752               for ( Iterator i = session.getSortedProjects().iterator(); i.hasNext(); )
  753               {
  754                   MavenProject reactorProject = (MavenProject) i.next();
  755   
  756                   line();
  757   
  758                   getLogger().info( "Building " + reactorProject.getName() );
  759   
  760                   line();
  761   
  762                   forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, reactorProject );
  763               }
  764           }
  765           else
  766           {
  767               forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, project );
  768           }
  769       }
  770   
  771       private void forkProjectLifecycle( MojoDescriptor mojoDescriptor, Stack forkEntryPoints, MavenSession session,
  772                                          MavenProject project )
  773           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
  774       {
  775           forkEntryPoints.push( mojoDescriptor );
  776   
  777           PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
  778   
  779           String targetPhase = mojoDescriptor.getExecutePhase();
  780   
  781           Map lifecycleMappings = null;
  782           if ( targetPhase != null )
  783           {
  784               Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
  785   
  786               // Create new lifecycle
  787               lifecycleMappings = constructLifecycleMappings( session, targetPhase, project, lifecycle );
  788   
  789               String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
  790               if ( executeLifecycle != null )
  791               {
  792                   org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
  793                   try
  794                   {
  795                       lifecycleOverlay = pluginDescriptor.getLifecycleMapping( executeLifecycle );
  796                   }
  797                   catch ( IOException e )
  798                   {
  799                       throw new LifecycleExecutionException( "Unable to read lifecycle mapping file: " + e.getMessage(),
  800                                                              e );
  801                   }
  802                   catch ( XmlPullParserException e )
  803                   {
  804                       throw new LifecycleExecutionException( "Unable to parse lifecycle mapping file: " + e.getMessage(),
  805                                                              e );
  806                   }
  807   
  808                   if ( lifecycleOverlay == null )
  809                   {
  810                       throw new LifecycleExecutionException( "Lifecycle '" + executeLifecycle + "' not found in plugin" );
  811                   }
  812   
  813                   for ( Iterator i = lifecycleOverlay.getPhases().iterator(); i.hasNext(); )
  814                   {
  815                       Phase phase = (Phase) i.next();
  816                       for ( Iterator j = phase.getExecutions().iterator(); j.hasNext(); )
  817                       {
  818                           Execution exec = (Execution) j.next();
  819   
  820                           for ( Iterator k = exec.getGoals().iterator(); k.hasNext(); )
  821                           {
  822                               String goal = (String) k.next();
  823   
  824                               PluginDescriptor lifecyclePluginDescriptor;
  825                               String lifecycleGoal;
  826   
  827                               // Here we are looking to see if we have a mojo from an external plugin.
  828                               // If we do then we need to lookup the plugin descriptor for the externally
  829                               // referenced plugin so that we can overly the execution into the lifecycle.
  830                               // An example of this is the corbertura plugin that needs to call the surefire
  831                               // plugin in forking mode.
  832                               //
  833                               //<phase>
  834                               //  <id>test</id>
  835                               //  <executions>
  836                               //    <execution>
  837                               //      <goals>
  838                               //        <goal>org.apache.maven.plugins:maven-surefire-plugin:test</goal>
  839                               //      </goals>
  840                               //      <configuration>
  841                               //        <classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
  842                               //        <ignoreFailures>true</ignoreFailures>
  843                               //        <forkMode>once</forkMode>
  844                               //      </configuration>
  845                               //    </execution>
  846                               //  </executions>
  847                               //</phase>
  848   
  849                               // ----------------------------------------------------------------------
  850                               //
  851                               // ----------------------------------------------------------------------
  852   
  853                               if ( goal.indexOf( ":" ) > 0 )
  854                               {
  855                                   String[] s = StringUtils.split( goal, ":" );
  856   
  857                                   String groupId = s[0];
  858                                   String artifactId = s[1];
  859                                   lifecycleGoal = s[2];
  860   
  861                                   Plugin plugin = new Plugin();
  862                                   plugin.setGroupId( groupId );
  863                                   plugin.setArtifactId( artifactId );
  864                                   lifecyclePluginDescriptor = verifyPlugin( plugin, project, session.getSettings(),
  865                                                                             session.getLocalRepository() );
  866                                   if ( lifecyclePluginDescriptor == null )
  867                                   {
  868                                       throw new LifecycleExecutionException(
  869                                           "Unable to find plugin " + groupId + ":" + artifactId );
  870                                   }
  871                               }
  872                               else
  873                               {
  874                                   lifecyclePluginDescriptor = pluginDescriptor;
  875                                   lifecycleGoal = goal;
  876                               }
  877   
  878                               Xpp3Dom configuration = (Xpp3Dom) exec.getConfiguration();
  879                               if ( phase.getConfiguration() != null )
  880                               {
  881                                   configuration = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ),
  882                                                                         configuration );
  883                               }
  884   
  885                               MojoDescriptor desc = getMojoDescriptor( lifecyclePluginDescriptor, lifecycleGoal );
  886                               MojoExecution mojoExecution = new MojoExecution( desc, configuration );
  887                               addToLifecycleMappings( lifecycleMappings, phase.getId(), mojoExecution,
  888                                                       session.getSettings() );
  889                           }
  890                       }
  891   
  892                       if ( phase.getConfiguration() != null )
  893                       {
  894                           // Merge in general configuration for a phase.
  895                           // TODO: this is all kind of backwards from the POMM. Let's align it all under 2.1.
  896                           //   We should create a new lifecycle executor for modelVersion >5.0.0
  897                           for ( Iterator j = lifecycleMappings.values().iterator(); j.hasNext(); )
  898                           {
  899                               List tasks = (List) j.next();
  900   
  901                               for ( Iterator k = tasks.iterator(); k.hasNext(); )
  902                               {
  903                                   MojoExecution exec = (MojoExecution) k.next();
  904   
  905                                   Xpp3Dom configuration = Xpp3Dom.mergeXpp3Dom(
  906                                       new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ), exec.getConfiguration() );
  907   
  908                                   exec.setConfiguration( configuration );
  909                               }
  910                           }
  911                       }
  912   
  913                   }
  914               }
  915   
  916               removeFromLifecycle( forkEntryPoints, lifecycleMappings );
  917           }
  918   
  919           MavenProject executionProject = new MavenProject( project );
  920           if ( targetPhase != null )
  921           {
  922               Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
  923   
  924               executeGoalWithLifecycle( targetPhase, forkEntryPoints, session, lifecycleMappings, executionProject,
  925                                         lifecycle );
  926           }
  927           else
  928           {
  929               String goal = mojoDescriptor.getExecuteGoal();
  930               MojoDescriptor desc = getMojoDescriptor( pluginDescriptor, goal );
  931               executeGoals( Collections.singletonList( new MojoExecution( desc ) ), forkEntryPoints, session,
  932                             executionProject );
  933           }
  934           project.setExecutionProject( executionProject );
  935       }
  936   
  937       private Lifecycle getLifecycleForPhase( String phase )
  938           throws BuildFailureException, LifecycleExecutionException
  939       {
  940           Lifecycle lifecycle = (Lifecycle) getPhaseToLifecycleMap().get( phase );
  941   
  942           if ( lifecycle == null )
  943           {
  944               throw new BuildFailureException( "Unable to find lifecycle for phase '" + phase + "'" );
  945           }
  946           return lifecycle;
  947       }
  948   
  949       private MojoDescriptor getMojoDescriptor( PluginDescriptor pluginDescriptor, String goal )
  950           throws LifecycleExecutionException
  951       {
  952           MojoDescriptor desc = pluginDescriptor.getMojo( goal );
  953   
  954           if ( desc == null )
  955           {
  956               String message =
  957                   "Required goal '" + goal + "' not found in plugin '" + pluginDescriptor.getGoalPrefix() + "'";
  958               int index = goal.indexOf( ':' );
  959               if ( index >= 0 )
  960               {
  961                   String prefix = goal.substring( index + 1 );
  962                   if ( prefix.equals( pluginDescriptor.getGoalPrefix() ) )
  963                   {
  964                       message = message + " (goals should not be prefixed - try '" + prefix + "')";
  965                   }
  966               }
  967               throw new LifecycleExecutionException( message );
  968           }
  969           return desc;
  970       }
  971   
  972       private void removeFromLifecycle( Stack lifecycleForkers, Map lifecycleMappings )
  973       {
  974           for ( Iterator lifecycleIterator = lifecycleMappings.values().iterator(); lifecycleIterator.hasNext(); )
  975           {
  976               List tasks = (List) lifecycleIterator.next();
  977   
  978               for ( Iterator taskIterator = tasks.iterator(); taskIterator.hasNext(); )
  979               {
  980                   MojoExecution execution = (MojoExecution) taskIterator.next();
  981   
  982                   if ( lifecycleForkers.contains( execution.getMojoDescriptor() ) )
  983                   {
  984                       taskIterator.remove();
  985                       getLogger().warn( "Removing: " + execution.getMojoDescriptor().getGoal()
  986                                         + " from forked lifecycle, to prevent recursive invocation." );
  987                   }
  988               }
  989           }
  990       }
  991   
  992       private Map constructLifecycleMappings( MavenSession session, String selectedPhase, MavenProject project,
  993                                               Lifecycle lifecycle )
  994           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
  995       {
  996           // first, bind those associated with the packaging
  997           Map lifecycleMappings = bindLifecycleForPackaging( session, selectedPhase, project, lifecycle );
  998   
  999           // next, loop over plugins and for any that have a phase, bind it
 1000           for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1001           {
 1002               Plugin plugin = (Plugin) i.next();
 1003   
 1004               bindPluginToLifecycle( plugin, session, lifecycleMappings, project );
 1005           }
 1006   
 1007           return lifecycleMappings;
 1008       }
 1009   
 1010       private Map bindLifecycleForPackaging( MavenSession session, String selectedPhase, MavenProject project,
 1011                                              Lifecycle lifecycle )
 1012           throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1013       {
 1014           Map mappings = findMappingsForLifecycle( session, project, lifecycle );
 1015   
 1016           List optionalMojos = findOptionalMojosForLifecycle( session, project, lifecycle );
 1017   
 1018           Map lifecycleMappings = new HashMap();
 1019   
 1020           for ( Iterator i = lifecycle.getPhases().iterator(); i.hasNext(); )
 1021           {
 1022               String phase = (String) i.next();
 1023   
 1024               String phaseTasks = (String) mappings.get( phase );
 1025   
 1026               if ( phaseTasks != null )
 1027               {
 1028                   for ( StringTokenizer tok = new StringTokenizer( phaseTasks, "," ); tok.hasMoreTokens(); )
 1029                   {
 1030                       String goal = tok.nextToken().trim();
 1031   
 1032                       // Not from the CLI, don't use prefix
 1033                       MojoDescriptor mojoDescriptor = getMojoDescriptor( goal, session, project, selectedPhase, false,
 1034                                                                          optionalMojos.contains( goal ) );
 1035   
 1036                       if ( mojoDescriptor == null )
 1037                       {
 1038                           continue;
 1039                       }
 1040   
 1041                       if ( mojoDescriptor.isDirectInvocationOnly() )
 1042                       {
 1043                           throw new LifecycleExecutionException( "Mojo: \'" + goal +
 1044                               "\' requires direct invocation. It cannot be used as part of lifecycle: \'" +
 1045                               project.getPackaging() + "\'." );
 1046                       }
 1047   
 1048                       addToLifecycleMappings( lifecycleMappings, phase, new MojoExecution( mojoDescriptor ),
 1049                                               session.getSettings() );
 1050                   }
 1051               }
 1052   
 1053               if ( phase.equals( selectedPhase ) )
 1054               {
 1055                   break;
 1056               }
 1057           }
 1058   
 1059           return lifecycleMappings;
 1060       }
 1061   
 1062       private Map findMappingsForLifecycle( MavenSession session, MavenProject project, Lifecycle lifecycle )
 1063           throws LifecycleExecutionException, PluginNotFoundException
 1064       {
 1065           String packaging = project.getPackaging();
 1066           Map mappings = null;
 1067   
 1068           LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging,
 1069                                                                  session.getSettings(), session.getLocalRepository() );
 1070           if ( m != null )
 1071           {
 1072               mappings = m.getPhases( lifecycle.getId() );
 1073           }
 1074   
 1075           Map defaultMappings = lifecycle.getDefaultPhases();
 1076   
 1077           if ( mappings == null )
 1078           {
 1079               try
 1080               {
 1081                   m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
 1082                   mappings = m.getPhases( lifecycle.getId() );
 1083               }
 1084               catch ( ComponentLookupException e )
 1085               {
 1086                   if ( defaultMappings == null )
 1087                   {
 1088                       throw new LifecycleExecutionException(
 1089                           "Cannot find lifecycle mapping for packaging: \'" + packaging + "\'.", e );
 1090                   }
 1091               }
 1092           }
 1093   
 1094           if ( mappings == null )
 1095           {
 1096               if ( defaultMappings == null )
 1097               {
 1098                   throw new LifecycleExecutionException(
 1099                       "Cannot find lifecycle mapping for packaging: \'" + packaging + "\', and there is no default" );
 1100               }
 1101               else
 1102               {
 1103                   mappings = defaultMappings;
 1104               }
 1105           }
 1106   
 1107           return mappings;
 1108       }
 1109   
 1110       private List findOptionalMojosForLifecycle( MavenSession session, MavenProject project, Lifecycle lifecycle )
 1111           throws LifecycleExecutionException, PluginNotFoundException
 1112       {
 1113           String packaging = project.getPackaging();
 1114           List optionalMojos = null;
 1115   
 1116           LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session
 1117               .getSettings(), session.getLocalRepository() );
 1118   
 1119           if ( m != null )
 1120           {
 1121               optionalMojos = m.getOptionalMojos( lifecycle.getId() );
 1122           }
 1123   
 1124           if ( optionalMojos == null )
 1125           {
 1126               try
 1127               {
 1128                   m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
 1129                   optionalMojos = m.getOptionalMojos( lifecycle.getId() );
 1130               }
 1131               catch ( ComponentLookupException e )
 1132               {
 1133                   getLogger().debug( "Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle ID: " +
 1134                       lifecycle.getId() + ". Error: " + e.getMessage(), e );
 1135               }
 1136           }
 1137   
 1138           if ( optionalMojos == null )
 1139           {
 1140               optionalMojos = Collections.EMPTY_LIST;
 1141           }
 1142   
 1143           return optionalMojos;
 1144       }
 1145   
 1146       private Object findExtension( MavenProject project, String role, String roleHint, Settings settings,
 1147                                     ArtifactRepository localRepository )
 1148           throws LifecycleExecutionException, PluginNotFoundException
 1149       {
 1150           Object pluginComponent = null;
 1151   
 1152           for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext() && pluginComponent == null; )
 1153           {
 1154               Plugin plugin = (Plugin) i.next();
 1155   
 1156               if ( plugin.isExtensions() )
 1157               {
 1158                   verifyPlugin( plugin, project, settings, localRepository );
 1159   
 1160                   // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
 1161                   try
 1162                   {
 1163                       pluginComponent = pluginManager.getPluginComponent( plugin, role, roleHint );
 1164                   }
 1165                   catch ( ComponentLookupException e )
 1166                   {
 1167                       getLogger().debug( "Unable to find the lifecycle component in the extension", e );
 1168                   }
 1169                   catch ( PluginManagerException e )
 1170                   {
 1171                       throw new LifecycleExecutionException(
 1172                           "Error getting extensions from the plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1173                   }
 1174               }
 1175           }
 1176           return pluginComponent;
 1177       }
 1178   
 1179       /**
 1180        * @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
 1181        * lookup directly, or have them passed in
 1182        */
 1183       private Map findArtifactTypeHandlers( MavenProject project, Settings settings, ArtifactRepository localRepository )
 1184           throws LifecycleExecutionException, PluginNotFoundException
 1185       {
 1186           Map map = new HashMap();
 1187           for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1188           {
 1189               Plugin plugin = (Plugin) i.next();
 1190   
 1191               if ( plugin.isExtensions() )
 1192               {
 1193                   verifyPlugin( plugin, project, settings, localRepository );
 1194   
 1195                   // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
 1196                   try
 1197                   {
 1198                       Map components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
 1199                       map.putAll( components );
 1200                   }
 1201                   catch ( ComponentLookupException e )
 1202                   {
 1203                       getLogger().debug( "Unable to find the lifecycle component in the extension", e );
 1204                   }
 1205                   catch ( PluginManagerException e )
 1206                   {
 1207                       throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
 1208                           plugin.getKey() + "': " + e.getMessage(), e );
 1209                   }
 1210   
 1211                   // shudder...
 1212                   for ( Iterator j = map.values().iterator(); j.hasNext(); )
 1213                   {
 1214                       ArtifactHandler handler = (ArtifactHandler) j.next();
 1215                       if ( project.getPackaging().equals( handler.getPackaging() ) )
 1216                       {
 1217                           project.getArtifact().setArtifactHandler( handler );
 1218                       }
 1219                   }
 1220               }
 1221           }
 1222           return map;
 1223       }
 1224   
 1225       /**
 1226        * Take each mojo contained with a plugin, look to see whether it contributes to a
 1227        * phase in the lifecycle and if it does place it at the end of the list of goals
 1228        * to execute for that given phase.
 1229        *
 1230        * @param project
 1231        * @param session
 1232        */
 1233       private void bindPluginToLifecycle( Plugin plugin, MavenSession session, Map phaseMap, MavenProject project )
 1234           throws LifecycleExecutionException, PluginNotFoundException
 1235       {
 1236           Settings settings = session.getSettings();
 1237   
 1238           PluginDescriptor pluginDescriptor =
 1239               verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
 1240   
 1241           if ( pluginDescriptor.getMojos() != null && !pluginDescriptor.getMojos().isEmpty() )
 1242           {
 1243               // use the plugin if inherit was true in a base class, or it is in the current POM, otherwise use the default inheritence setting
 1244               if ( plugin.isInheritanceApplied() || pluginDescriptor.isInheritedByDefault() )
 1245               {
 1246                   if ( plugin.getGoals() != null )
 1247                   {
 1248                       getLogger().error(
 1249                           "Plugin contains a <goals/> section: this is IGNORED - please use <executions/> instead." );
 1250                   }
 1251   
 1252                   List executions = plugin.getExecutions();
 1253   
 1254                   if ( executions != null )
 1255                   {
 1256                       for ( Iterator it = executions.iterator(); it.hasNext(); )
 1257                       {
 1258                           PluginExecution execution = (PluginExecution) it.next();
 1259   
 1260                           bindExecutionToLifecycle( pluginDescriptor, phaseMap, execution, settings );
 1261                       }
 1262                   }
 1263               }
 1264           }
 1265       }
 1266   
 1267       private PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, Settings settings,
 1268                                              ArtifactRepository localRepository )
 1269           throws LifecycleExecutionException, PluginNotFoundException
 1270       {
 1271           PluginDescriptor pluginDescriptor;
 1272           try
 1273           {
 1274               pluginDescriptor = pluginManager.verifyPlugin( plugin, project, settings, localRepository );
 1275           }
 1276           catch ( PluginManagerException e )
 1277           {
 1278               throw new LifecycleExecutionException(
 1279                   "Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1280           }
 1281           catch ( PluginVersionResolutionException e )
 1282           {
 1283               throw new LifecycleExecutionException( e.getMessage(), e );
 1284           }
 1285           catch ( InvalidVersionSpecificationException e )
 1286           {
 1287               throw new LifecycleExecutionException( e.getMessage(), e );
 1288           }
 1289           catch ( InvalidPluginException e )
 1290           {
 1291               throw new LifecycleExecutionException( e.getMessage(), e );
 1292           }
 1293           catch ( ArtifactNotFoundException e )
 1294           {
 1295               throw new LifecycleExecutionException( e.getMessage(), e );
 1296           }
 1297           catch ( ArtifactResolutionException e )
 1298           {
 1299               throw new LifecycleExecutionException( e.getMessage(), e );
 1300           }
 1301           catch ( PluginVersionNotFoundException e )
 1302           {
 1303               throw new LifecycleExecutionException( e.getMessage(), e );
 1304           }
 1305           return pluginDescriptor;
 1306       }
 1307   
 1308       private PluginDescriptor verifyReportPlugin( ReportPlugin plugin, MavenProject project, MavenSession session )
 1309           throws LifecycleExecutionException, PluginNotFoundException
 1310       {
 1311           PluginDescriptor pluginDescriptor;
 1312           try
 1313           {
 1314               pluginDescriptor = pluginManager.verifyReportPlugin( plugin, project, session );
 1315           }
 1316           catch ( PluginManagerException e )
 1317           {
 1318               throw new LifecycleExecutionException(
 1319                   "Internal error in the plugin manager getting report '" + plugin.getKey() + "': " + e.getMessage(), e );
 1320           }
 1321           catch ( PluginVersionResolutionException e )
 1322           {
 1323               throw new LifecycleExecutionException( e.getMessage(), e );
 1324           }
 1325           catch ( InvalidVersionSpecificationException e )
 1326           {
 1327               throw new LifecycleExecutionException( e.getMessage(), e );
 1328           }
 1329           catch ( InvalidPluginException e )
 1330           {
 1331               throw new LifecycleExecutionException( e.getMessage(), e );
 1332           }
 1333           catch ( ArtifactNotFoundException e )
 1334           {
 1335               throw new LifecycleExecutionException( e.getMessage(), e );
 1336           }
 1337           catch ( ArtifactResolutionException e )
 1338           {
 1339               throw new LifecycleExecutionException( e.getMessage(), e );
 1340           }
 1341           catch ( PluginVersionNotFoundException e )
 1342           {
 1343               throw new LifecycleExecutionException( e.getMessage(), e );
 1344           }
 1345           return pluginDescriptor;
 1346       }
 1347   
 1348       private void bindExecutionToLifecycle( PluginDescriptor pluginDescriptor, Map phaseMap, PluginExecution execution,
 1349                                              Settings settings )
 1350           throws LifecycleExecutionException
 1351       {
 1352           for ( Iterator i = execution.getGoals().iterator(); i.hasNext(); )
 1353           {
 1354               String goal = (String) i.next();
 1355   
 1356               MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
 1357               if ( mojoDescriptor == null )
 1358               {
 1359                   throw new LifecycleExecutionException(
 1360                       "'" + goal + "' was specified in an execution, but not found in the plugin" );
 1361               }
 1362   
 1363               // We have to check to see that the inheritance rules have been applied before binding this mojo.
 1364               if ( execution.isInheritanceApplied() || mojoDescriptor.isInheritedByDefault() )
 1365               {
 1366                   MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
 1367   
 1368                   String phase = execution.getPhase();
 1369   
 1370                   if ( phase == null )
 1371                   {
 1372                       // if the phase was not in the configuration, use the phase in the descriptor
 1373                       phase = mojoDescriptor.getPhase();
 1374                   }
 1375   
 1376                   if ( phase != null )
 1377                   {
 1378                       if ( mojoDescriptor.isDirectInvocationOnly() )
 1379                       {
 1380                           throw new LifecycleExecutionException( "Mojo: \'" + goal +
 1381                               "\' requires direct invocation. It cannot be used as part of the lifecycle (it was included via the POM)." );
 1382                       }
 1383   
 1384                       addToLifecycleMappings( phaseMap, phase, mojoExecution, settings );
 1385                   }
 1386               }
 1387           }
 1388       }
 1389   
 1390       private void addToLifecycleMappings( Map lifecycleMappings, String phase, MojoExecution mojoExecution,
 1391                                            Settings settings )
 1392       {
 1393           List goals = (List) lifecycleMappings.get( phase );
 1394   
 1395           if ( goals == null )
 1396           {
 1397               goals = new ArrayList();
 1398               lifecycleMappings.put( phase, goals );
 1399           }
 1400   
 1401           MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 1402           if ( settings.isOffline() && mojoDescriptor.isOnlineRequired() )
 1403           {
 1404               String goal = mojoDescriptor.getGoal();
 1405               getLogger().warn( goal + " requires online mode, but maven is currently offline. Disabling " + goal + "." );
 1406           }
 1407           else
 1408           {
 1409               goals.add( mojoExecution );
 1410           }
 1411       }
 1412   
 1413       private List processGoalChain( String task, Map phaseMap, Lifecycle lifecycle )
 1414       {
 1415           List goals = new ArrayList();
 1416   
 1417           // only execute up to the given phase
 1418           int index = lifecycle.getPhases().indexOf( task );
 1419   
 1420           for ( int i = 0; i <= index; i++ )
 1421           {
 1422               String p = (String) lifecycle.getPhases().get( i );
 1423   
 1424               List phaseGoals = (List) phaseMap.get( p );
 1425   
 1426               if ( phaseGoals != null )
 1427               {
 1428                   goals.addAll( phaseGoals );
 1429               }
 1430           }
 1431           return goals;
 1432       }
 1433   
 1434       private MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project,
 1435                                                 String invokedVia, boolean canUsePrefix, boolean isOptionalMojo )
 1436           throws BuildFailureException, LifecycleExecutionException, PluginNotFoundException
 1437       {
 1438           String goal;
 1439           Plugin plugin;
 1440   
 1441           PluginDescriptor pluginDescriptor = null;
 1442   
 1443           try
 1444           {
 1445               StringTokenizer tok = new StringTokenizer( task, ":" );
 1446               int numTokens = tok.countTokens();
 1447   
 1448               if ( numTokens == 2 )
 1449               {
 1450                   if ( !canUsePrefix )
 1451                   {
 1452                       String msg = "Mapped-prefix lookup of mojos are only supported from direct invocation. " +
 1453                           "Please use specification of the form groupId:artifactId[:version]:goal instead. " +
 1454                           "(Offending mojo: \'" + task + "\', invoked via: \'" + invokedVia + "\')";
 1455                       throw new LifecycleExecutionException( msg );
 1456                   }
 1457   
 1458                   String prefix = tok.nextToken();
 1459                   goal = tok.nextToken();
 1460   
 1461                   // Steps for retrieving the plugin model instance:
 1462                   // 1. request directly from the plugin collector by prefix
 1463                   pluginDescriptor = pluginManager.getPluginDescriptorForPrefix( prefix );
 1464   
 1465                   // 2. look in the repository via search groups
 1466                   if ( pluginDescriptor == null )
 1467                   {
 1468                       plugin = pluginManager.getPluginDefinitionForPrefix( prefix, session, project );
 1469                   }
 1470                   else
 1471                   {
 1472                       plugin = new Plugin();
 1473   
 1474                       plugin.setGroupId( pluginDescriptor.getGroupId() );
 1475                       plugin.setArtifactId( pluginDescriptor.getArtifactId() );
 1476                       plugin.setVersion( pluginDescriptor.getVersion() );
 1477                   }
 1478   
 1479                   // 3. search plugins in the current POM
 1480                   if ( plugin == null )
 1481                   {
 1482                       for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1483                       {
 1484                           Plugin buildPlugin = (Plugin) i.next();
 1485   
 1486                           PluginDescriptor desc = verifyPlugin( buildPlugin, project, session.getSettings(), session
 1487                               .getLocalRepository() );
 1488                           if ( prefix.equals( desc.getGoalPrefix() ) )
 1489                           {
 1490                               plugin = buildPlugin;
 1491                           }
 1492                       }
 1493                   }
 1494   
 1495                   // 4. default to o.a.m.plugins and maven-<prefix>-plugin
 1496                   if ( plugin == null )
 1497                   {
 1498                       plugin = new Plugin();
 1499                       plugin.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
 1500                       plugin.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( prefix ) );
 1501                   }
 1502               }
 1503               else if ( numTokens == 3 || numTokens == 4 )
 1504               {
 1505                   plugin = new Plugin();
 1506   
 1507                   plugin.setGroupId( tok.nextToken() );
 1508                   plugin.setArtifactId( tok.nextToken() );
 1509   
 1510                   if ( numTokens == 4 )
 1511                   {
 1512                       plugin.setVersion( tok.nextToken() );
 1513                   }
 1514   
 1515                   goal = tok.nextToken();
 1516               }
 1517               else
 1518               {
 1519                   String message = "Invalid task '" + task + "': you must specify a valid lifecycle phase, or" +
 1520                       " a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal";
 1521                   throw new BuildFailureException( message );
 1522               }
 1523   
 1524               if ( plugin.getVersion() == null )
 1525               {
 1526                   for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1527                   {
 1528                       Plugin buildPlugin = (Plugin) i.next();
 1529   
 1530                       if ( buildPlugin.getKey().equals( plugin.getKey() ) )
 1531                       {
 1532                           plugin = buildPlugin;
 1533                           break;
 1534                       }
 1535                   }
 1536   
 1537                   project.injectPluginManagementInfo( plugin );
 1538               }
 1539   
 1540               if ( pluginDescriptor == null )
 1541               {
 1542                   pluginDescriptor = verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
 1543               }
 1544   
 1545               // this has been simplified from the old code that injected the plugin management stuff, since
 1546               // pluginManagement injection is now handled by the project method.
 1547               project.addPlugin( plugin );
 1548   
 1549               MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
 1550               if ( mojoDescriptor == null )
 1551               {
 1552                   if ( isOptionalMojo )
 1553                   {
 1554                       getLogger().info( "Skipping missing optional mojo: " + task );
 1555                   }
 1556                   else
 1557                   {
 1558                       throw new BuildFailureException( "Required goal not found: " + task + " in "
 1559                           + pluginDescriptor.getId() );
 1560                   }
 1561               }
 1562   
 1563               return mojoDescriptor;
 1564           }
 1565           catch ( PluginNotFoundException e )
 1566           {
 1567               if ( isOptionalMojo )
 1568               {
 1569                   getLogger().info( "Skipping missing optional mojo: " + task );
 1570                   getLogger().debug( "Mojo: " + task + " could not be found. Reason: " + e.getMessage(), e );
 1571               }
 1572               else
 1573               {
 1574                   throw e;
 1575               }
 1576           }
 1577   
 1578           return null;
 1579       }
 1580   
 1581       protected void line()
 1582       {
 1583           getLogger().info( "------------------------------------------------------------------------" );
 1584       }
 1585   
 1586       public Map getPhaseToLifecycleMap()
 1587           throws LifecycleExecutionException
 1588       {
 1589           if ( phaseToLifecycleMap == null )
 1590           {
 1591               phaseToLifecycleMap = new HashMap();
 1592   
 1593               for ( Iterator i = lifecycles.iterator(); i.hasNext(); )
 1594               {
 1595                   Lifecycle lifecycle = (Lifecycle) i.next();
 1596   
 1597                   for ( Iterator p = lifecycle.getPhases().iterator(); p.hasNext(); )
 1598                   {
 1599                       String phase = (String) p.next();
 1600   
 1601                       if ( phaseToLifecycleMap.containsKey( phase ) )
 1602                       {
 1603                           Lifecycle prevLifecycle = (Lifecycle) phaseToLifecycleMap.get( phase );
 1604                           throw new LifecycleExecutionException( "Phase '" + phase +
 1605                               "' is defined in more than one lifecycle: '" + lifecycle.getId() + "' and '" +
 1606                               prevLifecycle.getId() + "'" );
 1607                       }
 1608                       else
 1609                       {
 1610                           phaseToLifecycleMap.put( phase, lifecycle );
 1611                       }
 1612                   }
 1613               }
 1614           }
 1615           return phaseToLifecycleMap;
 1616       }
 1617   
 1618       private static class TaskSegment
 1619       {
 1620           private boolean aggregate;
 1621   
 1622           private List tasks = new ArrayList();
 1623   
 1624           TaskSegment()
 1625           {
 1626   
 1627           }
 1628   
 1629           TaskSegment( boolean aggregate )
 1630           {
 1631               this.aggregate = aggregate;
 1632           }
 1633   
 1634           public String toString()
 1635           {
 1636               StringBuffer message = new StringBuffer();
 1637   
 1638               message.append( " task-segment: [" );
 1639   
 1640               for ( Iterator it = tasks.iterator(); it.hasNext(); )
 1641               {
 1642                   String task = (String) it.next();
 1643   
 1644                   message.append( task );
 1645   
 1646                   if ( it.hasNext() )
 1647                   {
 1648                       message.append( ", " );
 1649                   }
 1650               }
 1651   
 1652               message.append( "]" );
 1653   
 1654               if ( aggregate )
 1655               {
 1656                   message.append( " (aggregator-style)" );
 1657               }
 1658   
 1659               return message.toString();
 1660           }
 1661   
 1662           boolean aggregate()
 1663           {
 1664               return aggregate;
 1665           }
 1666   
 1667           void add( String task )
 1668           {
 1669               tasks.add( task );
 1670           }
 1671   
 1672           List getTasks()
 1673           {
 1674               return tasks;
 1675           }
 1676       }
 1677   }

Save This Page
Home » maven-2.0.9-src » org.apache » maven » lifecycle » [javadoc | source]