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