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