Coverage Report - org.apache.maven.lifecycle.DefaultLifecycleExecutor
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultLifecycleExecutor
0 %
0/752
0 %
0/362
6,5
DefaultLifecycleExecutor$TaskSegment
0 %
0/22
0 %
0/6
6,5
 
 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 783173 2009-06-10 01:31:06Z 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  0
             }
 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  0
         }
 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  0
                         }
 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  0
                 }
 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  0
                             }
 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  0
                     }
 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  0
                 }
 360  
             }
 361  0
         }
 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  0
             }
 491  
 
 492  0
             segments.add( currentSegment );
 493  0
         }
 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  0
             }
 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, MojoExecution.CLI_EXECUTION_ID ) ),
 554  
                       forkEntryPoints, session, 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  0
                 }
 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  0
                     }
 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, mojoExecution.getExecutionId() );
 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, forkedExecution.getExecutionId() );
 648  
 
 649  0
                         forkEntryPoints.pop();
 650  
                     }
 651  0
                 }
 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  0
                     }
 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  0
         }
 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  0
                     }
 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  0
             }
 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  0
                     }
 898  
                 }
 899  0
             }
 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  
                 else
 934  
                 {
 935  0
                     id = mojoExecution.getExecutionId();
 936  
                 }
 937  
                 
 938  
                 MojoExecution reportExecution;
 939  0
                 if ( id.startsWith( MojoExecution.DEFAULT_EXEC_ID_PREFIX ) )
 940  
                 {
 941  0
                     reportExecution = new MojoExecution( mojoDescriptor );
 942  
                 }
 943  
                 else
 944  
                 {
 945  0
                     reportExecution = new MojoExecution( mojoDescriptor, id );
 946  
                 }
 947  
 
 948  0
                 reports.add( reportExecution );
 949  
             }
 950  0
         }
 951  0
         return reports;
 952  
     }
 953  
 
 954  
     private List getReports( List reportExecutions, MavenProject project, MojoExecution mojoExecution, MavenSession session )
 955  
         throws LifecycleExecutionException
 956  
     {
 957  0
         List reports = new ArrayList();
 958  
         
 959  0
         for ( Iterator it = reportExecutions.iterator(); it.hasNext(); )
 960  
         {
 961  0
             MojoExecution reportExecution = (MojoExecution) it.next();
 962  0
             PluginDescriptor pluginDescriptor = reportExecution.getMojoDescriptor().getPluginDescriptor();
 963  
             
 964  
             try
 965  
             {
 966  0
                 MavenReport reportMojo = pluginManager.getReport( project, reportExecution, session );
 967  
 
 968  
                 // Comes back null if it was a plugin, not a report - these are mojos in the reporting plugins that are not reports
 969  0
                 if ( reportMojo != null )
 970  
                 {
 971  0
                     reports.add( reportMojo );
 972  0
                     mojoExecution.addMojoExecution( reportExecution );
 973  
                 }
 974  
             }
 975  0
             catch ( PluginManagerException e )
 976  
             {
 977  0
                 throw new LifecycleExecutionException(
 978  
                     "Error getting reports from the plugin '" + pluginDescriptor.getId() + "': " + e.getMessage(), e );
 979  
             }
 980  0
             catch ( PluginConfigurationException e )
 981  
             {
 982  0
                 throw new LifecycleExecutionException(
 983  
                     "Error getting reports from the plugin '" + pluginDescriptor.getId() + "'", e );
 984  
             }
 985  0
             catch ( ArtifactNotFoundException e )
 986  
             {
 987  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 988  
             }
 989  0
             catch ( ArtifactResolutionException e )
 990  
             {
 991  0
                 throw new LifecycleExecutionException( e.getMessage(), e );
 992  0
             }
 993  0
         }
 994  
         
 995  0
         return reports;
 996  
     }
 997  
 
 998  
     private void forkLifecycle( MojoDescriptor mojoDescriptor, Stack ancestorLifecycleForkers, MavenSession session,
 999  
                                 MavenProject project, String executionId )
 1000  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1001  
     {
 1002  0
         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 1003  0
         getLogger().info( "Preparing " + pluginDescriptor.getGoalPrefix() + ":" + mojoDescriptor.getGoal() );
 1004  
 
 1005  0
         if ( mojoDescriptor.isAggregator() )
 1006  
         {
 1007  0
             for ( Iterator i = session.getSortedProjects().iterator(); i.hasNext(); )
 1008  
             {
 1009  0
                 MavenProject reactorProject = (MavenProject) i.next();
 1010  
                 
 1011  0
                 line();
 1012  
 
 1013  0
                 getLogger().info( "Building " + reactorProject.getName() );
 1014  
 
 1015  0
                 line();
 1016  
 
 1017  0
                 forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, reactorProject, executionId );
 1018  0
             }
 1019  
         }
 1020  
         else
 1021  
         {
 1022  0
             forkProjectLifecycle( mojoDescriptor, ancestorLifecycleForkers, session, project, executionId );
 1023  
         }
 1024  0
     }
 1025  
 
 1026  
     private void forkProjectLifecycle( MojoDescriptor mojoDescriptor, Stack forkEntryPoints, MavenSession session,
 1027  
                                        MavenProject project, String executionId )
 1028  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1029  
     {
 1030  0
         project = project.getExecutionProject();
 1031  
         
 1032  0
         forkEntryPoints.push( mojoDescriptor );
 1033  
 
 1034  0
         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 1035  
 
 1036  0
         String targetPhase = mojoDescriptor.getExecutePhase();
 1037  
 
 1038  0
         Map lifecycleMappings = null;
 1039  0
         if ( targetPhase != null )
 1040  
         {
 1041  0
             Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
 1042  
 
 1043  
             // Create new lifecycle
 1044  0
             lifecycleMappings = constructLifecycleMappings( session, targetPhase, project, lifecycle );
 1045  
 
 1046  0
             String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
 1047  0
             if ( executeLifecycle != null )
 1048  
             {
 1049  
                 org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
 1050  
                 try
 1051  
                 {
 1052  0
                     lifecycleOverlay = pluginDescriptor.getLifecycleMapping( executeLifecycle );
 1053  
                 }
 1054  0
                 catch ( IOException e )
 1055  
                 {
 1056  0
                     throw new LifecycleExecutionException( "Unable to read lifecycle mapping file: " + e.getMessage(),
 1057  
                                                            e );
 1058  
                 }
 1059  0
                 catch ( XmlPullParserException e )
 1060  
                 {
 1061  0
                     throw new LifecycleExecutionException( "Unable to parse lifecycle mapping file: " + e.getMessage(),
 1062  
                                                            e );
 1063  0
                 }
 1064  
 
 1065  0
                 if ( lifecycleOverlay == null )
 1066  
                 {
 1067  0
                     throw new LifecycleExecutionException( "Lifecycle '" + executeLifecycle + "' not found in plugin" );
 1068  
                 }
 1069  
 
 1070  0
                 for ( Iterator i = lifecycleOverlay.getPhases().iterator(); i.hasNext(); )
 1071  
                 {
 1072  0
                     Phase phase = (Phase) i.next();
 1073  0
                     for ( Iterator j = phase.getExecutions().iterator(); j.hasNext(); )
 1074  
                     {
 1075  0
                         Execution exec = (Execution) j.next();
 1076  
 
 1077  0
                         for ( Iterator k = exec.getGoals().iterator(); k.hasNext(); )
 1078  
                         {
 1079  0
                             String goal = (String) k.next();
 1080  
 
 1081  
                             PluginDescriptor lifecyclePluginDescriptor;
 1082  
                             String lifecycleGoal;
 1083  
 
 1084  
                             // Here we are looking to see if we have a mojo from an external plugin.
 1085  
                             // If we do then we need to lookup the plugin descriptor for the externally
 1086  
                             // referenced plugin so that we can overly the execution into the lifecycle.
 1087  
                             // An example of this is the corbertura plugin that needs to call the surefire
 1088  
                             // plugin in forking mode.
 1089  
                             //
 1090  
                             //<phase>
 1091  
                             //  <id>test</id>
 1092  
                             //  <executions>
 1093  
                             //    <execution>
 1094  
                             //      <goals>
 1095  
                             //        <goal>org.apache.maven.plugins:maven-surefire-plugin:test</goal>
 1096  
                             //      </goals>
 1097  
                             //      <configuration>
 1098  
                             //        <classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
 1099  
                             //        <ignoreFailures>true</ignoreFailures>
 1100  
                             //        <forkMode>once</forkMode>
 1101  
                             //      </configuration>
 1102  
                             //    </execution>
 1103  
                             //  </executions>
 1104  
                             //</phase>
 1105  
 
 1106  
                             // ----------------------------------------------------------------------
 1107  
                             //
 1108  
                             // ----------------------------------------------------------------------
 1109  
 
 1110  0
                             if ( goal.indexOf( ":" ) > 0 )
 1111  
                             {
 1112  0
                                 String[] s = StringUtils.split( goal, ":" );
 1113  
 
 1114  0
                                 String groupId = s[0];
 1115  0
                                 String artifactId = s[1];
 1116  0
                                 lifecycleGoal = s[2];
 1117  
 
 1118  0
                                 Plugin plugin = new Plugin();
 1119  0
                                 plugin.setGroupId( groupId );
 1120  0
                                 plugin.setArtifactId( artifactId );
 1121  0
                                 lifecyclePluginDescriptor = verifyPlugin( plugin, project, session.getSettings(),
 1122  
                                                                           session.getLocalRepository() );
 1123  0
                                 if ( lifecyclePluginDescriptor == null )
 1124  
                                 {
 1125  0
                                     throw new LifecycleExecutionException(
 1126  
                                         "Unable to find plugin " + groupId + ":" + artifactId );
 1127  
                                 }
 1128  0
                             }
 1129  
                             else
 1130  
                             {
 1131  0
                                 lifecyclePluginDescriptor = pluginDescriptor;
 1132  0
                                 lifecycleGoal = goal;
 1133  
                             }
 1134  
 
 1135  0
                             Xpp3Dom configuration = (Xpp3Dom) exec.getConfiguration();
 1136  
                             // NOTE: This seems to be duplicated below. Why??
 1137  0
                             if ( phase.getConfiguration() != null )
 1138  
                             {
 1139  0
                                 configuration = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ),
 1140  
                                                                       configuration );
 1141  
                             }
 1142  
 
 1143  0
                             MojoDescriptor desc = getMojoDescriptor( lifecyclePluginDescriptor, lifecycleGoal );
 1144  
                             MojoExecution mojoExecution;
 1145  0
                             if ( executionId.startsWith( MojoExecution.DEFAULT_EXEC_ID_PREFIX ) )
 1146  
                             {
 1147  0
                                 mojoExecution = new MojoExecution( desc, configuration );
 1148  
                             }
 1149  
                             else
 1150  
                             {
 1151  0
                                 mojoExecution = new MojoExecution( desc, configuration, executionId );
 1152  
                             }
 1153  
                             
 1154  0
                             addToLifecycleMappings( lifecycleMappings, phase.getId(), mojoExecution,
 1155  
                                                     session.getSettings() );
 1156  0
                         }
 1157  0
                     }
 1158  
 
 1159  0
                     if ( phase.getConfiguration() != null )
 1160  
                     {
 1161  
                         // Merge in general configuration for a phase.
 1162  
                         // TODO: this is all kind of backwards from the POMM. Let's align it all under 2.1.
 1163  
                         //   We should create a new lifecycle executor for modelVersion >5.0.0
 1164  0
                         for ( Iterator j = lifecycleMappings.values().iterator(); j.hasNext(); )
 1165  
                         {
 1166  0
                             List tasks = (List) j.next();
 1167  
 
 1168  0
                             for ( Iterator k = tasks.iterator(); k.hasNext(); )
 1169  
                             {
 1170  0
                                 MojoExecution exec = (MojoExecution) k.next();
 1171  
 
 1172  0
                                 Xpp3Dom configuration = Xpp3Dom.mergeXpp3Dom(
 1173  
                                     new Xpp3Dom( (Xpp3Dom) phase.getConfiguration() ), exec.getConfiguration() );
 1174  
 
 1175  0
                                 exec.setConfiguration( configuration );
 1176  0
                             }
 1177  0
                         }
 1178  
                     }
 1179  
 
 1180  0
                 }
 1181  
             }
 1182  
 
 1183  0
             removeFromLifecycle( forkEntryPoints, lifecycleMappings );
 1184  
         }
 1185  
 
 1186  0
         if ( targetPhase != null )
 1187  
         {
 1188  0
             Lifecycle lifecycle = getLifecycleForPhase( targetPhase );
 1189  
 
 1190  0
             executeGoalWithLifecycle( targetPhase, forkEntryPoints, session, lifecycleMappings, project, lifecycle );
 1191  0
         }
 1192  
         else
 1193  
         {
 1194  0
             String goal = mojoDescriptor.getExecuteGoal();
 1195  0
             MojoDescriptor desc = getMojoDescriptor( pluginDescriptor, goal );
 1196  0
             executeGoals( Collections.singletonList( new MojoExecution( desc, goal ) ), forkEntryPoints, session, project );
 1197  
         }
 1198  0
     }
 1199  
 
 1200  
     private Lifecycle getLifecycleForPhase( String phase )
 1201  
         throws BuildFailureException, LifecycleExecutionException
 1202  
     {
 1203  0
         Lifecycle lifecycle = (Lifecycle) getPhaseToLifecycleMap().get( phase );
 1204  
 
 1205  0
         if ( lifecycle == null )
 1206  
         {
 1207  0
             throw new BuildFailureException( "Unable to find lifecycle for phase '" + phase + "'" );
 1208  
         }
 1209  0
         return lifecycle;
 1210  
     }
 1211  
 
 1212  
     private MojoDescriptor getMojoDescriptor( PluginDescriptor pluginDescriptor, String goal )
 1213  
         throws LifecycleExecutionException
 1214  
     {
 1215  0
         MojoDescriptor desc = pluginDescriptor.getMojo( goal );
 1216  
 
 1217  0
         if ( desc == null )
 1218  
         {
 1219  0
             String message =
 1220  
                 "Required goal '" + goal + "' not found in plugin '" + pluginDescriptor.getGoalPrefix() + "'";
 1221  0
             int index = goal.indexOf( ':' );
 1222  0
             if ( index >= 0 )
 1223  
             {
 1224  0
                 String prefix = goal.substring( index + 1 );
 1225  0
                 if ( prefix.equals( pluginDescriptor.getGoalPrefix() ) )
 1226  
                 {
 1227  0
                     message = message + " (goals should not be prefixed - try '" + prefix + "')";
 1228  
                 }
 1229  
             }
 1230  0
             throw new LifecycleExecutionException( message );
 1231  
         }
 1232  0
         return desc;
 1233  
     }
 1234  
 
 1235  
     private void removeFromLifecycle( Stack lifecycleForkers, Map lifecycleMappings )
 1236  
     {
 1237  0
         for ( Iterator lifecycleIterator = lifecycleMappings.values().iterator(); lifecycleIterator.hasNext(); )
 1238  
         {
 1239  0
             List tasks = (List) lifecycleIterator.next();
 1240  
 
 1241  0
             for ( Iterator taskIterator = tasks.iterator(); taskIterator.hasNext(); )
 1242  
             {
 1243  0
                 MojoExecution execution = (MojoExecution) taskIterator.next();
 1244  
 
 1245  0
                 if ( lifecycleForkers.contains( execution.getMojoDescriptor() ) )
 1246  
                 {
 1247  0
                     taskIterator.remove();
 1248  0
                     getLogger().warn( "Removing: " + execution.getMojoDescriptor().getGoal()
 1249  
                                       + " from forked lifecycle, to prevent recursive invocation." );
 1250  
                 }
 1251  0
             }
 1252  0
         }
 1253  0
     }
 1254  
 
 1255  
     private Map constructLifecycleMappings( MavenSession session, String selectedPhase, MavenProject project,
 1256  
                                             Lifecycle lifecycle )
 1257  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1258  
     {
 1259  
         // first, bind those associated with the packaging
 1260  0
         Map lifecycleMappings = bindLifecycleForPackaging( session, selectedPhase, project, lifecycle );
 1261  
 
 1262  
         // next, loop over plugins and for any that have a phase, bind it
 1263  0
         for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1264  
         {
 1265  0
             Plugin plugin = (Plugin) i.next();
 1266  
 
 1267  0
             bindPluginToLifecycle( plugin, session, lifecycleMappings, project );
 1268  0
         }
 1269  
 
 1270  0
         return lifecycleMappings;
 1271  
     }
 1272  
 
 1273  
     private Map bindLifecycleForPackaging( MavenSession session, String selectedPhase, MavenProject project,
 1274  
                                            Lifecycle lifecycle )
 1275  
         throws LifecycleExecutionException, BuildFailureException, PluginNotFoundException
 1276  
     {
 1277  0
         Map mappings = findMappingsForLifecycle( session, project, lifecycle );
 1278  
 
 1279  0
         List optionalMojos = findOptionalMojosForLifecycle( session, project, lifecycle );
 1280  
 
 1281  0
         Map lifecycleMappings = new HashMap();
 1282  
 
 1283  0
         for ( Iterator i = lifecycle.getPhases().iterator(); i.hasNext(); )
 1284  
         {
 1285  0
             String phase = (String) i.next();
 1286  
 
 1287  0
             String phaseTasks = (String) mappings.get( phase );
 1288  
 
 1289  0
             if ( phaseTasks != null )
 1290  
             {
 1291  0
                 for ( StringTokenizer tok = new StringTokenizer( phaseTasks, "," ); tok.hasMoreTokens(); )
 1292  
                 {
 1293  0
                     String goal = tok.nextToken().trim();
 1294  
 
 1295  
                     // Not from the CLI, don't use prefix
 1296  0
                     MojoDescriptor mojoDescriptor = getMojoDescriptor( goal, session, project, selectedPhase, false,
 1297  
                                                                        optionalMojos.contains( goal ) );
 1298  
 
 1299  0
                     if ( mojoDescriptor == null )
 1300  
                     {
 1301  0
                         continue;
 1302  
                     }
 1303  
 
 1304  0
                     if ( mojoDescriptor.isDirectInvocationOnly() )
 1305  
                     {
 1306  0
                         throw new LifecycleExecutionException( "Mojo: \'" + goal +
 1307  
                             "\' requires direct invocation. It cannot be used as part of lifecycle: \'" +
 1308  
                             project.getPackaging() + "\'." );
 1309  
                     }
 1310  
 
 1311  0
                     addToLifecycleMappings( lifecycleMappings, phase, new MojoExecution( mojoDescriptor ),
 1312  
                                             session.getSettings() );
 1313  0
                 }
 1314  
             }
 1315  
 
 1316  0
             if ( phase.equals( selectedPhase ) )
 1317  
             {
 1318  0
                 break;
 1319  
             }
 1320  0
         }
 1321  
 
 1322  0
         return lifecycleMappings;
 1323  
     }
 1324  
 
 1325  
     private Map findMappingsForLifecycle( MavenSession session, MavenProject project, Lifecycle lifecycle )
 1326  
         throws LifecycleExecutionException, PluginNotFoundException
 1327  
     {
 1328  0
         String packaging = project.getPackaging();
 1329  0
         Map mappings = null;
 1330  
 
 1331  0
         LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging,
 1332  
                                                                session.getSettings(), session.getLocalRepository() );
 1333  0
         if ( m != null )
 1334  
         {
 1335  0
             mappings = m.getPhases( lifecycle.getId() );
 1336  
         }
 1337  
 
 1338  0
         Map defaultMappings = lifecycle.getDefaultPhases();
 1339  
 
 1340  0
         if ( mappings == null )
 1341  
         {
 1342  
             try
 1343  
             {
 1344  0
                 m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
 1345  0
                 mappings = m.getPhases( lifecycle.getId() );
 1346  
             }
 1347  0
             catch ( ComponentLookupException e )
 1348  
             {
 1349  0
                 if ( defaultMappings == null )
 1350  
                 {
 1351  0
                     throw new LifecycleExecutionException(
 1352  
                         "Cannot find lifecycle mapping for packaging: \'" + packaging + "\'.", e );
 1353  
                 }
 1354  0
             }
 1355  
         }
 1356  
 
 1357  0
         if ( mappings == null )
 1358  
         {
 1359  0
             if ( defaultMappings == null )
 1360  
             {
 1361  0
                 throw new LifecycleExecutionException(
 1362  
                     "Cannot find lifecycle mapping for packaging: \'" + packaging + "\', and there is no default" );
 1363  
             }
 1364  
             else
 1365  
             {
 1366  0
                 mappings = defaultMappings;
 1367  
             }
 1368  
         }
 1369  
 
 1370  0
         return mappings;
 1371  
     }
 1372  
 
 1373  
     private List findOptionalMojosForLifecycle( MavenSession session, MavenProject project, Lifecycle lifecycle )
 1374  
         throws LifecycleExecutionException, PluginNotFoundException
 1375  
     {
 1376  0
         String packaging = project.getPackaging();
 1377  0
         List optionalMojos = null;
 1378  
 
 1379  0
         LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session
 1380  
             .getSettings(), session.getLocalRepository() );
 1381  
 
 1382  0
         if ( m != null )
 1383  
         {
 1384  0
             optionalMojos = m.getOptionalMojos( lifecycle.getId() );
 1385  
         }
 1386  
 
 1387  0
         if ( optionalMojos == null )
 1388  
         {
 1389  
             try
 1390  
             {
 1391  0
                 m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
 1392  0
                 optionalMojos = m.getOptionalMojos( lifecycle.getId() );
 1393  
             }
 1394  0
             catch ( ComponentLookupException e )
 1395  
             {
 1396  0
                 getLogger().debug( "Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle ID: " +
 1397  
                     lifecycle.getId() + ". Error: " + e.getMessage(), e );
 1398  0
             }
 1399  
         }
 1400  
 
 1401  0
         if ( optionalMojos == null )
 1402  
         {
 1403  0
             optionalMojos = Collections.EMPTY_LIST;
 1404  
         }
 1405  
 
 1406  0
         return optionalMojos;
 1407  
     }
 1408  
 
 1409  
     private Object findExtension( MavenProject project, String role, String roleHint, Settings settings,
 1410  
                                   ArtifactRepository localRepository )
 1411  
         throws LifecycleExecutionException, PluginNotFoundException
 1412  
     {
 1413  0
         Object pluginComponent = null;
 1414  
 
 1415  0
         for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext() && pluginComponent == null; )
 1416  
         {
 1417  0
             Plugin plugin = (Plugin) i.next();
 1418  
 
 1419  0
             if ( plugin.isExtensions() )
 1420  
             {
 1421  0
                 verifyPlugin( plugin, project, settings, localRepository );
 1422  
 
 1423  
                 // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
 1424  
                 try
 1425  
                 {
 1426  0
                     pluginComponent = pluginManager.getPluginComponent( plugin, role, roleHint );
 1427  
                 }
 1428  0
                 catch ( ComponentLookupException e )
 1429  
                 {
 1430  0
                     getLogger().debug( "Unable to find the lifecycle component in the extension", e );
 1431  
                 }
 1432  0
                 catch ( PluginManagerException e )
 1433  
                 {
 1434  0
                     throw new LifecycleExecutionException(
 1435  
                         "Error getting extensions from the plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1436  0
                 }
 1437  
             }
 1438  0
         }
 1439  0
         return pluginComponent;
 1440  
     }
 1441  
 
 1442  
     /**
 1443  
      * @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
 1444  
      * lookup directly, or have them passed in
 1445  
      */
 1446  
     private Map findArtifactTypeHandlers( MavenProject project, Settings settings, ArtifactRepository localRepository )
 1447  
         throws LifecycleExecutionException, PluginNotFoundException
 1448  
     {
 1449  0
         Map map = new HashMap();
 1450  0
         for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1451  
         {
 1452  0
             Plugin plugin = (Plugin) i.next();
 1453  
 
 1454  0
             if ( plugin.isExtensions() )
 1455  
             {
 1456  0
                 verifyPlugin( plugin, project, settings, localRepository );
 1457  
 
 1458  
                 // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
 1459  
                 try
 1460  
                 {
 1461  0
                     Map components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
 1462  0
                     map.putAll( components );
 1463  
                 }
 1464  0
                 catch ( ComponentLookupException e )
 1465  
                 {
 1466  0
                     getLogger().debug( "Unable to find the lifecycle component in the extension", e );
 1467  
                 }
 1468  0
                 catch ( PluginManagerException e )
 1469  
                 {
 1470  0
                     throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
 1471  
                         plugin.getKey() + "': " + e.getMessage(), e );
 1472  0
                 }
 1473  
 
 1474  
                 // shudder...
 1475  0
                 for ( Iterator j = map.values().iterator(); j.hasNext(); )
 1476  
                 {
 1477  0
                     ArtifactHandler handler = (ArtifactHandler) j.next();
 1478  0
                     if ( project.getPackaging().equals( handler.getPackaging() ) )
 1479  
                     {
 1480  0
                         project.getArtifact().setArtifactHandler( handler );
 1481  
                     }
 1482  0
                 }
 1483  
             }
 1484  0
         }
 1485  0
         return map;
 1486  
     }
 1487  
 
 1488  
     /**
 1489  
      * Take each mojo contained with a plugin, look to see whether it contributes to a
 1490  
      * phase in the lifecycle and if it does place it at the end of the list of goals
 1491  
      * to execute for that given phase.
 1492  
      *
 1493  
      * @param project
 1494  
      * @param session
 1495  
      */
 1496  
     private void bindPluginToLifecycle( Plugin plugin, MavenSession session, Map phaseMap, MavenProject project )
 1497  
         throws LifecycleExecutionException, PluginNotFoundException
 1498  
     {
 1499  0
         Settings settings = session.getSettings();
 1500  
 
 1501  0
         PluginDescriptor pluginDescriptor =
 1502  
             verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
 1503  
 
 1504  0
         if ( pluginDescriptor.getMojos() != null && !pluginDescriptor.getMojos().isEmpty() )
 1505  
         {
 1506  
             // use the plugin if inherit was true in a base class, or it is in the current POM, otherwise use the default inheritence setting
 1507  0
             if ( plugin.isInheritanceApplied() || pluginDescriptor.isInheritedByDefault() )
 1508  
             {
 1509  0
                 if ( plugin.getGoals() != null )
 1510  
                 {
 1511  0
                     getLogger().error(
 1512  
                         "Plugin contains a <goals/> section: this is IGNORED - please use <executions/> instead." );
 1513  
                 }
 1514  
 
 1515  0
                 List executions = plugin.getExecutions();
 1516  
 
 1517  0
                 if ( executions != null )
 1518  
                 {
 1519  0
                     for ( Iterator it = executions.iterator(); it.hasNext(); )
 1520  
                     {
 1521  0
                         PluginExecution execution = (PluginExecution) it.next();
 1522  
 
 1523  0
                         bindExecutionToLifecycle( pluginDescriptor, phaseMap, execution, settings );
 1524  0
                     }
 1525  
                 }
 1526  
             }
 1527  
         }
 1528  0
     }
 1529  
 
 1530  
     private PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, Settings settings,
 1531  
                                            ArtifactRepository localRepository )
 1532  
         throws LifecycleExecutionException, PluginNotFoundException
 1533  
     {
 1534  
         PluginDescriptor pluginDescriptor;
 1535  
         try
 1536  
         {
 1537  
             // TODO: MNG-4081...need to flush this plugin once we look at it, to avoid using an external
 1538  
             // version of a plugin when a newer version will be created in the current reactor...
 1539  0
             pluginDescriptor = pluginManager.verifyPlugin( plugin, project, settings, localRepository );
 1540  
         }
 1541  0
         catch ( PluginManagerException e )
 1542  
         {
 1543  0
             throw new LifecycleExecutionException(
 1544  
                 "Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 1545  
         }
 1546  0
         catch ( PluginVersionResolutionException e )
 1547  
         {
 1548  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1549  
         }
 1550  0
         catch ( InvalidVersionSpecificationException e )
 1551  
         {
 1552  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1553  
         }
 1554  0
         catch ( InvalidPluginException e )
 1555  
         {
 1556  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1557  
         }
 1558  0
         catch ( ArtifactNotFoundException e )
 1559  
         {
 1560  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1561  
         }
 1562  0
         catch ( ArtifactResolutionException e )
 1563  
         {
 1564  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1565  
         }
 1566  0
         catch ( PluginVersionNotFoundException e )
 1567  
         {
 1568  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1569  0
         }
 1570  0
         return pluginDescriptor;
 1571  
     }
 1572  
 
 1573  
     private PluginDescriptor verifyReportPlugin( ReportPlugin plugin, MavenProject project, MavenSession session )
 1574  
         throws LifecycleExecutionException, PluginNotFoundException
 1575  
     {
 1576  
         PluginDescriptor pluginDescriptor;
 1577  
         try
 1578  
         {
 1579  0
             pluginDescriptor = pluginManager.verifyReportPlugin( plugin, project, session );
 1580  
         }
 1581  0
         catch ( PluginManagerException e )
 1582  
         {
 1583  0
             throw new LifecycleExecutionException(
 1584  
                 "Internal error in the plugin manager getting report '" + plugin.getKey() + "': " + e.getMessage(), e );
 1585  
         }
 1586  0
         catch ( PluginVersionResolutionException e )
 1587  
         {
 1588  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1589  
         }
 1590  0
         catch ( InvalidVersionSpecificationException e )
 1591  
         {
 1592  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1593  
         }
 1594  0
         catch ( InvalidPluginException e )
 1595  
         {
 1596  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1597  
         }
 1598  0
         catch ( ArtifactNotFoundException e )
 1599  
         {
 1600  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1601  
         }
 1602  0
         catch ( ArtifactResolutionException e )
 1603  
         {
 1604  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1605  
         }
 1606  0
         catch ( PluginVersionNotFoundException e )
 1607  
         {
 1608  0
             throw new LifecycleExecutionException( e.getMessage(), e );
 1609  0
         }
 1610  0
         return pluginDescriptor;
 1611  
     }
 1612  
 
 1613  
     private void bindExecutionToLifecycle( PluginDescriptor pluginDescriptor, Map phaseMap, PluginExecution execution,
 1614  
                                            Settings settings )
 1615  
         throws LifecycleExecutionException
 1616  
     {
 1617  0
         for ( Iterator i = execution.getGoals().iterator(); i.hasNext(); )
 1618  
         {
 1619  0
             String goal = (String) i.next();
 1620  
 
 1621  0
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
 1622  0
             if ( mojoDescriptor == null )
 1623  
             {
 1624  0
                 throw new LifecycleExecutionException(
 1625  
                     "'" + goal + "' was specified in an execution, but not found in the plugin" );
 1626  
             }
 1627  
 
 1628  
             // We have to check to see that the inheritance rules have been applied before binding this mojo.
 1629  0
             if ( execution.isInheritanceApplied() || mojoDescriptor.isInheritedByDefault() )
 1630  
             {
 1631  0
                 MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
 1632  
 
 1633  0
                 String phase = execution.getPhase();
 1634  
 
 1635  0
                 if ( phase == null )
 1636  
                 {
 1637  
                     // if the phase was not in the configuration, use the phase in the descriptor
 1638  0
                     phase = mojoDescriptor.getPhase();
 1639  
                 }
 1640  
 
 1641  0
                 if ( phase != null )
 1642  
                 {
 1643  0
                     if ( mojoDescriptor.isDirectInvocationOnly() )
 1644  
                     {
 1645  0
                         throw new LifecycleExecutionException( "Mojo: \'" + goal +
 1646  
                             "\' requires direct invocation. It cannot be used as part of the lifecycle (it was included via the POM)." );
 1647  
                     }
 1648  
 
 1649  0
                     addToLifecycleMappings( phaseMap, phase, mojoExecution, settings );
 1650  
                 }
 1651  
             }
 1652  0
         }
 1653  0
     }
 1654  
 
 1655  
     private void addToLifecycleMappings( Map lifecycleMappings, String phase, MojoExecution mojoExecution,
 1656  
                                          Settings settings )
 1657  
     {
 1658  0
         List goals = (List) lifecycleMappings.get( phase );
 1659  
 
 1660  0
         if ( goals == null )
 1661  
         {
 1662  0
             goals = new ArrayList();
 1663  0
             lifecycleMappings.put( phase, goals );
 1664  
         }
 1665  
 
 1666  0
         MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 1667  0
         if ( settings.isOffline() && mojoDescriptor.isOnlineRequired() )
 1668  
         {
 1669  0
             String goal = mojoDescriptor.getGoal();
 1670  0
             getLogger().warn( goal + " requires online mode, but maven is currently offline. Disabling " + goal + "." );
 1671  0
         }
 1672  
         else
 1673  
         {
 1674  0
             goals.add( mojoExecution );
 1675  
         }
 1676  0
     }
 1677  
 
 1678  
     private List processGoalChain( String task, Map phaseMap, Lifecycle lifecycle )
 1679  
     {
 1680  0
         List goals = new ArrayList();
 1681  
 
 1682  
         // only execute up to the given phase
 1683  0
         int index = lifecycle.getPhases().indexOf( task );
 1684  
 
 1685  0
         for ( int i = 0; i <= index; i++ )
 1686  
         {
 1687  0
             String p = (String) lifecycle.getPhases().get( i );
 1688  
 
 1689  0
             List phaseGoals = (List) phaseMap.get( p );
 1690  
 
 1691  0
             if ( phaseGoals != null )
 1692  
             {
 1693  0
                 goals.addAll( phaseGoals );
 1694  
             }
 1695  
         }
 1696  0
         return goals;
 1697  
     }
 1698  
 
 1699  
     private MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project,
 1700  
                                               String invokedVia, boolean canUsePrefix, boolean isOptionalMojo )
 1701  
         throws BuildFailureException, LifecycleExecutionException, PluginNotFoundException
 1702  
     {
 1703  
         String goal;
 1704  0
         Plugin plugin = null;
 1705  
 
 1706  0
         PluginDescriptor pluginDescriptor = null;
 1707  
 
 1708  
         try
 1709  
         {
 1710  0
             StringTokenizer tok = new StringTokenizer( task, ":" );
 1711  0
             int numTokens = tok.countTokens();
 1712  
 
 1713  0
             if ( numTokens == 2 )
 1714  
             {
 1715  0
                 if ( !canUsePrefix )
 1716  
                 {
 1717  0
                     String msg = "Mapped-prefix lookup of mojos are only supported from direct invocation. " +
 1718  
                         "Please use specification of the form groupId:artifactId[:version]:goal instead. " +
 1719  
                         "(Offending mojo: \'" + task + "\', invoked via: \'" + invokedVia + "\')";
 1720  0
                     throw new LifecycleExecutionException( msg );
 1721  
                 }
 1722  
 
 1723  0
                 String prefix = tok.nextToken();
 1724  0
                 goal = tok.nextToken();
 1725  
 
 1726  
                 // Steps for retrieving the plugin model instance:
 1727  
                 // 1. request directly from the plugin collector by prefix
 1728  0
                 pluginDescriptor = pluginManager.getPluginDescriptorForPrefix( prefix );
 1729  0
                 if ( pluginDescriptor != null )
 1730  
                 {
 1731  0
                     plugin = new Plugin();
 1732  0
                     plugin.setGroupId( pluginDescriptor.getGroupId() );
 1733  0
                     plugin.setArtifactId( pluginDescriptor.getArtifactId() );
 1734  0
                     plugin.setVersion( pluginDescriptor.getVersion() );
 1735  
                 }
 1736  
 
 1737  
                 // 2. search plugins in the current POM
 1738  0
                 if ( plugin == null )
 1739  
                 {
 1740  0
                     for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1741  
                     {
 1742  0
                         Plugin buildPlugin = (Plugin) i.next();
 1743  
 
 1744  0
                         PluginDescriptor desc =
 1745  
                             verifyPlugin( buildPlugin, project, session.getSettings(), session.getLocalRepository() );
 1746  0
                         if ( prefix.equals( desc.getGoalPrefix() ) )
 1747  
                         {
 1748  0
                             plugin = buildPlugin;
 1749  0
                             pluginDescriptor = desc;
 1750  0
                             break;
 1751  
                         }
 1752  0
                     }
 1753  
                 }
 1754  
 
 1755  
                 // 3. look in the repository via search groups
 1756  0
                 if ( plugin == null )
 1757  
                 {
 1758  0
                     plugin = pluginManager.getPluginDefinitionForPrefix( prefix, session, project );
 1759  
                 }
 1760  
 
 1761  
                 // 4. default to o.a.m.plugins and maven-<prefix>-plugin
 1762  0
                 if ( plugin == null )
 1763  
                 {
 1764  0
                     plugin = new Plugin();
 1765  0
                     plugin.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
 1766  0
                     plugin.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( prefix ) );
 1767  
                 }
 1768  0
             }
 1769  0
             else if ( numTokens == 3 || numTokens == 4 )
 1770  
             {
 1771  0
                 plugin = new Plugin();
 1772  
 
 1773  0
                 plugin.setGroupId( tok.nextToken() );
 1774  0
                 plugin.setArtifactId( tok.nextToken() );
 1775  
 
 1776  0
                 if ( numTokens == 4 )
 1777  
                 {
 1778  0
                     plugin.setVersion( tok.nextToken() );
 1779  
                 }
 1780  
 
 1781  0
                 goal = tok.nextToken();
 1782  
             }
 1783  
             else
 1784  
             {
 1785  0
                 String message = "Invalid task '" + task + "': you must specify a valid lifecycle phase, or" +
 1786  
                     " a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal";
 1787  0
                 throw new BuildFailureException( message );
 1788  
             }
 1789  
 
 1790  0
             if ( plugin.getVersion() == null )
 1791  
             {
 1792  0
                 for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
 1793  
                 {
 1794  0
                     Plugin buildPlugin = (Plugin) i.next();
 1795  
 
 1796  0
                     if ( buildPlugin.getKey().equals( plugin.getKey() ) )
 1797  
                     {
 1798  0
                         plugin = buildPlugin;
 1799  0
                         break;
 1800  
                     }
 1801  0
                 }
 1802  
 
 1803  0
                 project.injectPluginManagementInfo( plugin );
 1804  
             }
 1805  
 
 1806  0
             if ( pluginDescriptor == null )
 1807  
             {
 1808  0
                 pluginDescriptor = verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
 1809  
             }
 1810  
 
 1811  
             // this has been simplified from the old code that injected the plugin management stuff, since
 1812  
             // pluginManagement injection is now handled by the project method.
 1813  0
             project.addPlugin( plugin );
 1814  
 
 1815  0
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
 1816  0
             if ( mojoDescriptor == null )
 1817  
             {
 1818  0
                 if ( isOptionalMojo )
 1819  
                 {
 1820  0
                     getLogger().info( "Skipping missing optional mojo: " + task );
 1821  
                 }
 1822  
                 else
 1823  
                 {
 1824  0
                     throw new BuildFailureException( "Required goal not found: " + task + " in "
 1825  
                         + pluginDescriptor.getId() );
 1826  
                 }
 1827  
             }
 1828  
 
 1829  0
             return mojoDescriptor;
 1830  
         }
 1831  0
         catch ( PluginNotFoundException e )
 1832  
         {
 1833  0
             if ( isOptionalMojo )
 1834  
             {
 1835  0
                 getLogger().info( "Skipping missing optional mojo: " + task );
 1836  0
                 getLogger().debug( "Mojo: " + task + " could not be found. Reason: " + e.getMessage(), e );
 1837  
             }
 1838  
             else
 1839  
             {
 1840  0
                 throw e;
 1841  
             }
 1842  
         }
 1843  
 
 1844  0
         return null;
 1845  
     }
 1846  
 
 1847  
     protected void line()
 1848  
     {
 1849  0
         getLogger().info( "------------------------------------------------------------------------" );
 1850  0
     }
 1851  
 
 1852  
     public Map getPhaseToLifecycleMap()
 1853  
         throws LifecycleExecutionException
 1854  
     {
 1855  0
         if ( phaseToLifecycleMap == null )
 1856  
         {
 1857  0
             phaseToLifecycleMap = new HashMap();
 1858  
 
 1859  0
             for ( Iterator i = lifecycles.iterator(); i.hasNext(); )
 1860  
             {
 1861  0
                 Lifecycle lifecycle = (Lifecycle) i.next();
 1862  
 
 1863  0
                 for ( Iterator p = lifecycle.getPhases().iterator(); p.hasNext(); )
 1864  
                 {
 1865  0
                     String phase = (String) p.next();
 1866  
 
 1867  0
                     if ( phaseToLifecycleMap.containsKey( phase ) )
 1868  
                     {
 1869  0
                         Lifecycle prevLifecycle = (Lifecycle) phaseToLifecycleMap.get( phase );
 1870  0
                         throw new LifecycleExecutionException( "Phase '" + phase +
 1871  
                             "' is defined in more than one lifecycle: '" + lifecycle.getId() + "' and '" +
 1872  
                             prevLifecycle.getId() + "'" );
 1873  
                     }
 1874  
                     else
 1875  
                     {
 1876  0
                         phaseToLifecycleMap.put( phase, lifecycle );
 1877  
                     }
 1878  0
                 }
 1879  0
             }
 1880  
         }
 1881  0
         return phaseToLifecycleMap;
 1882  
     }
 1883  
 
 1884  0
     private static class TaskSegment
 1885  
     {
 1886  
         private boolean aggregate;
 1887  
 
 1888  0
         private List tasks = new ArrayList();
 1889  
 
 1890  
         TaskSegment()
 1891  0
         {
 1892  
 
 1893  0
         }
 1894  
 
 1895  
         TaskSegment( boolean aggregate )
 1896  0
         {
 1897  0
             this.aggregate = aggregate;
 1898  0
         }
 1899  
 
 1900  
         public String toString()
 1901  
         {
 1902  0
             StringBuffer message = new StringBuffer();
 1903  
 
 1904  0
             message.append( " task-segment: [" );
 1905  
 
 1906  0
             for ( Iterator it = tasks.iterator(); it.hasNext(); )
 1907  
             {
 1908  0
                 String task = (String) it.next();
 1909  
 
 1910  0
                 message.append( task );
 1911  
 
 1912  0
                 if ( it.hasNext() )
 1913  
                 {
 1914  0
                     message.append( ", " );
 1915  
                 }
 1916  0
             }
 1917  
 
 1918  0
             message.append( "]" );
 1919  
 
 1920  0
             if ( aggregate )
 1921  
             {
 1922  0
                 message.append( " (aggregator-style)" );
 1923  
             }
 1924  
 
 1925  0
             return message.toString();
 1926  
         }
 1927  
 
 1928  
         boolean aggregate()
 1929  
         {
 1930  0
             return aggregate;
 1931  
         }
 1932  
 
 1933  
         void add( String task )
 1934  
         {
 1935  0
             tasks.add( task );
 1936  0
         }
 1937  
 
 1938  
         List getTasks()
 1939  
         {
 1940  0
             return tasks;
 1941  
         }
 1942  
     }
 1943  
     
 1944  
     public List getLifecycles()
 1945  
     {
 1946  0
         return lifecycles;
 1947  
     }
 1948  
 
 1949  
     // -------------------------------------------------------------------------
 1950  
     // TODO: The methods and fields below are only needed for products like Hudson,
 1951  
     // that provide their own LifecycleExecutor and component configuration that extend
 1952  
     // default implementation, and which may become out-of-date as component requirements
 1953  
     // are updated within Maven itself.
 1954  
     public void initialize()
 1955  
         throws InitializationException
 1956  
     {
 1957  0
         if ( mavenProjectBuilder == null )
 1958  
         {
 1959  0
             warnOfIncompleteComponentConfiguration( MavenProjectBuilder.ROLE );
 1960  
             try
 1961  
             {
 1962  0
                 mavenProjectBuilder = (MavenProjectBuilder) container.lookup( MavenProjectBuilder.ROLE );
 1963  
             }
 1964  0
             catch ( ComponentLookupException e )
 1965  
             {
 1966  0
                 throw new InitializationException( "Failed to lookup project builder after it was NOT injected via component requirement." );
 1967  0
             }
 1968  
         }
 1969  
         
 1970  0
         if ( modelInterpolator == null )
 1971  
         {
 1972  0
             warnOfIncompleteComponentConfiguration( ModelInterpolator.ROLE );
 1973  
             try
 1974  
             {
 1975  0
                 modelInterpolator = (ModelInterpolator) container.lookup( ModelInterpolator.ROLE );
 1976  
             }
 1977  0
             catch ( ComponentLookupException e )
 1978  
             {
 1979  0
                 throw new InitializationException( "Failed to lookup model interpolator after it was NOT injected via component requirement." );
 1980  0
             }
 1981  
         }
 1982  
         
 1983  0
         if ( configInterpolator == null )
 1984  
         {
 1985  0
             warnOfIncompleteComponentConfiguration( ConfigurationInterpolator.ROLE );
 1986  
             try
 1987  
             {
 1988  0
                 configInterpolator = (ConfigurationInterpolator) container.lookup( ConfigurationInterpolator.ROLE );
 1989  
             }
 1990  0
             catch ( ComponentLookupException e )
 1991  
             {
 1992  0
                 throw new InitializationException( "Failed to lookup plugin-configuration interpolator after it was NOT injected via component requirement." );
 1993  0
             }
 1994  
         }
 1995  0
     }
 1996  
     
 1997  
     private void warnOfIncompleteComponentConfiguration( String role )
 1998  
     {
 1999  0
         StringBuffer buffer = new StringBuffer();
 2000  0
         buffer.append( "\n************ WARNING ************" );
 2001  0
         buffer.append( "\n\nThis Maven runtime contains a LifecycleExecutor component with an incomplete configuration." );
 2002  0
         buffer.append( "\n\nLifecycleExecutor class: " ).append( getClass().getName() );
 2003  0
         buffer.append( "\nMissing component requirement: " ).append( role );
 2004  0
         buffer.append( "\n" );
 2005  0
         buffer.append( "\nNOTE: This seems to be a third-party Maven derivative you are using. If so, please" );
 2006  0
         buffer.append( "\nnotify the developers for this derivative project of the problem. The Apache Maven team is not" );
 2007  0
         buffer.append( "\nresponsible for maintaining the integrity of third-party component overrides." );
 2008  0
         buffer.append( "\n\n" );
 2009  
         
 2010  0
         getLogger().warn( buffer.toString() );
 2011  0
     }
 2012  
 
 2013  
     private PlexusContainer container;
 2014  
 
 2015  
     public void contextualize( Context context )
 2016  
         throws ContextException
 2017  
     {
 2018  0
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 2019  0
     }
 2020  
 }