Coverage Report - org.apache.maven.lifecycle.DefaultLifecycleExecutor
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultLifecycleExecutor
0 %
0/769
0 %
0/364
0
DefaultLifecycleExecutor$TaskSegment
0 %
0/22
0 %
0/6
0
 
 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.ConfigurationInterpolationException;
 24  
 import org.apache.maven.ConfigurationInterpolator;
 25  
 import org.apache.maven.artifact.handler.ArtifactHandler;
 26  
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 27  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 28  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 29  
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 30  
 import org.apache.maven.execution.MavenSession;
 31  
 import org.apache.maven.execution.ReactorManager;
 32  
 import org.apache.maven.extension.ExtensionManager;
 33  
 import org.apache.maven.lifecycle.mapping.LifecycleMapping;
 34  
 import org.apache.maven.model.Extension;
 35  
 import org.apache.maven.model.Plugin;
 36  
 import org.apache.maven.model.PluginExecution;
 37  
 import org.apache.maven.model.ReportPlugin;
 38  
 import org.apache.maven.model.ReportSet;
 39  
 import org.apache.maven.monitor.event.EventDispatcher;
 40  
 import org.apache.maven.monitor.event.MavenEvents;
 41  
 import org.apache.maven.plugin.InvalidPluginException;
 42  
 import org.apache.maven.plugin.MojoExecution;
 43  
 import org.apache.maven.plugin.MojoExecutionException;
 44  
 import org.apache.maven.plugin.MojoFailureException;
 45  
 import org.apache.maven.plugin.PluginConfigurationException;
 46  
 import org.apache.maven.plugin.PluginManager;
 47  
 import org.apache.maven.plugin.PluginManagerException;
 48  
 import org.apache.maven.plugin.PluginNotFoundException;
 49  
 import org.apache.maven.plugin.descriptor.MojoDescriptor;
 50  
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 51  
 import org.apache.maven.plugin.lifecycle.Execution;
 52  
 import org.apache.maven.plugin.lifecycle.Phase;
 53  
 import org.apache.maven.plugin.version.PluginVersionNotFoundException;
 54  
 import org.apache.maven.plugin.version.PluginVersionResolutionException;
 55  
 import org.apache.maven.project.MavenProject;
 56  
 import org.apache.maven.project.MavenProjectBuilder;
 57  
 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
 58  
 import org.apache.maven.project.interpolation.ModelInterpolationException;
 59  
 import org.apache.maven.project.interpolation.ModelInterpolator;
 60  
 import org.apache.maven.reporting.MavenReport;
 61  
 import org.apache.maven.settings.Settings;
 62  
 import org.codehaus.plexus.PlexusConstants;
 63  
 import org.codehaus.plexus.PlexusContainer;
 64  
 import org.codehaus.plexus.PlexusContainerException;
 65  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 66  
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 67  
 import org.codehaus.plexus.context.Context;
 68  
 import org.codehaus.plexus.context.ContextException;
 69  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 70  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 71  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 72  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
 73  
 import org.codehaus.plexus.util.StringUtils;
 74  
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 75  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 76  
 
 77  
 import java.io.IOException;
 78  
 import java.util.ArrayList;
 79  
 import java.util.Collections;
 80  
 import java.util.HashMap;
 81  
 import java.util.Iterator;
 82  
 import java.util.List;
 83  
 import java.util.Map;
 84  
 import java.util.Stack;
 85  
 import java.util.StringTokenizer;
 86  
 
 87  
 /**
 88  
  * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
 89  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 90  
  * @version $Id: DefaultLifecycleExecutor.java 799759 2009-07-31 22:19:49Z jdcasey $
 91  
  * @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)
 92  
  */
 93  0
 public class DefaultLifecycleExecutor
 94  
     extends AbstractLogEnabled
 95  
     implements LifecycleExecutor, Initializable, Contextualizable
 96  
 {
 97  
     // ----------------------------------------------------------------------
 98  
     // Components
 99  
     // ----------------------------------------------------------------------
 100  
 
 101  
     private PluginManager pluginManager;
 102  
 
 103  
     private ExtensionManager extensionManager;
 104  
 
 105  
     private List lifecycles;
 106  
 
 107  
     private ArtifactHandlerManager artifactHandlerManager;
 108  
 
 109  
     private List defaultReports;
 110  
 
 111  
     private Map phaseToLifecycleMap;
 112  
 
 113  
     private MavenProjectBuilder mavenProjectBuilder;
 114  
 
 115  
     private ModelInterpolator modelInterpolator;
 116  
     
 117  
     private ConfigurationInterpolator configInterpolator;
 118  
 
 119  
     // ----------------------------------------------------------------------
 120  
     //
 121  
     // ----------------------------------------------------------------------
 122  
 
 123  
     /**
 124  
      * Execute a task. Each task may be a phase in the lifecycle or the
 125  
      * execution of a mojo.
 126  
      *
 127  
      * @param session
 128  
      * @param rm
 129  
      * @param dispatcher
 130  
      */
 131  
     public void execute( final MavenSession session, final ReactorManager rm, final EventDispatcher dispatcher )
 132  
         throws BuildFailureException, LifecycleExecutionException
 133  
     {
 134  
         // TODO: This is dangerous, particularly when it's just a collection of loose-leaf projects being built
 135  
         // within the same reactor (using an inclusion pattern to gather them up)...
 136  0
         MavenProject rootProject = rm.getTopLevelProject();
 137  
 
 138  0
         List goals = session.getGoals();
 139  
 
 140  0
         if ( goals.isEmpty() && rootProject != null )
 141  
         {
 142  0
             String goal = rootProject.getDefaultGoal();
 143  
 
 144  0
             if ( goal != null )
 145  
             {
 146  0
                 goals = Collections.singletonList( goal );
 147  
             }
 148  
         }
 149  
 
 150  0
         if ( goals.isEmpty() )
 151  
         {
 152  0
             StringBuffer buffer = new StringBuffer( 1024 );
 153  
 
 154  0
             buffer.append( "\n\n" );
 155  0
             buffer.append( "You must specify at least one goal or lifecycle phase to perform build steps.\n" );
 156  0
             buffer.append( "The following list illustrates some commonly used build commands:\n\n" );
 157  0
             buffer.append( "  mvn clean\n" );
 158  0
             buffer.append( "    Deletes any build output (e.g. class files or JARs).\n" );
 159  0
             buffer.append( "  mvn test\n" );
 160  0
             buffer.append( "    Runs the unit tests for the project.\n" );
 161  0
             buffer.append( "  mvn install\n" );
 162  0
             buffer.append( "    Copies the project artifacts into your local repository.\n" );
 163  0
             buffer.append( "  mvn deploy\n" );
 164  0
             buffer.append( "    Copies the project artifacts into the remote repository.\n" );
 165  0
             buffer.append( "  mvn site\n" );
 166  0
             buffer.append( "    Creates project documentation (e.g. reports or Javadoc).\n\n" );
 167  0
             buffer.append( "Please see\n" );
 168  0
             buffer.append( "http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html\n" );
 169  0
             buffer.append( "for a complete description of available lifecycle phases.\n\n" );
 170  0
             buffer.append( "Use \"mvn --help\" to show general usage information about Maven's command line.\n\n" );
 171  
 
 172  0
             throw new BuildFailureException( buffer.toString() );
 173  
         }
 174  
 
 175  0
         List taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject );
 176  
 
 177  
         // TODO: probably don't want to do all this up front
 178  0
         findExtensions( session );
 179  
 
 180  0
         executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
 181  0
     }
 182  
 
 183  
     private void findExtensions( final MavenSession session )
 184  
         throws LifecycleExecutionException
 185  
     {
 186  
         // TODO: MNG-4081. What about extensions within the current reactor??
 187  0
         Map<String, ArtifactHandler> handlers = new HashMap<String, ArtifactHandler>();
 188  0
         for ( MavenProject project : session.getSortedProjects() )
 189  
         {
 190  0
             for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
 191  
             {
 192  0
                 Extension extension = (Extension) j.next();
 193  
                 try
 194  
                 {
 195  0
                     getLogger().debug( "Adding extension: " + extension );
 196  0
                     extensionManager.addExtension( extension, project, session.getLocalRepository() );
 197  
                 }
 198  0
                 catch ( PlexusContainerException e )
 199  
                 {
 200  0
                     throw new LifecycleExecutionException( "Unable to initialise extensions", e );
 201  
                 }
 202  0
                 catch ( ArtifactResolutionException e )
 203  
                 {
 204  0
                     throw new LifecycleExecutionException( e.getMessage(), e );
 205  
                 }
 206  0
                 catch ( ArtifactNotFoundException e )
 207  
                 {
 208  0
                     throw new LifecycleExecutionException( e.getMessage(), e );
 209  0
                 }
 210  0
             }
 211  
 
 212  
         }
 213  
         
 214  0
         extensionManager.registerWagons();
 215  
         
 216  0
         handlers.putAll( extensionManager.getArtifactTypeHandlers() );
 217  
 
 218  0
         for ( MavenProject project : session.getSortedProjects() )
 219  
         {
 220  
             try
 221  
             {
 222  0
                 handlers.putAll( findArtifactTypeHandlersInPlugins( project, session ) );
 223  
 
 224  
                 // shudder...
 225  0
                 for ( ArtifactHandler handler : handlers.values() )
 226  
                 {
 227  0
                     if ( project.getPackaging().equals( handler.getPackaging() ) )
 228  
                     {
 229  0
                         project.getArtifact().setArtifactHandler( handler );
 230  
                         
 231  
                         // NOTE: Adding this (maven 2.2.1) to short-circuit things. This means first match is used, NOT LAST.
 232  0
                         break;
 233  
                     }
 234  
                 }
 235  
             }
 236  0
             catch ( PluginNotFoundException e )
 237  
             {
 238  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 239  0
             }
 240  
         }
 241  
         
 242  0
         artifactHandlerManager.addHandlers( handlers );
 243  0
     }
 244  
 
 245  
     private void executeTaskSegments( final List taskSegments, final ReactorManager rm, final MavenSession session,
 246  
                                       final MavenProject rootProject, final EventDispatcher dispatcher )
 247  
         throws LifecycleExecutionException, BuildFailureException
 248  
     {
 249  0
         for ( Iterator it = taskSegments.iterator(); it.hasNext(); )
 250  
         {
 251  0
             TaskSegment segment = (TaskSegment) it.next();
 252  
 
 253  0
             if ( segment.aggregate() )
 254  
             {
 255  0
                 if ( !rm.isBlackListed( rootProject ) )
 256  
                 {
 257  0
                     line();
 258  
 
 259  0
                     getLogger().info( "Building " + rootProject.getName() );
 260  
 
 261  0
                     getLogger().info( "  " + segment );
 262  
 
 263  0
                     line();
 264  
 
 265  
                     // !! This is ripe for refactoring to an aspect.
 266  
                     // Event monitoring.
 267  0
                     String event = MavenEvents.PROJECT_EXECUTION;
 268  
 
 269  0
                     long buildStartTime = System.currentTimeMillis();
 270  
 
 271  0
                     String target = rootProject.getId() + " ( " + segment + " )";
 272  
 
 273  0
                     dispatcher.dispatchStart( event, target );
 274  
 
 275  
                     try
 276  
                     {
 277  0
                         session.setCurrentProject( rootProject );
 278  
 
 279  
                         // only call once, with the top-level project (assumed to be provided as a parameter)...
 280  0
                         for ( Iterator goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); )
 281  
                         {
 282  0
                             String task = (String) goalIterator.next();
 283  
 
 284  0
                             executeGoalAndHandleFailures( task, session, rootProject, dispatcher, event, rm, buildStartTime,
 285  
                                                           target );
 286  0
                         }
 287  
 
 288  0
                         rm.registerBuildSuccess( rootProject, System.currentTimeMillis() - buildStartTime );
 289  
 
 290  
                     }
 291  
                     finally
 292  
                     {
 293  0
                         session.setCurrentProject( null );
 294  0
                     }
 295  
 
 296  0
                     dispatcher.dispatchEnd( event, target );
 297  0
                 }
 298  
                 else
 299  
                 {
 300  0
                     line();
 301  
 
 302  0
                     getLogger().info( "SKIPPING " + rootProject.getName() );
 303  
 
 304  0
                     getLogger().info( "  " + segment );
 305  
 
 306  0
                     getLogger().info(
 307  
                         "This project has been banned from further executions due to previous failures." );
 308  
 
 309  0
                     line();
 310  
                 }
 311  
             }
 312  
             else
 313  
             {
 314  0
                 List sortedProjects = session.getSortedProjects();
 315  
 
 316  
                 // iterate over projects, and execute on each...
 317  0
                 for ( Iterator projectIterator = sortedProjects.iterator(); projectIterator.hasNext(); )
 318  
                 {
 319  0
                     MavenProject currentProject = (MavenProject) projectIterator.next();
 320  
 
 321  0
                     if ( !rm.isBlackListed( currentProject ) )
 322  
                     {
 323  0
                         line();
 324  
 
 325  0
                         getLogger().info( "Building " + currentProject.getName() );
 326  
 
 327  0
                         getLogger().info( "  " + segment );
 328  
 
 329  0
                         line();
 330  
 
 331  
                         // !! This is ripe for refactoring to an aspect.
 332  
                         // Event monitoring.
 333  0
                         String event = MavenEvents.PROJECT_EXECUTION;
 334  
 
 335  0
                         long buildStartTime = System.currentTimeMillis();
 336  
 
 337  0
                         String target = currentProject.getId() + " ( " + segment + " )";
 338  0
                         dispatcher.dispatchStart( event, target );
 339  
 
 340  
                         try
 341  
                         {
 342  0
                             session.setCurrentProject( currentProject );
 343  
 
 344  0
                             for ( Iterator goalIterator = segment.getTasks().iterator(); goalIterator.hasNext(); )
 345  
                             {
 346  0
                                 String task = (String) goalIterator.next();
 347  
 
 348  0
                                 executeGoalAndHandleFailures( task, session, currentProject, dispatcher, event, rm,
 349  
                                                               buildStartTime, target );
 350  0
                             }
 351  
 
 352  
                         }
 353  
                         finally
 354  
                         {
 355  0
                             session.setCurrentProject( null );
 356  0
                         }
 357  
 
 358  0
                         rm.registerBuildSuccess( currentProject, System.currentTimeMillis() - buildStartTime );
 359  
 
 360  0
                         dispatcher.dispatchEnd( event, target );
 361  0
                     }
 362  
                     else
 363  
                     {
 364  0
                         line();
 365  
 
 366  0
                         getLogger().info( "SKIPPING " + currentProject.getName() );
 367  
 
 368  0
                         getLogger().info( "  " + segment );
 369  
 
 370  0
                         getLogger().info(
 371  
                             "This project has been banned from further executions due to previous failures." );
 372  
 
 373  0
                         line();
 374  
                     }
 375  0
                 }
 376  
             }
 377  0
         }
 378  0
     }
 379  
 
 380  
     private void executeGoalAndHandleFailures( final String task, final MavenSession session, final MavenProject project,
 381  
                                                final EventDispatcher dispatcher, final String event, final ReactorManager rm,
 382  
                                                final long buildStartTime, final String target )
 383  
         throws BuildFailureException, LifecycleExecutionException
 384  
     {
 385  
         try
 386  
         {
 387  0
             executeGoal( task, session, project );
 388  
         }
 389  0
         catch ( LifecycleExecutionException e )
 390  
         {
 391  0
             dispatcher.dispatchError( event, target, e );
 392  
 
 393  0
             if ( handleExecutionFailure( rm, project, e, task, buildStartTime ) )
 394  
             {
 395  0
                 throw e;
 396  
             }
 397  
         }
 398  0
         catch ( BuildFailureException e )
 399  
         {
 400  0
             dispatcher.dispatchError( event, target, e );
 401  
 
 402  0
             if ( handleExecutionFailure( rm, project, e, task, buildStartTime ) )
 403  
             {
 404  0
                 throw e;
 405  
             }
 406  0
         }
 407  0
     }
 408  
 
 409  
     private boolean handleExecutionFailure( final ReactorManager rm, final MavenProject project, final Exception e, final String task,
 410  
                                             final long buildStartTime )
 411  
     {
 412  0
         rm.registerBuildFailure( project, e, task, System.currentTimeMillis() - buildStartTime );
 413  
 
 414  0
         if ( ReactorManager.FAIL_FAST.equals( rm.getFailureBehavior() ) )
 415  
         {
 416  0
             return true;
 417  
         }
 418  0
         else if ( ReactorManager.FAIL_AT_END.equals( rm.getFailureBehavior() ) )
 419  
         {
 420  0
             rm.blackList( project );
 421  
         }
 422  
         // if NEVER, don't blacklist
 423  0
         return false;
 424  
     }
 425  
 
 426  
     private List segmentTaskListByAggregationNeeds( final List tasks, final MavenSession session, final MavenProject project )
 427  
         throws LifecycleExecutionException, BuildFailureException
 428  
     {
 429  0
         List segments = new ArrayList();
 430  
 
 431  0
         if ( project != null )
 432  
         {
 433  
 
 434  0
             TaskSegment currentSegment = null;
 435  0
             for ( Iterator it = tasks.iterator(); it.hasNext(); )
 436  
             {
 437  0
                 String task = (String) it.next();
 438  
 
 439  
                 // if it's a phase, then we don't need to check whether it's an aggregator.
 440  
                 // simply add it to the current task partition.
 441  0
                 if ( getPhaseToLifecycleMap().containsKey( task ) )
 442  
                 {
 443  0
                     if ( currentSegment != null && currentSegment.aggregate() )
 444  
                     {
 445  0
                         segments.add( currentSegment );
 446  0
                         currentSegment = null;
 447  
                     }
 448  
 
 449  0
                     if ( currentSegment == null )
 450  
                     {
 451  0
                         currentSegment = new TaskSegment();
 452  
                     }
 453  
 
 454  0
                     currentSegment.add( task );
 455  
                 }
 456  
                 else
 457  
                 {
 458  0
                     MojoDescriptor mojo = null;
 459  
                     try
 460  
                     {
 461  
                         // definitely a CLI goal, can use prefix
 462  0
                         mojo = getMojoDescriptor( task, session, project, task, true, false );
 463  
                     }
 464  0
                     catch ( PluginNotFoundException e )
 465  
                     {
 466  
                         // TODO: shouldn't hit this, investigate using the same resolution logic as otheres for plugins in the reactor
 467  0
                         getLogger().info(
 468  
                             "Cannot find mojo descriptor for: \'" + task + "\' - Treating as non-aggregator." );
 469  0
                         getLogger().debug( "", e );
 470  0
                     }
 471  
 
 472  
                     // if the mojo descriptor was found, determine aggregator status according to:
 473  
                     // 1. whether the mojo declares itself an aggregator
 474  
                     // 2. whether the mojo DOES NOT require a project to function (implicitly avoid reactor)
 475  0
                     if ( mojo != null && ( mojo.isAggregator() || !mojo.isProjectRequired() ) )
 476  
                     {
 477  0
                         if ( currentSegment != null && !currentSegment.aggregate() )
 478  
                         {
 479  0
                             segments.add( currentSegment );
 480  0
                             currentSegment = null;
 481  
                         }
 482  
 
 483  0
                         if ( currentSegment == null )
 484  
                         {
 485  0
                             currentSegment = new TaskSegment( true );
 486  
                         }
 487  
 
 488  0
                         currentSegment.add( task );
 489  
                     }
 490  
                     else
 491  
                     {
 492  0
                         if ( currentSegment != null && currentSegment.aggregate() )
 493  
                         {
 494  0
                             segments.add( currentSegment );
 495  0
                             currentSegment = null;
 496  
                         }
 497  
 
 498  0
                         if ( currentSegment == null )
 499  
                         {
 500  0
                             currentSegment = new TaskSegment();
 501  
                         }
 502  
 
 503  0
                         currentSegment.add( task );
 504  
                     }
 505  
                 }
 506  0
             }
 507  
 
 508  0
             segments.add( currentSegment );
 509  0
         }
 510  
         else
 511  
         {
 512  0
             TaskSegment segment = new TaskSegment( false );
 513  0
             for ( Iterator i = tasks.iterator(); i.hasNext(); )
 514  
             {
 515  0
                 segment.add( (String) i.next() );
 516  
             }
 517  0
             segments.add( segment );
 518  
         }
 519  
 
 520  0
         return segments;
 521  
     }
 522  
 
 523  
     private void executeGoal( final String task, final MavenSession session, final MavenProject project )
 524  
         throws LifecycleExecutionException, BuildFailureException
 525  
     {
 526  
         try
 527  
         {
 528  0
             Stack forkEntryPoints = new Stack();
 529  0
             if ( getPhaseToLifecycleMap().containsKey( task ) )
 530  
             {
 531  0
                 Lifecycle lifecycle = getLifecycleForPhase( task );
 532  
 
 533  
                 // we have a lifecycle phase, so lets bind all the necessary goals
 534  0
                 Map lifecycleMappings = constructLifecycleMappings( session, task, project, lifecycle );
 535  0
                 executeGoalWithLifecycle( task, forkEntryPoints, session, lifecycleMappings, project, lifecycle );
 536  0
             }
 537  
             else
 538  
             {
 539  0
                 executeStandaloneGoal( task, forkEntryPoints, session, project );
 540  
             }
 541  
         }
 542  0
         catch ( PluginNotFoundException e )
 543  
         {
 544  0
             throw new BuildFailureException( "A required plugin was not found: " + e.getMessage(), e );
 545  0
         }
 546  0
     }
 547  
 
 548  
     private void executeGoalWithLifecycle( final String task, final Stack forkEntryPoints, final MavenSession session,
 549  
                                            final Map lifecycleMappings, final MavenProject project, final Lifecycle lifecycle )
 550  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 551  
     {
 552  0
         List goals = processGoalChain( task, lifecycleMappings, lifecycle );
 553  
 
 554  0
         if ( !goals.isEmpty() )
 555  
         {
 556  0
             executeGoals( goals, forkEntryPoints, session, project );
 557  
         }
 558  
         else
 559  
         {
 560  0
             getLogger().info( "No goals needed for project - skipping" );
 561  
         }
 562  0
     }
 563  
 
 564  
     private void executeStandaloneGoal( final String task, final Stack forkEntryPoints, final MavenSession session, final MavenProject project )
 565  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 566  
     {
 567  
         // guaranteed to come from the CLI and not be part of a phase
 568  0
         MojoDescriptor mojoDescriptor = getMojoDescriptor( task, session, project, task, true, false );
 569  0
         executeGoals( Collections.singletonList( new MojoExecution( mojoDescriptor, MojoExecution.CLI_EXECUTION_ID ) ),
 570  
                       forkEntryPoints, session, project );
 571  0
     }
 572  
 
 573  
     private void executeGoals( final List goals, final Stack forkEntryPoints, final MavenSession session, final MavenProject project )
 574  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 575  
     {
 576  0
         for ( Iterator i = goals.iterator(); i.hasNext(); )
 577  
         {
 578  0
             MojoExecution mojoExecution = (MojoExecution) i.next();
 579  
 
 580  0
             MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 581  
             
 582  0
             PlexusConfiguration configuration = mojoDescriptor.getMojoConfiguration();
 583  0
             boolean usesReactorProjects = mojoDescriptor.isAggregator() || usesSessionOrReactorProjects( configuration );
 584  
             
 585  0
             if ( usesReactorProjects )
 586  
             {
 587  0
                 calculateAllConcreteStates( session );
 588  
             }
 589  
             else
 590  
             {
 591  0
                 calculateConcreteState( project, session, true );
 592  
             }
 593  
             
 594  0
             calculateConcreteConfiguration( mojoExecution, project, session );
 595  
             
 596  0
             List reportExecutions = null;
 597  0
             if ( mojoDescriptor.isRequiresReports() )
 598  
             {
 599  0
                 reportExecutions = getReportExecutions( project, forkEntryPoints, mojoExecution, session );
 600  
             }
 601  
             
 602  0
             boolean hasFork = false;
 603  0
             if ( mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null )
 604  
             {
 605  0
                 hasFork = true;
 606  
             }
 607  0
             else if ( reportExecutions != null )
 608  
             {
 609  0
                 for ( Iterator it = reportExecutions.iterator(); it.hasNext(); )
 610  
                 {
 611  0
                     MojoExecution reportExecution = (MojoExecution) it.next();
 612  0
                     MojoDescriptor reportDescriptor = reportExecution.getMojoDescriptor();
 613  0
                     if ( reportDescriptor.getExecutePhase() != null || reportDescriptor.getExecuteGoal() != null )
 614  
                     {
 615  0
                         hasFork = true;
 616  
                     }
 617  0
                 }
 618  
             }
 619  
             
 620  0
             if ( hasFork )
 621  
             {
 622  
                 // NOTE: This must always happen, regardless of treatment of reactorProjects below, because
 623  
                 // if we're in a forked execution right now, the current project will itself be an execution project of
 624  
                 // something in the reactorProjects list, and won't have a next-stage executionProject created
 625  
                 // for it otherwise, which leaves the project == null for the upcoming forked execution.
 626  0
                 createExecutionProject( project, session, true );
 627  
                 
 628  0
                 if ( usesReactorProjects )
 629  
                 {
 630  0
                     List reactorProjects = session.getSortedProjects();
 631  0
                     for ( Iterator it = reactorProjects.iterator(); it.hasNext(); )
 632  
                     {
 633  0
                         MavenProject reactorProject = (MavenProject) it.next();
 634  0
                         createExecutionProject( reactorProject, session, false );
 635  0
                     }
 636  
                 }
 637  
             }
 638  
 
 639  0
             if ( mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null )
 640  
             {
 641  0
                 forkEntryPoints.push( mojoDescriptor );
 642  
 
 643  0
                 forkLifecycle( mojoDescriptor, forkEntryPoints, session, project, mojoExecution.getExecutionId() );
 644  
 
 645  0
                 forkEntryPoints.pop();
 646  
             }
 647  
             
 648  0
             if ( mojoDescriptor.isRequiresReports() )
 649  
             {
 650  0
                 List reports = getReports( reportExecutions, project, mojoExecution, session );
 651  
 
 652  0
                 mojoExecution.setReports( reports );
 653  
 
 654  0
                 for ( Iterator j = mojoExecution.getForkedExecutions().iterator(); j.hasNext(); )
 655  
                 {
 656  0
                     MojoExecution forkedExecution = (MojoExecution) j.next();
 657  0
                     MojoDescriptor descriptor = forkedExecution.getMojoDescriptor();
 658  
 
 659  0
                     if ( descriptor.getExecutePhase() != null )
 660  
                     {
 661  0
                         forkEntryPoints.push( descriptor );
 662  
 
 663  0
                         forkLifecycle( descriptor, forkEntryPoints, session, project, forkedExecution.getExecutionId() );
 664  
 
 665  0
                         forkEntryPoints.pop();
 666  
                     }
 667  0
                 }
 668  
             }
 669  
             
 670  0
             if ( hasFork )
 671  
             {
 672  
                 // NOTE: This must always happen, regardless of treatment of reactorProjects below, because
 673  
                 // if we're in a forked execution right now, the current project will itself be an execution project of
 674  
                 // something in the reactorProjects list, and may not have had its own executionProject instance reset to 
 675  
                 // a concrete state again after the previous forked executions.
 676  0
                 calculateConcreteState( project.getExecutionProject(), session, true );
 677  
                 
 678  
                 // FIXME: Would be nice to find a way to cause the execution project to stay in a concrete state...
 679  
                 // TODO: Test this! It should be fixed, but I don't want to destabilize until I have the issue I'm working on fixed.
 680  0
                 if ( usesReactorProjects )
 681  
                 {
 682  0
                     calculateAllConcreteStates( session );
 683  0
                     List reactorProjects = session.getSortedProjects();
 684  0
                     for ( Iterator it = reactorProjects.iterator(); it.hasNext(); )
 685  
                     {
 686  0
                         MavenProject reactorProject = (MavenProject) it.next();
 687  0
                         calculateConcreteState( reactorProject.getExecutionProject(), session, false );
 688  0
                     }
 689  
                 }
 690  
             }
 691  
 
 692  
             try
 693  
             {
 694  0
                 pluginManager.executeMojo( project, mojoExecution, session );
 695  
             }
 696  0
             catch ( PluginManagerException e )
 697  
             {
 698  0
                 throw new LifecycleExecutionException( "Internal error in the plugin manager executing goal '" +
 699  
                     mojoDescriptor.getId() + "': " + e.getMessage(), e );
 700  
             }
 701  0
             catch ( ArtifactNotFoundException e )
 702  
             {
 703  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 704  
             }
 705  0
             catch ( InvalidDependencyVersionException e )
 706  
             {
 707  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 708  
             }
 709  0
             catch ( ArtifactResolutionException e )
 710  
             {
 711  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 712  
             }
 713  0
             catch ( MojoFailureException e )
 714  
             {
 715  0
                 throw new BuildFailureException( e.getMessage(), e );
 716  
             }
 717  0
             catch ( MojoExecutionException e )
 718  
             {
 719  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 720  
             }
 721  0
             catch ( PluginConfigurationException e )
 722  
             {
 723  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 724  0
             }
 725  0
         }
 726  0
     }
 727  
     
 728  
     private void createExecutionProject( final MavenProject project, final MavenSession session, final boolean processProjectReferences )
 729  
         throws LifecycleExecutionException
 730  
     {
 731  0
         MavenProject executionProject = new MavenProject( project );
 732  
         
 733  0
         calculateConcreteState( executionProject, session, processProjectReferences );
 734  
         
 735  0
         project.setExecutionProject( executionProject );
 736  0
     }
 737  
 
 738  
     private boolean usesSessionOrReactorProjects( final PlexusConfiguration configuration )
 739  
     {
 740  0
         String value = configuration != null ? String.valueOf( configuration ) : null;
 741  
         
 742  0
         if ( value != null )
 743  
         {
 744  0
             if ( value.indexOf( "${session" ) > -1 || value.indexOf( "${reactorProjects}" ) > -1 )
 745  
             {
 746  0
                 return true;
 747  
             }
 748  
         }
 749  
         
 750  0
         return false;
 751  
     }
 752  
 
 753  
     private void calculateConcreteConfiguration( final MojoExecution mojoExecution, final MavenProject project, final MavenSession session )
 754  
         throws LifecycleExecutionException
 755  
     {
 756  0
         if ( mojoExecution.getConfiguration() == null )
 757  
         {
 758  0
             return;
 759  
         }
 760  
         
 761  
         try
 762  
         {
 763  0
             mojoExecution.setConfiguration( (Xpp3Dom) configInterpolator.interpolate(
 764  
                                                                                       mojoExecution.getConfiguration(),
 765  
                                                                                       project,
 766  
                                                                                       session.getProjectBuilderConfiguration() ) );
 767  
         }
 768  0
         catch ( ConfigurationInterpolationException e )
 769  
         {
 770  0
             throw new LifecycleExecutionException( "Error interpolating configuration for: '" + mojoExecution.getMojoDescriptor().getRoleHint() +
 771  
                                                    "' (execution: '" + mojoExecution.getExecutionId() + "')", e );
 772  0
         }
 773  0
     }
 774  
     
 775  
     private void calculateAllConcreteStates( final MavenSession session )
 776  
         throws LifecycleExecutionException
 777  
     {
 778  0
         List projects = session.getSortedProjects();
 779  0
         if ( projects != null )
 780  
         {
 781  0
             for ( Iterator it = projects.iterator(); it.hasNext(); )
 782  
             {
 783  0
                 calculateConcreteState( (MavenProject) it.next(), session, false );
 784  
             }
 785  
         }
 786  0
     }
 787  
 
 788  
     private void calculateConcreteState( final MavenProject project, final MavenSession session, final boolean processReferences )
 789  
         throws LifecycleExecutionException
 790  
     {
 791  0
         if ( mavenProjectBuilder != null && project != null )
 792  
         {
 793  
             try
 794  
             {
 795  0
                 mavenProjectBuilder.calculateConcreteState( project, session.getProjectBuilderConfiguration(), processReferences );
 796  
             }
 797  0
             catch ( ModelInterpolationException e )
 798  
             {
 799  0
                 throw new LifecycleExecutionException( "Failed to calculate concrete state for project: " + project,
 800  
                                                          e );
 801  0
             }
 802  
         }
 803  0
     }
 804  
     
 805  
 //    private void restoreAllDynamicStates( MavenSession session )
 806  
 //        throws LifecycleExecutionException
 807  
 //    {
 808  
 //        List reactorProjects = session.getSortedProjects();
 809  
 //        if ( reactorProjects != null )
 810  
 //        {
 811  
 //            for ( Iterator it = reactorProjects.iterator(); it.hasNext(); )
 812  
 //            {
 813  
 //                MavenProject project = (MavenProject) it.next();
 814  
 //                restoreDynamicState( project, session, false );
 815  
 //            }
 816  
 //        }
 817  
 //    }
 818  
 //
 819  
 //    private void restoreDynamicState( MavenProject project, MavenSession session, boolean processReferences )
 820  
 //        throws LifecycleExecutionException
 821  
 //    {
 822  
 //        try
 823  
 //        {
 824  
 //            mavenProjectBuilder.restoreDynamicState( project, session.getProjectBuilderConfiguration(), processReferences );
 825  
 //        }
 826  
 //        catch ( ModelInterpolationException e )
 827  
 //        {
 828  
 //            throw new LifecycleExecutionException( "Failed to restore dynamic state for project: " + project, e );
 829  
 //        }
 830  
 //    }
 831  
 
 832  
     private List getReportExecutions( final MavenProject project, final Stack forkEntryPoints, final MojoExecution mojoExecution, final MavenSession session )
 833  
         throws LifecycleExecutionException, PluginNotFoundException
 834  
     {
 835  0
         List reportPlugins = project.getReportPlugins();
 836  
 
 837  0
         if ( project.getModel().getReports() != null )
 838  
         {
 839  0
             getLogger().error(
 840  
                 "Plugin contains a <reports/> section: this is IGNORED - please use <reporting/> instead." );
 841  
         }
 842  
 
 843  0
         if ( project.getReporting() == null || !project.getReporting().isExcludeDefaults() )
 844  
         {
 845  0
             if ( reportPlugins == null )
 846  
             {
 847  0
                 reportPlugins = new ArrayList();
 848  
             }
 849  
             else
 850  
             {
 851  0
                 reportPlugins = new ArrayList( reportPlugins );
 852  
             }
 853  
 
 854  0
             for ( Iterator i = defaultReports.iterator(); i.hasNext(); )
 855  
             {
 856  0
                 String report = (String) i.next();
 857  
 
 858  0
                 StringTokenizer tok = new StringTokenizer( report, ":" );
 859  0
                 int count = tok.countTokens();
 860  0
                 if ( count != 2 && count != 3 )
 861  
                 {
 862  0
                     getLogger().warn( "Invalid default report ignored: '" + report + "' (must be groupId:artifactId[:version])" );
 863  
                 }
 864  
                 else
 865  
                 {
 866  0
                     String groupId = tok.nextToken();
 867  0
                     String artifactId = tok.nextToken();
 868  0
                     String version = tok.hasMoreTokens() ? tok.nextToken() : null;
 869  
 
 870  0
                     boolean found = false;
 871  0
                     for ( Iterator j = reportPlugins.iterator(); j.hasNext() && !found; )
 872  
                     {
 873  0
                         ReportPlugin reportPlugin = (ReportPlugin) j.next();
 874  0
                         if ( reportPlugin.getGroupId().equals( groupId ) &&
 875  
                             reportPlugin.getArtifactId().equals( artifactId ) )
 876  
                         {
 877  0
                             found = true;
 878  
                         }
 879  0
                     }
 880  
 
 881  0
                     if ( !found )
 882  
                     {
 883  0
                         ReportPlugin reportPlugin = new ReportPlugin();
 884  0
                         reportPlugin.setGroupId( groupId );
 885  0
                         reportPlugin.setArtifactId( artifactId );
 886  0
                         reportPlugin.setVersion( version );
 887  0
                         reportPlugins.add( reportPlugin );
 888  
                     }
 889  
                 }
 890  0
             }
 891  
         }
 892  
 
 893  0
         List reports = new ArrayList();
 894  0
         if ( reportPlugins != null )
 895  
         {
 896  0
             for ( Iterator it = reportPlugins.iterator(); it.hasNext(); )
 897  
             {
 898  0
                 ReportPlugin reportPlugin = (ReportPlugin) it.next();
 899  
 
 900  0
                 List reportSets = reportPlugin.getReportSets();
 901  
 
 902  0
                 if ( reportSets == null || reportSets.isEmpty() )
 903  
                 {
 904  0
                     reports.addAll( getReportExecutions( reportPlugin, forkEntryPoints, null, project, session, mojoExecution ) );
 905  
                 }
 906  
                 else
 907  
                 {
 908  0
                     for ( Iterator j = reportSets.iterator(); j.hasNext(); )
 909  
                     {
 910  0
                         ReportSet reportSet = (ReportSet) j.next();
 911  
 
 912  0
                         reports.addAll( getReportExecutions( reportPlugin, forkEntryPoints, reportSet, project, session, mojoExecution ) );
 913  0
                     }
 914  
                 }
 915  0
             }
 916  
         }
 917  0
         return reports;
 918  
     }
 919  
     
 920  
     private List getReportExecutions( final ReportPlugin reportPlugin,
 921  
                              final Stack forkEntryPoints,
 922  
                              final ReportSet reportSet,
 923  
                              final MavenProject project,
 924  
                              final MavenSession session,
 925  
                              final MojoExecution mojoExecution )
 926  
         throws LifecycleExecutionException, PluginNotFoundException
 927  
     {
 928  0
         PluginDescriptor pluginDescriptor = verifyReportPlugin( reportPlugin, project, session );
 929  
 
 930  0
         List reports = new ArrayList();
 931  0
         for ( Iterator i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
 932  
         {
 933  0
             MojoDescriptor mojoDescriptor = (MojoDescriptor) i.next();
 934  0
             if ( forkEntryPoints.contains( mojoDescriptor ) )
 935  
             {
 936  0
                 getLogger().debug( "Omitting report: " + mojoDescriptor.getFullGoalName() + " from reports list. It initiated part of the fork currently executing." );
 937  0
                 continue;
 938  
             }
 939  
 
 940  
             // TODO: check ID is correct for reports
 941  
             // if the POM configured no reports, give all from plugin
 942  0
             if ( reportSet == null || reportSet.getReports().contains( mojoDescriptor.getGoal() ) )
 943  
             {
 944  0
                 String id = null;
 945  0
                 if ( reportSet != null )
 946  
                 {
 947  0
                     id = reportSet.getId();
 948  
                 }
 949  
                 else
 950  
                 {
 951  0
                     id = mojoExecution.getExecutionId();
 952  
                 }
 953  
                 
 954  
                 MojoExecution reportExecution;
 955  0
                 if ( id.startsWith( MojoExecution.DEFAULT_EXEC_ID_PREFIX ) )
 956  
                 {
 957  0
                     reportExecution = new MojoExecution( mojoDescriptor );
 958  
                 }
 959  
                 else
 960  
                 {
 961  0
                     reportExecution = new MojoExecution( mojoDescriptor, id );
 962  
                 }
 963  
 
 964  0
                 reports.add( reportExecution );
 965  
             }
 966  0
         }
 967  0
         return reports;
 968  
     }
 969  
 
 970  
     private List getReports( final List reportExecutions, final MavenProject project, final MojoExecution mojoExecution, final MavenSession session )
 971  
         throws LifecycleExecutionException
 972  
     {
 973  0
         List reports = new ArrayList();
 974  
         
 975  0
         for ( Iterator it = reportExecutions.iterator(); it.hasNext(); )
 976  
         {
 977  0
             MojoExecution reportExecution = (MojoExecution) it.next();
 978  0
             PluginDescriptor pluginDescriptor = reportExecution.getMojoDescriptor().getPluginDescriptor();
 979  
             
 980  
             try
 981  
             {
 982  0
                 MavenReport reportMojo = pluginManager.getReport( project, reportExecution, session );
 983  
 
 984  
                 // Comes back null if it was a plugin, not a report - these are mojos in the reporting plugins that are not reports
 985  0
                 if ( reportMojo != null )
 986  
                 {
 987  0
                     reports.add( reportMojo );
 988  0
                     mojoExecution.addMojoExecution( reportExecution );
 989  
                 }
 990  
             }
 991  0
             catch ( PluginManagerException e )
 992  
             {
 993  0
                 throw new LifecycleExecutionException(
 994  
                     "Error getting reports from the plugin '" + pluginDescriptor.getId() + "': " + e.getMessage(), e );
 995  
             }
 996  0
             catch ( PluginConfigurationException e )
 997  
             {
 998  0
                 throw new LifecycleExecutionException(
 999  
                     "Error getting reports from the plugin '" + pluginDescriptor.getId() + "'", e );
 1000  
             }
 1001  0
             catch ( ArtifactNotFoundException e )
 1002  
             {
 1003  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 1004  
             }
 1005  0
             catch ( ArtifactResolutionException e )
 1006  
             {
 1007  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 1008  0
             }
 1009  0
         }
 1010  
         
 1011  0
         return reports;
 1012  
     }
 1013  
 
 1014  
     private void forkLifecycle( final MojoDescriptor mojoDescriptor, final Stack ancestorLifecycleForkers, final MavenSession session,
 1015  
                                 final MavenProject project, final String executionId )
 1016  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1017  
     {
 1018  0
         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 1019  0
         getLogger().info( "Preparing " + pluginDescriptor.getGoalPrefix() + ":" + mojoDescriptor.getGoal() );
 1020  
 
 1021  0
         if ( mojoDescriptor.isAggregator() )
 1022  
         {
 1023  0
             for ( Iterator i = session.getSortedProjects().iterator(); i.hasNext(); )
 1024  
             {
 1025  0
                 MavenProject reactorProject = (MavenProject) i.next();
 1026  
                 
 1027  0
                 line();
 1028  
 
 1029  0
                 getLogger().info( "Building " + reactorProject.getName() );
 1030  
 
 1031  0
                 line();
 1032  
 
 1033  0
                 forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, reactorProject, executionId );
 1034  0
             }
 1035  
         }
 1036  
         else
 1037  
         {
 1038  0
             forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, project, executionId );
 1039  
         }
 1040  0
     }
 1041  
 
 1042  
     private void forkProjectLifecycle( final MojoDescriptor mojoDescriptor, final Stack forkEntryPoints, final MavenSession session,
 1043  
                                        MavenProject project, final String executionId )
 1044  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1045  
     {
 1046  0
         project = project.getExecutionProject();
 1047  
         
 1048  0
         forkEntryPoints.push( mojoDescriptor );
 1049  
 
 1050  0
         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 1051  
 
 1052  0
         String targetPhase = mojoDescriptor.getExecutePhase();
 1053  
 
 1054  0
         Map lifecycleMappings = null;
 1055  0
         if ( targetPhase != null )
 1056  
         {
 1057  0
             Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
 1058  
 
 1059  
             // Create new lifecycle
 1060  0
             lifecycleMappings = constructLifecycleMappings( session, targetPhase, project, lifecycle );
 1061  
 
 1062  0
             String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
 1063  0
             if ( executeLifecycle != null )
 1064  
             {
 1065  
                 org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
 1066  
                 try
 1067  
                 {
 1068  0
                     lifecycleOverlay = pluginDescriptor.getLifecycleMapping( executeLifecycle );
 1069  
                 }
 1070  0
                 catch ( IOException e )
 1071  
                 {
 1072  0
                     throw new LifecycleExecutionException( "Unable to read lifecycle mapping file: " + e.getMessage(),
 1073  
                                                            e );
 1074  
                 }
 1075  0
                 catch ( XmlPullParserException e )
 1076  
                 {
 1077  0
                     throw new LifecycleExecutionException( "Unable to parse lifecycle mapping file: " + e.getMessage(),
 1078  
                                                            e );
 1079  0
                 }
 1080  
 
 1081  0
                 if ( lifecycleOverlay == null )
 1082  
                 {
 1083  0
                     throw new LifecycleExecutionException( "Lifecycle '" + executeLifecycle + "' not found in plugin" );
 1084  
                 }
 1085  
 
 1086  0
                 for ( Iterator i = lifecycleOverlay.getPhases().iterator(); i.hasNext(); )
 1087  
                 {
 1088  0
                     Phase phase = (Phase) i.next();
 1089  0
                     for ( Iterator j = phase.getExecutions().iterator(); j.hasNext(); )
 1090  
                     {
 1091  0
                         Execution exec = (Execution) j.next();
 1092  
 
 1093  0
                         for ( Iterator k = exec.getGoals().iterator(); k.hasNext(); )
 1094  
                         {
 1095  0
                             String goal = (String) k.next();
 1096  
 
 1097  
                             PluginDescriptor lifecyclePluginDescriptor;
 1098  
                             String lifecycleGoal;
 1099  
 
 1100  
                             // Here we are looking to see if we have a mojo from an external plugin.
 1101  
                             // If we do then we need to lookup the plugin descriptor for the externally
 1102  
                             // referenced plugin so that we can overly the execution into the lifecycle.
 1103  
                             // An example of this is the corbertura plugin that needs to call the surefire
 1104  
                             // plugin in forking mode.
 1105  
                             //
 1106  
                             //<phase>
 1107  
                             //  <id>test</id>
 1108  
                             //  <executions>
 1109  
                             //    <execution>
 1110  
                             //      <goals>
 1111  
                             //        <goal>org.apache.maven.plugins:maven-surefire-plugin:test</goal>
 1112  
                             //      </goals>
 1113  
                             //      <configuration>
 1114  
                             //        <classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
 1115  
                             //        <ignoreFailures>true</ignoreFailures>
 1116  
                             //        <forkMode>once</forkMode>
 1117  
                             //      </configuration>
 1118  
                             //    </execution>
 1119  
                             //  </executions>
 1120  
                             //</phase>
 1121  
 
 1122  
                             // ----------------------------------------------------------------------
 1123  
                             //
 1124  
                             // ----------------------------------------------------------------------
 1125  
 
 1126  0
                             if ( goal.indexOf( ":" ) > 0 )
 1127  
                             {
 1128  0
                                 String[] s = StringUtils.split( goal, ":" );
 1129  
 
 1130  0
                                 String groupId = s[0];
 1131  0
                                 String artifactId = s[1];
 1132  0
                                 lifecycleGoal = s[2];
 1133  
 
 1134  0
                                 Plugin plugin = new Plugin();
 1135  0
                                 plugin.setGroupId( groupId );
 1136  0
                                 plugin.setArtifactId( artifactId );
 1137  0
                                 lifecyclePluginDescriptor = verifyPlugin( plugin, project, session );
 1138  0
                                 if ( lifecyclePluginDescriptor == null )
 1139  
                                 {
 1140  0
                                     throw new LifecycleExecutionException(
 1141  
                                         "Unable to find plugin " + groupId + ":" + artifactId );
 1142  
                                 }
 1143  0
                             }
 1144  
                             else
 1145  
                             {
 1146  0
                                 lifecyclePluginDescriptor = pluginDescriptor;
 1147  0
                                 lifecycleGoal = goal;
 1148  
                             }
 1149  
 
 1150  0
                             Xpp3Dom configuration = (Xpp3Dom) exec.getConfiguration();
 1151  
                             // NOTE: This seems to be duplicated below. Why??
 1152  0
                             if ( phase.getConfiguration() != null )
 1153  
                             {
 1154  0
                                 configuration = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ),
 1155  
                                                                       configuration );
 1156  
                             }
 1157  
 
 1158  0
                             MojoDescriptor desc = getMojoDescriptor( lifecyclePluginDescriptor, lifecycleGoal );
 1159  
                             MojoExecution mojoExecution;
 1160  0
                             if ( executionId.startsWith( MojoExecution.DEFAULT_EXEC_ID_PREFIX ) )
 1161  
                             {
 1162  0
                                 mojoExecution = new MojoExecution( desc, configuration );
 1163  
                             }
 1164  
                             else
 1165  
                             {
 1166  0
                                 mojoExecution = new MojoExecution( desc, configuration, executionId );
 1167  
                             }
 1168  
                             
 1169  0
                             addToLifecycleMappings( lifecycleMappings, phase.getId(), mojoExecution,
 1170  
                                                     session.getSettings() );
 1171  0
                         }
 1172  0
                     }
 1173  
 
 1174  0
                     if ( phase.getConfiguration() != null )
 1175  
                     {
 1176  
                         // Merge in general configuration for a phase.
 1177  
                         // TODO: this is all kind of backwards from the POMM. Let's align it all under 2.1.
 1178  
                         //   We should create a new lifecycle executor for modelVersion >5.0.0
 1179  0
                         for ( Iterator j = lifecycleMappings.values().iterator(); j.hasNext(); )
 1180  
                         {
 1181  0
                             List tasks = (List) j.next();
 1182  
 
 1183  0
                             for ( Iterator k = tasks.iterator(); k.hasNext(); )
 1184  
                             {
 1185  0
                                 MojoExecution exec = (MojoExecution) k.next();
 1186  
 
 1187  0
                                 Xpp3Dom configuration = Xpp3Dom.mergeXpp3Dom(
 1188  
                                     new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ), exec.getConfiguration() );
 1189  
 
 1190  0
                                 exec.setConfiguration( configuration );
 1191  0
                             }
 1192  0
                         }
 1193  
                     }
 1194  
 
 1195  0
                 }
 1196  
             }
 1197  
 
 1198  0
             removeFromLifecycle( forkEntryPoints, lifecycleMappings );
 1199  
         }
 1200  
 
 1201  0
         if ( targetPhase != null )
 1202  
         {
 1203  0
             Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
 1204  
 
 1205  0
             executeGoalWithLifecycle( targetPhase, forkEntryPoints, session, lifecycleMappings, project, lifecycle );
 1206  0
         }
 1207  
         else
 1208  
         {
 1209  0
             String goal = mojoDescriptor.getExecuteGoal();
 1210  0
             MojoDescriptor desc = getMojoDescriptor( pluginDescriptor, goal );
 1211  0
             executeGoals( Collections.singletonList( new MojoExecution( desc, goal ) ), forkEntryPoints, session, project );
 1212  
         }
 1213  0
     }
 1214  
 
 1215  
     private Lifecycle getLifecycleForPhase( final String phase )
 1216  
         throws BuildFailureException, LifecycleExecutionException
 1217  
     {
 1218  0
         Lifecycle lifecycle = (Lifecycle) getPhaseToLifecycleMap().get( phase );
 1219  
 
 1220  0
         if ( lifecycle == null )
 1221  
         {
 1222  0
             throw new BuildFailureException( "Unable to find lifecycle for phase '" + phase + "'" );
 1223  
         }
 1224  0
         return lifecycle;
 1225  
     }
 1226  
 
 1227  
     private MojoDescriptor getMojoDescriptor( final PluginDescriptor pluginDescriptor, final String goal )
 1228  
         throws LifecycleExecutionException
 1229  
     {
 1230  0
         MojoDescriptor desc = pluginDescriptor.getMojo( goal );
 1231  
 
 1232  0
         if ( desc == null )
 1233  
         {
 1234  0
             String message =
 1235  
                 "Required goal '" + goal + "' not found in plugin '" + pluginDescriptor.getGoalPrefix() + "'";
 1236  0
             int index = goal.indexOf( ':' );
 1237  0
             if ( index >= 0 )
 1238  
             {
 1239  0
                 String prefix = goal.substring( index + 1 );
 1240  0
                 if ( prefix.equals( pluginDescriptor.getGoalPrefix() ) )
 1241  
                 {
 1242  0
                     message = message + " (goals should not be prefixed - try '" + prefix + "')";
 1243  
                 }
 1244  
             }
 1245  0
             throw new LifecycleExecutionException( message );
 1246  
         }
 1247  0
         return desc;
 1248  
     }
 1249  
 
 1250  
     private void removeFromLifecycle( final Stack lifecycleForkers, final Map lifecycleMappings )
 1251  
     {
 1252  0
         for ( Iterator lifecycleIterator = lifecycleMappings.values().iterator(); lifecycleIterator.hasNext(); )
 1253  
         {
 1254  0
             List tasks = (List) lifecycleIterator.next();
 1255  
 
 1256  0
             for ( Iterator taskIterator = tasks.iterator(); taskIterator.hasNext(); )
 1257  
             {
 1258  0
                 MojoExecution execution = (MojoExecution) taskIterator.next();
 1259  
 
 1260  0
                 if ( lifecycleForkers.contains( execution.getMojoDescriptor() ) )
 1261  
                 {
 1262  0
                     taskIterator.remove();
 1263  0
                     getLogger().warn( "Removing: " + execution.getMojoDescriptor().getGoal()
 1264  
                                       + " from forked lifecycle, to prevent recursive invocation." );
 1265  
                 }
 1266  0
             }
 1267  0
         }
 1268  0
     }
 1269  
 
 1270  
     private Map constructLifecycleMappings( final MavenSession session, final String selectedPhase, final MavenProject project,
 1271  
                                             final Lifecycle lifecycle )
 1272  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1273  
     {
 1274  
         // first, bind those associated with the packaging
 1275  0
         Map lifecycleMappings = bindLifecycleForPackaging( session, selectedPhase, project, lifecycle );
 1276  
 
 1277  
         // next, loop over plugins and for any that have a phase, bind it
 1278  0
         for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1279  
         {
 1280  0
             Plugin plugin = (Plugin) i.next();
 1281  
 
 1282  0
             bindPluginToLifecycle( plugin, session, lifecycleMappings, project );
 1283  0
         }
 1284  
 
 1285  0
         return lifecycleMappings;
 1286  
     }
 1287  
 
 1288  
     private Map bindLifecycleForPackaging( final MavenSession session, final String selectedPhase, final MavenProject project,
 1289  
                                            final Lifecycle lifecycle )
 1290  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1291  
     {
 1292  0
         Map mappings = findMappingsForLifecycle( session, project, lifecycle );
 1293  
 
 1294  0
         List optionalMojos = findOptionalMojosForLifecycle( session, project, lifecycle );
 1295  
 
 1296  0
         Map lifecycleMappings = new HashMap();
 1297  
 
 1298  0
         for ( Iterator i = lifecycle.getPhases().iterator(); i.hasNext(); )
 1299  
         {
 1300  0
             String phase = (String) i.next();
 1301  
 
 1302  0
             String phaseTasks = (String) mappings.get( phase );
 1303  
 
 1304  0
             if ( phaseTasks != null )
 1305  
             {
 1306  0
                 for ( StringTokenizer tok = new StringTokenizer( phaseTasks, "," ); tok.hasMoreTokens(); )
 1307  
                 {
 1308  0
                     String goal = tok.nextToken().trim();
 1309  
 
 1310  
                     // Not from the CLI, don't use prefix
 1311  0
                     MojoDescriptor mojoDescriptor = getMojoDescriptor( goal, session, project, selectedPhase, false,
 1312  
                                                                        optionalMojos.contains( goal ) );
 1313  
 
 1314  0
                     if ( mojoDescriptor == null )
 1315  
                     {
 1316  0
                         continue;
 1317  
                     }
 1318  
 
 1319  0
                     if ( mojoDescriptor.isDirectInvocationOnly() )
 1320  
                     {
 1321  0
                         throw new LifecycleExecutionException( "Mojo: \'" + goal +
 1322  
                             "\' requires direct invocation. It cannot be used as part of lifecycle: \'" +
 1323  
                             project.getPackaging() + "\'." );
 1324  
                     }
 1325  
 
 1326  0
                     addToLifecycleMappings( lifecycleMappings, phase, new MojoExecution( mojoDescriptor ),
 1327  
                                             session.getSettings() );
 1328  0
                 }
 1329  
             }
 1330  
 
 1331  0
             if ( phase.equals( selectedPhase ) )
 1332  
             {
 1333  0
                 break;
 1334  
             }
 1335  0
         }
 1336  
 
 1337  0
         return lifecycleMappings;
 1338  
     }
 1339  
 
 1340  
     private Map findMappingsForLifecycle( final MavenSession session, final MavenProject project, final Lifecycle lifecycle )
 1341  
         throws LifecycleExecutionException, PluginNotFoundException
 1342  
     {
 1343  0
         String packaging = project.getPackaging();
 1344  0
         Map mappings = null;
 1345  
 
 1346  0
         LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session );
 1347  0
         if ( m != null )
 1348  
         {
 1349  0
             mappings = m.getPhases( lifecycle.getId() );
 1350  
         }
 1351  
 
 1352  0
         Map defaultMappings = lifecycle.getDefaultPhases();
 1353  
 
 1354  0
         if ( mappings == null )
 1355  
         {
 1356  
             try
 1357  
             {
 1358  0
                 m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
 1359  0
                 mappings = m.getPhases( lifecycle.getId() );
 1360  
             }
 1361  0
             catch ( ComponentLookupException e )
 1362  
             {
 1363  0
                 if ( defaultMappings == null )
 1364  
                 {
 1365  0
                     throw new LifecycleExecutionException(
 1366  
                         "Cannot find lifecycle mapping for packaging: \'" + packaging + "\'.", e );
 1367  
                 }
 1368  0
             }
 1369  
         }
 1370  
 
 1371  0
         if ( mappings == null )
 1372  
         {
 1373  0
             if ( defaultMappings == null )
 1374  
             {
 1375  0
                 throw new LifecycleExecutionException(
 1376  
                     "Cannot find lifecycle mapping for packaging: \'" + packaging + "\', and there is no default" );
 1377  
             }
 1378  
             else
 1379  
             {
 1380  0
                 mappings = defaultMappings;
 1381  
             }
 1382  
         }
 1383  
 
 1384  0
         return mappings;
 1385  
     }
 1386  
 
 1387  
     private List findOptionalMojosForLifecycle( final MavenSession session, final MavenProject project, final Lifecycle lifecycle )
 1388  
         throws LifecycleExecutionException, PluginNotFoundException
 1389  
     {
 1390  0
         String packaging = project.getPackaging();
 1391  0
         List optionalMojos = null;
 1392  
 
 1393  0
         LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session );
 1394  
 
 1395  0
         if ( m != null )
 1396  
         {
 1397  0
             optionalMojos = m.getOptionalMojos( lifecycle.getId() );
 1398  
         }
 1399  
 
 1400  0
         if ( optionalMojos == null )
 1401  
         {
 1402  
             try
 1403  
             {
 1404  0
                 m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
 1405  0
                 optionalMojos = m.getOptionalMojos( lifecycle.getId() );
 1406  
             }
 1407  0
             catch ( ComponentLookupException e )
 1408  
             {
 1409  0
                 getLogger().debug( "Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle ID: " +
 1410  
                     lifecycle.getId() + ". Error: " + e.getMessage(), e );
 1411  0
             }
 1412  
         }
 1413  
 
 1414  0
         if ( optionalMojos == null )
 1415  
         {
 1416  0
             optionalMojos = Collections.EMPTY_LIST;
 1417  
         }
 1418  
 
 1419  0
         return optionalMojos;
 1420  
     }
 1421  
 
 1422  
     private Object findExtension( final MavenProject project, final String role, final String roleHint, final MavenSession session )
 1423  
         throws LifecycleExecutionException, PluginNotFoundException
 1424  
     {
 1425  0
         Object pluginComponent = null;
 1426  
 
 1427  0
         for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext() && pluginComponent == null; )
 1428  
         {
 1429  0
             Plugin plugin = (Plugin) i.next();
 1430  
 
 1431  0
             if ( plugin.isExtensions() )
 1432  
             {
 1433  0
                 loadPluginFully( plugin, project, session );
 1434  
 
 1435  
                 // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
 1436  
                 try
 1437  
                 {
 1438  0
                     pluginComponent = pluginManager.getPluginComponent( plugin, role, roleHint );
 1439  
                 }
 1440  0
                 catch ( ComponentLookupException e )
 1441  
                 {
 1442  0
                     getLogger().debug( "Unable to find the lifecycle component in the extension", e );
 1443  
                 }
 1444  0
                 catch ( PluginManagerException e )
 1445  
                 {
 1446  0
                     throw new LifecycleExecutionException(
 1447  
                         "Error getting extensions from the plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1448  0
                 }
 1449  
             }
 1450  0
         }
 1451  0
         return pluginComponent;
 1452  
     }
 1453  
 
 1454  
     /**
 1455  
      * @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
 1456  
      * lookup directly, or have them passed in
 1457  
      */
 1458  
     private Map<String, ArtifactHandler> findArtifactTypeHandlersInPlugins( final MavenProject project, final MavenSession session )
 1459  
         throws LifecycleExecutionException, PluginNotFoundException
 1460  
     {
 1461  0
         Map<String, ArtifactHandler> map = new HashMap<String, ArtifactHandler>();
 1462  0
         for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1463  
         {
 1464  0
             Plugin plugin = (Plugin) i.next();
 1465  
 
 1466  0
             if ( plugin.isExtensions() )
 1467  
             {
 1468  0
                 loadPluginFully( plugin, project, session );
 1469  
 
 1470  
                 // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
 1471  
                 try
 1472  
                 {
 1473  0
                     Map components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
 1474  0
                     map.putAll( components );
 1475  
                 }
 1476  0
                 catch ( ComponentLookupException e )
 1477  
                 {
 1478  0
                     getLogger().debug( "Unable to find the lifecycle component in the extension", e );
 1479  
                 }
 1480  0
                 catch ( PluginManagerException e )
 1481  
                 {
 1482  0
                     throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
 1483  
                         plugin.getKey() + "': " + e.getMessage(), e );
 1484  0
                 }
 1485  
             }
 1486  0
         }
 1487  0
         return map;
 1488  
     }
 1489  
 
 1490  
     /**
 1491  
      * Take each mojo contained with a plugin, look to see whether it contributes to a
 1492  
      * phase in the lifecycle and if it does place it at the end of the list of goals
 1493  
      * to execute for that given phase.
 1494  
      *
 1495  
      * @param project
 1496  
      * @param session
 1497  
      */
 1498  
     private void bindPluginToLifecycle( final Plugin plugin, final MavenSession session, final Map phaseMap, final MavenProject project )
 1499  
         throws LifecycleExecutionException, PluginNotFoundException
 1500  
     {
 1501  0
         Settings settings = session.getSettings();
 1502  
 
 1503  0
         PluginDescriptor pluginDescriptor =
 1504  
             verifyPlugin( plugin, project, session );
 1505  
 
 1506  0
         if ( pluginDescriptor.getMojos() != null && !pluginDescriptor.getMojos().isEmpty() )
 1507  
         {
 1508  
             // use the plugin if inherit was true in a base class, or it is in the current POM, otherwise use the default inheritence setting
 1509  0
             if ( plugin.isInheritanceApplied() || pluginDescriptor.isInheritedByDefault() )
 1510  
             {
 1511  0
                 if ( plugin.getGoals() != null )
 1512  
                 {
 1513  0
                     getLogger().error(
 1514  
                         "Plugin contains a <goals/> section: this is IGNORED - please use <executions/> instead." );
 1515  
                 }
 1516  
 
 1517  0
                 List executions = plugin.getExecutions();
 1518  
 
 1519  0
                 if ( executions != null )
 1520  
                 {
 1521  0
                     for ( Iterator it = executions.iterator(); it.hasNext(); )
 1522  
                     {
 1523  0
                         PluginExecution execution = (PluginExecution) it.next();
 1524  
 
 1525  0
                         bindExecutionToLifecycle( pluginDescriptor, phaseMap, execution, settings );
 1526  0
                     }
 1527  
                 }
 1528  
             }
 1529  
         }
 1530  0
     }
 1531  
 
 1532  
     private PluginDescriptor verifyPlugin( final Plugin plugin, final MavenProject project, final MavenSession session )
 1533  
         throws LifecycleExecutionException, PluginNotFoundException
 1534  
     {
 1535  
         PluginDescriptor pluginDescriptor;
 1536  
         try
 1537  
         {
 1538  
             // TODO: MNG-4081...need to flush this plugin once we look at it, to avoid using an external
 1539  
             // version of a plugin when a newer version will be created in the current reactor...
 1540  0
             pluginDescriptor = pluginManager.loadPluginDescriptor( plugin, project, session );
 1541  
         }
 1542  0
         catch ( PluginManagerException e )
 1543  
         {
 1544  0
             throw new LifecycleExecutionException(
 1545  
                 "Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1546  
         }
 1547  0
         catch ( PluginVersionResolutionException e )
 1548  
         {
 1549  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1550  
         }
 1551  0
         catch ( InvalidVersionSpecificationException e )
 1552  
         {
 1553  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1554  
         }
 1555  0
         catch ( InvalidPluginException e )
 1556  
         {
 1557  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1558  
         }
 1559  0
         catch ( ArtifactNotFoundException e )
 1560  
         {
 1561  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1562  
         }
 1563  0
         catch ( ArtifactResolutionException e )
 1564  
         {
 1565  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1566  
         }
 1567  0
         catch ( PluginVersionNotFoundException e )
 1568  
         {
 1569  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1570  0
         }
 1571  0
         return pluginDescriptor;
 1572  
     }
 1573  
 
 1574  
     private PluginDescriptor loadPluginFully( final Plugin plugin, final MavenProject project, final MavenSession session )
 1575  
         throws LifecycleExecutionException, PluginNotFoundException
 1576  
     {
 1577  
         PluginDescriptor pluginDescriptor;
 1578  
         try
 1579  
         {
 1580  
             // TODO: MNG-4081...need to flush this plugin once we look at it, to avoid using an external
 1581  
             // version of a plugin when a newer version will be created in the current reactor...
 1582  0
             pluginDescriptor = pluginManager.loadPluginFully( plugin, project, session );
 1583  
         }
 1584  0
         catch ( PluginManagerException e )
 1585  
         {
 1586  0
             throw new LifecycleExecutionException(
 1587  
                 "Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1588  
         }
 1589  0
         catch ( PluginVersionResolutionException e )
 1590  
         {
 1591  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1592  
         }
 1593  0
         catch ( InvalidVersionSpecificationException e )
 1594  
         {
 1595  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1596  
         }
 1597  0
         catch ( InvalidPluginException e )
 1598  
         {
 1599  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1600  
         }
 1601  0
         catch ( ArtifactNotFoundException e )
 1602  
         {
 1603  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1604  
         }
 1605  0
         catch ( ArtifactResolutionException e )
 1606  
         {
 1607  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1608  
         }
 1609  0
         catch ( PluginVersionNotFoundException e )
 1610  
         {
 1611  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1612  0
         }
 1613  0
         return pluginDescriptor;
 1614  
     }
 1615  
 
 1616  
     private PluginDescriptor verifyReportPlugin( final ReportPlugin plugin, final MavenProject project, final MavenSession session )
 1617  
         throws LifecycleExecutionException, PluginNotFoundException
 1618  
     {
 1619  
         PluginDescriptor pluginDescriptor;
 1620  
         try
 1621  
         {
 1622  0
             pluginDescriptor = pluginManager.verifyReportPlugin( plugin, project, session );
 1623  
         }
 1624  0
         catch ( PluginManagerException e )
 1625  
         {
 1626  0
             throw new LifecycleExecutionException(
 1627  
                 "Internal error in the plugin manager getting report '" + plugin.getKey() + "': " + e.getMessage(), e );
 1628  
         }
 1629  0
         catch ( PluginVersionResolutionException e )
 1630  
         {
 1631  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1632  
         }
 1633  0
         catch ( InvalidVersionSpecificationException e )
 1634  
         {
 1635  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1636  
         }
 1637  0
         catch ( InvalidPluginException e )
 1638  
         {
 1639  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1640  
         }
 1641  0
         catch ( ArtifactNotFoundException e )
 1642  
         {
 1643  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1644  
         }
 1645  0
         catch ( ArtifactResolutionException e )
 1646  
         {
 1647  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1648  
         }
 1649  0
         catch ( PluginVersionNotFoundException e )
 1650  
         {
 1651  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1652  0
         }
 1653  0
         return pluginDescriptor;
 1654  
     }
 1655  
 
 1656  
     private void bindExecutionToLifecycle( final PluginDescriptor pluginDescriptor, final Map phaseMap, final PluginExecution execution,
 1657  
                                            final Settings settings )
 1658  
         throws LifecycleExecutionException
 1659  
     {
 1660  0
         for ( Iterator i = execution.getGoals().iterator(); i.hasNext(); )
 1661  
         {
 1662  0
             String goal = (String) i.next();
 1663  
 
 1664  0
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
 1665  0
             if ( mojoDescriptor == null )
 1666  
             {
 1667  0
                 throw new LifecycleExecutionException(
 1668  
                     "'" + goal + "' was specified in an execution, but not found in the plugin" );
 1669  
             }
 1670  
 
 1671  
             // We have to check to see that the inheritance rules have been applied before binding this mojo.
 1672  0
             if ( execution.isInheritanceApplied() || mojoDescriptor.isInheritedByDefault() )
 1673  
             {
 1674  0
                 MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
 1675  
 
 1676  0
                 String phase = execution.getPhase();
 1677  
 
 1678  0
                 if ( phase == null )
 1679  
                 {
 1680  
                     // if the phase was not in the configuration, use the phase in the descriptor
 1681  0
                     phase = mojoDescriptor.getPhase();
 1682  
                 }
 1683  
 
 1684  0
                 if ( phase != null )
 1685  
                 {
 1686  0
                     if ( mojoDescriptor.isDirectInvocationOnly() )
 1687  
                     {
 1688  0
                         throw new LifecycleExecutionException( "Mojo: \'" + goal +
 1689  
                             "\' requires direct invocation. It cannot be used as part of the lifecycle (it was included via the POM)." );
 1690  
                     }
 1691  
 
 1692  0
                     addToLifecycleMappings( phaseMap, phase, mojoExecution, settings );
 1693  
                 }
 1694  
             }
 1695  0
         }
 1696  0
     }
 1697  
 
 1698  
     private void addToLifecycleMappings( final Map lifecycleMappings, final String phase, final MojoExecution mojoExecution,
 1699  
                                          final Settings settings )
 1700  
     {
 1701  0
         List goals = (List) lifecycleMappings.get( phase );
 1702  
 
 1703  0
         if ( goals == null )
 1704  
         {
 1705  0
             goals = new ArrayList();
 1706  0
             lifecycleMappings.put( phase, goals );
 1707  
         }
 1708  
 
 1709  0
         MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 1710  0
         if ( settings.isOffline() && mojoDescriptor.isOnlineRequired() )
 1711  
         {
 1712  0
             String goal = mojoDescriptor.getGoal();
 1713  0
             getLogger().warn( goal + " requires online mode, but maven is currently offline. Disabling " + goal + "." );
 1714  0
         }
 1715  
         else
 1716  
         {
 1717  0
             goals.add( mojoExecution );
 1718  
         }
 1719  0
     }
 1720  
 
 1721  
     private List processGoalChain( final String task, final Map phaseMap, final Lifecycle lifecycle )
 1722  
     {
 1723  0
         List goals = new ArrayList();
 1724  
 
 1725  
         // only execute up to the given phase
 1726  0
         int index = lifecycle.getPhases().indexOf( task );
 1727  
 
 1728  0
         for ( int i = 0; i <= index; i++ )
 1729  
         {
 1730  0
             String p = (String) lifecycle.getPhases().get( i );
 1731  
 
 1732  0
             List phaseGoals = (List) phaseMap.get( p );
 1733  
 
 1734  0
             if ( phaseGoals != null )
 1735  
             {
 1736  0
                 goals.addAll( phaseGoals );
 1737  
             }
 1738  
         }
 1739  0
         return goals;
 1740  
     }
 1741  
 
 1742  
     private MojoDescriptor getMojoDescriptor( final String task, final MavenSession session, final MavenProject project,
 1743  
                                               final String invokedVia, final boolean canUsePrefix, final boolean isOptionalMojo )
 1744  
         throws BuildFailureException, LifecycleExecutionException, PluginNotFoundException
 1745  
     {
 1746  
         String goal;
 1747  0
         Plugin plugin = null;
 1748  
 
 1749  0
         PluginDescriptor pluginDescriptor = null;
 1750  
 
 1751  
         try
 1752  
         {
 1753  0
             StringTokenizer tok = new StringTokenizer( task, ":" );
 1754  0
             int numTokens = tok.countTokens();
 1755  
 
 1756  0
             if ( numTokens == 2 )
 1757  
             {
 1758  0
                 if ( !canUsePrefix )
 1759  
                 {
 1760  0
                     String msg = "Mapped-prefix lookup of mojos are only supported from direct invocation. " +
 1761  
                         "Please use specification of the form groupId:artifactId[:version]:goal instead. " +
 1762  
                         "(Offending mojo: \'" + task + "\', invoked via: \'" + invokedVia + "\')";
 1763  0
                     throw new LifecycleExecutionException( msg );
 1764  
                 }
 1765  
 
 1766  0
                 String prefix = tok.nextToken();
 1767  0
                 goal = tok.nextToken();
 1768  
 
 1769  
                 // Steps for retrieving the plugin model instance:
 1770  
                 // 1. request directly from the plugin collector by prefix
 1771  0
                 pluginDescriptor = pluginManager.getPluginDescriptorForPrefix( prefix );
 1772  0
                 if ( pluginDescriptor != null )
 1773  
                 {
 1774  0
                     plugin = new Plugin();
 1775  0
                     plugin.setGroupId( pluginDescriptor.getGroupId() );
 1776  0
                     plugin.setArtifactId( pluginDescriptor.getArtifactId() );
 1777  0
                     plugin.setVersion( pluginDescriptor.getVersion() );
 1778  
                 }
 1779  
 
 1780  
                 // 2. search plugins in the current POM
 1781  0
                 if ( plugin == null )
 1782  
                 {
 1783  0
                     for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1784  
                     {
 1785  0
                         Plugin buildPlugin = (Plugin) i.next();
 1786  
 
 1787  0
                         PluginDescriptor desc =
 1788  
                             verifyPlugin( buildPlugin, project, session );
 1789  0
                         if ( prefix.equals( desc.getGoalPrefix() ) )
 1790  
                         {
 1791  0
                             plugin = buildPlugin;
 1792  0
                             pluginDescriptor = desc;
 1793  0
                             break;
 1794  
                         }
 1795  0
                     }
 1796  
                 }
 1797  
 
 1798  
                 // 3. look in the repository via search groups
 1799  0
                 if ( plugin == null )
 1800  
                 {
 1801  0
                     plugin = pluginManager.getPluginDefinitionForPrefix( prefix, session, project );
 1802  
                 }
 1803  
 
 1804  
                 // 4. default to o.a.m.plugins and maven-<prefix>-plugin
 1805  0
                 if ( plugin == null )
 1806  
                 {
 1807  0
                     plugin = new Plugin();
 1808  0
                     plugin.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
 1809  0
                     plugin.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( prefix ) );
 1810  
                 }
 1811  0
             }
 1812  0
             else if ( numTokens == 3 || numTokens == 4 )
 1813  
             {
 1814  0
                 plugin = new Plugin();
 1815  
 
 1816  0
                 plugin.setGroupId( tok.nextToken() );
 1817  0
                 plugin.setArtifactId( tok.nextToken() );
 1818  
 
 1819  0
                 if ( numTokens == 4 )
 1820  
                 {
 1821  0
                     plugin.setVersion( tok.nextToken() );
 1822  
                 }
 1823  
 
 1824  0
                 goal = tok.nextToken();
 1825  
             }
 1826  
             else
 1827  
             {
 1828  0
                 String message = "Invalid task '" + task + "': you must specify a valid lifecycle phase, or" +
 1829  
                     " a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal";
 1830  0
                 throw new BuildFailureException( message );
 1831  
             }
 1832  
 
 1833  0
             if ( plugin.getVersion() == null )
 1834  
             {
 1835  0
                 for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1836  
                 {
 1837  0
                     Plugin buildPlugin = (Plugin) i.next();
 1838  
 
 1839  0
                     if ( buildPlugin.getKey().equals( plugin.getKey() ) )
 1840  
                     {
 1841  0
                         plugin = buildPlugin;
 1842  0
                         break;
 1843  
                     }
 1844  0
                 }
 1845  
 
 1846  0
                 project.injectPluginManagementInfo( plugin );
 1847  
             }
 1848  
 
 1849  0
             if ( pluginDescriptor == null )
 1850  
             {
 1851  0
                 pluginDescriptor = verifyPlugin( plugin, project, session );
 1852  
             }
 1853  
 
 1854  
             // this has been simplified from the old code that injected the plugin management stuff, since
 1855  
             // pluginManagement injection is now handled by the project method.
 1856  0
             project.addPlugin( plugin );
 1857  
 
 1858  0
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
 1859  0
             if ( mojoDescriptor == null )
 1860  
             {
 1861  0
                 if ( isOptionalMojo )
 1862  
                 {
 1863  0
                     getLogger().info( "Skipping missing optional mojo: " + task );
 1864  
                 }
 1865  
                 else
 1866  
                 {
 1867  0
                     throw new BuildFailureException( "Required goal not found: " + task + " in "
 1868  
                         + pluginDescriptor.getId() );
 1869  
                 }
 1870  
             }
 1871  
 
 1872  0
             return mojoDescriptor;
 1873  
         }
 1874  0
         catch ( PluginNotFoundException e )
 1875  
         {
 1876  0
             if ( isOptionalMojo )
 1877  
             {
 1878  0
                 getLogger().info( "Skipping missing optional mojo: " + task );
 1879  0
                 getLogger().debug( "Mojo: " + task + " could not be found. Reason: " + e.getMessage(), e );
 1880  
             }
 1881  
             else
 1882  
             {
 1883  0
                 throw e;
 1884  
             }
 1885  
         }
 1886  
 
 1887  0
         return null;
 1888  
     }
 1889  
 
 1890  
     protected void line()
 1891  
     {
 1892  0
         getLogger().info( "------------------------------------------------------------------------" );
 1893  0
     }
 1894  
 
 1895  
     public Map getPhaseToLifecycleMap()
 1896  
         throws LifecycleExecutionException
 1897  
     {
 1898  0
         if ( phaseToLifecycleMap == null )
 1899  
         {
 1900  0
             phaseToLifecycleMap = new HashMap();
 1901  
 
 1902  0
             for ( Iterator i = lifecycles.iterator(); i.hasNext(); )
 1903  
             {
 1904  0
                 Lifecycle lifecycle = (Lifecycle) i.next();
 1905  
 
 1906  0
                 for ( Iterator p = lifecycle.getPhases().iterator(); p.hasNext(); )
 1907  
                 {
 1908  0
                     String phase = (String) p.next();
 1909  
 
 1910  0
                     if ( phaseToLifecycleMap.containsKey( phase ) )
 1911  
                     {
 1912  0
                         Lifecycle prevLifecycle = (Lifecycle) phaseToLifecycleMap.get( phase );
 1913  0
                         throw new LifecycleExecutionException( "Phase '" + phase +
 1914  
                             "' is defined in more than one lifecycle: '" + lifecycle.getId() + "' and '" +
 1915  
                             prevLifecycle.getId() + "'" );
 1916  
                     }
 1917  
                     else
 1918  
                     {
 1919  0
                         phaseToLifecycleMap.put( phase, lifecycle );
 1920  
                     }
 1921  0
                 }
 1922  0
             }
 1923  
         }
 1924  0
         return phaseToLifecycleMap;
 1925  
     }
 1926  
 
 1927  0
     private static class TaskSegment
 1928  
     {
 1929  
         private boolean aggregate;
 1930  
 
 1931  0
         private final List tasks = new ArrayList();
 1932  
 
 1933  
         TaskSegment()
 1934  0
         {
 1935  
 
 1936  0
         }
 1937  
 
 1938  
         TaskSegment( final boolean aggregate )
 1939  0
         {
 1940  0
             this.aggregate = aggregate;
 1941  0
         }
 1942  
 
 1943  
         public String toString()
 1944  
         {
 1945  0
             StringBuffer message = new StringBuffer();
 1946  
 
 1947  0
             message.append( " task-segment: [" );
 1948  
 
 1949  0
             for ( Iterator it = tasks.iterator(); it.hasNext(); )
 1950  
             {
 1951  0
                 String task = (String) it.next();
 1952  
 
 1953  0
                 message.append( task );
 1954  
 
 1955  0
                 if ( it.hasNext() )
 1956  
                 {
 1957  0
                     message.append( ", " );
 1958  
                 }
 1959  0
             }
 1960  
 
 1961  0
             message.append( "]" );
 1962  
 
 1963  0
             if ( aggregate )
 1964  
             {
 1965  0
                 message.append( " (aggregator-style)" );
 1966  
             }
 1967  
 
 1968  0
             return message.toString();
 1969  
         }
 1970  
 
 1971  
         boolean aggregate()
 1972  
         {
 1973  0
             return aggregate;
 1974  
         }
 1975  
 
 1976  
         void add( final String task )
 1977  
         {
 1978  0
             tasks.add( task );
 1979  0
         }
 1980  
 
 1981  
         List getTasks()
 1982  
         {
 1983  0
             return tasks;
 1984  
         }
 1985  
     }
 1986  
     
 1987  
     public List getLifecycles()
 1988  
     {
 1989  0
         return lifecycles;
 1990  
     }
 1991  
 
 1992  
     // -------------------------------------------------------------------------
 1993  
     // TODO: The methods and fields below are only needed for products like Hudson,
 1994  
     // that provide their own LifecycleExecutor and component configuration that extend
 1995  
     // default implementation, and which may become out-of-date as component requirements
 1996  
     // are updated within Maven itself.
 1997  
     public void initialize()
 1998  
         throws InitializationException
 1999  
     {
 2000  0
         if ( mavenProjectBuilder == null )
 2001  
         {
 2002  0
             warnOfIncompleteComponentConfiguration( MavenProjectBuilder.ROLE );
 2003  
             try
 2004  
             {
 2005  0
                 mavenProjectBuilder = (MavenProjectBuilder) container.lookup( MavenProjectBuilder.ROLE );
 2006  
             }
 2007  0
             catch ( ComponentLookupException e )
 2008  
             {
 2009  0
                 throw new InitializationException( "Failed to lookup project builder after it was NOT injected via component requirement." );
 2010  0
             }
 2011  
         }
 2012  
         
 2013  0
         if ( modelInterpolator == null )
 2014  
         {
 2015  0
             warnOfIncompleteComponentConfiguration( ModelInterpolator.ROLE );
 2016  
             try
 2017  
             {
 2018  0
                 modelInterpolator = (ModelInterpolator) container.lookup( ModelInterpolator.ROLE );
 2019  
             }
 2020  0
             catch ( ComponentLookupException e )
 2021  
             {
 2022  0
                 throw new InitializationException( "Failed to lookup model interpolator after it was NOT injected via component requirement." );
 2023  0
             }
 2024  
         }
 2025  
         
 2026  0
         if ( configInterpolator == null )
 2027  
         {
 2028  0
             warnOfIncompleteComponentConfiguration( ConfigurationInterpolator.ROLE );
 2029  
             try
 2030  
             {
 2031  0
                 configInterpolator = (ConfigurationInterpolator) container.lookup( ConfigurationInterpolator.ROLE );
 2032  
             }
 2033  0
             catch ( ComponentLookupException e )
 2034  
             {
 2035  0
                 throw new InitializationException( "Failed to lookup plugin-configuration interpolator after it was NOT injected via component requirement." );
 2036  0
             }
 2037  
         }
 2038  0
     }
 2039  
     
 2040  
     private void warnOfIncompleteComponentConfiguration( final String role )
 2041  
     {
 2042  0
         StringBuffer buffer = new StringBuffer();
 2043  0
         buffer.append( "\n************ WARNING ************" );
 2044  0
         buffer.append( "\n\nThis Maven runtime contains a LifecycleExecutor component with an incomplete configuration." );
 2045  0
         buffer.append( "\n\nLifecycleExecutor class: " ).append( getClass().getName() );
 2046  0
         buffer.append( "\nMissing component requirement: " ).append( role );
 2047  0
         buffer.append( "\n" );
 2048  0
         buffer.append( "\nNOTE: This seems to be a third-party Maven derivative you are using. If so, please" );
 2049  0
         buffer.append( "\nnotify the developers for this derivative project of the problem. The Apache Maven team is not" );
 2050  0
         buffer.append( "\nresponsible for maintaining the integrity of third-party component overrides." );
 2051  0
         buffer.append( "\n\n" );
 2052  
         
 2053  0
         getLogger().warn( buffer.toString() );
 2054  0
     }
 2055  
 
 2056  
     private PlexusContainer container;
 2057  
 
 2058  
     public void contextualize( final Context context )
 2059  
         throws ContextException
 2060  
     {
 2061  0
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 2062  0
     }
 2063  
 }